import format from '@af/formatting/sync'; import { CURRENT_SURFACE_CSS_VAR } from '@atlaskit/tokens/constants'; 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: { readonly opacity: { readonly objectName: 'opacity'; readonly prefix: 'opacity.'; readonly cssProperty: 'opacity'; readonly filterFn: (t: T) => boolean; }; readonly shadow: { readonly objectName: 'shadow'; readonly prefix: 'elevation.shadow.'; readonly cssProperty: 'boxShadow'; readonly filterFn: (t: T) => boolean; }; readonly surface: { readonly objectName: 'surfaceColor'; readonly prefix: 'elevation.surface.'; readonly cssProperty: '--ds-elevation-surface-current'; readonly filterFn: (t: T) => boolean; }; } = { opacity: { objectName: 'opacity', prefix: 'opacity.', cssProperty: 'opacity', filterFn: (t: T): boolean => t.token.startsWith(tokenStyles.opacity.prefix), }, shadow: { objectName: 'shadow', prefix: 'elevation.shadow.', cssProperty: 'boxShadow', filterFn: (t: T): boolean => t.token.startsWith(tokenStyles.shadow.prefix), }, surface: { objectName: 'surfaceColor', prefix: 'elevation.surface.', cssProperty: CURRENT_SURFACE_CSS_VAR, filterFn: (t: T): boolean => t.token.startsWith(tokenStyles.surface.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 createElevationStylesFromTemplate: (property: keyof typeof tokenStyles) => string = ( property: keyof typeof tokenStyles, ) => { if (!tokenStyles[property]) { throw new Error(`[codegen] Unknown option found "${property}"`); } const { filterFn, objectName } = tokenStyles[property]; 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` ); };