Skip to content

Commit c6b89ba

Browse files
authored
refactor(tokens): improve format and pkg structure (#1526)
* chore: move to tokens dir * refactor: break out themes * refactor: unitless sizes * fix: transforms * chore: use enums * feat: add tests * fix: use number for size * fix: update turbo externals * chore: remove prettier
1 parent 4dbf77f commit c6b89ba

22 files changed

+765
-327
lines changed

.github/workflows/chromatic.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ jobs:
4949
buildScriptName: 'storybook:build'
5050
exitOnceUploaded: true
5151
onlyChanged: true
52-
externals: packages/(icons/src/img|tokens/src)/**
52+
externals: packages/(icons/src/img|tokens/tokens)/**
5353

5454
a11y:
5555
name: a11y

CONTRIBUTING.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ There are just a few things to keep in mind:
129129
Note: if you are creating a pull request from a fork, CI checks will only run when it is `ready for review`. To run Chromatic, you will need to make a build locally in the terminal using the project token found in Chromatic:
130130

131131
```sh
132-
$ pnpm chromatic --project-token PROJECT_TOKEN --branch-name FORKED_BRANCH --build-script-name storybook:build --exit-once-uploaded --only-changed --externals "packages/icons/src/img/**" --externals "packages/tokens/src/**"
132+
$ pnpm chromatic --project-token PROJECT_TOKEN --branch-name FORKED_BRANCH --build-script-name storybook:build --exit-once-uploaded --only-changed --externals "packages/icons/src/img/**" --externals "packages/tokens/tokens/**"
133133
```
134134

135135
---
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2+
3+
exports[`Tokens > builds dark alias tokens 1`] = `
4+
"/**
5+
* Do not edit directly, this file was auto-generated.
6+
*/
7+
8+
[data-theme='dark'] {
9+
--lp-color-bg-interactive-link: rgba(71, 97, 255, 0.2);
10+
--lp-color-bg-feedback-error: var(--lp-color-red-900);
11+
--lp-color-bg-feedback-info: var(--lp-color-blue-900);
12+
--lp-color-bg-feedback-success: var(--lp-color-green-900);
13+
--lp-color-bg-interactive-primary-base: var(--lp-color-blue-600);
14+
--lp-color-bg-interactive-primary-active: var(--lp-color-blue-600);
15+
--lp-color-bg-interactive-primary-focus: var(--lp-color-blue-500);
16+
--lp-color-bg-interactive-primary-hover: var(--lp-color-blue-500);
17+
--lp-color-bg-interactive-secondary-focus: var(--lp-color-gray-800);
18+
--lp-color-bg-interactive-secondary-hover: var(--lp-color-gray-800);
19+
--lp-color-bg-interactive-tertiary-focus: var(--lp-color-gray-800);
20+
--lp-color-bg-interactive-tertiary-hover: var(--lp-color-gray-800);
21+
--lp-color-bg-interactive-destructive-base: var(--lp-color-red-600);
22+
--lp-color-bg-interactive-destructive-active: var(--lp-color-red-600);
23+
--lp-color-bg-interactive-destructive-focus: var(--lp-color-red-500);
24+
--lp-color-bg-interactive-destructive-hover: var(--lp-color-red-500);
25+
--lp-color-bg-interactive-disabled: var(--lp-color-gray-800);
26+
--lp-color-bg-interactive-selected: var(--lp-color-blue-950);
27+
--lp-color-bg-ui-primary: var(--lp-color-gray-950);
28+
--lp-color-bg-ui-secondary: var(--lp-color-gray-900);
29+
--lp-color-bg-ui-tertiary: var(--lp-color-gray-800);
30+
--lp-color-bg-product-beta: var(--lp-color-purple-900);
31+
--lp-color-bg-product-federal: var(--lp-color-brand-yellow-dark);
32+
--lp-color-border-feedback-error: var(--lp-color-red-400);
33+
--lp-color-border-feedback-info: var(--lp-color-blue-400);
34+
--lp-color-border-feedback-success: var(--lp-color-green-400);
35+
--lp-color-border-field-active: var(--lp-color-blue-400);
36+
--lp-color-border-field-focus: var(--lp-color-blue-400);
37+
--lp-color-border-interactive-focus: var(--lp-color-blue-400);
38+
--lp-color-border-interactive-selected: var(--lp-color-blue-400);
39+
--lp-color-border-ui-primary: var(--lp-color-gray-700);
40+
--lp-color-border-ui-secondary: var(--lp-color-gray-800);
41+
--lp-color-fill-ui-primary: var(--lp-color-gray-200);
42+
--lp-color-fill-field-base: var(--lp-color-gray-400);
43+
--lp-color-shadow-interactive-focus: var(--lp-color-blue-400);
44+
--lp-color-shadow-interactive-primary: var(--lp-color-gray-950);
45+
--lp-color-shadow-ui-primary: var(--lp-color-black-200);
46+
--lp-color-shadow-ui-secondary: var(--lp-color-black-100);
47+
--lp-color-text-feedback-error: var(--lp-color-red-400);
48+
--lp-color-text-feedback-success: var(--lp-color-green-400);
49+
--lp-color-text-feedback-info: var(--lp-color-blue-400);
50+
--lp-color-text-interactive-base: var(--lp-color-blue-400);
51+
--lp-color-text-interactive-active: var(--lp-color-purple-400);
52+
--lp-color-text-interactive-secondary: var(--lp-color-gray-400);
53+
--lp-color-text-interactive-disabled: var(--lp-color-gray-600);
54+
--lp-color-text-ui-primary-base: var(--lp-color-gray-0);
55+
--lp-color-text-ui-primary-inverted: var(--lp-color-gray-950);
56+
--lp-color-text-ui-secondary: var(--lp-color-gray-400);
57+
--lp-color-text-field-placeholder: var(--lp-color-gray-400);
58+
--lp-color-text-product-beta: var(--lp-color-purple-400);
59+
--lp-color-text-code-function: var(--lp-color-brand-purple-base);
60+
--lp-color-text-code-tag: var(--lp-color-brand-orange-base);
61+
--lp-color-text-code-string: var(--lp-color-brand-cyan-light);
62+
--lp-color-text-code-base: var(--lp-color-gray-200);
63+
--lp-color-text-code-keyword: var(--lp-color-brand-pink-light);
64+
--lp-color-text-code-title: var(--lp-color-brand-orange-light);
65+
--lp-color-text-code-number: var(--lp-color-brand-blue-light);
66+
--lp-color-bg-overlay-secondary: var(--lp-color-bg-ui-secondary);
67+
--lp-color-bg-field-base: var(--lp-color-bg-ui-secondary);
68+
}
69+
"
70+
`;
71+
72+
exports[`Tokens > builds default alias tokens 1`] = `
73+
"/**
74+
* Do not edit directly, this file was auto-generated.
75+
*/
76+
77+
:root, [data-theme] {
78+
--lp-color-bg-interactive-tertiary-base: rgba(0, 0, 0, 0);
79+
--lp-color-bg-interactive-tertiary-active: rgba(0, 0, 0, 0);
80+
--lp-color-border-interactive-primary-base: rgba(0, 0, 0, 0);
81+
--lp-color-border-interactive-primary-active: rgba(0, 0, 0, 0);
82+
--lp-color-border-interactive-primary-focus: rgba(0, 0, 0, 0);
83+
--lp-color-border-interactive-primary-hover: rgba(0, 0, 0, 0);
84+
--lp-color-border-interactive-disabled: rgba(0, 0, 0, 0);
85+
--lp-color-bg-feedback-primary: var(--lp-color-gray-800);
86+
--lp-color-bg-feedback-error: var(--lp-color-red-50);
87+
--lp-color-bg-feedback-info: var(--lp-color-blue-50);
88+
--lp-color-bg-feedback-success: var(--lp-color-green-50);
89+
--lp-color-bg-interactive-primary-base: var(--lp-color-blue-500);
90+
--lp-color-bg-interactive-primary-active: var(--lp-color-blue-500);
91+
--lp-color-bg-interactive-primary-focus: var(--lp-color-blue-600);
92+
--lp-color-bg-interactive-primary-hover: var(--lp-color-blue-600);
93+
--lp-color-bg-interactive-secondary-focus: var(--lp-color-gray-50);
94+
--lp-color-bg-interactive-secondary-hover: var(--lp-color-gray-50);
95+
--lp-color-bg-interactive-tertiary-focus: var(--lp-color-gray-50);
96+
--lp-color-bg-interactive-tertiary-hover: var(--lp-color-gray-50);
97+
--lp-color-bg-interactive-destructive-base: var(--lp-color-red-500);
98+
--lp-color-bg-interactive-destructive-active: var(--lp-color-red-500);
99+
--lp-color-bg-interactive-destructive-focus: var(--lp-color-red-600);
100+
--lp-color-bg-interactive-destructive-hover: var(--lp-color-red-600);
101+
--lp-color-bg-interactive-disabled: var(--lp-color-gray-100);
102+
--lp-color-bg-interactive-link: var(--lp-color-blue-50);
103+
--lp-color-bg-interactive-selected: var(--lp-color-blue-0);
104+
--lp-color-bg-ui-primary: var(--lp-color-white-950);
105+
--lp-color-bg-ui-secondary: var(--lp-color-gray-0);
106+
--lp-color-bg-ui-tertiary: var(--lp-color-gray-50);
107+
--lp-color-bg-product-beta: var(--lp-color-purple-100);
108+
--lp-color-bg-product-federal: var(--lp-color-brand-yellow-base);
109+
--lp-color-border-feedback-error: var(--lp-color-red-500);
110+
--lp-color-border-feedback-info: var(--lp-color-blue-500);
111+
--lp-color-border-feedback-success: var(--lp-color-green-500);
112+
--lp-color-border-field-active: var(--lp-color-blue-500);
113+
--lp-color-border-field-focus: var(--lp-color-blue-500);
114+
--lp-color-border-interactive-focus: var(--lp-color-blue-500);
115+
--lp-color-border-interactive-selected: var(--lp-color-blue-500);
116+
--lp-color-border-ui-primary: var(--lp-color-gray-100);
117+
--lp-color-border-ui-secondary: var(--lp-color-gray-50);
118+
--lp-color-fill-feedback-error: var(--lp-color-red-500);
119+
--lp-color-fill-feedback-info: var(--lp-color-blue-500);
120+
--lp-color-fill-feedback-success: var(--lp-color-green-500);
121+
--lp-color-fill-interactive-primary: var(--lp-color-white-950);
122+
--lp-color-fill-interactive-destructive: var(--lp-color-red-500);
123+
--lp-color-fill-ui-primary: var(--lp-color-gray-700);
124+
--lp-color-fill-ui-secondary: var(--lp-color-gray-500);
125+
--lp-color-fill-field-base: var(--lp-color-gray-600);
126+
--lp-color-shadow-interactive-focus: var(--lp-color-blue-600);
127+
--lp-color-shadow-interactive-primary: var(--lp-color-white-950);
128+
--lp-color-shadow-ui-primary: var(--lp-color-black-50);
129+
--lp-color-shadow-ui-secondary: var(--lp-color-black-0);
130+
--lp-color-text-feedback-error: var(--lp-color-red-600);
131+
--lp-color-text-feedback-success: var(--lp-color-green-600);
132+
--lp-color-text-feedback-info: var(--lp-color-blue-600);
133+
--lp-color-text-interactive-base: var(--lp-color-blue-600);
134+
--lp-color-text-interactive-active: var(--lp-color-purple-700);
135+
--lp-color-text-interactive-primary-base: var(--lp-color-white-950);
136+
--lp-color-text-interactive-primary-active: var(--lp-color-white-950);
137+
--lp-color-text-interactive-primary-focus: var(--lp-color-white-950);
138+
--lp-color-text-interactive-primary-hover: var(--lp-color-white-950);
139+
--lp-color-text-interactive-secondary: var(--lp-color-gray-600);
140+
--lp-color-text-interactive-disabled: var(--lp-color-gray-500);
141+
--lp-color-text-ui-primary-base: var(--lp-color-gray-900);
142+
--lp-color-text-ui-primary-inverted: var(--lp-color-white-950);
143+
--lp-color-text-ui-secondary: var(--lp-color-gray-600);
144+
--lp-color-text-field-disabled: var(--lp-color-gray-500);
145+
--lp-color-text-field-placeholder: var(--lp-color-gray-500);
146+
--lp-color-text-product-beta: var(--lp-color-purple-600);
147+
--lp-color-text-product-federal: var(--lp-color-gray-950);
148+
--lp-color-text-code-function: var(--lp-color-brand-purple-dark);
149+
--lp-color-text-code-tag: var(--lp-color-brand-orange-dark);
150+
--lp-color-text-code-string: var(--lp-color-brand-cyan-dark);
151+
--lp-color-text-code-comment: var(--lp-color-gray-400);
152+
--lp-color-text-code-base: var(--lp-color-gray-600);
153+
--lp-color-text-code-keyword: var(--lp-color-brand-pink-base);
154+
--lp-color-text-code-title: var(--lp-color-brand-orange-base);
155+
--lp-color-text-code-number: var(--lp-color-brand-blue-dark);
156+
--lp-color-bg-interactive-secondary-base: var(--lp-color-bg-ui-primary);
157+
--lp-color-bg-interactive-secondary-active: var(--lp-color-bg-ui-primary);
158+
--lp-color-bg-overlay-primary: var(--lp-color-bg-ui-primary);
159+
--lp-color-bg-overlay-secondary: var(--lp-color-bg-ui-primary);
160+
--lp-color-bg-field-base: var(--lp-color-bg-ui-primary);
161+
--lp-color-bg-field-disabled: var(--lp-color-bg-ui-tertiary);
162+
--lp-color-border-field-base: var(--lp-color-border-ui-primary);
163+
--lp-color-border-field-error: var(--lp-color-border-feedback-error);
164+
--lp-color-border-field-disabled: var(--lp-color-border-ui-secondary);
165+
--lp-color-border-interactive-secondary-base: var(--lp-color-border-ui-primary);
166+
--lp-color-border-interactive-secondary-active: var(--lp-color-border-ui-primary);
167+
--lp-color-border-interactive-secondary-focus: var(--lp-color-border-ui-primary);
168+
--lp-color-border-interactive-secondary-hover: var(--lp-color-border-ui-primary);
169+
--lp-color-border-interactive-destructive: var(--lp-color-border-feedback-error);
170+
--lp-color-text-feedback-base: var(--lp-color-text-ui-primary-base);
171+
--lp-color-text-interactive-destructive: var(--lp-color-text-feedback-error);
172+
}
173+
"
174+
`;
+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import type { DesignTokens } from 'style-dictionary/types';
2+
3+
import path from 'path';
4+
import StyleDictionary from 'style-dictionary';
5+
import { describe, expect, it } from 'vitest';
6+
7+
import { css } from '../src/themes';
8+
import aliasDark from '../tokens/color-aliases.dark.json' with { type: 'json' };
9+
import aliasDefault from '../tokens/color-aliases.default.json' with { type: 'json' };
10+
11+
const sameKeys = (tokens1: DesignTokens, tokens2: DesignTokens) => {
12+
for (const key in tokens1) {
13+
if (!(key in tokens2)) {
14+
return false;
15+
}
16+
17+
if (typeof tokens1[key] === 'object' && typeof tokens2[key] === 'object') {
18+
if (!sameKeys(tokens1[key], tokens2[key])) {
19+
return false;
20+
}
21+
}
22+
}
23+
24+
return true;
25+
};
26+
27+
describe('Tokens', () => {
28+
it('uses default theme as base for dark theme', () => {
29+
expect(sameKeys(aliasDark, aliasDefault)).toBeTruthy();
30+
});
31+
32+
it('builds default alias tokens', async () => {
33+
const config = css('default');
34+
config.source = [
35+
path.resolve(__dirname, '../tokens/color-primitives.json'),
36+
path.resolve(__dirname, '../tokens/color-aliases.default.json'),
37+
];
38+
39+
const sd = new StyleDictionary(config);
40+
const [file] = await sd.formatPlatform('css');
41+
42+
expect(file.output).toMatchSnapshot();
43+
});
44+
45+
it('builds dark alias tokens', async () => {
46+
const config = css('dark');
47+
config.source = [
48+
path.resolve(__dirname, '../tokens/color-primitives.json'),
49+
path.resolve(__dirname, '../tokens/color-aliases.dark.json'),
50+
];
51+
52+
const sd = new StyleDictionary(config);
53+
const [file] = await sd.formatPlatform('css');
54+
55+
expect(file.output).toMatchSnapshot();
56+
});
57+
});

packages/tokens/package.json

+2-3
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,13 @@
3838
"./dist/tokens.json": "./dist/tokens.json"
3939
},
4040
"scripts": {
41-
"build": "tsx build.ts && tsc --noEmit",
41+
"build": "tsx src/build.ts && tsc --noEmit",
4242
"clean": "rm -rf dist",
4343
"lint": "exit 0",
44-
"test": "exit 0"
44+
"test": "vitest run"
4545
},
4646
"devDependencies": {
4747
"json-to-ts": "^2.1.0",
48-
"prettier": "^3.4.1",
4948
"style-dictionary": "^4.3.0",
5049
"tsx": "^4.19.0"
5150
}

0 commit comments

Comments
 (0)