UNPKG

@nex-ui/system

Version:

A lightweight and performant styling library based on Emotion, focusing on component architecture and developer experience.

173 lines (167 loc) 5.14 kB
'use strict'; var utils = require('@nex-ui/utils'); var serialize = require('@x1ngyu/serialize-javascript'); var knownCssProperties = require('known-css-properties'); function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; } var serialize__default = /*#__PURE__*/_interopDefault(serialize); function pathToTokenName(path) { return path.join('.'); } function isDecimalString(str) { return /^\d+\.\d+$/.test(str); } function createCssVarName(prefix, path) { return `--${prefix}-${path.map((k)=>{ if (isDecimalString(k)) { return k.split('.').join('-'); } return utils.kebabCase(k); }).join('-')}`; } function isResponsiveColor(value) { return utils.isPlainObject(value) && (value._light || value._dark || value._DEFAULT); } function isValidTokenValue(value) { if (!utils.isString(value) && typeof value !== 'number') { return false; } return true; } function isValidSemanticTokenValue(value) { if (!utils.isString(value) && typeof value !== 'number' && !isResponsiveColor(value)) { return false; } return true; } function isValidTokenCategory(category) { if (!utils.isString(category)) { return false; } switch(category){ case 'colors': case 'fontFamilies': case 'fontSizes': case 'fontWeights': case 'sizes': case 'spaces': case 'lineHeights': case 'borders': case 'radii': case 'breakpoints': case 'shadows': case 'transitions': case 'borderWidths': case 'zIndices': return true; default: return false; } } function isValidAliasValue(value) { if (utils.isString(value) || Array.isArray(value) && value.every(utils.isString)) { return true; } return false; } function isValidBreakpointValue(value) { if (utils.isString(value) && parseInt(value, 10) >= 0) { return true; } return false; } function memoizeFn(fn) { return utils.memoize(fn, (...args)=>serialize__default.default(args)); } function extractTokenPlaceholders(value) { const regex = /\{(.*?)\}/g; const matches = value.matchAll(regex); return [ ...matches ]; } // TODO 明确 CSS 合并规则 function mergeRecipeConfigs(...args) { const recipes = JSON.parse(JSON.stringify(args)); return utils.mergeWith({}, ...recipes, (targetValue, srcValue, key)=>{ if (key === 'compoundVariants') { if (targetValue === undefined) { return srcValue; } if (Array.isArray(targetValue) && Array.isArray(srcValue)) { return [ ...targetValue, ...srcValue ]; } } if (typeof targetValue !== typeof srcValue || Array.isArray(targetValue) !== Array.isArray(srcValue) || utils.isPlainObject(targetValue) !== utils.isPlainObject(srcValue)) { return srcValue; } }); } const toExpression = (operator, ...operands)=>operands.map(String).join(` ${operator} `).replace(/calc/g, ''); const multiply = (...operands)=>`calc(${toExpression('*', ...operands)})`; const negate = (x)=>{ const value = String(x); if (value != null && !Number.isNaN(parseFloat(value))) { if (Number(value) === 0) { return '0'; } return value.startsWith('-') ? value.slice(1) : `-${value}`; } return multiply(value, -1); }; const ALL_CSS_PROPERTIES = new Set(knownCssProperties.all.map(utils.camelCase)); const isCSSProperty = (key)=>{ // CSS variable if (key.startsWith('--')) return true; return ALL_CSS_PROPERTIES.has(key); }; const isSelector = (key)=>{ // start with & if (/&/.test(key)) { return true; } // combinators if (/^(?!.*@)(?!.*\()(\s*[>+~]\s*|[a-zA-Z]\s+[a-zA-Z])/.test(key)) { return true; } // special rules if (/^@(media|keyframes|supports|import|namespace|layer)/.test(key)) { return true; } // id or class selector if (/^[#.]/.test(key)) { return true; } // attribute selector if (/\[[^\]]*[=~|^$*]?[^\]]*\]/.test(key)) { return true; } // multiple selectors if (/,/.test(key)) { return true; } // wildcard selector if (/\*/.test(key)) { return true; } if (isCSSProperty(key)) { return false; } return true; }; exports.createCssVarName = createCssVarName; exports.extractTokenPlaceholders = extractTokenPlaceholders; exports.isResponsiveColor = isResponsiveColor; exports.isSelector = isSelector; exports.isValidAliasValue = isValidAliasValue; exports.isValidBreakpointValue = isValidBreakpointValue; exports.isValidSemanticTokenValue = isValidSemanticTokenValue; exports.isValidTokenCategory = isValidTokenCategory; exports.isValidTokenValue = isValidTokenValue; exports.memoizeFn = memoizeFn; exports.mergeRecipeConfigs = mergeRecipeConfigs; exports.multiply = multiply; exports.negate = negate; exports.pathToTokenName = pathToTokenName;