/** * Style Dictionary configuration for FA Design System (v4) * * Transforms W3C DTCG token JSON into: * - CSS custom properties (for runtime theming) * - JavaScript ES6 module (for MUI theme consumption) * - JSON (for Penpot import) */ import StyleDictionary from 'style-dictionary'; const sd = new StyleDictionary({ source: ['tokens/**/*.json'], usesDtcg: true, platforms: { // CSS custom properties css: { transformGroup: 'css', prefix: 'fa', buildPath: 'src/theme/generated/', files: [{ destination: 'tokens.css', format: 'css/variables', options: { outputReferences: true, }, }], }, // JavaScript ES6 module for MUI theme js: { transformGroup: 'js', buildPath: 'src/theme/generated/', files: [{ destination: 'tokens.js', format: 'javascript/es6', }], }, // Flat JSON for Penpot import and other tools json: { transformGroup: 'js', buildPath: 'tokens/export/', files: [{ destination: 'tokens-flat.json', format: 'json/flat', }], }, }, }); await sd.buildAllPlatforms(); // Generate TypeScript declarations for the JS token output import { readFileSync, writeFileSync } from 'fs'; const jsPath = 'src/theme/generated/tokens.js'; const dtsPath = 'src/theme/generated/tokens.d.ts'; const jsContent = readFileSync(jsPath, 'utf-8') .replace(/=\n\s+/g, '= '); // join continuation lines const declarations = ['/**', ' * Do not edit directly, this file was auto-generated.', ' */']; for (const line of jsContent.split('\n')) { const m = line.match(/^export const (\w+)\s*=\s*(.+?)\s*;/); if (!m) continue; const [, name, val] = m; const isNum = !val.startsWith('"') && !val.startsWith("'") && !isNaN(Number(val)); declarations.push(`export declare const ${name}: ${isNum ? 'number' : 'string'};`); } writeFileSync(dtsPath, declarations.join('\n') + '\n'); console.log(`✓ Generated ${declarations.length - 3} TypeScript declarations`);