@servicetitan/hammer-token 2.5.2 → 3.0.1

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.
Files changed (146) hide show
  1. package/CHANGELOG.md +52 -2
  2. package/README.md +332 -0
  3. package/build/web/core/component-variables.scss +1088 -131
  4. package/build/web/core/component.d.ts +558 -0
  5. package/build/web/core/component.js +6685 -249
  6. package/build/web/core/component.scss +557 -69
  7. package/build/web/core/css-utils/a2-border.css +23 -51
  8. package/build/web/core/css-utils/a2-color.css +221 -233
  9. package/build/web/core/css-utils/a2-font.css +1 -29
  10. package/build/web/core/css-utils/a2-spacing.css +238 -483
  11. package/build/web/core/css-utils/a2-utils.css +496 -781
  12. package/build/web/core/css-utils/border.css +23 -51
  13. package/build/web/core/css-utils/color.css +221 -233
  14. package/build/web/core/css-utils/font.css +1 -29
  15. package/build/web/core/css-utils/spacing.css +238 -483
  16. package/build/web/core/css-utils/utils.css +496 -781
  17. package/build/web/core/index.d.ts +6 -0
  18. package/build/web/core/index.js +1 -1
  19. package/build/web/core/primitive-variables.scss +148 -65
  20. package/build/web/core/primitive.d.ts +209 -0
  21. package/build/web/core/primitive.js +779 -61
  22. package/build/web/core/primitive.scss +207 -124
  23. package/build/web/core/semantic-variables.scss +363 -245
  24. package/build/web/core/semantic.d.ts +221 -0
  25. package/build/web/core/semantic.js +1592 -347
  26. package/build/web/core/semantic.scss +219 -140
  27. package/build/web/index.d.ts +3 -4
  28. package/build/web/types.d.ts +17 -0
  29. package/config.js +121 -496
  30. package/eslint.config.mjs +11 -1
  31. package/package.json +15 -5
  32. package/src/global/primitive/breakpoint.tokens.json +54 -0
  33. package/src/global/primitive/color.tokens.json +1092 -0
  34. package/src/global/primitive/duration.tokens.json +44 -0
  35. package/src/global/primitive/font.tokens.json +151 -0
  36. package/src/global/primitive/radius.tokens.json +94 -0
  37. package/src/global/primitive/size.tokens.json +174 -0
  38. package/src/global/primitive/transition.tokens.json +32 -0
  39. package/src/theme/core/background.tokens.json +1312 -0
  40. package/src/theme/core/border.tokens.json +192 -0
  41. package/src/theme/core/chart.tokens.json +982 -0
  42. package/src/theme/core/component/ai-mark.tokens.json +20 -0
  43. package/src/theme/core/component/alert.tokens.json +261 -0
  44. package/src/theme/core/component/announcement.tokens.json +460 -0
  45. package/src/theme/core/component/avatar.tokens.json +137 -0
  46. package/src/theme/core/component/badge.tokens.json +42 -0
  47. package/src/theme/core/component/breadcrumb.tokens.json +42 -0
  48. package/src/theme/core/component/button-toggle.tokens.json +428 -0
  49. package/src/theme/core/component/button.tokens.json +941 -0
  50. package/src/theme/core/component/calendar.tokens.json +391 -0
  51. package/src/theme/core/component/card.tokens.json +107 -0
  52. package/src/theme/core/component/checkbox.tokens.json +631 -0
  53. package/src/theme/core/component/chip.tokens.json +169 -0
  54. package/src/theme/core/component/combobox.tokens.json +269 -0
  55. package/src/theme/core/component/details.tokens.json +152 -0
  56. package/src/theme/core/component/dialog.tokens.json +87 -0
  57. package/src/theme/core/component/divider.tokens.json +23 -0
  58. package/src/theme/core/component/dnd.tokens.json +208 -0
  59. package/src/theme/core/component/drawer.tokens.json +61 -0
  60. package/src/theme/core/component/drilldown.tokens.json +61 -0
  61. package/src/theme/core/component/edit-card.tokens.json +381 -0
  62. package/src/theme/core/component/field-label.tokens.json +42 -0
  63. package/src/theme/core/component/field-message.tokens.json +65 -0
  64. package/src/theme/core/component/icon.tokens.json +42 -0
  65. package/src/theme/core/component/link.tokens.json +108 -0
  66. package/src/theme/core/component/list-view.tokens.json +82 -0
  67. package/src/theme/core/component/listbox.tokens.json +283 -0
  68. package/src/theme/core/component/menu.tokens.json +230 -0
  69. package/src/theme/core/component/overflow.tokens.json +84 -0
  70. package/src/theme/core/component/page.tokens.json +377 -0
  71. package/src/theme/core/component/pagination.tokens.json +63 -0
  72. package/src/theme/core/component/popover.tokens.json +122 -0
  73. package/src/theme/core/component/progress-bar.tokens.json +133 -0
  74. package/src/theme/core/component/radio.tokens.json +631 -0
  75. package/src/theme/core/component/segmented-control.tokens.json +175 -0
  76. package/src/theme/core/component/select-card.tokens.json +943 -0
  77. package/src/theme/core/component/side-nav.tokens.json +349 -0
  78. package/src/theme/core/component/skeleton.tokens.json +42 -0
  79. package/src/theme/core/component/spinner.tokens.json +96 -0
  80. package/src/theme/core/component/status-icon.tokens.json +164 -0
  81. package/src/theme/core/component/stepper.tokens.json +484 -0
  82. package/src/theme/core/component/switch.tokens.json +285 -0
  83. package/src/theme/core/component/tab.tokens.json +192 -0
  84. package/src/theme/core/component/text-field.tokens.json +160 -0
  85. package/src/theme/core/component/text.tokens.json +59 -0
  86. package/src/theme/core/component/toast.tokens.json +343 -0
  87. package/src/theme/core/component/toolbar.tokens.json +114 -0
  88. package/src/theme/core/component/tooltip.tokens.json +61 -0
  89. package/src/theme/core/focus.tokens.json +56 -0
  90. package/src/theme/core/foreground.tokens.json +416 -0
  91. package/src/theme/core/gradient.tokens.json +41 -0
  92. package/src/theme/core/opacity.tokens.json +25 -0
  93. package/src/theme/core/shadow.tokens.json +81 -0
  94. package/src/theme/core/status.tokens.json +74 -0
  95. package/src/theme/core/typography.tokens.json +163 -0
  96. package/src/utils/__tests__/css-utils-format-utils.test.js +312 -0
  97. package/src/utils/__tests__/sd-build-configs.test.js +306 -0
  98. package/src/utils/__tests__/sd-formats.test.js +942 -0
  99. package/src/utils/__tests__/sd-transforms.test.js +336 -0
  100. package/src/utils/__tests__/token-helpers.test.js +1160 -0
  101. package/src/utils/copy-css-utils-cli.js +13 -1
  102. package/src/utils/css-utils-format-utils.js +105 -176
  103. package/src/utils/figma/__tests__/sync-gradient.test.js +561 -0
  104. package/src/utils/figma/__tests__/token-conversion.test.js +117 -0
  105. package/src/utils/figma/__tests__/token-resolution.test.js +231 -0
  106. package/src/utils/figma/auth.js +355 -0
  107. package/src/utils/figma/constants.js +22 -0
  108. package/src/utils/figma/errors.js +80 -0
  109. package/src/utils/figma/figma-api.js +1069 -0
  110. package/src/utils/figma/get-token.js +348 -0
  111. package/src/utils/figma/sync-components.js +909 -0
  112. package/src/utils/figma/sync-main.js +692 -0
  113. package/src/utils/figma/sync-orchestration.js +683 -0
  114. package/src/utils/figma/sync-primitives.js +230 -0
  115. package/src/utils/figma/sync-semantic.js +1056 -0
  116. package/src/utils/figma/token-conversion.js +340 -0
  117. package/src/utils/figma/token-parsing.js +186 -0
  118. package/src/utils/figma/token-resolution.js +569 -0
  119. package/src/utils/figma/utils.js +199 -0
  120. package/src/utils/sd-build-configs.js +305 -0
  121. package/src/utils/sd-formats.js +948 -0
  122. package/src/utils/sd-transforms.js +165 -0
  123. package/src/utils/token-helpers.js +848 -0
  124. package/tsconfig.json +18 -0
  125. package/vitest.config.js +17 -0
  126. package/.turbo/turbo-build.log +0 -37
  127. package/build/web/core/raw.js +0 -234
  128. package/src/global/primitive/breakpoint.js +0 -19
  129. package/src/global/primitive/color.js +0 -231
  130. package/src/global/primitive/duration.js +0 -16
  131. package/src/global/primitive/font.js +0 -60
  132. package/src/global/primitive/radius.js +0 -31
  133. package/src/global/primitive/size.js +0 -55
  134. package/src/global/primitive/transition.js +0 -16
  135. package/src/theme/core/background.js +0 -170
  136. package/src/theme/core/border.js +0 -103
  137. package/src/theme/core/charts.js +0 -464
  138. package/src/theme/core/component/button.js +0 -708
  139. package/src/theme/core/component/checkbox.js +0 -405
  140. package/src/theme/core/focus.js +0 -35
  141. package/src/theme/core/foreground.js +0 -148
  142. package/src/theme/core/overlay.js +0 -137
  143. package/src/theme/core/shadow.js +0 -29
  144. package/src/theme/core/status.js +0 -49
  145. package/src/theme/core/typography.js +0 -82
  146. package/type/types.ts +0 -344
