@carbon/themes 11.81.0 → 11.82.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -9,10 +9,8 @@ industry-standard format.
9
9
 
10
10
  ```
11
11
  dtcg/
12
- ├── white.json # White theme (light, high contrast)
13
- ├── g10.json # Gray 10 theme (light)
14
- ├── g90.json # Gray 90 theme (dark)
15
- ├── g100.json # Gray 100 theme (dark, high contrast)
12
+ ├── themes.json # All four themes in one file (white, g10, g90, g100)
13
+ ├── color-palette.json # Color palette aliases (generated from @carbon/colors)
16
14
  └── components/
17
15
  ├── button.json # Button component tokens
18
16
  ├── tag.json # Tag component tokens
@@ -21,6 +19,111 @@ dtcg/
21
19
  └── content-switcher.json # Content switcher tokens
22
20
  ```
23
21
 
22
+ ## Token categories in each theme file
23
+
24
+ `themes.json` is organised into top-level groups. When searching for a token,
25
+ start with the group that matches the first segment of its name:
26
+
27
+ | Top-level key | Token name prefix examples |
28
+ | ------------- | ----------------------------------------------------------- |
29
+ | `ai` | `ai-aura-*`, `ai-popover-*`, `ai-skeleton-*` |
30
+ | `background` | `background`, `background-active`, `background-hover` |
31
+ | `border` | `border-subtle-*`, `border-strong-*`, `border-tile-*` |
32
+ | `button` | _(component tokens — see `components/button.json` instead)_ |
33
+ | `field` | `field-01`, `field-02`, `field-hover-01` |
34
+ | `focus` | `focus`, `focus-inset`, `focus-inverse` |
35
+ | `icon` | `icon-primary`, `icon-on-color`, `icon-disabled` |
36
+ | `layer` | `layer-01`, `layer-active-01`, `layer-hover-01` |
37
+ | `link` | `link-primary`, `link-visited`, `link-inverse` |
38
+ | `overlay` | `overlay` |
39
+ | `skeleton` | `skeleton-background`, `skeleton-element` |
40
+ | `support` | `support-error`, `support-warning`, `support-success` |
41
+ | `text` | `text-primary`, `text-on-color`, `text-disabled` |
42
+
43
+ > **Note:** Component tokens (`button`, `tag`, etc.) live in
44
+ > `components/<name>.json`, **not** in `themes.json`.
45
+
46
+ ## Nested key → flat token name mapping
47
+
48
+ Token names in Carbon use a hyphenated convention (e.g. `border-subtle-02`,
49
+ `text-on-color-disabled`). In the DTCG JSON files these are represented as
50
+ **nested objects**, where each hyphen-separated segment becomes a JSON key
51
+ level:
52
+
53
+ | Flat token name | JSON path |
54
+ | ------------------------ | ------------------------------------ |
55
+ | `border-subtle-02` | `border` → `subtle` → `02` |
56
+ | `text-on-color-disabled` | `text` → `on-color` → `disabled` |
57
+ | `layer-accent-active-03` | `layer` → `accent` → `active` → `03` |
58
+
59
+ > **Tip for agents:** Do not `grep` for the full hyphenated name — it will not
60
+ > match. Instead grep for the last segment (`"02"`, `"disabled"`) and navigate
61
+ > up the JSON hierarchy to confirm the full path, or read the surrounding
62
+ > context to resolve ambiguity when short keys like `"01"` or `"02"` appear in
63
+ > multiple token groups.
64
+
65
+ ## Contextual layer tokens (`$layer-*` without numbers)
66
+
67
+ In component styles (e.g. `$layer-accent`, `$layer-hover`, `$field`,
68
+ `$border-subtle`), you will often see unnumbered tokens used. These are
69
+ **dynamic layer-set tokens** defined in
70
+ `packages/styles/scss/layer/_layer-sets.scss`.
71
+
72
+ In DTCG JSON, tokens only exist as explicit numbered levels (`01`, `02`, `03`):
73
+
74
+ - `layer.01` / `layer.02` / `layer.03`
75
+ - `layer.accent.01` / `layer.accent.02` / `layer.accent.03`
76
+ - `layer.accent.active.01` / `layer.accent.active.02` / `layer.accent.active.03`
77
+
78
+ At runtime or inside a `<Layer>` component context, Carbon automatically
79
+ resolves the unnumbered token (e.g. `$layer-accent`) to its corresponding
80
+ numbered tier (`01`, `02`, or `03`) based on container nesting depth.
81
+
82
+ ## Dual-role nodes (tokens that are also groups)
83
+
84
+ Some tokens are simultaneously a value **and** a group of related tokens. For
85
+ example, `background` has its own per-theme value but also has children like
86
+ `background-active` and `background-hover`. In `themes.json` these look like:
87
+
88
+ ```json
89
+ "background": {
90
+ "$type": "color",
91
+ "$description": "…",
92
+ "$extensions": {
93
+ "carbon.themes": {
94
+ "white": "{white.default}", "g10": "{gray.10}",
95
+ "g90": "{gray.90}", "g100": "{gray.100}"
96
+ }
97
+ },
98
+ "active": {
99
+ "$type": "color",
100
+ "$extensions": { "carbon.themes": { "white": { "value": "{gray.50}", "alpha": 0.5 }, … } }
101
+ },
102
+ "hover": {
103
+ "$type": "color",
104
+ "$extensions": { "carbon.themes": { "white": { "value": "{gray.50}", "alpha": 0.12 }, … } }
105
+ }
106
+ }
107
+ ```
108
+
109
+ The flat names generated are `background`, `background-active`,
110
+ `background-hover` — all siblings in the output even though they are
111
+ parent/child in the source JSON.
112
+
113
+ > **Tip for agents:** If you read a node and it has both a
114
+ > `$extensions["carbon.themes"]` entry and non-`$` children, both the node
115
+ > itself **and** every child are valid tokens. Do not assume a node with
116
+ > children is only a group.
117
+
118
+ ## `carbon.themes` value aliases and `color-palette.json`
119
+
120
+ The `value` field inside each `carbon.themes` entry uses curly-brace alias
121
+ syntax referencing the color palette, e.g. `"{blue.60}"` or `"{gray.20}"`. These
122
+ references are resolved during the build against
123
+ `packages/themes/src/dtcg/color-palette.json`, which contains the full Carbon
124
+ color ramp (`gray.10` … `gray.100`, `blue.10` … `blue.100`, etc.) with their hex
125
+ values. If you need the actual hex for an alias, look it up in that file.
126
+
24
127
  ## Token Format
