From 9326e3b3480a0de79a06384deb95a1d99acf3dbf Mon Sep 17 00:00:00 2001 From: Lukas Oppermann Date: Mon, 25 Nov 2024 13:40:00 +0100 Subject: [PATCH] working pre-processor --- scripts/themes.config.ts | 2 ++ src/PrimerStyleDictionary.ts | 4 +-- src/platforms/css.ts | 3 ++- src/preprocessor/getModeValue.ts | 7 ------ src/preprocessor/getThemeValue.ts | 19 ++++++++++++++ src/preprocessor/utilities/transformTokens.ts | 25 +++++++++++++++++++ .../functional/color/light/app-light.json5 | 4 +++ src/types/StyleDictionaryConfigGenerator.d.ts | 1 + src/types/TokenBuildInput.d.ts | 2 ++ 9 files changed, 57 insertions(+), 10 deletions(-) delete mode 100644 src/preprocessor/getModeValue.ts create mode 100644 src/preprocessor/getThemeValue.ts create mode 100644 src/preprocessor/utilities/transformTokens.ts diff --git a/scripts/themes.config.ts b/scripts/themes.config.ts index 402ad4e5c..fccb31249 100644 --- a/scripts/themes.config.ts +++ b/scripts/themes.config.ts @@ -3,6 +3,7 @@ import type {TokenBuildInput} from '../src/types/TokenBuildInput.js' export const themes: TokenBuildInput[] = [ { filename: 'light', + theme: 'light', source: [ `src/tokens/functional/color/light/*.json5`, `src/tokens/functional/shadow/light.json5`, @@ -13,6 +14,7 @@ export const themes: TokenBuildInput[] = [ }, { filename: 'light-tritanopia', + theme: 'light-tritanopia', source: [ `src/tokens/functional/color/light/*.json5`, `src/tokens/functional/shadow/light.json5`, diff --git a/src/PrimerStyleDictionary.ts b/src/PrimerStyleDictionary.ts index d9c3c6e9f..d33236f6f 100644 --- a/src/PrimerStyleDictionary.ts +++ b/src/PrimerStyleDictionary.ts @@ -37,7 +37,7 @@ import { cssAdvanced, jsonFigma, } from './formats/index.js' -import {getModeValue} from './preprocessor/getModeValue.js' +import {getThemeValue} from './preprocessor/getThemeValue.js' /** * @name {@link PrimerStyleDictionary} @@ -152,4 +152,4 @@ PrimerStyleDictionary.registerTransform(fontFamilyToCss) PrimerStyleDictionary.registerTransform(fontFamilyToFigma) -PrimerStyleDictionary.registerPreprocessor(getModeValue) +PrimerStyleDictionary.registerPreprocessor(getThemeValue) diff --git a/src/platforms/css.ts b/src/platforms/css.ts index 786da8cbf..1a251926b 100644 --- a/src/platforms/css.ts +++ b/src/platforms/css.ts @@ -24,7 +24,7 @@ export const css: PlatformInitializer = (outputFile, prefix, buildPath, options) return { prefix, buildPath, - preprocessors: ['getModeValue'], + preprocessors: ['getThemeValue'], transforms: [ 'name/pathToKebabCase', 'color/hex', @@ -40,6 +40,7 @@ export const css: PlatformInitializer = (outputFile, prefix, buildPath, options) ], options: { basePxFontSize: 16, + theme: options?.theme, }, files: [ { diff --git a/src/preprocessor/getModeValue.ts b/src/preprocessor/getModeValue.ts deleted file mode 100644 index ba45cde4a..000000000 --- a/src/preprocessor/getModeValue.ts +++ /dev/null @@ -1,7 +0,0 @@ -export const getModeValue = { - name: 'getModeValue', - preprocessor: (dictionary, options) => { - console.log('dictionary', dictionary) - return dictionary - }, -} diff --git a/src/preprocessor/getThemeValue.ts b/src/preprocessor/getThemeValue.ts new file mode 100644 index 000000000..bc5329324 --- /dev/null +++ b/src/preprocessor/getThemeValue.ts @@ -0,0 +1,19 @@ +import type {Dictionary, PlatformConfig, PreprocessedTokens} from 'style-dictionary/types' +import {transformTokens} from './utilities/transformTokens.js' + +export const getThemeValue = { + name: 'getThemeValue', + preprocessor: (dictionary: Dictionary, config: PlatformConfig): PreprocessedTokens => { + const tokens = transformTokens(dictionary, token => { + // return early if no theme value is set + if (!config.options?.theme || !token.$extensions?.['org.primer.theme']?.[config.options.theme]) return token + // token an theme value exist + const valueProp = 'value' in token ? 'value' : '$value' + return { + ...token, + [valueProp]: token.$extensions['org.primer.theme'][config.options.theme], + } + }) + return tokens + }, +} diff --git a/src/preprocessor/utilities/transformTokens.ts b/src/preprocessor/utilities/transformTokens.ts new file mode 100644 index 000000000..63413957c --- /dev/null +++ b/src/preprocessor/utilities/transformTokens.ts @@ -0,0 +1,25 @@ +import type {DesignToken} from 'style-dictionary/types' +/** + * jsonToNestedValue + * @description creates a nested json tree where every final value is the `.value` prop + * @param token StyleDictionary.DesignToken + * @returns nested json three + */ +export const transformTokens = ( + token: DesignToken | Record, + transform: (token: DesignToken) => DesignToken, +) => { + // is non-object value + if (typeof token !== 'object') return token + // is design token + if ('$value' in token || 'value' in token) { + return transform(token as DesignToken) + } + // is obj + const nextObj = {} + for (const [prop, value] of Object.entries(token)) { + // @ts-expect-error: can't predict type + nextObj[prop] = transformTokens(value, transform) + } + return nextObj +} diff --git a/src/tokens/functional/color/light/app-light.json5 b/src/tokens/functional/color/light/app-light.json5 index 72e0d1ced..199bdca25 100644 --- a/src/tokens/functional/color/light/app-light.json5 +++ b/src/tokens/functional/color/light/app-light.json5 @@ -10,6 +10,10 @@ group: 'component', scopes: ['borderColor'], }, + 'org.primer.theme': { + light: '{base.color.red.5}', + 'light-tritanopia': '{base.color.pink.5}', + }, }, }, }, diff --git a/src/types/StyleDictionaryConfigGenerator.d.ts b/src/types/StyleDictionaryConfigGenerator.d.ts index ffa53f330..9990e4ec2 100644 --- a/src/types/StyleDictionaryConfigGenerator.d.ts +++ b/src/types/StyleDictionaryConfigGenerator.d.ts @@ -4,6 +4,7 @@ export type ConfigGeneratorOptions = { buildPath: string prefix?: string themed?: boolean + theme?: string } export type StyleDictionaryConfigGenerator = ( diff --git a/src/types/TokenBuildInput.d.ts b/src/types/TokenBuildInput.d.ts index fc00fe31d..6cc65bf42 100644 --- a/src/types/TokenBuildInput.d.ts +++ b/src/types/TokenBuildInput.d.ts @@ -3,6 +3,8 @@ export type TokenBuildInput = { filename: string // Array of `filepaths` to token files that should be converted and included in the output. Accepts relative or glob paths. source: string[] + // The mode of the theme + theme?: string // Array of `filepaths` to token fils that should NOT be included in the output, but should be available to reference during compilation e.g. base color scales include: string[] }