import { SDTFEngine, SpecifyDesignTokenTypeName } from '@specifyapp/specify-design-token-format'; import { createAliasToVarStrategy } from '../../../converters/scss/aliasStrategies/resolvableToVar.js'; import { createThrowOnUnresolvableStrategy } from '../../../converters/scss/aliasStrategies/throwOnUnresolvable.js'; import { DEFAULT_TEMPLATE, renderVariable } from '../../../converters/scss/utils/template.js'; import { ToScssVariablesParserOptions } from './definition.js'; import { dimensionToCss, breakpointToCss, colorToCss, cubicBezierToCss, durationToCss, borderToCss, gradientToCss, gradientsToCss, fontToCss, fontWeightToCss, opacityToCss, radiiToCss, radiusToCss, shadowToCss, shadowsToCss, spacingToCss, spacingsToCss, textStyleToCss, stepsTimingFunctionToCss, transitionToCss, zIndexToCss, } from '../../../converters/css/index.js'; import { makeScssVariable } from '../../../converters/scss/utils/makeScssVariable.js'; import { dataOfToken } from '../../utils/template.js'; export function convertTokens( sdtfEngine: SDTFEngine, parserOptions: Exclude, undefined>, ) { const tokenNameTemplate = parserOptions.tokenNameTemplate ?? DEFAULT_TEMPLATE; const aliasStrategy = createAliasToVarStrategy(tokenNameTemplate); const unresolvableStrategy = createThrowOnUnresolvableStrategy(); const tokens = sdtfEngine.query.getAllTokenStates(); const convertedTokensByType = tokens.reduce( (acc, token) => { const tempOutput = token.matchByType< { [mode: string]: string | Record | number } | undefined >( { dimension: dimensionToCss(aliasStrategy, unresolvableStrategy), breakpoint: breakpointToCss(aliasStrategy, unresolvableStrategy), color: colorToCss(aliasStrategy, unresolvableStrategy), cubicBezier: cubicBezierToCss(aliasStrategy, unresolvableStrategy), duration: durationToCss(aliasStrategy, unresolvableStrategy), border: borderToCss(aliasStrategy, unresolvableStrategy), gradient: gradientToCss(aliasStrategy, unresolvableStrategy), gradients: gradientsToCss(aliasStrategy, unresolvableStrategy), font: fontToCss(aliasStrategy, unresolvableStrategy), fontWeight: fontWeightToCss(aliasStrategy, unresolvableStrategy), opacity: opacityToCss(aliasStrategy, unresolvableStrategy), radius: radiusToCss(aliasStrategy, unresolvableStrategy), radii: radiiToCss(aliasStrategy, unresolvableStrategy), shadow: shadowToCss(aliasStrategy, unresolvableStrategy), shadows: shadowsToCss(aliasStrategy, unresolvableStrategy), spacing: spacingToCss(aliasStrategy, unresolvableStrategy), spacings: spacingsToCss(aliasStrategy, unresolvableStrategy), textStyle: textStyleToCss(aliasStrategy, unresolvableStrategy), stepsTimingFunction: stepsTimingFunctionToCss(aliasStrategy, unresolvableStrategy), transition: transitionToCss(aliasStrategy, unresolvableStrategy), zIndex: zIndexToCss(aliasStrategy, unresolvableStrategy), }, _ => undefined, ); if (!tempOutput) return acc; acc[token.type] ??= ''; const hasOnlyOneMode = Object.keys(tempOutput).length === 1; acc[token.type] += Object.entries( tempOutput as { [mode: string]: string | Record }, ).reduce((acc, [mode, value]) => { const variableName = renderVariable( tokenNameTemplate, dataOfToken( token, hasOnlyOneMode && !parserOptions.shouldRenderSingleMode ? undefined : mode, ), ); acc += `${ typeof value === 'string' || typeof value === 'number' ? makeScssVariable(variableName, value) : Object.entries(value) .map(([key, value]) => makeScssVariable(`${variableName}-${key}`, value)) .join('\n') }\n`; return acc; }, ''); return acc; }, {} as { [T in SpecifyDesignTokenTypeName]?: string }, ); return Object.entries(convertedTokensByType).reduce((acc, [type, value]) => { return acc + `/* ${type.toUpperCase()} */\n${value}\n\n`; }, ''); }