import { fileHeader } from 'style-dictionary/utils'; import { type FormatFn, type DesignToken } from 'style-dictionary/types'; /** * Configuration options for the CSS theme format */ interface CssThemeFormatOptions { /** Version string for version-specific variables (e.g., '2-0-2', 'latest') */ version?: string; /** Token set name (e.g., 'cross-brand-light-color', 'my-purple-theme') */ tokenSet?: string; } /** * Transforms any theme token path to version-specific MFUI variable name * * @param token - The design token from Style Dictionary * @param version - Version string for version-specific variables * @returns Object with version-specific variable name and value */ function transformThemeToken(token: DesignToken, version: string) { // Extract the path after the tokenSet name // e.g., ['my-purple-theme', 'accent', 'content', 'none'] -> ['accent', 'content', 'none'] // or ['cross-brand-light-color', 'accent', 'content', 'none'] -> ['accent', 'content', 'none'] const pathSegments = token['path'].slice(1); // Remove tokenSet name const dotPath = pathSegments.join('\\.'); // 'accent\.content\.none' const value = token.$value; return { // Version-specific variable (what components consume) // Always use mfui.color namespace regardless of source theme versionSpecific: `--mfui-${version}-colors-mfui\\.color\\.${dotPath}`, // Token value value: value, }; } /** * Custom CSS format that generates version-specific theme variables */ export const cssThemeWithOverridesFormat: FormatFn = async ({ dictionary, options, file }) => { const { version = 'latest', tokenSet = 'cross-brand-light-color' } = (options || {}) as CssThemeFormatOptions; // Filter to only tokens from the specified token set const themeTokens = dictionary.allTokens.filter( (token) => token.filePath.includes(tokenSet) || (tokenSet !== 'cross-brand-light-color' && token['path'][0] === tokenSet), ); if (themeTokens.length === 0) { console.warn(`No ${tokenSet} tokens found for theme generation`); } // Generate CSS variables const cssVariables: string[] = []; themeTokens.forEach((token) => { const { versionSpecific, value } = transformThemeToken(token, version); // Generate only version-specific variables (what components consume) cssVariables.push(` ${versionSpecific}: ${value};`); }); // Build the complete CSS output const cssContent = [ ':root, :host {', ...cssVariables, '}', '', // Empty line at end ].join('\n'); // Add file header const header = await fileHeader({ file }); return header + cssContent; };