Skip to content

Commit

Permalink
🎉 create trimmed variables output
Browse files Browse the repository at this point in the history
* feat(eds-tokens): ✨ create trimmed variables output with raw color values (without references)
  • Loading branch information
torleifhalseth authored Jun 11, 2024
1 parent 5ff52f3 commit 394164a
Show file tree
Hide file tree
Showing 7 changed files with 738 additions and 399 deletions.
259 changes: 149 additions & 110 deletions packages/eds-tokens-build/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ const cssDistPath = `${outputDirectory}/css`
const tsDistPath = `${outputDirectory}/ts`
const jsonDistPath = `${outputDirectory}/json`

const outputReferences = true

const {
filter: { isColor },
} = StyleDictionary
Expand All @@ -36,35 +34,41 @@ const resolveReference = (value: string, prefix: string): string => {
const darkTokens = readJsonFiles([
`./${TOKENS_DIR}/${FILE_KEY_THEMES}/🌗 Themes.Dark.json`,
])

const lightDarkTransform: StyleDictionary.Transform = {
type: 'value',
transitive: true,
matcher: isColor,
transformer: (token: StyleDictionary.TransformedToken, options) => {
const path = token.path.join('/')
const darkValue = darkTokens['🌗 Themes.Dark.json']?.[`${path}`]?.['$value']
let newValue = `${token.value}`

if (darkValue) {
//it is a reference
if (String(darkValue).startsWith('{')) {
const resolvedReference = resolveReference(
`${darkValue}`,
`${options.prefix}`,
)
//make sure it is not a local variable, in which case it has light-dark set already
if (token.original.value != darkValue) {
newValue = `light-dark(${token.value}, ${
outputReferences ? resolvedReference : darkValue
})`
const outputReferences =
options?.files?.[0]?.options?.outputReferences
if (outputReferences) {
const resolvedReference = resolveReference(
`${darkValue}`,
`${options.prefix}`,
)
return `light-dark(${token.value}, ${resolvedReference})`
} else {
return `light-dark(${token.value}, ${darkValue})`
}
}
} else {
//the dark value was hardcoded (color with alpha transparency)
newValue = `light-dark(${token.value}, ${new Color(darkValue as string)
return `light-dark(${token.value}, ${new Color(darkValue as string)
.to('oklch')
.toString({ precision: OKLCH_PRECISION })})`
}
}
return newValue

return `${token.value}`
},
}

Expand Down Expand Up @@ -93,38 +97,8 @@ StyleDictionary.registerTransform({
...lightDarkTransform,
})

/* const fileHeader = (defaultMessage: string[]) => [
...defaultMessage,
'@tokens Colors',
'@presenter Color',
] */

const fileHeader = () => ['Do not edit directly']

const lightDark = StyleDictionary.extend({
include: [`./${TOKENS_DIR}/${FILE_KEY_PRIMITIVES}/🎨 Color.Color.json`],
source: [`./${TOKENS_DIR}/${FILE_KEY_THEMES}/🌗 Themes.Light.json`],
platforms: {
css: {
transformGroup: 'css',
prefix: 'eds-color',
buildPath: `${cssDistPath}/color/`,
transforms: ['name/cti/kebab', 'color/css', 'color/oklch', 'lightDark'],
files: [
{
filter: (token) => token.filePath.includes('Light'),
destination: 'theme.css',
format: 'css/variables',
options: {
fileHeader,
outputReferences,
},
},
],
},
},
})

StyleDictionary.registerTransform({
type: 'value',
transitive: false,
Expand Down Expand Up @@ -235,6 +209,7 @@ const _extend = ({
selector,
filter,
include,
outputReferences,
}: {
include?: string[]
source: string[]
Expand All @@ -243,6 +218,7 @@ const _extend = ({
prefix: string
selector?: string
filter?: (token: TransformedToken) => boolean
outputReferences?: boolean
}): StyleDictionary.Core => {
return StyleDictionary.extend({
include,
Expand Down Expand Up @@ -318,87 +294,150 @@ const _extend = ({
})
}

const COLOR_PRIMITIVE_SOURCE = `./${TOKENS_DIR}/${FILE_KEY_PRIMITIVES}/🎨 Color.Color.json`
export function run({ outputReferences } = { outputReferences: true }) {
console.info('Running Style Dictionary build script')
console.info('outputReferences:', outputReferences)

const primitives = _extend({
source: [COLOR_PRIMITIVE_SOURCE],
dirName: 'color',
fileName: 'primitives',
prefix: 'eds-color',
})
const systemName = 'eds'
const colorPrefix = `${systemName}-color`
const colorDirName = 'color'

const lightMode = _extend({
include: [COLOR_PRIMITIVE_SOURCE],
source: [`./${TOKENS_DIR}/${FILE_KEY_THEMES}/🌗 Themes.Light.json`],
filter: (token) => token.filePath.includes('Light'),
fileName: 'theme-light',
dirName: 'color',
prefix: 'eds-color',
})
const spacingDirName = 'spacing'

const darkMode = _extend({
include: [COLOR_PRIMITIVE_SOURCE],
source: [`./${TOKENS_DIR}/${FILE_KEY_THEMES}/🌗 Themes.Dark.json`],
filter: (token) => token.filePath.includes('Dark'),
fileName: 'theme-dark',
dirName: 'color',
prefix: 'eds-color',
selector: '[data-theme="dark"]',
})
const COLOR_PRIMITIVE_SOURCE = `./${TOKENS_DIR}/${FILE_KEY_PRIMITIVES}/🎨 Color.Color.json`
const SPACING_PRIMITIVE_SOURCE = `./${TOKENS_DIR}/${FILE_KEY_SPACING}/👾 Spacing Primitives.Value.json`
const THEME_LIGHT_SOURCE = `./${TOKENS_DIR}/${FILE_KEY_THEMES}/🌗 Themes.Light.json`
const THEME_DARK_SOURCE = `./${TOKENS_DIR}/${FILE_KEY_THEMES}/🌗 Themes.Dark.json`

const SPACING_PRIMITIVE_SOURCE = `./${TOKENS_DIR}/${FILE_KEY_SPACING}/👾 Spacing Primitives.Value.json`
const DENSITY_COMFORTABLE_SOURCE = `./${TOKENS_DIR}/${FILE_KEY_TYPOGRAPHY_MODES}/💎 Density.Comfortable.json`
const DENSITY_COMPACT_SOURCE = `./${TOKENS_DIR}/${FILE_KEY_TYPOGRAPHY_MODES}/💎 Density.Compact.json`
const DENSITY_SPACIOUS_SOURCE = `./${TOKENS_DIR}/${FILE_KEY_TYPOGRAPHY_MODES}/💎 Density.Spacious.json`

const spacingPrimitives = _extend({
source: [SPACING_PRIMITIVE_SOURCE],
dirName: 'spacing',
fileName: 'primitives',
prefix: 'eds',
})
const primitives = _extend({
source: [COLOR_PRIMITIVE_SOURCE],
dirName: colorDirName,
prefix: colorPrefix,
fileName: 'primitives',
outputReferences, // The primitives should not reference other tokens. This can always be false.
})

const densityComfortable = _extend({
include: [SPACING_PRIMITIVE_SOURCE],
source: [
`./${TOKENS_DIR}/${FILE_KEY_TYPOGRAPHY_MODES}/💎 Density.Comfortable.json`,
],
dirName: 'spacing',
fileName: 'comfortable',
prefix: 'eds',
selector: ':root, [data-density="comfortable"]',
filter: (token) => token.filePath.includes('Density'),
})
const lightMode = _extend({
include: [COLOR_PRIMITIVE_SOURCE],
source: [THEME_LIGHT_SOURCE],
filter: (token) => token.filePath.includes('Light'),
dirName: colorDirName,
prefix: colorPrefix,
fileName: 'theme-light',
outputReferences,
})

const densityCompact = _extend({
include: [SPACING_PRIMITIVE_SOURCE],
source: [
`./${TOKENS_DIR}/${FILE_KEY_TYPOGRAPHY_MODES}/💎 Density.Compact.json`,
],
dirName: 'spacing',
fileName: 'compact',
prefix: 'eds',
selector: '[data-density="compact"]',
filter: (token) => {
const isDensityToken = token.filePath.includes('Density')
return isDensityToken
},
})
const darkMode = _extend({
include: [COLOR_PRIMITIVE_SOURCE],
source: [THEME_DARK_SOURCE],
filter: (token) => token.filePath.includes('Dark'),
dirName: colorDirName,
prefix: colorPrefix,
fileName: 'theme-dark',
selector: '[data-theme="dark"]',
outputReferences,
})

const densitySpacious = _extend({
include: [SPACING_PRIMITIVE_SOURCE],
source: [
`./${TOKENS_DIR}/${FILE_KEY_TYPOGRAPHY_MODES}/💎 Density.Spacious.json`,
],
dirName: 'spacing',
fileName: 'spacious',
prefix: 'eds',
selector: '[data-density="Spacious"]',
filter: (token) => token.filePath.includes('Density'),
})
const spacingPrimitives = _extend({
source: [SPACING_PRIMITIVE_SOURCE],
dirName: spacingDirName,
prefix: systemName,
fileName: 'primitives',
})

const densityComfortable = _extend({
include: [SPACING_PRIMITIVE_SOURCE],
source: [DENSITY_COMFORTABLE_SOURCE],
dirName: spacingDirName,
prefix: systemName,
fileName: 'comfortable',
selector: ':root, [data-density="comfortable"]',
filter: (token) => token.filePath.includes('Density'),
outputReferences,
})

const densityCompact = _extend({
include: [SPACING_PRIMITIVE_SOURCE],
source: [DENSITY_COMPACT_SOURCE],
dirName: spacingDirName,
prefix: systemName,
fileName: 'compact',
selector: '[data-density="compact"]',
filter: (token) => {
const isDensityToken = token.filePath.includes('Density')
return isDensityToken
},
outputReferences,
})

const densitySpacious = _extend({
include: [SPACING_PRIMITIVE_SOURCE],
source: [DENSITY_SPACIOUS_SOURCE],
dirName: spacingDirName,
prefix: systemName,
fileName: 'spacious',
selector: '[data-density="Spacious"]',
filter: (token) => token.filePath.includes('Density'),
outputReferences,
})

const lightDark = StyleDictionary.extend({
include: [COLOR_PRIMITIVE_SOURCE],
source: [THEME_LIGHT_SOURCE],
platforms: {
css: {
transformGroup: 'css',
prefix: colorPrefix,
buildPath: `${cssDistPath}/color/`,
transforms: ['name/cti/kebab', 'color/css', 'color/oklch', 'lightDark'],
files: [
{
filter: (token) => token.filePath.includes('Light'),
destination: 'theme.css',
format: 'css/variables',
options: {
fileHeader,
outputReferences,
},
},
],
},
},
})

const lightDarkTrimmed = StyleDictionary.extend({
include: [COLOR_PRIMITIVE_SOURCE],
source: [THEME_LIGHT_SOURCE],
platforms: {
css: {
transformGroup: 'css',
prefix: colorPrefix,
buildPath: `${cssDistPath}/`,
transforms: ['name/cti/kebab', 'color/css', 'color/oklch', 'lightDark'],
files: [
{
filter: (token) => token.filePath.includes('Light'),
destination: 'variables-trimmed.css',
format: 'css/variables',
options: {
fileHeader,
outputReferences: false, // The trimmed theme should not reference other tokens
},
},
],
},
},
})

export function run() {
primitives.buildAllPlatforms()
lightMode.buildAllPlatforms()
darkMode.buildAllPlatforms()
lightDark.buildAllPlatforms()
lightDarkTrimmed.buildAllPlatforms()
spacingPrimitives.buildAllPlatforms()
densityComfortable.buildAllPlatforms()
densityCompact.buildAllPlatforms()
Expand Down
Loading

0 comments on commit 394164a

Please sign in to comment.