Skip to content

Commit

Permalink
working on preprocessor
Browse files Browse the repository at this point in the history
  • Loading branch information
lukasoppermann committed Dec 5, 2024
1 parent 813e375 commit 0cb917b
Show file tree
Hide file tree
Showing 25 changed files with 358 additions and 104 deletions.
17 changes: 12 additions & 5 deletions scripts/buildTokens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,16 @@ const getStyleDictionaryConfig: StyleDictionaryConfigGenerator = (
},
platforms: Object.fromEntries(
Object.entries({
css: css(`css/${filename}.css`, options.prefix, options.buildPath, {themed: options.themed}),
docJson: docJson(`docs/${filename}.json`, options.prefix, options.buildPath),
styleLint: styleLint(`styleLint/${filename}.json`, options.prefix, options.buildPath),
css: css(`css/${filename}.css`, options.prefix, options.buildPath, {
themed: options.themed,
theme: options.theme,
}),
docJson: docJson(`docs/${filename}.json`, options.prefix, options.buildPath, {
theme: options.theme,
}),
styleLint: styleLint(`styleLint/${filename}.json`, options.prefix, options.buildPath, {
theme: options.theme,
}),
fallbacks: fallbacks(`fallbacks/${filename}.json`, options.prefix, options.buildPath),
...platforms,
}).filter((entry: [string, unknown]) => entry[1] !== undefined),
Expand Down Expand Up @@ -71,14 +78,14 @@ export const buildDesignTokens = async (buildOptions: ConfigGeneratorOptions): P
* Colors, shadows & borders
* ----------------------------------- */
try {
for (const {filename, source, include} of themes) {
for (const {filename, source, include, theme} of themes) {
// build functional scales
const extendedSD = await PrimerStyleDictionary.extend(
getStyleDictionaryConfig(
`functional/themes/${filename}`,
source,
include,
{...buildOptions, themed: true},
{...buildOptions, themed: true, theme},
// disable fallbacks for themes
{fallbacks: undefined},
),
Expand Down
23 changes: 21 additions & 2 deletions scripts/themes.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,40 +3,48 @@ 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`,
`src/tokens/functional/border/light.json5`,
`src/tokens/functional/color/components/*.json5`,
],
include: [`src/tokens/base/color/light/light.json5`, `src/tokens/base/color/light/display-light.json5`],
},
{
filename: 'light-tritanopia',
theme: 'light-tritanopia',
source: [
`src/tokens/functional/color/light/*.json5`,
`src/tokens/functional/shadow/light.json5`,
`src/tokens/functional/border/light.json5`,
`src/tokens/functional/color/components/*.json5`,
`src/tokens/functional/color/light/overrides/light.tritanopia.json5`,
],
include: [`src/tokens/base/color/light/light.json5`, `src/tokens/base/color/light/display-light.json5`],
},
{
filename: 'light-colorblind',
theme: 'light-protanopia-deuteranopia',
source: [
`src/tokens/functional/color/light/*.json5`,
`src/tokens/functional/shadow/light.json5`,
`src/tokens/functional/border/light.json5`,
`src/tokens/functional/color/components/*.json5`,
`src/tokens/functional/color/light/overrides/light.protanopia-deuteranopia.json5`,
],
include: [`src/tokens/base/color/light/light.json5`, `src/tokens/base/color/light/display-light.json5`],
},
{
filename: 'light-high-contrast',
theme: 'light-high-contrast',
source: [
`src/tokens/functional/color/light/*.json5`,
`src/tokens/functional/color/light/overrides/light.high-contrast.json5`,
`src/tokens/functional/shadow/light.json5`,
`src/tokens/functional/border/light.json5`,
`src/tokens/functional/color/components/*.json5`,
`src/tokens/functional/color/light/overrides/light.high-contrast.json5`,
],
include: [
`src/tokens/base/color/light/light.json5`,
Expand All @@ -46,54 +54,65 @@ export const themes: TokenBuildInput[] = [
},
{
filename: 'dark',
theme: 'dark',
source: [
`src/tokens/functional/color/dark/*.json5`,
`src/tokens/functional/shadow/dark.json5`,
`src/tokens/functional/border/dark.json5`,
`src/tokens/functional/color/components/*.json5`,
],
include: [`src/tokens/base/color/dark/dark.json5`, `src/tokens/base/color/dark/display-dark.json5`],
},
{
filename: 'dark-dimmed',
theme: 'dark-dimmed',
source: [
`src/tokens/functional/color/dark/*.json5`,
`src/tokens/functional/color/dark/overrides/dark.dimmed.json5`,
`src/tokens/functional/shadow/dark.json5`,
`src/tokens/functional/border/dark.json5`,
`src/tokens/functional/color/components/*.json5`,
],
include: [
`src/tokens/base/color/dark/dark.json5`,
`src/tokens/base/color/dark/dark.dimmed.json5`,
`src/tokens/base/color/dark/display-dark.json5`,
`src/tokens/functional/color/components/*.json5`,
],
},
{
filename: 'dark-tritanopia',
theme: 'dark-tritanopia',
source: [
`src/tokens/functional/color/dark/*.json5`,
`src/tokens/functional/shadow/dark.json5`,
`src/tokens/functional/border/dark.json5`,
`src/tokens/functional/color/components/*.json5`,
`src/tokens/functional/color/dark/overrides/dark.tritanopia.json5`,
],
include: [`src/tokens/base/color/dark/dark.json5`, `src/tokens/base/color/dark/display-dark.json5`],
},
{
filename: 'dark-colorblind',
theme: 'dark-protanopia-deuteranopia',
source: [
`src/tokens/functional/color/dark/*.json5`,
`src/tokens/functional/shadow/dark.json5`,
`src/tokens/functional/border/dark.json5`,
`src/tokens/functional/color/components/*.json5`,
`src/tokens/functional/color/dark/overrides/dark.protanopia-deuteranopia.json5`,
],
include: [`src/tokens/base/color/dark/dark.json5`, `src/tokens/base/color/dark/display-dark.json5`],
},
{
filename: 'dark-high-contrast',
theme: 'dark-high-contrast',
source: [
`src/tokens/functional/color/dark/*.json5`,
`src/tokens/functional/color/dark/overrides/dark.high-contrast.json5`,
`src/tokens/functional/shadow/dark.json5`,
`src/tokens/functional/border/dark.json5`,
`src/tokens/functional/color/components/*.json5`,
`src/tokens/functional/color/dark/overrides/dark.high-contrast.json5`,
],
include: [
`src/tokens/base/color/dark/dark.json5`,
Expand Down
4 changes: 4 additions & 0 deletions src/platforms/css.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export const css: PlatformInitializer = (outputFile, prefix, buildPath, options)
return {
prefix,
buildPath,
preprocessors: ['themeOverrides'],
transforms: [
'name/pathToKebabCase',
'color/hex',
Expand All @@ -39,6 +40,9 @@ export const css: PlatformInitializer = (outputFile, prefix, buildPath, options)
],
options: {
basePxFontSize: 16,
themeOverrides: {
theme: options?.theme,
},
},
files: [
{
Expand Down
1 change: 1 addition & 0 deletions src/platforms/docJson.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import type {PlatformConfig} from 'style-dictionary/types'
export const docJson: PlatformInitializer = (outputFile, prefix, buildPath): PlatformConfig => ({
prefix,
buildPath,
preprocessors: ['getThemeValue'],
transforms: [
'name/pathToKebabCase',
'color/hex',
Expand Down
1 change: 1 addition & 0 deletions src/platforms/figma.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ const validFigmaToken = async (token: TransformedToken, options: Config) => {
export const figma: PlatformInitializer = (outputFile, prefix, buildPath, options): PlatformConfig => ({
prefix,
buildPath,
preprocessors: ['getThemeValue'],
transforms: [
'color/rgbaFloat',
'fontFamily/figma',
Expand Down
1 change: 1 addition & 0 deletions src/platforms/javascript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {isSource} from '../filters/index.js'
export const javascript: PlatformInitializer = (outputFile, prefix, buildPath): PlatformConfig => ({
prefix,
buildPath,
preprocessors: ['getThemeValue'],
transforms: [
'color/hex',
'color/hexMix',
Expand Down
1 change: 1 addition & 0 deletions src/platforms/json.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import type {PlatformConfig} from 'style-dictionary/types'
export const json: PlatformInitializer = (outputFile, prefix, buildPath): PlatformConfig => ({
prefix,
buildPath,
preprocessors: ['getThemeValue'],
transforms: [
'color/hex',
'color/hexMix',
Expand Down
1 change: 1 addition & 0 deletions src/platforms/styleLint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import type {PlatformConfig} from 'style-dictionary/types'
export const styleLint: PlatformInitializer = (outputFile, prefix, buildPath): PlatformConfig => ({
prefix,
buildPath,
preprocessors: ['getThemeValue'],
transforms: [
'name/pathToKebabCase',
'color/hex',
Expand Down
1 change: 1 addition & 0 deletions src/platforms/typeDefinitions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import type {PlatformConfig} from 'style-dictionary/types'
export const typeDefinitions: PlatformInitializer = (outputFile, prefix, buildPath): PlatformConfig => ({
prefix,
buildPath,
preprocessors: ['getThemeValue'],
transforms: [
'color/hex',
'shadow/css',
Expand Down
1 change: 1 addition & 0 deletions src/platforms/typescript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {isSource} from '../filters/index.js'
export const typescript: PlatformInitializer = (outputFile, prefix, buildPath): PlatformConfig => ({
prefix,
buildPath,
preprocessors: ['getThemeValue'],
transforms: [
'color/hex',
'color/hexMix',
Expand Down
144 changes: 144 additions & 0 deletions src/preprocessor/themeOverrides.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
import {getMockDictionary} from '../test-utilities/getMockDictionary.js'
import {themeOverrides} from './themeOverrides.js'
import {getMockToken} from '../test-utilities/getMockToken.js'

describe('Preprocessor: themeOverrides', () => {
it('works with default settings', () => {
const dictionary = getMockDictionary({
valueOverride: getMockToken({
name: 'red',
description: 'This is a description',
$value: 'transformedValue',
path: ['tokens', 'subgroup', 'red'],
$extensions: {
'org.primer.overrides': {
dark: 'darkValue',
},
},
}),
objectOverride: getMockToken({
name: 'red',
description: 'This is a description',
$value: 'transformedValue',
path: ['tokens', 'subgroup', 'red'],
$extensions: {
'org.primer.overrides': {
dark: {
$value: 'darkValue',
description: 'DarkMode description',
},
},
},
}),
})

const resultDictionary = getMockDictionary({
valueOverride: getMockToken({
name: 'red',
description: 'This is a description',
$value: 'darkValue',
path: ['tokens', 'subgroup', 'red'],
$extensions: {
'org.primer.overrides': {
dark: 'darkValue',
},
},
}),
objectOverride: getMockToken({
name: 'red',
description: 'DarkMode description',
$value: 'darkValue',
path: ['tokens', 'subgroup', 'red'],
$extensions: {
'org.primer.overrides': {
dark: {
$value: 'darkValue',
description: 'DarkMode description',
},
},
},
}),
})

expect(themeOverrides.preprocessor(dictionary.tokens, {})).toStrictEqual(dictionary.tokens)
expect(
themeOverrides.preprocessor(dictionary.tokens, {
options: {themeOverrides: {theme: 'dark'}},
}),
).toStrictEqual(resultDictionary.tokens)
})
})

describe('Preprocessor: themeOverrides', () => {
it('works with custom configuration', () => {
const dictionary = getMockDictionary({
valueOverride: getMockToken({
name: 'red',
description: 'This is a description',
value: 'transformedValue',
path: ['tokens', 'subgroup', 'red'],
$extensions: {
theme: {
dark: 'darkValue',
},
},
}),
objectOverride: getMockToken({
name: 'red',
description: 'This is a description',
value: 'transformedValue',
path: ['tokens', 'subgroup', 'red'],
$extensions: {
theme: {
dark: {
value: 'darkValue',
description: 'DarkMode description',
},
},
},
}),
})

const resultDictionary = getMockDictionary({
valueOverride: getMockToken({
name: 'red',
description: 'This is a description',
value: 'darkValue',
path: ['tokens', 'subgroup', 'red'],
$extensions: {
theme: {
dark: 'darkValue',
},
},
}),
objectOverride: getMockToken({
name: 'red',
description: 'DarkMode description',
value: 'darkValue',
path: ['tokens', 'subgroup', 'red'],
$extensions: {
theme: {
dark: {
value: 'darkValue',
description: 'DarkMode description',
},
},
},
}),
})

expect(
themeOverrides.preprocessor(dictionary.tokens, {
themeOverrides: {
valueProp: 'value',
extensionProp: 'theme',
},
}),
).toStrictEqual(dictionary.tokens)
expect(
themeOverrides.preprocessor(dictionary.tokens, {
options: {themeOverrides: {theme: 'dark', valueProp: 'value', extensionProp: 'theme'}},
}),
).toStrictEqual(resultDictionary.tokens)
})
})
25 changes: 25 additions & 0 deletions src/preprocessor/themeOverrides.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import type {PlatformConfig, PreprocessedTokens, Preprocessor} from 'style-dictionary/types'
import {transformTokens} from './utilities/transformTokens.js'

export const themeOverrides: Preprocessor = {
name: 'themeOverrides',
preprocessor: (dictionary: PreprocessedTokens, config: PlatformConfig): PreprocessedTokens => {
const extensionProp = config.options?.themeOverrides?.extensionProp || 'org.primer.overrides'
const valueProp = config.options?.themeOverrides?.valueProp || '$value'
const currentTheme = config.options?.themeOverrides?.theme

const tokens = transformTokens(dictionary, token => {
// return early if no theme value is set
if (!currentTheme || !token.$extensions?.[extensionProp] || !token.$extensions?.[extensionProp][currentTheme])
return token
// get override
const override = token.$extensions?.[extensionProp][currentTheme]
// token an theme value exist
return {
...token,
...(typeof override === 'object' ? override : {[valueProp]: override}),
}
})
return tokens
},
}
Loading

0 comments on commit 0cb917b

Please sign in to comment.