import format from '@af/formatting/sync'; import tokens from '@atlaskit/tokens/atlassian-light'; import { capitalize } from './capitalize'; import { generateTypeDefs } from './generate-type-defs'; import { constructTokenFunctionCall, type ShadowDefinition } from './utils'; type Token = { token: string; fallback: string | ShadowDefinition; isDeprecated: boolean; }; // NB: Fallback CSS variables can be deleted when tokens are no longer behind a feature flag const tokenStyles = { text: { objectName: 'textColor', prefix: 'color.text.', cssProperty: 'color', filterFn: (t: T): boolean => t.token.startsWith(tokenStyles.text.prefix) || t.token.startsWith('color.link'), }, background: { objectName: 'backgroundColor', prefix: 'color.background.', cssProperty: 'backgroundColor', filterFn: (t: T): boolean => t.token.startsWith(tokenStyles.background.prefix) || t.token.startsWith('elevation.surface') || t.token.startsWith('utility.elevation.surface') || t.token.startsWith('color.blanket') || t.token.startsWith('color.skeleton') || t.token.startsWith('color.rovo.background.'), }, border: { objectName: 'borderColor', prefix: 'color.border.', cssProperty: 'borderColor', filterFn: (t: T): boolean => t.token.startsWith(tokenStyles.border.prefix), }, fill: { objectName: 'fill', prefix: 'color.icon.', cssProperty: 'fill', filterFn: (t: T): boolean => t.token.startsWith(tokenStyles.fill.prefix), }, } as const; const activeTokens = tokens .filter((t) => t.attributes.state !== 'deleted') .map( (t): Token => ({ token: t.name, fallback: t.value as string | ShadowDefinition, isDeprecated: t.attributes.state === 'deprecated', }), ); export const createColorStylesFromTemplate: (colorProperty: keyof typeof tokenStyles) => string = ( colorProperty: keyof typeof tokenStyles, ) => { if (!tokenStyles[colorProperty]) { throw new Error(`[codegen] Unknown option found "${colorProperty}"`); } const { filterFn, objectName } = tokenStyles[colorProperty]; const typeDefsTokens = activeTokens .filter(filterFn) // @ts-ignore .map((t) => t.token.replaceAll('.[default]', '')); return ( format( ` export const ${objectName}Map: { ${generateTypeDefs(typeDefsTokens)} } = { ${activeTokens .filter(filterFn) // @ts-ignore .map((t) => ({ ...t, token: t.token.replaceAll('.[default]', '') })) .map((t) => { return ` ${t.isDeprecated ? '// @deprecated' : ''} '${t.token}': ${constructTokenFunctionCall(t.token, t.fallback)} `.trim(); }) .join(',\n\t')} } as const;`, 'typescript', ) + `\nexport type ${capitalize(objectName)} = keyof typeof ${objectName}Map;\n` ); };