You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The Tokens Studio platform has no TypeScript export format, so this adds a small dependency-free codegen script that combines the two exports the release workflow already produces:
DTCG export (new EDS-DTCG configuration, added as a workflow step) provides the token tree structure and $type metadata — its values are unresolved {alias} references and colour formulas
CSS export provides the evaluated concrete values; the script dereferences the var(--eds-*) chains per dimension context (colour scheme × density)
scripts/generate-ts-tokens.mjs then emits as const TypeScript modules to packages/eds-tokens/src/tokens/ts/, mirroring the export layout. Modules that resolve differently per colour scheme (currently semantic/) are automatically split into per-scheme files.
Values are converted to React Native friendly forms for equinor/design-system-mobile (the only known TS-token consumer, see #5164):
oklch() → hex via CSS Color 4 §13.2 gamut mapping (chroma bisection, not naive channel clipping) — verified identical to lightningcss for all 199 unique colours in the current export
px dimensions → unitless numbers
Also fixes the workflow referencing the CSS export by name: the configuration was renamed EDS → EDS-CSS in Tokens Studio, which would have broken the next release run. Both exports are now referenced by ID, which is rename-proof.
Verified locally against real platform exports: 10 generated modules, tsc --noEmit --strict passes. Like the CSS output, the generated TS is not yet wired into the package exports map.
Note for the mobile migration: the new density dimension is comfortable/compact/relaxed — spacious (which mobile imports today) no longer exists.
Nice piece of work — the dependency-free oklch→hex gamut mapping (CSS Color 4 §13.2 chroma bisection rather than naive channel clipping), the fail-loud philosophy throughout, the clean rm(OUT_DIR) regeneration, and referencing the exports by ID instead of name are all the right calls. A few things worth considering, roughly in order of importance.
1. toTsSource string serialisation is fragile (latent correctness)
packages/eds-tokens/scripts/generate-ts-tokens.mjs:284-292 builds the source by regex-rewriting JSON.stringify output, ending with a global .replace(/"/g, "'"). That's safe for hex colours and numbers, but it breaks for any string value that itself contains a ", ', or the general shape of a font stack. The realistic case is a fontFamily token (returned verbatim by convertValue, line 233):
It passes tsc --strict today only because the current export's font-family values happen to be simple. The moment a stack or a quoted family appears, the generated module is malformed and the release PR gets no CI to catch it (per the workflow comment). Safer to serialise each string value through JSON.stringify on its own (which escapes correctly) and only special-case the key rewriting, rather than a blanket quote swap over the whole document. Fix this →
2. Generated files won't pass the package's own prettier:check
The output lands in src/tokens/ts/ and package.json already exposes "prettier:check": "prettier --check src/". The repo's .prettierrc.yaml sets trailingComma: all, but JSON.stringify(value, null, 2) emits no trailing commas, and src/tokens/ts is not in any .prettierignore (root .prettierignore only covers packages/eds-tokens/build/*). So prettier --check src/ will report every generated module as unformatted. singleQuote, semi: false and tabWidth: 2 all match already — trailing commas are the only gap. Either run the output through Prettier at the end of the script, or add src/tokens/ts (and likely src/tokens/css) to a prettier-ignore. Fix this →
Minor notes (no action strictly required)
buildContext layout coupling (lines 85-101): the CSS part list and the two-level file.split('/') assumption (line 327) are hardwired to the current saved-export shape. Extra CSS files are silently ignored and a deeper nesting would be mis-parsed. Fine given the comment tying it to the saved config, but a new folder in the export would need a code change (and it'd only fail loudly for the listed files, not for silently-dropped new ones).
Density uses schemes[0] (line 351): resolving density files against an arbitrary scheme assumes density tokens never depend on colour scheme. True for spacing/sizing, but if a density token ever referenced a scheme-varying colour it would silently bake in schemes[0].
Parser strictness: oklchToHex/rgbToHex and the numeric regex (lines 171, 210, 229) accept only the exact current forms — no oklch(... / a), deg/% hue, rem, or scientific notation. That's a deliberate fail-loud, which is good; just noting the pipeline is pinned to today's CSS export syntax.
Cosmetic: oklch resolves to 6-digit hex while rgb() resolves to 8-digit #rrggbbaa (alpha emitted even when opaque). Consumers on RN handle both, so harmless — just inconsistent.
Overall this looks solid and well-reasoned; #1 is the one I'd address before this pipeline runs unattended, since a malformed module there would be silent.
• chore/tokens-studio-ts-tokens
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #5164
The Tokens Studio platform has no TypeScript export format, so this adds a small dependency-free codegen script that combines the two exports the release workflow already produces:
EDS-DTCGconfiguration, added as a workflow step) provides the token tree structure and$typemetadata — its values are unresolved{alias}references and colour formulasvar(--eds-*)chains per dimension context (colour scheme × density)scripts/generate-ts-tokens.mjsthen emitsas constTypeScript modules topackages/eds-tokens/src/tokens/ts/, mirroring the export layout. Modules that resolve differently per colour scheme (currentlysemantic/) are automatically split into per-scheme files.Values are converted to React Native friendly forms for
equinor/design-system-mobile(the only known TS-token consumer, see #5164):oklch()→ hex via CSS Color 4 §13.2 gamut mapping (chroma bisection, not naive channel clipping) — verified identical to lightningcss for all 199 unique colours in the current exportpxdimensions → unitless numbersAlso fixes the workflow referencing the CSS export by name: the configuration was renamed
EDS→EDS-CSSin Tokens Studio, which would have broken the next release run. Both exports are now referenced by ID, which is rename-proof.Verified locally against real platform exports: 10 generated modules,
tsc --noEmit --strictpasses. Like the CSS output, the generated TS is not yet wired into the packageexportsmap.Note for the mobile migration: the new density dimension is comfortable/compact/relaxed —
spacious(which mobile imports today) no longer exists.