Current Path : /var/www/www-root/data/www/www.monolith-realty.ru/bitrix/js/ui/design-tokens/src/ |
Current File : /var/www/www-root/data/www/www.monolith-realty.ru/bitrix/js/ui/design-tokens/src/config.js |
const fs = require('fs'); const StyleDictionary = require('style-dictionary'); const { fileHeader, sortByReference, createPropertyFormatter } = StyleDictionary.formatHelpers; const Color = require('tinycolor2'); const fontWeights = { 100: 'Thin', 200: 'Extra Light', 300: 'Light', 400: 'Regular', 500: 'Medium', 600: 'Semi Bold', 700: 'Bold', 800: 'Extra Bold', 900: 'Black', 950: 'Extra Black', }; module.exports = { source: ['*.json'], transform: { 'css/shadow': { type: 'value', matcher: (prop) => { return prop.attributes.category === 'shadow'; }, transformer: (prop) => { const { x, y, blur, spread, color, alpha } = prop.original.value; //const shadowColor = tinycolor(color); //shadowColor.setAlpha(alpha); //shadowColor.toRgbString(); return `${x}px ${y}px ${blur}px ${spread}px ${color}` }, }, 'rgb-color-value': { type: 'value', matcher: (prop) => { return prop.attributes.category === 'color'; }, transformer: (token) => { if (token.value === 'none' || token.value === 'transparent') { return token.value; } const color = Color(token.value); if (color.getAlpha() === 1) { return color.toHexString(); } else { return color.toRgbString(); } }, }, 'figma/font-weight': { type: 'value', matcher: (prop) => { return prop.attributes.category === 'font' && prop.attributes.type === 'weight'; }, transformer: (token) => { return fontWeights[token.value]; }, }, 'figma/letter-spacing': { type: 'value', matcher: (prop) => { return prop.attributes.category === 'text' && prop.attributes.type === 'letter-spacing'; }, transformer: (token) => { const value = parseFloat(token.value); if (isNaN(value)) { return token.value; } return (value * 100) + '%'; }, }, 'figma/line-height': { type: 'value', matcher: (prop) => { return prop.attributes.category === 'font' && prop.attributes.type === 'line-height'; }, transformer: (token) => { const value = parseFloat(token.value); if (isNaN(value)) { return token.value; } return (value * 100) + '%'; }, }, }, transformGroup: { 'css-design-tokens': [ 'attribute/cti', 'name/cti/kebab', 'time/seconds', 'content/icon', 'css/shadow', 'rgb-color-value', ], 'figma-design-tokens': [ 'attribute/cti', 'name/cti/kebab', 'rgb-color-value', 'figma/line-height', 'figma/font-weight', 'figma/letter-spacing', ], }, format: { cssFormat: ({dictionary, file, options={}}) => { const selector = options.selector ? options.selector : `:root`; const { outputReferences } = options; const formatProperty = createPropertyFormatter({ outputReferences, dictionary, format: 'css', /*formatting: { prefix: '--', commentStyle: 'long', indentation: '\t', separator: ':', suffix: ';', }*/ }); const formatColor = (token) => { const prop = formatProperty(token); if (token.value === 'transparent' || token.value === 'none') { return `${prop}\n`; } let propRgb = prop .replace(/(--[^:]+):/, '$1-rgb:') .replace(/:(\s*var\([^)]+)/, ':$1-rgb') ; if (!/var\(/.test(prop)) { const color = Color(token.value); if (color.isValid() && color.getAlpha() === 1) { propRgb = propRgb.replace(token.value, `${color._r}, ${color._g}, ${color._b}`); } else { propRgb = ''; } } return `${prop}\n${propRgb === '' ? '' : propRgb + '\n' }`; }; // Variables let result = `${fileHeader({file})}${selector} {\n`; dictionary.allTokens.sort(sortByReference(dictionary)).forEach(token => { if (token.attributes.category === 'color') { result += formatColor(token); } else { const prop = formatProperty(token); result += `${prop}\n`; } }); result +=`}\n\n`; // Typography const typography = dictionary.tokens.typography; Object.keys(typography).forEach(category => { Object.keys(typography[category]).forEach((item) => { const props = typography[category][item]; result += `.ui-typography-${category}-${item} {\n`; Object.keys(props).forEach(prop => { const propData = props[prop]; result += `\t${prop}: var(--${propData.name});\n`; }); result += `}\n\n`; }); }); return result; }, figmaFormat: ({dictionary}) => { const minifyDictionary = (obj) => { if (typeof obj !== 'object' || Array.isArray(obj)) { return obj; } const result = {}; if (obj.hasOwnProperty('ignoreFigma')) { return null; } else if (obj.hasOwnProperty('value')) { if (obj.figmaValue) { return { value: obj.figmaValue }; } else { const value = /\{.+\}/.test(obj.original.value) ? obj.original.value : obj.value; return { value }; } } else { for (const name in obj) { if (obj.hasOwnProperty(name)) { const value = minifyDictionary(obj[name]); if (value !== null) { result[name] = minifyDictionary(obj[name]); } } } } return result; } const toCamelCase = (str) => { const regex = /[-_\s]+(.)?/g; if (!regex.test(str)) { return str.match(/^[A-Z]+$/) ? str.toLowerCase() : str[0].toLowerCase() + str.slice(1); } str = str.toLowerCase(); str = str.replace(regex, (match, letter) => { return letter ? letter.toUpperCase() : ''; }); return str[0].toLowerCase() + str.substr(1); } const typo = { type: 'typography' }; const typography = dictionary.tokens.typography; Object.keys(typography).forEach(category => { typo[category] = {}; Object.keys(typography[category]).forEach((item) => {; const complexValue = {}; const props = typography[category][item]; Object.keys(props).forEach(prop => { const propData = props[prop]; complexValue[toCamelCase(prop)] = propData.original.value; }); typo[category][item] = { value: complexValue }; }); }); const result = minifyDictionary(dictionary.tokens); result.typography = typo; return JSON.stringify({ Bitrix24: result }, null, '\t'); }, }, platforms: { css: { transformGroup: 'css-design-tokens', prefix: 'ui', buildPath: '../dist/', outputReferences: true, files: [ { destination: 'ui.design-tokens.css', format: 'cssFormat', options: { outputReferences: true, }, } ], }, figma: { transformGroup: 'figma-design-tokens', buildPath: '../dist/', outputReferences: true, files: [ { destination: 'figma-tokens.json', format: 'figmaFormat', /*filter: (token) => { if ( token.attributes.category === 'text' && token.attributes.type === 'decoration' && token.attributes.item === 'style' ) { return false; } return true; }*/ } ], }, }, };