@servicetitan/hammer-token 2.5.0 → 3.0.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.
- package/CHANGELOG.md +56 -0
- package/README.md +332 -0
- package/build/web/core/component-variables.scss +1088 -131
- package/build/web/core/component.d.ts +558 -0
- package/build/web/core/component.js +6685 -249
- package/build/web/core/component.scss +557 -69
- package/build/web/core/css-utils/a2-border.css +47 -45
- package/build/web/core/css-utils/a2-color.css +443 -227
- package/build/web/core/css-utils/a2-font.css +0 -2
- package/build/web/core/css-utils/a2-spacing.css +476 -478
- package/build/web/core/css-utils/a2-utils.css +992 -772
- package/build/web/core/css-utils/border.css +47 -45
- package/build/web/core/css-utils/color.css +443 -227
- package/build/web/core/css-utils/font.css +0 -2
- package/build/web/core/css-utils/spacing.css +476 -478
- package/build/web/core/css-utils/utils.css +992 -772
- package/build/web/core/index.d.ts +6 -0
- package/build/web/core/index.js +1 -1
- package/build/web/core/primitive-variables.scss +148 -65
- package/build/web/core/primitive.d.ts +209 -0
- package/build/web/core/primitive.js +779 -61
- package/build/web/core/primitive.scss +207 -124
- package/build/web/core/semantic-variables.scss +363 -239
- package/build/web/core/semantic.d.ts +221 -0
- package/build/web/core/semantic.js +1613 -347
- package/build/web/core/semantic.scss +219 -137
- package/build/web/index.d.ts +3 -4
- package/build/web/index.js +0 -1
- package/build/web/types.d.ts +17 -0
- package/config.js +121 -497
- package/eslint.config.mjs +11 -1
- package/package.json +15 -5
- package/src/global/primitive/breakpoint.tokens.json +54 -0
- package/src/global/primitive/color.tokens.json +1092 -0
- package/src/global/primitive/duration.tokens.json +44 -0
- package/src/global/primitive/font.tokens.json +151 -0
- package/src/global/primitive/radius.tokens.json +94 -0
- package/src/global/primitive/size.tokens.json +174 -0
- package/src/global/primitive/transition.tokens.json +32 -0
- package/src/theme/core/background.tokens.json +1312 -0
- package/src/theme/core/border.tokens.json +192 -0
- package/src/theme/core/chart.tokens.json +982 -0
- package/src/theme/core/component/ai-mark.tokens.json +20 -0
- package/src/theme/core/component/alert.tokens.json +261 -0
- package/src/theme/core/component/announcement.tokens.json +460 -0
- package/src/theme/core/component/avatar.tokens.json +137 -0
- package/src/theme/core/component/badge.tokens.json +42 -0
- package/src/theme/core/component/breadcrumb.tokens.json +42 -0
- package/src/theme/core/component/button-toggle.tokens.json +428 -0
- package/src/theme/core/component/button.tokens.json +941 -0
- package/src/theme/core/component/calendar.tokens.json +391 -0
- package/src/theme/core/component/card.tokens.json +107 -0
- package/src/theme/core/component/checkbox.tokens.json +631 -0
- package/src/theme/core/component/chip.tokens.json +169 -0
- package/src/theme/core/component/combobox.tokens.json +269 -0
- package/src/theme/core/component/details.tokens.json +152 -0
- package/src/theme/core/component/dialog.tokens.json +87 -0
- package/src/theme/core/component/divider.tokens.json +23 -0
- package/src/theme/core/component/dnd.tokens.json +208 -0
- package/src/theme/core/component/drawer.tokens.json +61 -0
- package/src/theme/core/component/drilldown.tokens.json +61 -0
- package/src/theme/core/component/edit-card.tokens.json +381 -0
- package/src/theme/core/component/field-label.tokens.json +42 -0
- package/src/theme/core/component/field-message.tokens.json +74 -0
- package/src/theme/core/component/icon.tokens.json +42 -0
- package/src/theme/core/component/link.tokens.json +108 -0
- package/src/theme/core/component/list-view.tokens.json +82 -0
- package/src/theme/core/component/listbox.tokens.json +283 -0
- package/src/theme/core/component/menu.tokens.json +230 -0
- package/src/theme/core/component/overflow.tokens.json +84 -0
- package/src/theme/core/component/page.tokens.json +377 -0
- package/src/theme/core/component/pagination.tokens.json +63 -0
- package/src/theme/core/component/popover.tokens.json +122 -0
- package/src/theme/core/component/progress-bar.tokens.json +133 -0
- package/src/theme/core/component/radio.tokens.json +631 -0
- package/src/theme/core/component/segmented-control.tokens.json +175 -0
- package/src/theme/core/component/select-card.tokens.json +943 -0
- package/src/theme/core/component/side-nav.tokens.json +349 -0
- package/src/theme/core/component/skeleton.tokens.json +42 -0
- package/src/theme/core/component/spinner.tokens.json +96 -0
- package/src/theme/core/component/status-icon.tokens.json +164 -0
- package/src/theme/core/component/stepper.tokens.json +484 -0
- package/src/theme/core/component/switch.tokens.json +285 -0
- package/src/theme/core/component/tab.tokens.json +192 -0
- package/src/theme/core/component/text-field.tokens.json +160 -0
- package/src/theme/core/component/text.tokens.json +59 -0
- package/src/theme/core/component/toast.tokens.json +343 -0
- package/src/theme/core/component/toolbar.tokens.json +114 -0
- package/src/theme/core/component/tooltip.tokens.json +61 -0
- package/src/theme/core/focus.tokens.json +56 -0
- package/src/theme/core/foreground.tokens.json +416 -0
- package/src/theme/core/gradient.tokens.json +41 -0
- package/src/theme/core/opacity.tokens.json +25 -0
- package/src/theme/core/shadow.tokens.json +81 -0
- package/src/theme/core/status.tokens.json +74 -0
- package/src/theme/core/typography.tokens.json +163 -0
- package/src/utils/__tests__/css-utils-format-utils.test.js +312 -0
- package/src/utils/__tests__/sd-build-configs.test.js +306 -0
- package/src/utils/__tests__/sd-formats.test.js +950 -0
- package/src/utils/__tests__/sd-transforms.test.js +336 -0
- package/src/utils/__tests__/token-helpers.test.js +1160 -0
- package/src/utils/copy-css-utils-cli.js +13 -1
- package/src/utils/css-utils-format-utils.js +105 -176
- package/src/utils/figma/__tests__/sync-gradient.test.js +561 -0
- package/src/utils/figma/__tests__/token-conversion.test.js +117 -0
- package/src/utils/figma/__tests__/token-resolution.test.js +231 -0
- package/src/utils/figma/auth.js +355 -0
- package/src/utils/figma/constants.js +22 -0
- package/src/utils/figma/errors.js +80 -0
- package/src/utils/figma/figma-api.js +1069 -0
- package/src/utils/figma/get-token.js +348 -0
- package/src/utils/figma/sync-components.js +909 -0
- package/src/utils/figma/sync-main.js +692 -0
- package/src/utils/figma/sync-orchestration.js +683 -0
- package/src/utils/figma/sync-primitives.js +230 -0
- package/src/utils/figma/sync-semantic.js +1056 -0
- package/src/utils/figma/token-conversion.js +340 -0
- package/src/utils/figma/token-parsing.js +186 -0
- package/src/utils/figma/token-resolution.js +569 -0
- package/src/utils/figma/utils.js +199 -0
- package/src/utils/sd-build-configs.js +305 -0
- package/src/utils/sd-formats.js +965 -0
- package/src/utils/sd-transforms.js +165 -0
- package/src/utils/token-helpers.js +848 -0
- package/tsconfig.json +18 -0
- package/vitest.config.js +17 -0
- package/.turbo/turbo-build.log +0 -37
- package/build/web/core/raw.js +0 -229
- package/src/global/primitive/breakpoint.js +0 -19
- package/src/global/primitive/color.js +0 -231
- package/src/global/primitive/duration.js +0 -16
- package/src/global/primitive/font.js +0 -60
- package/src/global/primitive/radius.js +0 -31
- package/src/global/primitive/size.js +0 -55
- package/src/global/primitive/transition.js +0 -16
- package/src/theme/core/background.js +0 -170
- package/src/theme/core/border.js +0 -103
- package/src/theme/core/charts.js +0 -439
- package/src/theme/core/component/button.js +0 -708
- package/src/theme/core/component/checkbox.js +0 -405
- package/src/theme/core/focus.js +0 -35
- package/src/theme/core/foreground.js +0 -148
- package/src/theme/core/overlay.js +0 -137
- package/src/theme/core/shadow.js +0 -29
- package/src/theme/core/status.js +0 -49
- package/src/theme/core/typography.js +0 -82
- package/type/types.ts +0 -341
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,61 @@
|
|
|
1
1
|
# @servicetitan/hammer-token
|
|
2
2
|
|
|
3
|
+
## 3.0.0
|
|
4
|
+
|
|
5
|
+
### Major Changes
|
|
6
|
+
|
|
7
|
+
- [#1899](https://github.com/servicetitan/hammer/pull/1899) [`6ea319a`](https://github.com/servicetitan/hammer/commit/6ea319a282209312485756bfd37f1e2102f8c7e5) Thanks [@tounsoo](https://github.com/tounsoo)! - [Tokens] Renaming of interactive tokens for clarity and better typeahead support.
|
|
8
|
+
|
|
9
|
+
- [#1899](https://github.com/servicetitan/hammer/pull/1899) [`6ea319a`](https://github.com/servicetitan/hammer/commit/6ea319a282209312485756bfd37f1e2102f8c7e5) Thanks [@tounsoo](https://github.com/tounsoo)! - 3.0 Pre-release.
|
|
10
|
+
|
|
11
|
+
- [#1899](https://github.com/servicetitan/hammer/pull/1899) [`6ea319a`](https://github.com/servicetitan/hammer/commit/6ea319a282209312485756bfd37f1e2102f8c7e5) Thanks [@tounsoo](https://github.com/tounsoo)! - [Tokens] Chart stroke token is split into `stroke.color` and `fill.pattern` for clarity; chart category collections renamed from `ChartsCategorical`/`ChartsMonochrome`/`ChartsStatus` to `ChartCategorical`/`ChartMonochrome`/`ChartStatus`. Consumers of the ext-charts themes receive the new names automatically
|
|
12
|
+
|
|
13
|
+
- [#1899](https://github.com/servicetitan/hammer/pull/1899) [`6ea319a`](https://github.com/servicetitan/hammer/commit/6ea319a282209312485756bfd37f1e2102f8c7e5) Thanks [@tounsoo](https://github.com/tounsoo)! - [Tokens] JS import object changed to match DTCG format.
|
|
14
|
+
|
|
15
|
+
- [#1899](https://github.com/servicetitan/hammer/pull/1899) [`6ea319a`](https://github.com/servicetitan/hammer/commit/6ea319a282209312485756bfd37f1e2102f8c7e5) Thanks [@tounsoo](https://github.com/tounsoo)! - [Tokens] Prefix all CSS variables with `a2-` to prevent naming collisions (e.g., `--color-primary` becomes `--a2-color-primary`)
|
|
16
|
+
|
|
17
|
+
- [#1899](https://github.com/servicetitan/hammer/pull/1899) [`6ea319a`](https://github.com/servicetitan/hammer/commit/6ea319a282209312485756bfd37f1e2102f8c7e5) Thanks [@tounsoo](https://github.com/tounsoo)! - [Tokens] Renamed types exported for clarity of use.
|
|
18
|
+
|
|
19
|
+
### Minor Changes
|
|
20
|
+
|
|
21
|
+
- [#1899](https://github.com/servicetitan/hammer/pull/1899) [`6ea319a`](https://github.com/servicetitan/hammer/commit/6ea319a282209312485756bfd37f1e2102f8c7e5) Thanks [@tounsoo](https://github.com/tounsoo)! - [Tokens] Update color ramp and add T3 component tokens for breadcrumb, button, buttonToggle, and link
|
|
22
|
+
|
|
23
|
+
- [#1899](https://github.com/servicetitan/hammer/pull/1899) [`6ea319a`](https://github.com/servicetitan/hammer/commit/6ea319a282209312485756bfd37f1e2102f8c7e5) Thanks [@tounsoo](https://github.com/tounsoo)! - [Tokens] Add `mauves` and `lime` primitive color palettes.
|
|
24
|
+
|
|
25
|
+
### Patch Changes
|
|
26
|
+
|
|
27
|
+
- [#1899](https://github.com/servicetitan/hammer/pull/1899) [`6ea319a`](https://github.com/servicetitan/hammer/commit/6ea319a282209312485756bfd37f1e2102f8c7e5) Thanks [@tounsoo](https://github.com/tounsoo)! - [Tokens] Add Avatar component design tokens and migrate SCSS to use token variables.
|
|
28
|
+
|
|
29
|
+
- [#1899](https://github.com/servicetitan/hammer/pull/1899) [`6ea319a`](https://github.com/servicetitan/hammer/commit/6ea319a282209312485756bfd37f1e2102f8c7e5) Thanks [@tounsoo](https://github.com/tounsoo)! - [Tokens] Add Announcement component design tokens, missing foreground tokens for success, and migrate SCSS to use token variables.
|
|
30
|
+
|
|
31
|
+
- [#1899](https://github.com/servicetitan/hammer/pull/1899) [`6ea319a`](https://github.com/servicetitan/hammer/commit/6ea319a282209312485756bfd37f1e2102f8c7e5) Thanks [@tounsoo](https://github.com/tounsoo)! - [Tokens] Add `gradient.primary` semantic token and `ai-mark.primary.background.gradient` component token.
|
|
32
|
+
|
|
33
|
+
- [#1899](https://github.com/servicetitan/hammer/pull/1899) [`6ea319a`](https://github.com/servicetitan/hammer/commit/6ea319a282209312485756bfd37f1e2102f8c7e5) Thanks [@tounsoo](https://github.com/tounsoo)! - [Tokens][Menu] Add `menu.item` hover and active state tokens (`foreground.color-hover`, `foreground.color-active`, `background.color-active`) and wire them through Menu styles.
|
|
34
|
+
|
|
35
|
+
- [#1899](https://github.com/servicetitan/hammer/pull/1899) [`6ea319a`](https://github.com/servicetitan/hammer/commit/6ea319a282209312485756bfd37f1e2102f8c7e5) Thanks [@tounsoo](https://github.com/tounsoo)! - [Tokens] Add missing tokens and correct existing shapes for Listbox, ListView, Pagination, Stepper, and Toolbar component token files (Toolbar rebuilt from scratch).
|
|
36
|
+
|
|
37
|
+
- [#1899](https://github.com/servicetitan/hammer/pull/1899) [`6ea319a`](https://github.com/servicetitan/hammer/commit/6ea319a282209312485756bfd37f1e2102f8c7e5) Thanks [@tounsoo](https://github.com/tounsoo)! - [Tokens] Add Badge component design tokens and migrate SCSS to use token variables.
|
|
38
|
+
|
|
39
|
+
- [#1899](https://github.com/servicetitan/hammer/pull/1899) [`6ea319a`](https://github.com/servicetitan/hammer/commit/6ea319a282209312485756bfd37f1e2102f8c7e5) Thanks [@tounsoo](https://github.com/tounsoo)! - [Tokens][SideNav] Restructure SideNav tokens and update SideNav styles to match. Consumers referencing the prior SideNav token names must migrate to the new shape
|
|
40
|
+
|
|
41
|
+
- [#1899](https://github.com/servicetitan/hammer/pull/1899) [`6ea319a`](https://github.com/servicetitan/hammer/commit/6ea319a282209312485756bfd37f1e2102f8c7e5) Thanks [@tounsoo](https://github.com/tounsoo)! - [Tokens][Switch] Restructure Switch tokens (new hierarchy and shadow token scoping) and update Switch styles to match. Consumers referencing the prior Switch token names must migrate to the new shape
|
|
42
|
+
|
|
43
|
+
- [#1899](https://github.com/servicetitan/hammer/pull/1899) [`6ea319a`](https://github.com/servicetitan/hammer/commit/6ea319a282209312485756bfd37f1e2102f8c7e5) Thanks [@tounsoo](https://github.com/tounsoo)! - [Tokens] Consolidate TextField, Textarea, and SearchField tokens into a single `text-field` token set. `search-field.tokens.json` and `textarea.tokens.json` are removed; their tokens are merged into `text-field.tokens.json` with a flattened hierarchy and renames (e.g. `background-color-strong` → `background-color-disabled`). Consumers of the prior per-component token names must migrate
|
|
44
|
+
|
|
45
|
+
- [#1899](https://github.com/servicetitan/hammer/pull/1899) [`6ea319a`](https://github.com/servicetitan/hammer/commit/6ea319a282209312485756bfd37f1e2102f8c7e5) Thanks [@tounsoo](https://github.com/tounsoo)! - [Tokens] Add component tokens for Details, Dialog, Divider, Dnd, Drawer, and DrillDown
|
|
46
|
+
|
|
47
|
+
- [#1899](https://github.com/servicetitan/hammer/pull/1899) [`6ea319a`](https://github.com/servicetitan/hammer/commit/6ea319a282209312485756bfd37f1e2102f8c7e5) Thanks [@tounsoo](https://github.com/tounsoo)! - [Tokens] Use direct token references for button disabled colors; add calendar, opacity, card, checkbox, chip, and combobox component tokens.
|
|
48
|
+
|
|
49
|
+
- [#1899](https://github.com/servicetitan/hammer/pull/1899) [`6ea319a`](https://github.com/servicetitan/hammer/commit/6ea319a282209312485756bfd37f1e2102f8c7e5) Thanks [@tounsoo](https://github.com/tounsoo)! - [Tokens] Add component tokens for E-T components: EditCard, FieldLabel, FieldMessage, Icon, Link, ListView, Listbox, Menu, Overflow, Page, Pagination, Popover, ProgressBar, Radio, SearchField, SegmentedControl, SelectCard, SideNav, Skeleton, Spinner, Stepper, Switch, Tab, Text, TextField, Textarea, Toast, Toolbar, and Tooltip
|
|
50
|
+
|
|
51
|
+
- [#1899](https://github.com/servicetitan/hammer/pull/1899) [`6ea319a`](https://github.com/servicetitan/hammer/commit/6ea319a282209312485756bfd37f1e2102f8c7e5) Thanks [@tounsoo](https://github.com/tounsoo)! - [Tokens] Add Alert component design tokens and migrate SCSS to use token variables.
|
|
52
|
+
|
|
53
|
+
## 2.5.1
|
|
54
|
+
|
|
55
|
+
### Patch Changes
|
|
56
|
+
|
|
57
|
+
- [#1624](https://github.com/servicetitan/hammer/pull/1624) [`a0f7dad`](https://github.com/servicetitan/hammer/commit/a0f7dad3b885d5867df185b79ca1ae118d197a7d) Thanks [@rgdelato](https://github.com/rgdelato)! - [Charts] Add license and remove watermark from amCharts5 themes
|
|
58
|
+
|
|
3
59
|
## 2.5.0
|
|
4
60
|
|
|
5
61
|
### Minor Changes
|
package/README.md
ADDED
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
# @servicetitan/hammer-token
|
|
2
|
+
|
|
3
|
+
Design token system for the Hammer design system, built with [Style Dictionary v5](https://styledictionary.com/) and the [Design Tokens Community Group (DTCG) format](https://www.designtokens.org/tr/2025.10/format/).
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
This package transforms design tokens from JSON source files into multiple output formats for use across web applications. It generates JavaScript modules, SCSS variables, CSS utility classes, and TypeScript definitions to support both runtime and build-time token consumption.
|
|
8
|
+
|
|
9
|
+
## Token Structure
|
|
10
|
+
|
|
11
|
+
Tokens follow the [Design Tokens Community Group (DTCG) format](https://www.designtokens.org/tr/2025.10/format/).
|
|
12
|
+
|
|
13
|
+
### Primitive Color Token
|
|
14
|
+
|
|
15
|
+
Primitive tokens have a static value and declare their Figma variable scope via `$extensions["com.figma.scopes"]`. An empty array means no scope restriction (the variable appears in all pickers).
|
|
16
|
+
|
|
17
|
+
```json
|
|
18
|
+
{
|
|
19
|
+
"$type": "color",
|
|
20
|
+
"$value": "#ffffff",
|
|
21
|
+
"$extensions": {
|
|
22
|
+
"com.figma.scopes": []
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### Semantic Color Token (with dark mode)
|
|
28
|
+
|
|
29
|
+
Semantic tokens reference primitives and include light/dark appearance variants under `$extensions.appearance`. Both `light` and `dark` repeat the `$type` and use `$value`.
|
|
30
|
+
|
|
31
|
+
```json
|
|
32
|
+
{
|
|
33
|
+
"$type": "color",
|
|
34
|
+
"$value": "{status.color.info}",
|
|
35
|
+
"$extensions": {
|
|
36
|
+
"appearance": {
|
|
37
|
+
"light": {
|
|
38
|
+
"$type": "color",
|
|
39
|
+
"$value": "{status.color.info}"
|
|
40
|
+
},
|
|
41
|
+
"dark": {
|
|
42
|
+
"$type": "color",
|
|
43
|
+
"$value": "{status.color.info}"
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
"com.figma.scopes": ["STROKE_COLOR"]
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Composite Color Token (color + alpha)
|
|
52
|
+
|
|
53
|
+
Used for colors that need an alpha channel. The `color` field is a reference to a primitive token; the build system emits `color-mix()` in CSS output to preserve the live primitive CSS variable.
|
|
54
|
+
|
|
55
|
+
```json
|
|
56
|
+
{
|
|
57
|
+
"$type": "color",
|
|
58
|
+
"$value": {
|
|
59
|
+
"color": "{color.neutral.900}",
|
|
60
|
+
"alpha": 0.08
|
|
61
|
+
},
|
|
62
|
+
"$extensions": {
|
|
63
|
+
"appearance": {
|
|
64
|
+
"light": {
|
|
65
|
+
"$type": "color",
|
|
66
|
+
"$value": { "color": "{color.neutral.900}", "alpha": 0.08 }
|
|
67
|
+
},
|
|
68
|
+
"dark": {
|
|
69
|
+
"$type": "color",
|
|
70
|
+
"$value": { "color": "{color.neutral.0}", "alpha": 0.08 }
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
"com.figma.scopes": ["EFFECT_COLOR"]
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Dimension Token
|
|
79
|
+
|
|
80
|
+
Dimension tokens (sizes, radii, breakpoints) use a nested object for `$value` with `value` and `unit` fields.
|
|
81
|
+
|
|
82
|
+
```json
|
|
83
|
+
{
|
|
84
|
+
"$type": "dimension",
|
|
85
|
+
"$value": {
|
|
86
|
+
"value": 0.375,
|
|
87
|
+
"unit": "rem"
|
|
88
|
+
},
|
|
89
|
+
"$extensions": {
|
|
90
|
+
"com.figma.scopes": ["CORNER_RADIUS"]
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### The $root Pattern
|
|
96
|
+
|
|
97
|
+
The `$root` pattern allows a token group to have a default value while still containing sub-tokens (e.g. interactive states). A node with `$value` cannot normally also have children; `$root` bridges this by placing the default value one level deeper.
|
|
98
|
+
|
|
99
|
+
```json
|
|
100
|
+
"primary": {
|
|
101
|
+
"$root": {
|
|
102
|
+
"$type": "color",
|
|
103
|
+
"$value": "{color.blue.500}"
|
|
104
|
+
},
|
|
105
|
+
"hover": {
|
|
106
|
+
"$type": "color",
|
|
107
|
+
"$value": "{color.blue.600}"
|
|
108
|
+
},
|
|
109
|
+
"active": {
|
|
110
|
+
"$type": "color",
|
|
111
|
+
"$value": "{color.blue.700}"
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
You can reference the group directly as `{background.color.primary}` — the build system resolves it to the `.$root` token automatically. The `$root` segment is stripped from all generated names (e.g. `--a2-background-color-primary`, not `--a2-background-color-primary-root`).
|
|
117
|
+
|
|
118
|
+
## Token Naming Conventions
|
|
119
|
+
|
|
120
|
+
1. **Path to name**: JSON object paths become hyphen-separated names (CSS/SCSS) or PascalCase (JS exports).
|
|
121
|
+
2. **`$root` segments**: Stripped from the path in all outputs.
|
|
122
|
+
3. **State suffixes**: State names (`hover`, `active`) are included as-is in the hyphenated name and capitalized in PascalCase exports.
|
|
123
|
+
|
|
124
|
+
## Build Output (`/build/web`)
|
|
125
|
+
|
|
126
|
+
All generated CSS variable names use the `a2-` prefix by default (e.g. `--a2-background-color-primary`).
|
|
127
|
+
|
|
128
|
+
The build process executes three sequential Style Dictionary builds — **Primitive → Theme (semantic) → Component** — and writes output to `/build/web`:
|
|
129
|
+
|
|
130
|
+
```
|
|
131
|
+
build/web/
|
|
132
|
+
├── index.js # Main entry point
|
|
133
|
+
├── index.d.ts # TypeScript definitions
|
|
134
|
+
├── types.d.ts # Core types (TokenObj, Token)
|
|
135
|
+
└── core/
|
|
136
|
+
├── primitive.js # Primitive tokens (JS)
|
|
137
|
+
├── primitive.scss # Primitive tokens (SCSS)
|
|
138
|
+
├── primitive-variables.scss # Primitive tokens map (SCSS)
|
|
139
|
+
├── primitive.d.ts # Primitive tokens (TypeScript)
|
|
140
|
+
├── semantic.js # Semantic tokens (JS)
|
|
141
|
+
├── semantic.scss # Semantic tokens (SCSS)
|
|
142
|
+
├── semantic-variables.scss # Semantic tokens map (SCSS)
|
|
143
|
+
├── semantic.d.ts # Semantic tokens (TypeScript)
|
|
144
|
+
├── component.js # Component tokens (JS)
|
|
145
|
+
├── component.scss # Component tokens (SCSS)
|
|
146
|
+
├── component-variables.scss # Component tokens map (SCSS)
|
|
147
|
+
├── component.d.ts # Component tokens (TypeScript)
|
|
148
|
+
├── index.js # Core index
|
|
149
|
+
├── index.d.ts # Core TypeScript definitions
|
|
150
|
+
└── css-utils/ # CSS utility classes
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### File Types
|
|
154
|
+
|
|
155
|
+
#### `*.js` Files
|
|
156
|
+
|
|
157
|
+
ES6 named exports with static resolved values. Tokens with dark variants include an `extensions.appearance.dark.value` property.
|
|
158
|
+
|
|
159
|
+
```javascript
|
|
160
|
+
import { BackgroundColorPrimary } from "@servicetitan/hammer-token/build/web/core/semantic";
|
|
161
|
+
// { value: "#0265dc", extensions: { appearance: { dark: { value: "#78bbfa" } } } }
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
> **Caution**: Values are resolved at build time and do not respond to CSS variable changes at runtime. Use `*.scss` files when dynamic theming is needed.
|
|
165
|
+
|
|
166
|
+
#### `*.scss` Files
|
|
167
|
+
|
|
168
|
+
SCSS variables with `var(--a2-name, fallback)` syntax, supporting recursive reference chains and `light-dark()` for dark mode.
|
|
169
|
+
|
|
170
|
+
#### `*-variables.scss` Files
|
|
171
|
+
|
|
172
|
+
SCSS maps (`$light`, `$dark`, `$nonColor`) used by `ThemeProvider.module.scss`.
|
|
173
|
+
|
|
174
|
+
#### `.d.ts` Files
|
|
175
|
+
|
|
176
|
+
Auto-generated TypeScript definitions using the unified `TokenObj` type.
|
|
177
|
+
|
|
178
|
+
```typescript
|
|
179
|
+
import { TokenObj } from "../types";
|
|
180
|
+
export declare const ButtonPrimaryBackgroundColor: TokenObj;
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
## Utility Files (`src/utils/`)
|
|
184
|
+
|
|
185
|
+
### `token-helpers.js`
|
|
186
|
+
|
|
187
|
+
Core helpers for token value extraction, reference resolution, and CSS fallback building. Key points:
|
|
188
|
+
|
|
189
|
+
- **Smart `$root` resolution**: `resolveReference` automatically retries with `.$root` appended when a reference points to a group rather than a leaf token.
|
|
190
|
+
- **Memoized token map**: `buildTokenMap` caches an O(1) name→token `Map` per dictionary instance via `WeakMap`.
|
|
191
|
+
- **Composite colors**: `{ color, alpha }` tokens emit `color-mix(in srgb, var(--a2-name, #hex) N%, transparent)` in CSS contexts, preserving the live primitive CSS variable reference. Static contexts (JS exports, SCSS maps) fall back to hex8.
|
|
192
|
+
- **`buildFallbackWithRefs`**: Main entry point used by all formats. Builds recursive `var(--name, ...)` chains and inserts `light-dark()` at the level where light and dark values first diverge.
|
|
193
|
+
|
|
194
|
+
### `sd-transforms.js`
|
|
195
|
+
|
|
196
|
+
Registers DTCG transforms and the `dtcg` transform group:
|
|
197
|
+
|
|
198
|
+
- **`dtcg/set-token-names`** _(preprocessor)_: Pre-sets `token.name` to the full hyphenated path before transforms run. Prevents false name-collision warnings for tokens with unresolvable references that skip the transform pipeline.
|
|
199
|
+
- **`dtcg/name`**, **`dtcg/value`**, **`dtcg/cubic-bezier`**, **`dtcg/color-opacity`**: Path normalization, dimension formatting, cubicBezier→CSS, and composite color pass-through.
|
|
200
|
+
|
|
201
|
+
### `css-utils-format-utils.js`
|
|
202
|
+
|
|
203
|
+
Pure functions that generate CSS utility class strings — `generateBorderClasses`, `generateColorClasses`, `generateFontClasses`, `generateSpacingClasses`. Each accepts a pre-resolved `value` (which may already contain a `light-dark()` expression built by `buildFallbackWithRefs`) and an optional `prefix`.
|
|
204
|
+
|
|
205
|
+
### `sd-formats.js`
|
|
206
|
+
|
|
207
|
+
Registers all custom Style Dictionary output formats:
|
|
208
|
+
|
|
209
|
+
- `custom/scss-variables` — SCSS variables with `var()` + `light-dark()` fallbacks.
|
|
210
|
+
- `custom/scss-variables-map` — SCSS maps (`$light`, `$dark`, `$nonColor` / `$token`) for `ThemeProvider.module.scss`.
|
|
211
|
+
- `custom/es6-variable` — ES6 named exports with static resolved values.
|
|
212
|
+
- `custom/CSSVariables` — `:root {}` block with CSS custom properties.
|
|
213
|
+
- `custom/CSSUtils/{prefix}All|Borders|Colors|Fonts|Spacing` — CSS utility class files (registered for both `""` and `"a2-"` prefixes).
|
|
214
|
+
|
|
215
|
+
The `All` format uses a single-pass loop over `allTokens` (one `buildFallbackWithRefs` call per token for the light value, a second only when a dark variant exists) feeding three output buckets. The dedicated `Borders`, `Colors`, `Fonts`, and `Spacing` formats use separate filter+map pipelines.
|
|
216
|
+
|
|
217
|
+
## Figma Sync (`src/utils/figma/`)
|
|
218
|
+
|
|
219
|
+
Script to sync design tokens to Figma variables using the Figma REST API.
|
|
220
|
+
|
|
221
|
+
### Features
|
|
222
|
+
|
|
223
|
+
- Syncs all tokens (primitives, semantic, component) to a single Figma variable collection
|
|
224
|
+
- Creates Light and Dark modes for appearance variants
|
|
225
|
+
- Resolves primitive token references to actual values
|
|
226
|
+
- Creates variable aliases for semantic/component tokens that reference other tokens
|
|
227
|
+
- Handles `$root` pattern by creating separate variables for root and state variants
|
|
228
|
+
- Uses path-based naming (e.g., `color/blue/500`, `background/color/primary`)
|
|
229
|
+
- Applies **Figma variable scopes** so variables only appear in the relevant UI pickers
|
|
230
|
+
- Only updates variables when values change; still sends scope-only updates when scopes need to be applied
|
|
231
|
+
- Handles rate limiting with automatic retries
|
|
232
|
+
|
|
233
|
+
### Directory
|
|
234
|
+
|
|
235
|
+
- **`auth.js`** - Authentication and configuration
|
|
236
|
+
- **`constants.js`** - Figma file and collection constants
|
|
237
|
+
- **`errors.js`** - Custom error classes
|
|
238
|
+
- **`get-token.js`** - OAuth2 token helper script
|
|
239
|
+
- **`token-parsing.js`** - Token file loading, parsing, and flattening
|
|
240
|
+
- **`token-resolution.js`** - Reference resolution and dependency sorting
|
|
241
|
+
- **`token-conversion.js`** - Converting tokens to Figma format
|
|
242
|
+
- **`figma-api.js`** - Figma API requests, collections, and modes
|
|
243
|
+
- **`sync-primitives.js`** - Primitive token sync logic
|
|
244
|
+
- **`sync-semantic.js`** - Semantic token sync logic
|
|
245
|
+
- **`sync-components.js`** - Component token sync logic
|
|
246
|
+
- **`sync-orchestration.js`** - Theme sync orchestration
|
|
247
|
+
- **`sync-main.js`** - Main entry point and CLI
|
|
248
|
+
- **`utils.js`** - Shared utility functions
|
|
249
|
+
|
|
250
|
+
### Variable Scopes
|
|
251
|
+
|
|
252
|
+
Figma variables can be scoped so they only show in certain property pickers (e.g. a color variable only in stroke color, or a dimension only in corner radius).
|
|
253
|
+
|
|
254
|
+
Scopes are defined directly on each token in `$extensions["com.figma.scopes"]` — an array of Figma scope names (e.g. `SHAPE_FILL`, `STROKE_COLOR`, `CORNER_RADIUS`, `FONT_SIZE`). The sync reads this field when creating or updating variables; scopes are deduplicated before sending.
|
|
255
|
+
|
|
256
|
+
To change which pickers a token appears in, edit `$extensions["com.figma.scopes"]` in the token file.
|
|
257
|
+
|
|
258
|
+
### Commands
|
|
259
|
+
|
|
260
|
+
- `pnpm figma:sync` - Sync all tokens to Figma (default file)
|
|
261
|
+
- `pnpm figma:sync:file <fileKey>` - Sync tokens to a specific Figma file
|
|
262
|
+
- `pnpm figma:test` - Test Figma API access (default file)
|
|
263
|
+
- `pnpm figma:test:file <fileKey>` - Test access to a specific Figma file
|
|
264
|
+
- `pnpm figma:validate` - Validate token files without syncing
|
|
265
|
+
- `pnpm figma:get-token` - Interactive OAuth2 token helper script
|
|
266
|
+
|
|
267
|
+
**CLI Options:** `--file-key`/`-f`, `--dry-run`, `--verbose`/`-v`, `--full`, `--help`/`-h`
|
|
268
|
+
|
|
269
|
+
### Authentication
|
|
270
|
+
|
|
271
|
+
Supports Personal Access Tokens (PAT) and OAuth2 refresh tokens. Configure via environment variables or `.figma-config.json` (repo root, gitignored).
|
|
272
|
+
|
|
273
|
+
**Environment variables:**
|
|
274
|
+
|
|
275
|
+
| Variable | Description |
|
|
276
|
+
| --------------------- | -------------------------- |
|
|
277
|
+
| `FIGMA_ACCESS_TOKEN` | PAT |
|
|
278
|
+
| `FIGMA_CLIENT_ID` | OAuth2 client ID |
|
|
279
|
+
| `FIGMA_CLIENT_SECRET` | OAuth2 client secret |
|
|
280
|
+
| `FIGMA_REFRESH_TOKEN` | OAuth2 refresh token |
|
|
281
|
+
| `FIGMA_FILE_KEY` | Optional file key override |
|
|
282
|
+
|
|
283
|
+
**`.figma-config.json`:**
|
|
284
|
+
|
|
285
|
+
```json
|
|
286
|
+
{
|
|
287
|
+
"accessToken": "figd_...",
|
|
288
|
+
"clientId": "your-oauth-client-id",
|
|
289
|
+
"clientSecret": "your-oauth-client-secret",
|
|
290
|
+
"refreshToken": "your-oauth-refresh-token"
|
|
291
|
+
}
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
Environment variables take priority over the config file. OAuth2 access tokens are cached in memory and refreshed automatically on expiry (~1 hour).
|
|
295
|
+
|
|
296
|
+
**GitHub Actions:**
|
|
297
|
+
|
|
298
|
+
```yaml
|
|
299
|
+
- name: Sync tokens to Figma
|
|
300
|
+
env:
|
|
301
|
+
FIGMA_CLIENT_ID: ${{ secrets.FIGMA_CLIENT_ID }}
|
|
302
|
+
FIGMA_CLIENT_SECRET: ${{ secrets.FIGMA_CLIENT_SECRET }}
|
|
303
|
+
FIGMA_REFRESH_TOKEN: ${{ secrets.FIGMA_REFRESH_TOKEN }}
|
|
304
|
+
run: pnpm figma:sync
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
**Dry-run mode** (`--dry-run`): validates and reads existing variables without writing. Reports counts of what would be created/updated/skipped.
|
|
308
|
+
|
|
309
|
+
**Troubleshooting:**
|
|
310
|
+
|
|
311
|
+
- **Auth errors**: Verify credentials. For OAuth2, re-authenticate if refresh token has expired.
|
|
312
|
+
- **"Authentication Failed - Please Re-Login"**: OAuth2 refresh token expired or revoked.
|
|
313
|
+
- **403 Forbidden**: Token may lack organization-level access.
|
|
314
|
+
- **File not found**: Check the file key and access permissions.
|
|
315
|
+
- **Rate limiting**: Retried automatically with exponential backoff.
|
|
316
|
+
- **Refresh token rotation**: Update credentials with the new token logged to stdout.
|
|
317
|
+
- Run `pnpm figma:test` to diagnose issues before syncing; `pnpm figma:validate` to check token structure without API calls.
|
|
318
|
+
|
|
319
|
+
## Development
|
|
320
|
+
|
|
321
|
+
### Adding New Tokens
|
|
322
|
+
|
|
323
|
+
1. Add token JSON files to `src/global/primitive/` (primitives) or `src/theme/core/` (semantic/component)
|
|
324
|
+
2. Run `pnpm build` to regenerate output files
|
|
325
|
+
3. Import tokens in your code using the generated files
|
|
326
|
+
|
|
327
|
+
### Modifying Build Output
|
|
328
|
+
|
|
329
|
+
- **Transforms**: Edit `src/utils/sd-transforms.js`
|
|
330
|
+
- **Formats**: Edit `src/utils/sd-formats.js`
|
|
331
|
+
- **Build Configs**: Edit `src/utils/sd-build-configs.js`
|
|
332
|
+
- **CSS Utils**: Edit `src/utils/css-utils-format-utils.js`
|