UNPKG

zss-engine

Version:
118 lines (117 loc) 5.87 kB
import { camelToKebabCase, applyCssValue } from './helper.js'; const createKeyframes = (property, content) => { let keyframesRules = `${property} {\n`; for (const key in content) { if (Object.prototype.hasOwnProperty.call(content, key)) { const keyframeValue = content[key]; keyframesRules += ` ${key} {\n`; for (const prop in keyframeValue) { if (Object.prototype.hasOwnProperty.call(keyframeValue, prop)) { const CSSProp = camelToKebabCase(prop); const value = keyframeValue[prop]; if (typeof value === 'string' || typeof value === 'number') { const applyValue = applyCssValue(value, CSSProp); keyframesRules += ` ${CSSProp}: ${applyValue};\n`; } } } keyframesRules += ` }\n`; } } keyframesRules += `}\n`; return keyframesRules; }; export function transpile(object, base36Hash, core) { let styleSheet = ''; const mediaQueries = []; const classNameApply = (property) => { return core === '--global' ? property : `.${base36Hash}`; }; const rules = (indent, rulesValue, property) => { const value = rulesValue[property]; const cssProp = camelToKebabCase(property); return `${indent}${cssProp}: ${value};\n`; }; const stringConverter = (className, properties, indentLevel) => { const classSelector = {}; const indent = ''.repeat(indentLevel); const innerIndent = ' '.repeat(indentLevel + 1); let cssRule = ''; for (const property in properties) { if (Object.prototype.hasOwnProperty.call(properties, property)) { const value = properties[property]; if (typeof value === 'string' || typeof value === 'number') { let CSSProp = camelToKebabCase(property); const applyValue = applyCssValue(value, CSSProp); cssRule += ` ${CSSProp}: ${applyValue};\n`; } else if (!property.startsWith('@')) { const kebabPseudoSelector = camelToKebabCase(property.replace('&', '')); const styles = stringConverter(className + kebabPseudoSelector, value, indentLevel); Object.assign(classSelector, styles); } else if (property.startsWith('@media') || property.startsWith('@container')) { const mediaRule = property; let nestedRules = ''; let regularRules = ''; for (const mediaProp in value) { if (Object.prototype.hasOwnProperty.call(value, mediaProp)) { const mediaValue = value[mediaProp]; const isColon = mediaProp.startsWith(':'); const isAnd = mediaProp.startsWith('&'); if (isColon || isAnd) { const kebabMediaProp = camelToKebabCase(mediaProp.replace('&', '')); let pseudoClassRule = ''; if (typeof mediaValue === 'object' && mediaValue !== null) { for (const pseudoProp in mediaValue) { if (Object.prototype.hasOwnProperty.call(mediaValue, pseudoProp)) { const CSSProp = camelToKebabCase(pseudoProp); const applyValue = applyCssValue(mediaValue[pseudoProp], CSSProp); pseudoClassRule += rules(innerIndent + ' ', { [pseudoProp]: applyValue }, pseudoProp); } } } nestedRules += `${innerIndent}${className}${kebabMediaProp} {\n${pseudoClassRule}${innerIndent}}\n`; } else { const CSSProp = camelToKebabCase(mediaProp); const applyValue = applyCssValue(mediaValue, CSSProp); regularRules += rules(innerIndent + ' ', { [mediaProp]: applyValue }, mediaProp); } } } if (regularRules) { mediaQueries.push({ media: mediaRule, css: `${mediaRule} {\n${innerIndent}${className} {\n${regularRules} }\n${nestedRules}${indent}}${indent}\n`, }); } else { mediaQueries.push({ media: mediaRule, css: `${mediaRule} {\n${nestedRules}${indent}}\n`, }); } } } } classSelector[className] = cssRule; return classSelector; }; for (const property in object) { if (property.startsWith('@keyframes')) { const keyframesContent = object[property]; styleSheet += createKeyframes(property, keyframesContent); } const classSelectors = stringConverter(classNameApply(property), object[property], 1); for (const selector in classSelectors) { if (!selector.startsWith('@keyframes') && classSelectors[selector]) { styleSheet += selector + ' {\n' + classSelectors[selector] + '}\n'; } } } mediaQueries.forEach(({ css }) => { styleSheet += css; }); return { styleSheet }; }