@@ -0,0 +1,306 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import {
3
+ isSemanticToken,
4
+ isComponentToken,
5
+ createPrimitiveConfig,
6
+ createThemeConfig,
7
+ createComponentConfig,
8
+ } from "../sd-build-configs.js";
9
+
10
+ // We also need to test createPlatform and createCssUtilsFiles indirectly
11
+ // through createPrimitiveConfig / createThemeConfig.
12
+
13
+ // ---------------------------------------------------------------------------
14
+ // isSemanticToken
15
+ // ---------------------------------------------------------------------------
16
+
17
+ describe("isSemanticToken", () => {
18
+ it("returns true when filePath is absent", () => {
19
+ expect(isSemanticToken({})).toBe(true);
20
+ });
21
+
22
+ it("returns false for primitive tokens", () => {
23
+ expect(
24
+ isSemanticToken({ filePath: "src/global/primitive/color.tokens.json" }),
25
+ ).toBe(false);
26
+ });
27
+
28
+ it("returns false for component tokens", () => {
29
+ expect(
30
+ isSemanticToken({
31
+ filePath: "src/theme/core/component/button.tokens.json",
32
+ }),
33
+ ).toBe(false);
34
+ });
35
+
36
+ it("returns true for semantic theme tokens", () => {
37
+ expect(
38
+ isSemanticToken({ filePath: "src/theme/core/background.tokens.json" }),
39
+ ).toBe(true);
40
+ });
41
+
42
+ it("returns true for status tokens (no 'primitive' or '/component/' in path)", () => {
43
+ expect(
44
+ isSemanticToken({ filePath: "src/theme/core/status.tokens.json" }),
45
+ ).toBe(true);
46
+ });
47
+ });
48
+
49
+ // ---------------------------------------------------------------------------
50
+ // isComponentToken
51
+ // ---------------------------------------------------------------------------
52
+
53
+ describe("isComponentToken", () => {
54
+ it("returns true when filePath contains /component/", () => {
55
+ expect(
56
+ isComponentToken({
57
+ filePath: "src/theme/core/component/button.tokens.json",
58
+ }),
59
+ ).toBe(true);
60
+ });
61
+
62
+ it("returns false when filePath does not contain /component/", () => {
63
+ expect(
64
+ isComponentToken({ filePath: "src/theme/core/background.tokens.json" }),
65
+ ).toBe(false);
66
+ });
67
+
68
+ it("returns falsy when filePath is absent", () => {
69
+ expect(isComponentToken({})).toBeFalsy();
70
+ });
71
+ });
72
+
73
+ // ---------------------------------------------------------------------------
74
+ // createPrimitiveConfig
75
+ // ---------------------------------------------------------------------------
76
+
77
+ describe("createPrimitiveConfig", () => {
78
+ it("returns a configuration object with source", () => {
79
+ const config = createPrimitiveConfig();
80
+ expect(config).toHaveProperty("source");
81
+ expect(config.source).toContain("src/global/primitive/*.tokens.json");
82
+ });
83
+
84
+ it("includes the dtcg/set-token-names preprocessor", () => {
85
+ const config = createPrimitiveConfig();
86
+ expect(config.preprocessors).toContain("dtcg/set-token-names");
87
+ });
88
+
89
+ it("has scss, js, and css platforms", () => {
90
+ const config = createPrimitiveConfig();
91
+ expect(config.platforms).toHaveProperty("scss");
92
+ expect(config.platforms).toHaveProperty("js");
93
+ expect(config.platforms).toHaveProperty("css");
94
+ });
95
+
96
+ it("scss platform uses dtcg transformGroup", () => {
97
+ const config = createPrimitiveConfig();
98
+ expect(config.platforms.scss.transformGroup).toBe("dtcg");
99
+ });
100
+
101
+ it("scss platform outputs to build/web/core/", () => {
102
+ const config = createPrimitiveConfig();
103
+ expect(config.platforms.scss.buildPath).toBe("build/web/core/");
104
+ });
105
+
106
+ it("scss platform has primitive.scss and primitive-variables.scss files", () => {
107
+ const config = createPrimitiveConfig();
108
+ const destinations = config.platforms.scss.files.map((f) => f.destination);
109
+ expect(destinations).toContain("primitive.scss");
110
+ expect(destinations).toContain("primitive-variables.scss");
111
+ });
112
+
113
+ it("css platform has 8 files (2 prefixes × 4 types)", () => {
114
+ const config = createPrimitiveConfig();
115
+ expect(config.platforms.css.files).toHaveLength(8);
116
+ });
117
+
118
+ it("css platform files include both prefixed and unprefixed variants", () => {
119
+ const config = createPrimitiveConfig();
120
+ const destinations = config.platforms.css.files.map((f) => f.destination);
121
+ expect(destinations).toContain("utils.css");
122
+ expect(destinations).toContain("a2-utils.css");
123
+ expect(destinations).toContain("color.css");
124
+ expect(destinations).toContain("a2-color.css");
125
+ });
126
+
127
+ it("css platform color filter accepts color-prefixed token names", () => {
128
+ const config = createPrimitiveConfig();
129
+ const colorFile = config.platforms.css.files.find(
130
+ (f) => f.destination === "color.css",
131
+ );
132
+ expect(colorFile).toBeDefined();
133
+ expect(colorFile.filter({ path: ["color", "neutral", "0"] })).toBe(true);
134
+ expect(colorFile.filter({ path: ["size", "4"] })).toBe(false);
135
+ });
136
+
137
+ it("css platform font filter accepts font-prefixed token names", () => {
138
+ const config = createPrimitiveConfig();
139
+ const fontFile = config.platforms.css.files.find(
140
+ (f) => f.destination === "font.css",
141
+ );
142
+ expect(fontFile).toBeDefined();
143
+ expect(fontFile.filter({ path: ["font", "family", "base"] })).toBe(true);
144
+ expect(fontFile.filter({ path: ["color", "primary"] })).toBe(false);
145
+ });
146
+
147
+ it("css platform spacing filter accepts size-prefixed token names", () => {
148
+ const config = createPrimitiveConfig();
149
+ const spacingFile = config.platforms.css.files.find(
150
+ (f) => f.destination === "spacing.css",
151
+ );
152
+ expect(spacingFile).toBeDefined();
153
+ expect(spacingFile.filter({ path: ["size", "4"] })).toBe(true);
154
+ expect(spacingFile.filter({ path: ["color", "primary"] })).toBe(false);
155
+ });
156
+ });
157
+
158
+ // ---------------------------------------------------------------------------
159
+ // createThemeConfig
160
+ // ---------------------------------------------------------------------------
161
+
162
+ describe("createThemeConfig", () => {
163
+ it("has both include and source arrays", () => {
164
+ const config = createThemeConfig();
165
+ expect(Array.isArray(config.include)).toBe(true);
166
+ expect(Array.isArray(config.source)).toBe(true);
167
+ expect(config.include.length).toBeGreaterThan(0);
168
+ expect(config.source).toContain("src/theme/**/*.tokens.json");
169
+ });
170
+
171
+ it("includes the dtcg/set-token-names preprocessor", () => {
172
+ const config = createThemeConfig();
173
+ expect(config.preprocessors).toContain("dtcg/set-token-names");
174
+ });
175
+
176
+ it("has scss, js, and css platforms", () => {
177
+ const config = createThemeConfig();
178
+ expect(config.platforms).toHaveProperty("scss");
179
+ expect(config.platforms).toHaveProperty("js");
180
+ expect(config.platforms).toHaveProperty("css");
181
+ });
182
+
183
+ it("scss platform has semantic.scss and semantic-variables.scss with isSemanticToken filter", () => {
184
+ const config = createThemeConfig();
185
+ const destinations = config.platforms.scss.files.map((f) => f.destination);
186
+ expect(destinations).toContain("semantic.scss");
187
+ expect(destinations).toContain("semantic-variables.scss");
188
+
189
+ // Verify filter is applied
190
+ config.platforms.scss.files.forEach((f) => {
191
+ expect(f).toHaveProperty("filter");
192
+ });
193
+ });
194
+
195
+ it("css platform has 10 files (2 prefixes × 5 types including borders)", () => {
196
+ const config = createThemeConfig();
197
+ expect(config.platforms.css.files).toHaveLength(10);
198
+ });
199
+
200
+ it("css platform includes border files", () => {
201
+ const config = createThemeConfig();
202
+ const destinations = config.platforms.css.files.map((f) => f.destination);
203
+ expect(destinations).toContain("border.css");
204
+ expect(destinations).toContain("a2-border.css");
205
+ });
206
+
207
+ it("semantic border filter accepts tokens containing 'border'", () => {
208
+ const config = createThemeConfig();
209
+ const borderFile = config.platforms.css.files.find(
210
+ (f) => f.destination === "border.css",
211
+ );
212
+ expect(borderFile).toBeDefined();
213
+ expect(borderFile.filter({ path: ["border", "color", "default"] })).toBe(
214
+ true,
215
+ );
216
+ expect(
217
+ borderFile.filter({ path: ["background", "color", "primary"] }),
218
+ ).toBe(false);
219
+ });
220
+
221
+ it("semantic color filter accepts tokens with color-related names", () => {
222
+ const config = createThemeConfig();
223
+ const colorFile = config.platforms.css.files.find(
224
+ (f) => f.destination === "color.css",
225
+ );
226
+ expect(colorFile).toBeDefined();
227
+ expect(colorFile.filter({ path: ["background", "color", "primary"] })).toBe(
228
+ true,
229
+ );
230
+ expect(colorFile.filter({ path: ["foreground", "color", "default"] })).toBe(
231
+ true,
232
+ );
233
+ expect(colorFile.filter({ path: ["status", "color", "danger"] })).toBe(
234
+ true,
235
+ );
236
+ expect(colorFile.filter({ path: ["typography", "body"] })).toBe(false);
237
+ });
238
+
239
+ it("semantic typography filter accepts tokens with 'typography' in name", () => {
240
+ const config = createThemeConfig();
241
+ const fontFile = config.platforms.css.files.find(
242
+ (f) => f.destination === "font.css",
243
+ );
244
+ expect(fontFile).toBeDefined();
245
+ expect(fontFile.filter({ path: ["typography", "body", "font-size"] })).toBe(
246
+ true,
247
+ );
248
+ expect(fontFile.filter({ path: ["size", "4"] })).toBe(false);
249
+ });
250
+ });
251
+
252
+ // ---------------------------------------------------------------------------
253
+ // createComponentConfig
254
+ // ---------------------------------------------------------------------------
255
+
256
+ describe("createComponentConfig", () => {
257
+ it("has include and source for component tokens", () => {
258
+ const config = createComponentConfig();
259
+ expect(config.include).toBeDefined();
260
+ expect(config.source).toContain("src/theme/core/component/*.tokens.json");
261
+ });
262
+
263
+ it("includes the dtcg/set-token-names preprocessor", () => {
264
+ const config = createComponentConfig();
265
+ expect(config.preprocessors).toContain("dtcg/set-token-names");
266
+ });
267
+
268
+ it("has scss and js platforms but NOT css (no CSS utils for components)", () => {
269
+ const config = createComponentConfig();
270
+ expect(config.platforms).toHaveProperty("scss");
271
+ expect(config.platforms).toHaveProperty("js");
272
+ expect(config.platforms).not.toHaveProperty("css");
273
+ });
274
+
275
+ it("scss platform has component.scss and component-variables.scss with isComponentToken filter", () => {
276
+ const config = createComponentConfig();
277
+ const destinations = config.platforms.scss.files.map((f) => f.destination);
278
+ expect(destinations).toContain("component.scss");
279
+ expect(destinations).toContain("component-variables.scss");
280
+
281
+ config.platforms.scss.files.forEach((f) => {
282
+ expect(f).toHaveProperty("filter");
283
+ });
284
+ });
285
+
286
+ it("js platform outputs to component.js", () => {
287
+ const config = createComponentConfig();
288
+ const destinations = config.platforms.js.files.map((f) => f.destination);
289
+ expect(destinations).toContain("component.js");
290
+ });
291
+
292
+ it("component filter in scss files accepts component tokens", () => {
293
+ const config = createComponentConfig();
294
+ const scssFile = config.platforms.scss.files.find(
295
+ (f) => f.destination === "component.scss",
296
+ );
297
+ expect(
298
+ scssFile.filter({
299
+ filePath: "src/theme/core/component/button.tokens.json",
300
+ }),
301
+ ).toBe(true);
302
+ expect(
303
+ scssFile.filter({ filePath: "src/theme/core/background.tokens.json" }),
304
+ ).toBe(false);
305
+ });
306
+ });