@servicetitan/hammer-token 2.5.1 → 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.
Files changed (147) hide show
  1. package/CHANGELOG.md +50 -0
  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 +47 -45
  8. package/build/web/core/css-utils/a2-color.css +443 -227
  9. package/build/web/core/css-utils/a2-font.css +0 -2
  10. package/build/web/core/css-utils/a2-spacing.css +476 -478
  11. package/build/web/core/css-utils/a2-utils.css +992 -772
  12. package/build/web/core/css-utils/border.css +47 -45
  13. package/build/web/core/css-utils/color.css +443 -227
  14. package/build/web/core/css-utils/font.css +0 -2
  15. package/build/web/core/css-utils/spacing.css +476 -478
  16. package/build/web/core/css-utils/utils.css +992 -772
  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/index.js +0 -1
  29. package/build/web/types.d.ts +17 -0
  30. package/config.js +121 -497
  31. package/eslint.config.mjs +11 -1
  32. package/package.json +15 -5
  33. package/src/global/primitive/breakpoint.tokens.json +54 -0
  34. package/src/global/primitive/color.tokens.json +1092 -0
  35. package/src/global/primitive/duration.tokens.json +44 -0
  36. package/src/global/primitive/font.tokens.json +151 -0
  37. package/src/global/primitive/radius.tokens.json +94 -0
  38. package/src/global/primitive/size.tokens.json +174 -0
  39. package/src/global/primitive/transition.tokens.json +32 -0
  40. package/src/theme/core/background.tokens.json +1312 -0
  41. package/src/theme/core/border.tokens.json +192 -0
  42. package/src/theme/core/chart.tokens.json +982 -0
  43. package/src/theme/core/component/ai-mark.tokens.json +20 -0
  44. package/src/theme/core/component/alert.tokens.json +261 -0
  45. package/src/theme/core/component/announcement.tokens.json +460 -0
  46. package/src/theme/core/component/avatar.tokens.json +137 -0
  47. package/src/theme/core/component/badge.tokens.json +42 -0
  48. package/src/theme/core/component/breadcrumb.tokens.json +42 -0
  49. package/src/theme/core/component/button-toggle.tokens.json +428 -0
  50. package/src/theme/core/component/button.tokens.json +941 -0
  51. package/src/theme/core/component/calendar.tokens.json +391 -0
  52. package/src/theme/core/component/card.tokens.json +107 -0
  53. package/src/theme/core/component/checkbox.tokens.json +631 -0
  54. package/src/theme/core/component/chip.tokens.json +169 -0
  55. package/src/theme/core/component/combobox.tokens.json +269 -0
  56. package/src/theme/core/component/details.tokens.json +152 -0
  57. package/src/theme/core/component/dialog.tokens.json +87 -0
  58. package/src/theme/core/component/divider.tokens.json +23 -0
  59. package/src/theme/core/component/dnd.tokens.json +208 -0
  60. package/src/theme/core/component/drawer.tokens.json +61 -0
  61. package/src/theme/core/component/drilldown.tokens.json +61 -0
  62. package/src/theme/core/component/edit-card.tokens.json +381 -0
  63. package/src/theme/core/component/field-label.tokens.json +42 -0
  64. package/src/theme/core/component/field-message.tokens.json +74 -0
  65. package/src/theme/core/component/icon.tokens.json +42 -0
  66. package/src/theme/core/component/link.tokens.json +108 -0
  67. package/src/theme/core/component/list-view.tokens.json +82 -0
  68. package/src/theme/core/component/listbox.tokens.json +283 -0
  69. package/src/theme/core/component/menu.tokens.json +230 -0
  70. package/src/theme/core/component/overflow.tokens.json +84 -0
  71. package/src/theme/core/component/page.tokens.json +377 -0
  72. package/src/theme/core/component/pagination.tokens.json +63 -0
  73. package/src/theme/core/component/popover.tokens.json +122 -0
  74. package/src/theme/core/component/progress-bar.tokens.json +133 -0
  75. package/src/theme/core/component/radio.tokens.json +631 -0
  76. package/src/theme/core/component/segmented-control.tokens.json +175 -0
  77. package/src/theme/core/component/select-card.tokens.json +943 -0
  78. package/src/theme/core/component/side-nav.tokens.json +349 -0
  79. package/src/theme/core/component/skeleton.tokens.json +42 -0
  80. package/src/theme/core/component/spinner.tokens.json +96 -0
  81. package/src/theme/core/component/status-icon.tokens.json +164 -0
  82. package/src/theme/core/component/stepper.tokens.json +484 -0
  83. package/src/theme/core/component/switch.tokens.json +285 -0
  84. package/src/theme/core/component/tab.tokens.json +192 -0
  85. package/src/theme/core/component/text-field.tokens.json +160 -0
  86. package/src/theme/core/component/text.tokens.json +59 -0
  87. package/src/theme/core/component/toast.tokens.json +343 -0
  88. package/src/theme/core/component/toolbar.tokens.json +114 -0
  89. package/src/theme/core/component/tooltip.tokens.json +61 -0
  90. package/src/theme/core/focus.tokens.json +56 -0
  91. package/src/theme/core/foreground.tokens.json +416 -0
  92. package/src/theme/core/gradient.tokens.json +41 -0
  93. package/src/theme/core/opacity.tokens.json +25 -0
  94. package/src/theme/core/shadow.tokens.json +81 -0
  95. package/src/theme/core/status.tokens.json +74 -0
  96. package/src/theme/core/typography.tokens.json +163 -0
  97. package/src/utils/__tests__/css-utils-format-utils.test.js +312 -0
  98. package/src/utils/__tests__/sd-build-configs.test.js +306 -0
  99. package/src/utils/__tests__/sd-formats.test.js +950 -0
  100. package/src/utils/__tests__/sd-transforms.test.js +336 -0
  101. package/src/utils/__tests__/token-helpers.test.js +1160 -0
  102. package/src/utils/copy-css-utils-cli.js +13 -1
  103. package/src/utils/css-utils-format-utils.js +105 -176
  104. package/src/utils/figma/__tests__/sync-gradient.test.js +561 -0
  105. package/src/utils/figma/__tests__/token-conversion.test.js +117 -0
  106. package/src/utils/figma/__tests__/token-resolution.test.js +231 -0
  107. package/src/utils/figma/auth.js +355 -0
  108. package/src/utils/figma/constants.js +22 -0
  109. package/src/utils/figma/errors.js +80 -0
  110. package/src/utils/figma/figma-api.js +1069 -0
  111. package/src/utils/figma/get-token.js +348 -0
  112. package/src/utils/figma/sync-components.js +909 -0
  113. package/src/utils/figma/sync-main.js +692 -0
  114. package/src/utils/figma/sync-orchestration.js +683 -0
  115. package/src/utils/figma/sync-primitives.js +230 -0
  116. package/src/utils/figma/sync-semantic.js +1056 -0
  117. package/src/utils/figma/token-conversion.js +340 -0
  118. package/src/utils/figma/token-parsing.js +186 -0
  119. package/src/utils/figma/token-resolution.js +569 -0
  120. package/src/utils/figma/utils.js +199 -0
  121. package/src/utils/sd-build-configs.js +305 -0
  122. package/src/utils/sd-formats.js +965 -0
  123. package/src/utils/sd-transforms.js +165 -0
  124. package/src/utils/token-helpers.js +848 -0
  125. package/tsconfig.json +18 -0
  126. package/vitest.config.js +17 -0
  127. package/.turbo/turbo-build.log +0 -37
  128. package/build/web/core/raw.js +0 -234
  129. package/src/global/primitive/breakpoint.js +0 -19
  130. package/src/global/primitive/color.js +0 -231
  131. package/src/global/primitive/duration.js +0 -16
  132. package/src/global/primitive/font.js +0 -60
  133. package/src/global/primitive/radius.js +0 -31
  134. package/src/global/primitive/size.js +0 -55
  135. package/src/global/primitive/transition.js +0 -16
  136. package/src/theme/core/background.js +0 -170
  137. package/src/theme/core/border.js +0 -103
  138. package/src/theme/core/charts.js +0 -464
  139. package/src/theme/core/component/button.js +0 -708
  140. package/src/theme/core/component/checkbox.js +0 -405
  141. package/src/theme/core/focus.js +0 -35
  142. package/src/theme/core/foreground.js +0 -148
  143. package/src/theme/core/overlay.js +0 -137
  144. package/src/theme/core/shadow.js +0 -29
  145. package/src/theme/core/status.js +0 -49
  146. package/src/theme/core/typography.js +0 -82
  147. 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
+ });