Tokens are generated with Style Dictionary from a single tokens.json exported by Token Studio (Figma). This file contains:
- Tokens: the base/palette of values (colors, spacing, typography, etc.).
- Light Mode and Dark Mode: usage aliases that reference the base via
{references}.
Simplified example of the Token Studio format:
{
"Tokens": {
"neutral": {
"black": { "$type": "color", "$value": "#000000" },
"white": { "$type": "color", "$value": "#ffffff" }
}
},
"Light Mode": {
"background": {
"default": { "$type": "color", "$value": "{brown.50}" },
"inverse": { "$type": "color", "$value": "{gray.900}" }
}
},
"Dark Mode": {
"background": {
"default": { "$type": "color", "$value": "{gray.900}" },
"inverse": { "$type": "color", "$value": "{brown.50}" }
}
}
}Tools used:
style-dictionary@5@tokens-studio/sd-transforms
Key points from the current configuration (config.js):
- Two parsers filter the mode before building:
light-parserremoves theDark Modekey.dark-parserremoves theLight Modekey.
- For CSS we use
transformGroup: tokens-studioandname/kebab(generates--tokens-in-kebab-case). - For JS we use
transformGroup: tokens-studioandname/constant(generatesCONSTANT_CASE). - For Dark,
outputReferences: trueis enabled to keep variable references (for example,var(--gray-900)), aiding overrides and consistency.
Build script (package.json):
yarn build- CSS
dist/css/light.css: defines variables on:root(resolved values, e.g., hex/px).dist/css/dark.css: defines variables on.dark(many asvar(...)referencing the base palette).
- JS (ESM)
dist/js/light.jsdist/js/dark.js
Example (real snippets):
:root {
--background-default: #fdfcfc;
--background-inverse: #19191a;
// ... more variables
}.dark {
--background-default: var(--gray-900);
--background-inverse: var(--brown-50);
// ... more variables
}- Import the stylesheets:
@import url('@getpingback/design-tokens/css/light.css');
@import url('@getpingback/design-tokens/css/dark.css');- Apply the
darkclass on the root container when you want Dark Mode:
<html class="dark">
...
</html>- Consume the variables in your components:
background: var(--background-default);
color: var(--text-default-primary);import { BACKGROUND_DEFAULT } from '@getpingback/design-tokens/js/light';
// or
import { BACKGROUND_DEFAULT as DARK_BACKGROUND_DEFAULT } from '@getpingback/design-tokens/js/dark';- Update
tokens.jsonexported from Token Studio (keep the structure:Tokens,Light Mode,Dark Mode). - Run
yarn buildto generatedist/css/*.cssanddist/js/*.js.
- Naming: CSS in kebab-case (
--background-default), JS in CONSTANT_CASE (BACKGROUND_DEFAULT). - Light vs Dark: Light resolves values; Dark keeps references where possible to reflect the base palette.
- Single theme with modes: We no longer generate multiple theme folders nor
main.css. Consumption is via global variables and mode switching via.dark.