25
128
 
26
129
  All tokens follow the DTCG specification with a structured format using specific
@@ -47,86 +150,108 @@ keys:
47
150
  #### Optional Keys
48
151
 
49
152
  - **`$extensions`** - Custom metadata and vendor-specific information. Carbon
50
- uses this for:
153
+ uses two namespaces — see the dedicated sections below for full details.
51
154
 
52
- - **`carbon.themes`** - Theme-specific values for component tokens:
53
- ```json
54
- "$extensions": {
55
- "carbon.themes": {
56
- "white": "{blue.60}",
57
- "g10": "{blue.60}",
58
- "g90": "{blue.60}",
59
- "g100": "{blue.60}"
60
- }
61
- }
62
- ```
63
- - **`org.carbon`** - Carbon-specific metadata like alpha modifiers:
64
- ```json
65
- "$extensions": {
66
- "org.carbon": {
67
- "alphaModifier": 0.5,
68
- "color-scheme": "light"
69
- }
70
- }
71
- ```
155
+ ## Semi-transparent tokens — the `alpha` field
72
156
 
73
- ### Example: Theme Token
157
+ Some tokens are a base color with an opacity applied. In `themes.json` the
158
+ opacity is expressed as an `alpha` field co-located with `value` inside the
159
+ per-theme entry:
74
160
 
75
161
  ```json
76
- {
77
- "$schema": "https://tr.designtokens.org/format/",
78
- "$description": "White theme - Light theme with high contrast",
79
- "background": {
80
- "$type": "color",
81
- "$value": "{white.default}",
82
- "$description": "Default page background color. Use as the base surface for the entire application."
83
- },
84
- "background-hover": {
162
+ "background": {
163
+ "hover": {
85
164
  "$type": "color",
86
- "$value": "{gray.50}",
87
- "$description": "Background color for hover state. Use when user hovers over interactive elements.",
165
+ "$description": "Background color for hover state.",
88
166
  "$extensions": {
89
- "org.carbon": {
90
- "alphaModifier": 0.12
167
+ "carbon.themes": {
168
+ "white": { "value": "{gray.50}", "alpha": 0.12 },
169
+ "g10": { "value": "{gray.50}", "alpha": 0.12 },
170
+ "g90": { "value": "{gray.50}", "alpha": 0.16 },
171
+ "g100": { "value": "{gray.50}", "alpha": 0.16 }
91
172
  }
92
173
  }
93
174
  }
94
175
  }
95
176
  ```
96
177
 
97
- ### Example: Component Token
178
+ During the build the `carbon/alpha-modifier` Style Dictionary transform resolves
179
+ `{gray.50}` to its hex (`#8d8d8d`) and then emits `rgba(141, 141, 141, 0.12)`.
180
+
181
+ > **Reading the source:** When a `carbon.themes` entry is an object, the `value`
182
+ > field alone does **not** tell you the final color. The real output is
183
+ > `rgba(<palette hex at value>, <alpha>)`. Check `color-palette.json` for the
184
+ > hex, then apply `alpha` mentally.
185
+
186
+ > **`alpha: 0`** means fully transparent (`rgba(…, 0)`). Used for gradient "fade
187
+ > to transparent" endpoints (e.g. `ai-aura-end`).
188
+
189
+ > **Note for component token files:** `components/*.json` still use the legacy
190
+ > `$extensions["org.carbon"].alphaModifiers` map (plural, keyed by theme) rather
191
+ > than the co-located `alpha` field. The build preprocessor accepts both forms.
192
+
193
+ ## `$extensions["carbon.themes"]` — the unified per-theme format
194
+
195
+ Both theme tokens (`themes.json`) and component tokens (`components/*.json`)
196
+ store per-theme values under the same `$extensions["carbon.themes"]` key. Each
197
+ entry for a theme is either:
198
+
199
+ - **A bare string** (palette alias or hex) when there is no alpha modifier:
200
+ ```json
201
+ "white": "{gray.10}"
202
+ ```
203
+ - **An object `{ value, alpha }`** when an opacity modifier is needed:
204
+ ```json
205
+ "white": { "value": "{gray.50}", "alpha": 0.12 }
206
+ ```
207
+
208
+ Example token from `themes.json`:
98
209
 
