Skip to content

Commit aa92e26

Browse files
committed
feat(ui-scripts): refactor theme type generation and fix token fetching script
1 parent 732d946 commit aa92e26

6 files changed

Lines changed: 340 additions & 161 deletions

File tree

packages/emotion/src/styleUtils/applyColorModifiers.ts

Lines changed: 41 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -52,39 +52,56 @@ const formatHsla = (h: number, s: number, l: number, a: number): string => {
5252
: `hsl(${hh}, ${ss}%, ${ll}%)`
5353
}
5454

55+
const isModifyColor = (val: unknown): val is ModifyColor =>
56+
typeof val === 'object' &&
57+
val !== null &&
58+
typeof (val as ModifyColor).value === 'string' &&
59+
typeof (val as ModifyColor).modify === 'object' &&
60+
(val as ModifyColor).modify !== null
61+
62+
const resolveModifyColor = ({ value, modify }: ModifyColor): string => {
63+
if (modify.type === 'darken' || modify.type === 'lighten') {
64+
const { h, s, l, a } = colorToHsla(value)
65+
const newL = modifyLightness(l, modify.value, modify.type)
66+
return formatHsla(h, s, newL, a)
67+
}
68+
return value
69+
}
70+
5571
/**
5672
* Resolves a component theme object by applying color modifiers to any entries
5773
* shaped as `{ value, modify: { type, value } }`. Entries with `modify.type` of
5874
* `'darken'` or `'lighten'` are transformed in HSL space using the same math
5975
* Tokens Studio applies (`space: "hsl"`): `amount` is a 0–1 fraction of the
60-
* remaining distance to black/white. Plain string values and unrecognized
61-
* modifier types are passed through unchanged.
76+
* remaining distance to black/white. Plain values and unrecognized modifier
77+
* types are passed through unchanged. Nested plain objects are walked
78+
* recursively so modifiers anywhere in the tree get resolved.
6279
*
63-
* @param componentTheme - Theme map whose values are either plain CSS color strings
64-
* or `ModifyColor` objects describing a base color and a darken/lighten modifier.
65-
* @returns A new theme object with the same keys, where modifier objects have been
66-
* collapsed to their final resolved color string.
80+
* @param componentTheme - Theme map whose values can be CSS strings, `ModifyColor`
81+
* objects, or nested theme objects containing the same.
82+
* @returns A new theme object mirroring the input shape, with every `ModifyColor`
83+
* collapsed to its final resolved color string.
6784
*/
6885
const applyColorModifiers = (
69-
componentTheme: Record<string, string | ModifyColor> | undefined | null
70-
) => {
86+
componentTheme: Record<string, unknown> | undefined | null
87+
): Record<string, unknown> => {
7188
if (componentTheme == null) return {}
72-
return Object.keys(componentTheme).reduce<Record<string, string>>(
73-
(res, k) => {
74-
const entry = componentTheme[k]
75-
if (typeof entry === 'object' && entry !== null) {
76-
const { value, modify } = entry
77-
if (modify.type === 'darken' || modify.type === 'lighten') {
78-
const { h, s, l, a } = colorToHsla(value)
79-
const newL = modifyLightness(l, modify.value, modify.type)
80-
return { ...res, [k]: formatHsla(h, s, newL, a) }
81-
}
82-
return { ...res, [k]: value }
83-
}
84-
return { ...res, [k]: entry }
85-
},
86-
{}
87-
)
89+
const result: Record<string, unknown> = {}
90+
for (const key of Object.keys(componentTheme)) {
91+
const entry = componentTheme[key]
92+
if (isModifyColor(entry)) {
93+
result[key] = resolveModifyColor(entry)
94+
} else if (
95+
typeof entry === 'object' &&
96+
entry !== null &&
97+
!Array.isArray(entry)
98+
) {
99+
result[key] = applyColorModifiers(entry as Record<string, unknown>)
100+
} else {
101+
result[key] = entry
102+
}
103+
}
104+
return result
88105
}
89106

90107
export default applyColorModifiers

packages/ui-scripts/lib/build/buildThemes/generateComponents.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ const formatComponent = (collection, key) => {
3232
return { ...acc, [key]: formatComponent(value, key) }
3333
}, {})
3434
}
35+
// `$extensions` is the Design Tokens Format spec's escape hatch for tool-specific
36+
// metadata. Tokens Studio writes color modifiers there under `studio.tokens.modify`
37+
// (e.g. `{ type: 'darken', value: 0.1 }`); we forward that payload so the runtime
38+
// (`applyColorModifiers`) can resolve the final color at theme apply time.
3539
if (value['$extensions']) {
3640
return {
3741
value: value.value,

packages/ui-scripts/lib/build/buildThemes/generateSemantics.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
*/
2424

2525
//////////////////////////////////////////////////////////////////////////////////
26-
// START OF MERGFEDEEP
26+
// START OF MERGEDEEP
2727
//////////////////////////////////////////////////////////////////////////////////
2828
//This is needed because scripts can't have dependencies (e.g. ui-utils) because it needs to be resolved before build
2929

@@ -78,7 +78,7 @@ function isArray(item: unknown): boolean {
7878
}
7979

8080
//////////////////////////////////////////////////////////////////////////////////
81-
// END OF MERGFEDEEP
81+
// END OF MERGEDEEP
8282
//////////////////////////////////////////////////////////////////////////////////
8383

8484
const isReference = (expression: any): boolean =>

packages/ui-scripts/lib/build/buildThemes/setupThemes.ts

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,6 @@ const setupThemes = async (targetPath: string, input: any): Promise<void> => {
166166
const componentThemeVars = generateComponent(
167167
component.data[fullComponentName]
168168
)
169-
170169
const componentTypes = generateComponentType(
171170
component.data[fullComponentName]
172171
)
@@ -179,13 +178,10 @@ const setupThemes = async (targetPath: string, input: any): Promise<void> => {
179178
const componentFileContent = `
180179
181180
${usesSemantic ? "import type { Semantics} from '../semantics'" : ''}
182-
import type { ${capitalize(
183-
fullComponentName
184-
)} } from '../../componentTypes/${fullComponentName}'
185181
186182
const ${fullComponentName} = (${
187183
usesSemantic ? 'semantic: Semantics' : ''
188-
}): ${capitalize(fullComponentName)} => ({${componentThemeVars}})
184+
}) => ({${componentThemeVars}})
189185
export default ${fullComponentName}
190186
`
191187
await createFile(

0 commit comments

Comments
 (0)