@dnb/eufemia
Version:
DNB Eufemia Design System UI Library
266 lines • 8.45 kB
JavaScript
import _pushInstanceProperty from "core-js-pure/stable/instance/push.js";
import { warn } from "../../shared/component-helper.js";
export const spacingDefaultProps = {
space: null,
innerSpace: null,
top: null,
right: null,
bottom: null,
left: null
};
export const spacePatterns = {
'xx-small': 0.25,
'x-small': 0.5,
small: 1,
medium: 1.5,
large: 2,
'x-large': 3,
'xx-large': 3.5,
'xx-large-x2': 7
};
globalThis.CALC_CACHE = {};
export const calc = (...types) => {
const hash = types.join('|');
if (globalThis.CALC_CACHE[hash]) {
return globalThis.CALC_CACHE[hash];
}
const result = [];
types.forEach(rawTypes => {
createTypeModifiers(rawTypes).forEach(type => {
_pushInstanceProperty(result).call(result, `var(--spacing-${type})`);
});
});
return result.length ? globalThis.CALC_CACHE[hash] = `calc(${result.join(' + ')})` : null;
};
export const createSpacingProperties = props => {
if (props !== null && props !== void 0 && props.innerSpace) {
return computeProperties(props.innerSpace);
}
return {};
};
function hasMediaSize(media) {
const keys = Object.keys(media);
return keys.includes('small') || keys.includes('medium') || keys.includes('large');
}
function hasSize(space) {
const keys = Object.keys(space);
return keys.includes('top') || keys.includes('right') || keys.includes('bottom') || keys.includes('left') || keys.includes('inline') || keys.includes('block');
}
function computeProperties(space) {
if (!hasMediaSize(space)) {
space = {
small: space,
medium: space,
large: space
};
}
const result = {};
for (const size in space) {
var _space;
const value = (_space = space) === null || _space === void 0 ? void 0 : _space[size];
const props = transformToAll(value);
for (const key in props) {
if (isValidInnerSpaceProp(key)) {
const cur = props[key];
const name = `--space-${key[0]}-${size[0]}`;
if (String(cur) === '0' || String(cur) === 'false') {
result[name] = '0';
} else if (cur) {
const typeModifiers = createTypeModifiers(cur);
const sum = sumTypes(typeModifiers);
result[name] = `${sum}rem`;
}
}
}
}
return result;
}
function transformToAll(value) {
let result = value;
if (!hasSize(value)) {
result = {
top: value,
right: value,
bottom: value,
left: value
};
}
return expandInnerSpaceShorthand(result);
}
function expandInnerSpaceShorthand(space) {
const result = {
...space
};
if (typeof result.inline !== 'undefined') {
var _result$left, _result$right;
result.left = (_result$left = result.left) !== null && _result$left !== void 0 ? _result$left : result.inline;
result.right = (_result$right = result.right) !== null && _result$right !== void 0 ? _result$right : result.inline;
}
if (typeof result.block !== 'undefined') {
var _result$top, _result$bottom;
result.top = (_result$top = result.top) !== null && _result$top !== void 0 ? _result$top : result.block;
result.bottom = (_result$bottom = result.bottom) !== null && _result$bottom !== void 0 ? _result$bottom : result.block;
}
return result;
}
function isValidInnerSpaceProp(propName) {
return ['top', 'right', 'bottom', 'left'].includes(propName);
}
export const createSpacingClasses = (props, elementName = null) => {
const p = Object.isFrozen(props) ? {
...props
} : props;
if (typeof p.space !== 'undefined') {
if (typeof p.space === 'string' || typeof p.space === 'number' || typeof p.space === 'boolean' && p.space) {
var _p$left, _p$bottom, _p$right, _p$top;
p.left = (_p$left = p.left) !== null && _p$left !== void 0 ? _p$left : p.space;
p.bottom = (_p$bottom = p.bottom) !== null && _p$bottom !== void 0 ? _p$bottom : p.space;
p.right = (_p$right = p.right) !== null && _p$right !== void 0 ? _p$right : p.space;
p.top = (_p$top = p.top) !== null && _p$top !== void 0 ? _p$top : p.space;
}
if (typeof p.space === 'object') {
for (const i in p.space) {
if (!p[i] && isValidSpaceProp(i)) {
p[i] = p.space[i];
}
}
}
delete p.space;
}
return Object.entries(p).reduce((acc, [direction, cur]) => {
if (isValidSpaceProp(direction) && direction !== 'innerSpace') {
if (String(cur) === '0' || String(cur) === 'false') {
_pushInstanceProperty(acc).call(acc, `dnb-space__${direction}--zero`);
} else if (cur) {
const typeModifiers = createTypeModifiers(cur);
const sum = sumTypes(typeModifiers);
if (sum > 10) {
warn(`Spacing of more than 10rem is not supported! You used ${sum} / (${typeModifiers.join(',')})`);
} else {
const nearestTypes = findNearestTypes(sum, true);
acc = [...acc, ...nearestTypes.map(type => `dnb-space__${direction}--${type}`)];
}
}
} else if (direction === 'no_collapse') {
_pushInstanceProperty(acc).call(acc, 'dnb-space--no-collapse');
if (elementName && isInline(elementName)) {
_pushInstanceProperty(acc).call(acc, 'dnb-space--inline');
}
}
return acc;
}, []);
};
export const translateSpace = type => {
if (/-x2$/.test(String(type))) {
return spacePatterns[String(type).replace(/-x2$/, '')] * 2;
}
return spacePatterns[String(type)] || 0;
};
export const splitTypes = types => {
if (typeof types === 'string') {
const test = types.split(/ /g);
return clean(test);
} else if (typeof types === 'boolean') {
return [types ? 'small' : 0];
} else if (typeof types === 'number') {
return [types];
}
return clean(types) || null;
function clean(t) {
return t === null || t === void 0 ? void 0 : t.filter(r => r && String(r).length > 0);
}
};
export const sumTypes = types => splitTypes(types).map(type => translateSpace(type)).reduce((acc, cur) => {
if (cur > 0) {
acc += cur;
} else if (cur < 0) {
acc -= cur;
}
return acc;
}, 0);
export const createTypeModifiers = types => {
return (splitTypes(types) || []).reduce((acc, type) => {
if (type) {
const firstLetter = String(type)[0];
if (parseFloat(firstLetter) > -1) {
let num = parseFloat(String(type));
if (num >= 8 && /[0-9]px/.test(String(type))) {
num = num / 16;
}
const foundType = findType(num);
if (foundType) {
type = foundType;
} else {
findNearestTypes(num).forEach(type => {
if (type) {
_pushInstanceProperty(acc).call(acc, type);
}
});
}
}
if (!(parseFloat(String(type)) > 0)) {
_pushInstanceProperty(acc).call(acc, type);
}
}
return acc;
}, []);
};
export const findType = num => {
const found = findTypeAll(num);
if (found) {
return found[0];
}
return null;
};
export const findTypeAll = num => {
const listOfSpacePatterns = Object.entries(spacePatterns);
const found = listOfSpacePatterns.find(([k, v]) => k && v === num) || null;
return found;
};
export const findNearestTypes = (num, multiply = false) => {
let res = [];
const near = Object.entries(spacePatterns).reverse().filter(k => multiply ? true : !k[0].includes('-x')).find(([k, v]) => k && num >= v);
const nearNum = near && near[1] || num;
const types = findTypeAll(nearNum);
if (types) {
const nearType = types[0];
_pushInstanceProperty(res).call(res, nearType);
const leftOver = num - parseFloat(String(types[1]));
const foundMoreTypes = findNearestTypes(leftOver, multiply);
foundMoreTypes.forEach(type => {
const index = res.indexOf(type);
if (index !== -1) {
res[index] = multiply ? `${type}-x2` : type;
}
});
res = [...res, ...foundMoreTypes];
}
return res;
};
export const isValidSpaceProp = propName => propName && ['top', 'right', 'bottom', 'left', 'space', 'innerSpace'].includes(propName);
export const removeSpaceProps = props => {
const {
space,
innerSpace,
top,
bottom,
left,
right,
...restProps
} = props;
return restProps;
};
export const isInline = elementName => {
switch (elementName) {
case 'h1':
case 'h2':
case 'h3':
case 'h4':
case 'h5':
case 'h6':
case 'p':
return true;
}
return false;
};
//# sourceMappingURL=SpacingUtils.js.map