99
210
  ```json
100
- {
101
- "$schema": "https://tr.designtokens.org/format/",
102
- "$description": "Button component color tokens",
103
- "button": {
104
- "primary": {
105
- "$type": "color",
106
- "$description": "Background color for primary buttons in default state.",
107
- "$extensions": {
108
- "carbon.themes": {
109
- "white": "{blue.60}",
110
- "g10": "{blue.60}",
111
- "g90": "{blue.60}",
112
- "g100": "{blue.60}"
113
- }
211
+ "background": {
212
+ "hover": {
213
+ "$type": "color",
214
+ "$description": "Background color for hover state.",
215
+ "$extensions": {
216
+ "carbon.themes": {
217
+ "white": { "value": "{gray.50}", "alpha": 0.12 },
218
+ "g10": { "value": "{gray.50}", "alpha": 0.12 },
219
+ "g90": { "value": "{gray.50}", "alpha": 0.16 },
220
+ "g100": { "value": "{gray.50}", "alpha": 0.16 }
114
221
  }
115
222
  }
116
223
  }
117
224
  }
118
225
  ```
119
226
 
227
+ The `carbon/component-tokens` preprocessor understands both entry shapes and
228
+ expands them into per-theme leaf tokens before Style Dictionary processes them.
229
+
230
+ ### Comparison: theme tokens vs. component tokens
231
+
232
+ | | Theme token (`themes.json`) | Component token (`components/button.json`) |
233
+ | ------------- | --------------------------------------------------------------------- | -------------------------------------------------------------------------- |
234
+ | File scope | All four themes | All four themes |
235
+ | Value field | `$extensions["carbon.themes"]["<theme>"]` (string or `{value,alpha}`) | `$extensions["carbon.themes"]["<theme>"]` (string) |
236
+ | Alpha opacity | Co-located: `{ "value": "…", "alpha": 0.12 }` | Separate: `$extensions["org.carbon"].alphaModifiers.<theme>` (note plural) |
237
+ | Grepping | Navigate nested keys | Same nesting rules apply |
238
+
239
+ > **Note:** Component files still use the legacy `org.carbon.alphaModifiers` map
240
+ > for backwards compatibility. Both forms are accepted by the preprocessor.
241
+
242
+ > **Reading theme token values:** Navigate to the nested key in `themes.json`,
243
+ > then read the value for the theme you care about from `carbon.themes`.
244
+
120
245
  ## Theme Tokens
121
246
 
122
- All four Carbon themes are available in DTCG format:
247
+ All four Carbon themes are consolidated into `themes.json`:
123
248
 
124
- - **white.json** - White theme (light, high contrast)
125
- - **g10.json** - Gray 10 theme (light)
126
- - **g90.json** - Gray 90 theme (dark)
127
- - **g100.json** - Gray 100 theme (dark, high contrast)
249
+ - **white** — Light theme, high contrast for optimal readability
250
+ - **g10** — Gray 10 light theme, subtle contrast for data-dense interfaces
251
+ - **g90** — Gray 90 dark theme
252
+ - **g100** — Gray 100 dark theme, high contrast
128
253
 
129
- Each theme file contains 250+ tokens organized into categories:
254
+ The file contains 250+ tokens organised into categories:
130
255
 
131
256
  - **Color tokens**: Background, layer, field, border, text, link, icon, support
132
257
  colors
@@ -172,7 +297,7 @@ Manual validation can be performed using any JSON Schema validator:
172
297
 
173
298
  ```bash
174
299
  # Using ajv-cli
175
- ajv validate -s https://tr.designtokens.org/format/schema.json -d white.json
300
+ ajv validate -s https://tr.designtokens.org/format/schema.json -d themes.json
176
301
  ```
177
302
 
178
303
  ## Contributing
@@ -185,7 +310,8 @@ When adding or modifying tokens:
185
310
  `$description`
186
311
  3. **Use appropriate types** - Set correct `$type` values (color, dimension,
187
312
  etc.)
188
- 4. **Add theme-specific values** - Use `$extensions.carbon.themes` for component
313
+ 4. **Add theme-specific values** - Edit `themes.json` for theme tokens; use
314
+ `$extensions["carbon.themes"]` in `components/<name>.json` for component
189
315
  tokens
190
316
  5. **Validate your changes** - Run `yarn build` to validate against DTCG schema
191
317
  6. **Test generated output** - Verify SCSS generation works correctly