@primer/primitives 11.4.0-rc.f798df25 → 11.4.1-rc.4e2d1de5

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 (198) hide show
  1. package/DESIGN_TOKENS_GUIDE.md +185 -0
  2. package/DESIGN_TOKENS_SPEC.md +565 -0
  3. package/dist/build/filters/hasLlmExtensions.d.ts +7 -0
  4. package/dist/build/filters/hasLlmExtensions.js +11 -0
  5. package/dist/build/filters/index.d.ts +1 -0
  6. package/dist/build/filters/index.js +1 -0
  7. package/dist/build/formats/index.d.ts +1 -0
  8. package/dist/build/formats/index.js +1 -0
  9. package/dist/build/formats/markdownLlmGuidelines.d.ts +11 -0
  10. package/dist/build/formats/markdownLlmGuidelines.js +1168 -0
  11. package/dist/build/platforms/index.d.ts +1 -0
  12. package/dist/build/platforms/index.js +1 -0
  13. package/dist/build/platforms/llmGuidelines.d.ts +2 -0
  14. package/dist/build/platforms/llmGuidelines.js +17 -0
  15. package/dist/build/preprocessors/inheritGroupProperties.d.ts +7 -0
  16. package/dist/build/preprocessors/inheritGroupProperties.js +70 -0
  17. package/dist/build/primerStyleDictionary.js +7 -1
  18. package/dist/build/schemas/borderToken.d.ts +22 -2
  19. package/dist/build/schemas/borderToken.js +6 -0
  20. package/dist/build/schemas/colorToken.d.ts +4 -0
  21. package/dist/build/schemas/colorToken.js +2 -0
  22. package/dist/build/schemas/cubicBezierToken.d.ts +6 -0
  23. package/dist/build/schemas/cubicBezierToken.js +10 -2
  24. package/dist/build/schemas/designToken.d.ts +1 -1
  25. package/dist/build/schemas/designToken.js +113 -21
  26. package/dist/build/schemas/dimensionToken.d.ts +14 -3
  27. package/dist/build/schemas/dimensionToken.js +6 -2
  28. package/dist/build/schemas/dimensionValue.d.ts +24 -1
  29. package/dist/build/schemas/dimensionValue.js +20 -1
  30. package/dist/build/schemas/durationToken.d.ts +13 -1
  31. package/dist/build/schemas/durationToken.js +6 -0
  32. package/dist/build/schemas/durationValue.d.ts +11 -1
  33. package/dist/build/schemas/durationValue.js +13 -3
  34. package/dist/build/schemas/fontFamilyToken.d.ts +4 -0
  35. package/dist/build/schemas/fontFamilyToken.js +2 -0
  36. package/dist/build/schemas/fontWeightToken.d.ts +4 -0
  37. package/dist/build/schemas/fontWeightToken.js +2 -0
  38. package/dist/build/schemas/gradientToken.d.ts +4 -0
  39. package/dist/build/schemas/gradientToken.js +2 -0
  40. package/dist/build/schemas/llmExtension.d.ts +9 -0
  41. package/dist/build/schemas/llmExtension.js +11 -0
  42. package/dist/build/schemas/numberToken.d.ts +4 -0
  43. package/dist/build/schemas/numberToken.js +2 -0
  44. package/dist/build/schemas/shadowToken.d.ts +676 -84
  45. package/dist/build/schemas/shadowToken.js +2 -0
  46. package/dist/build/schemas/stringToken.d.ts +6 -0
  47. package/dist/build/schemas/stringToken.js +6 -0
  48. package/dist/build/schemas/transitionToken.d.ts +20 -2
  49. package/dist/build/schemas/transitionToken.js +6 -0
  50. package/dist/build/schemas/typographyToken.d.ts +38 -4
  51. package/dist/build/schemas/typographyToken.js +6 -0
  52. package/dist/build/schemas/validTokenType.d.ts +5 -1
  53. package/dist/build/schemas/validTokenType.js +71 -17
  54. package/dist/build/schemas/viewportRangeToken.d.ts +6 -0
  55. package/dist/build/schemas/viewportRangeToken.js +6 -0
  56. package/dist/build/transformers/dimensionToPixelUnitless.d.ts +3 -2
  57. package/dist/build/transformers/dimensionToPixelUnitless.js +22 -26
  58. package/dist/build/transformers/dimensionToRem.d.ts +2 -1
  59. package/dist/build/transformers/dimensionToRem.js +21 -22
  60. package/dist/build/transformers/dimensionToRemPxArray.d.ts +2 -1
  61. package/dist/build/transformers/dimensionToRemPxArray.js +21 -22
  62. package/dist/build/transformers/durationToCss.d.ts +2 -1
  63. package/dist/build/transformers/durationToCss.js +18 -11
  64. package/dist/build/transformers/utilities/parseDimension.d.ts +12 -0
  65. package/dist/build/transformers/utilities/parseDimension.js +31 -0
  66. package/dist/build/types/dimensionTokenValue.d.ts +9 -0
  67. package/dist/css/base/motion/motion.css +5 -4
  68. package/dist/css/functional/size/border.css +9 -14
  69. package/dist/css/functional/size/radius.css +7 -0
  70. package/dist/css/functional/size/size-coarse.css +3 -3
  71. package/dist/css/functional/size/size-fine.css +3 -3
  72. package/dist/css/functional/size/viewport.css +1 -1
  73. package/dist/css/functional/themes/dark-colorblind-high-contrast.css +194 -190
  74. package/dist/css/functional/themes/dark-colorblind.css +194 -190
  75. package/dist/css/functional/themes/dark-dimmed-high-contrast.css +194 -190
  76. package/dist/css/functional/themes/dark-dimmed.css +194 -190
  77. package/dist/css/functional/themes/dark-high-contrast.css +194 -190
  78. package/dist/css/functional/themes/dark-tritanopia-high-contrast.css +194 -190
  79. package/dist/css/functional/themes/dark-tritanopia.css +194 -190
  80. package/dist/css/functional/themes/dark.css +194 -190
  81. package/dist/css/functional/themes/light-colorblind-high-contrast.css +194 -190
  82. package/dist/css/functional/themes/light-colorblind.css +194 -190
  83. package/dist/css/functional/themes/light-high-contrast.css +194 -190
  84. package/dist/css/functional/themes/light-tritanopia-high-contrast.css +194 -190
  85. package/dist/css/functional/themes/light-tritanopia.css +194 -190
  86. package/dist/css/functional/themes/light.css +194 -190
  87. package/dist/css/functional/typography/typography.css +4 -4
  88. package/dist/css/primitives.css +5 -0
  89. package/dist/docs/base/motion/motion.json +181 -32
  90. package/dist/docs/base/size/size.json +76 -19
  91. package/dist/docs/base/typography/typography.json +24 -6
  92. package/dist/docs/functional/size/border.json +62 -182
  93. package/dist/docs/functional/size/breakpoints.json +24 -6
  94. package/dist/docs/functional/size/radius.json +221 -0
  95. package/dist/docs/functional/size/size-coarse.json +45 -3
  96. package/dist/docs/functional/size/size-fine.json +45 -3
  97. package/dist/docs/functional/size/size.json +60 -15
  98. package/dist/docs/functional/size/viewport.json +2 -2
  99. package/dist/docs/functional/themes/dark-colorblind-high-contrast.json +1043 -97
  100. package/dist/docs/functional/themes/dark-colorblind.json +1043 -97
  101. package/dist/docs/functional/themes/dark-dimmed-high-contrast.json +1043 -97
  102. package/dist/docs/functional/themes/dark-dimmed.json +1081 -135
  103. package/dist/docs/functional/themes/dark-high-contrast.json +1043 -97
  104. package/dist/docs/functional/themes/dark-tritanopia-high-contrast.json +1043 -97
  105. package/dist/docs/functional/themes/dark-tritanopia.json +1043 -97
  106. package/dist/docs/functional/themes/dark.json +1043 -97
  107. package/dist/docs/functional/themes/light-colorblind-high-contrast.json +1049 -103
  108. package/dist/docs/functional/themes/light-colorblind.json +1049 -103
  109. package/dist/docs/functional/themes/light-high-contrast.json +1049 -103
  110. package/dist/docs/functional/themes/light-tritanopia-high-contrast.json +1049 -103
  111. package/dist/docs/functional/themes/light-tritanopia.json +1049 -103
  112. package/dist/docs/functional/themes/light.json +1049 -103
  113. package/dist/docs/functional/typography/typography.json +180 -10
  114. package/dist/fallbacks/base/motion/motion.json +49 -12
  115. package/dist/fallbacks/functional/size/border.json +0 -5
  116. package/dist/fallbacks/functional/size/radius.json +7 -0
  117. package/dist/fallbacks/functional/size/viewport.json +1 -1
  118. package/dist/figma/dimension/dimension.json +30 -20
  119. package/dist/figma/themes/dark-colorblind.json +85 -0
  120. package/dist/figma/themes/dark-dimmed.json +134 -49
  121. package/dist/figma/themes/dark-high-contrast.json +85 -0
  122. package/dist/figma/themes/dark-tritanopia.json +85 -0
  123. package/dist/figma/themes/dark.json +85 -0
  124. package/dist/figma/themes/light-colorblind.json +89 -4
  125. package/dist/figma/themes/light-high-contrast.json +89 -4
  126. package/dist/figma/themes/light-tritanopia.json +89 -4
  127. package/dist/figma/themes/light.json +89 -4
  128. package/dist/figma/typography/typography.json +44 -40
  129. package/dist/internalCss/dark-colorblind-high-contrast.css +208 -218
  130. package/dist/internalCss/dark-colorblind.css +208 -218
  131. package/dist/internalCss/dark-dimmed-high-contrast.css +208 -218
  132. package/dist/internalCss/dark-dimmed.css +208 -218
  133. package/dist/internalCss/dark-high-contrast.css +208 -218
  134. package/dist/internalCss/dark-tritanopia-high-contrast.css +208 -218
  135. package/dist/internalCss/dark-tritanopia.css +208 -218
  136. package/dist/internalCss/dark.css +208 -218
  137. package/dist/internalCss/light-colorblind-high-contrast.css +208 -218
  138. package/dist/internalCss/light-colorblind.css +208 -218
  139. package/dist/internalCss/light-high-contrast.css +208 -218
  140. package/dist/internalCss/light-tritanopia-high-contrast.css +208 -218
  141. package/dist/internalCss/light-tritanopia.css +208 -218
  142. package/dist/internalCss/light.css +208 -218
  143. package/dist/styleLint/base/motion/motion.json +181 -32
  144. package/dist/styleLint/base/size/size.json +76 -19
  145. package/dist/styleLint/base/typography/typography.json +30 -12
  146. package/dist/styleLint/functional/size/border.json +55 -175
  147. package/dist/styleLint/functional/size/breakpoints.json +24 -6
  148. package/dist/styleLint/functional/size/radius.json +221 -0
  149. package/dist/styleLint/functional/size/size-coarse.json +45 -3
  150. package/dist/styleLint/functional/size/size-fine.json +45 -3
  151. package/dist/styleLint/functional/size/size.json +111 -66
  152. package/dist/styleLint/functional/size/viewport.json +2 -2
  153. package/dist/styleLint/functional/themes/dark-colorblind-high-contrast.json +975 -29
  154. package/dist/styleLint/functional/themes/dark-colorblind.json +975 -29
  155. package/dist/styleLint/functional/themes/dark-dimmed-high-contrast.json +975 -29
  156. package/dist/styleLint/functional/themes/dark-dimmed.json +1013 -67
  157. package/dist/styleLint/functional/themes/dark-high-contrast.json +975 -29
  158. package/dist/styleLint/functional/themes/dark-tritanopia-high-contrast.json +975 -29
  159. package/dist/styleLint/functional/themes/dark-tritanopia.json +975 -29
  160. package/dist/styleLint/functional/themes/dark.json +975 -29
  161. package/dist/styleLint/functional/themes/light-colorblind-high-contrast.json +981 -35
  162. package/dist/styleLint/functional/themes/light-colorblind.json +981 -35
  163. package/dist/styleLint/functional/themes/light-high-contrast.json +981 -35
  164. package/dist/styleLint/functional/themes/light-tritanopia-high-contrast.json +981 -35
  165. package/dist/styleLint/functional/themes/light-tritanopia.json +981 -35
  166. package/dist/styleLint/functional/themes/light.json +981 -35
  167. package/dist/styleLint/functional/typography/typography.json +196 -26
  168. package/package.json +6 -3
  169. package/src/tokens/base/motion/easing.json5 +39 -4
  170. package/src/tokens/base/motion/timing.json5 +12 -12
  171. package/src/tokens/base/size/size.json5 +19 -19
  172. package/src/tokens/base/typography/typography.json5 +6 -6
  173. package/src/tokens/functional/border/border.json5 +25 -0
  174. package/src/tokens/functional/color/bgColor.json5 +165 -0
  175. package/src/tokens/functional/color/borderColor.json5 +146 -0
  176. package/src/tokens/functional/color/control.json5 +24 -0
  177. package/src/tokens/functional/color/data-vis.json5 +7 -0
  178. package/src/tokens/functional/color/display.json5 +7 -0
  179. package/src/tokens/functional/color/fgColor.json5 +101 -1
  180. package/src/tokens/functional/color/focus.json5 +5 -0
  181. package/src/tokens/functional/color/selection.json5 +5 -0
  182. package/src/tokens/functional/color/syntax.json5 +14 -0
  183. package/src/tokens/functional/shadow/shadow.json5 +49 -4
  184. package/src/tokens/functional/size/border.json5 +22 -74
  185. package/src/tokens/functional/size/breakpoints.json5 +6 -6
  186. package/src/tokens/functional/size/radius.json5 +90 -0
  187. package/src/tokens/functional/size/size-coarse.json5 +24 -3
  188. package/src/tokens/functional/size/size-fine.json5 +45 -24
  189. package/src/tokens/functional/size/size.json5 +50 -15
  190. package/src/tokens/functional/size/viewport.json5 +1 -1
  191. package/src/tokens/functional/typography/font-stack.json5 +60 -0
  192. package/src/tokens/functional/typography/typography.json5 +71 -44
  193. package/dist/build/parsers/index.d.ts +0 -1
  194. package/dist/build/parsers/index.js +0 -1
  195. package/dist/build/parsers/w3cJsonParser.d.ts +0 -6
  196. package/dist/build/parsers/w3cJsonParser.js +0 -25
  197. package/dist/removed/testing.json5 +0 -4
  198. package/src/tokens/removed/testing.json5 +0 -4
@@ -6,6 +6,7 @@ import { alphaValue } from './alphaValue.js';
6
6
  import { dimensionValue } from './dimensionValue.js';
7
7
  import { tokenType } from './tokenType.js';
8
8
  import { collection, mode } from './collections.js';
9
+ import { llmExtension } from './llmExtension.js';
9
10
  export const shadowValue = z
10
11
  .object({
11
12
  color: z.union([colorHexValue, referenceValue]),
@@ -58,6 +59,7 @@ export const shadowToken = baseToken
58
59
  })
59
60
  .strict()
60
61
  .optional(),
62
+ 'org.primer.llm': llmExtension,
61
63
  })
62
64
  .optional(),
63
65
  })
@@ -4,4 +4,10 @@ export declare const stringToken: z.ZodObject<{
4
4
  $deprecated: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodBoolean]>>;
5
5
  $value: z.ZodUnion<readonly [z.ZodString, z.ZodString]>;
6
6
  $type: z.ZodLiteral<"string" | "number" | "border" | "color" | "fontFamily" | "fontWeight" | "transition" | "dimension" | "duration" | "gradient" | "shadow" | "typography" | "cubicBezier" | "custom-viewportRange">;
7
+ $extensions: z.ZodOptional<z.ZodObject<{
8
+ 'org.primer.llm': z.ZodOptional<z.ZodObject<{
9
+ usage: z.ZodOptional<z.ZodArray<z.ZodString>>;
10
+ rules: z.ZodOptional<z.ZodString>;
11
+ }, z.core.$strip>>;
12
+ }, z.core.$strip>>;
7
13
  }, z.core.$strict>;
@@ -2,9 +2,15 @@ import { z } from 'zod';
2
2
  import { baseToken } from './baseToken.js';
3
3
  import { referenceValue } from './referenceValue.js';
4
4
  import { tokenType } from './tokenType.js';
5
+ import { llmExtension } from './llmExtension.js';
5
6
  export const stringToken = baseToken
6
7
  .extend({
7
8
  $value: z.union([z.string(), referenceValue]),
8
9
  $type: tokenType('string'),
10
+ $extensions: z
11
+ .object({
12
+ 'org.primer.llm': llmExtension,
13
+ })
14
+ .optional(),
9
15
  })
10
16
  .strict();
@@ -3,9 +3,27 @@ export declare const transitionToken: z.ZodObject<{
3
3
  $description: z.ZodOptional<z.ZodString>;
4
4
  $deprecated: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodBoolean]>>;
5
5
  $value: z.ZodUnion<readonly [z.ZodObject<{
6
- duration: z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodString, z.ZodString]>, z.ZodString]>;
6
+ duration: z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodObject<{
7
+ value: z.ZodNumber;
8
+ unit: z.ZodEnum<{
9
+ s: "s";
10
+ ms: "ms";
11
+ }>;
12
+ }, z.core.$strict>, z.ZodString]>, z.ZodString]>;
7
13
  timingFunction: z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodArray<z.ZodNumber>, z.ZodString]>, z.ZodString]>;
8
- delay: z.ZodOptional<z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodString, z.ZodString]>, z.ZodString]>>;
14
+ delay: z.ZodOptional<z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodObject<{
15
+ value: z.ZodNumber;
16
+ unit: z.ZodEnum<{
17
+ s: "s";
18
+ ms: "ms";
19
+ }>;
20
+ }, z.core.$strict>, z.ZodString]>, z.ZodString]>>;
9
21
  }, z.core.$strip>, z.ZodString]>;
10
22
  $type: z.ZodLiteral<"string" | "number" | "border" | "color" | "fontFamily" | "fontWeight" | "transition" | "dimension" | "duration" | "gradient" | "shadow" | "typography" | "cubicBezier" | "custom-viewportRange">;
23
+ $extensions: z.ZodOptional<z.ZodObject<{
24
+ 'org.primer.llm': z.ZodOptional<z.ZodObject<{
25
+ usage: z.ZodOptional<z.ZodArray<z.ZodString>>;
26
+ rules: z.ZodOptional<z.ZodString>;
27
+ }, z.core.$strip>>;
28
+ }, z.core.$strip>>;
11
29
  }, z.core.$strict>;
@@ -4,6 +4,7 @@ import { referenceValue } from './referenceValue.js';
4
4
  import { durationToken } from './durationToken.js';
5
5
  import { cubicBezierToken } from './cubicBezierToken.js';
6
6
  import { tokenType } from './tokenType.js';
7
+ import { llmExtension } from './llmExtension.js';
7
8
  export const transitionToken = baseToken
8
9
  .extend({
9
10
  $value: z.union([
@@ -15,5 +16,10 @@ export const transitionToken = baseToken
15
16
  referenceValue,
16
17
  ]),
17
18
  $type: tokenType('transition'),
19
+ $extensions: z
20
+ .object({
21
+ 'org.primer.llm': llmExtension,
22
+ })
23
+ .optional(),
18
24
  })
19
25
  .strict();
@@ -1,7 +1,21 @@
1
1
  import { z } from 'zod';
2
2
  export declare const typographyValue: z.ZodObject<{
3
- fontSize: z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodString, z.ZodLiteral<"0">, z.ZodLiteral<0>]>, z.ZodString]>;
4
- lineHeight: z.ZodOptional<z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodString, z.ZodLiteral<"0">, z.ZodLiteral<0>]>, z.ZodString]>>;
3
+ fontSize: z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodObject<{
4
+ value: z.ZodNumber;
5
+ unit: z.ZodEnum<{
6
+ em: "em";
7
+ px: "px";
8
+ rem: "rem";
9
+ }>;
10
+ }, z.core.$strict>, z.ZodUnion<readonly [z.ZodString, z.ZodLiteral<"0">, z.ZodLiteral<0>]>]>, z.ZodString]>;
11
+ lineHeight: z.ZodOptional<z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodObject<{
12
+ value: z.ZodNumber;
13
+ unit: z.ZodEnum<{
14
+ em: "em";
15
+ px: "px";
16
+ rem: "rem";
17
+ }>;
18
+ }, z.core.$strict>, z.ZodUnion<readonly [z.ZodString, z.ZodLiteral<"0">, z.ZodLiteral<0>]>]>, z.ZodString]>>;
5
19
  fontWeight: z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>;
6
20
  fontFamily: z.ZodUnion<readonly [z.ZodString, z.ZodString]>;
7
21
  }, z.core.$strip>;
@@ -9,10 +23,30 @@ export declare const typographyToken: z.ZodObject<{
9
23
  $description: z.ZodOptional<z.ZodString>;
10
24
  $deprecated: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodBoolean]>>;
11
25
  $value: z.ZodUnion<readonly [z.ZodObject<{
12
- fontSize: z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodString, z.ZodLiteral<"0">, z.ZodLiteral<0>]>, z.ZodString]>;
13
- lineHeight: z.ZodOptional<z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodString, z.ZodLiteral<"0">, z.ZodLiteral<0>]>, z.ZodString]>>;
26
+ fontSize: z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodObject<{
27
+ value: z.ZodNumber;
28
+ unit: z.ZodEnum<{
29
+ em: "em";
30
+ px: "px";
31
+ rem: "rem";
32
+ }>;
33
+ }, z.core.$strict>, z.ZodUnion<readonly [z.ZodString, z.ZodLiteral<"0">, z.ZodLiteral<0>]>]>, z.ZodString]>;
34
+ lineHeight: z.ZodOptional<z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodObject<{
35
+ value: z.ZodNumber;
36
+ unit: z.ZodEnum<{
37
+ em: "em";
38
+ px: "px";
39
+ rem: "rem";
40
+ }>;
41
+ }, z.core.$strict>, z.ZodUnion<readonly [z.ZodString, z.ZodLiteral<"0">, z.ZodLiteral<0>]>]>, z.ZodString]>>;
14
42
  fontWeight: z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>;
15
43
  fontFamily: z.ZodUnion<readonly [z.ZodString, z.ZodString]>;
16
44
  }, z.core.$strip>, z.ZodString]>;
17
45
  $type: z.ZodLiteral<"string" | "number" | "border" | "color" | "fontFamily" | "fontWeight" | "transition" | "dimension" | "duration" | "gradient" | "shadow" | "typography" | "cubicBezier" | "custom-viewportRange">;
46
+ $extensions: z.ZodOptional<z.ZodObject<{
47
+ 'org.primer.llm': z.ZodOptional<z.ZodObject<{
48
+ usage: z.ZodOptional<z.ZodArray<z.ZodString>>;
49
+ rules: z.ZodOptional<z.ZodString>;
50
+ }, z.core.$strip>>;
51
+ }, z.core.$strip>>;
18
52
  }, z.core.$strict>;
@@ -4,6 +4,7 @@ import { dimensionValue } from './dimensionValue.js';
4
4
  import { baseToken } from './baseToken.js';
5
5
  import { fontWeightValue } from './fontWeightValue.js';
6
6
  import { tokenType } from './tokenType.js';
7
+ import { llmExtension } from './llmExtension.js';
7
8
  export const typographyValue = z.object({
8
9
  fontSize: z.union([dimensionValue, referenceValue]),
9
10
  lineHeight: z.union([dimensionValue, referenceValue]).optional(),
@@ -14,5 +15,10 @@ export const typographyToken = baseToken
14
15
  .extend({
15
16
  $value: z.union([typographyValue, referenceValue]),
16
17
  $type: tokenType('typography'),
18
+ $extensions: z
19
+ .object({
20
+ 'org.primer.llm': llmExtension,
21
+ })
22
+ .optional(),
17
23
  })
18
24
  .strict();
@@ -1,5 +1,9 @@
1
1
  import { z } from 'zod';
2
2
  declare const validTypes: readonly ["color", "cubicBezier", "typography", "dimension", "duration", "border", "shadow", "fontFamily", "fontWeight", "gradient", "number", "string", "transition", "custom-viewportRange"];
3
3
  export type TokenType = (typeof validTypes)[number];
4
- export declare const validateType: z.ZodRecord<z.ZodString, z.ZodLazy<z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>>>;
4
+ /**
5
+ * Recursively validates $type properties in token structure
6
+ * Allows group-level properties ($description, $extensions) per W3C Design Tokens spec
7
+ */
8
+ export declare const validateType: z.ZodType<unknown>;
5
9
  export {};
@@ -16,23 +16,77 @@ const validTypes = [
16
16
  'transition',
17
17
  'custom-viewportRange',
18
18
  ];
19
+ /**
20
+ * Token schema that validates $type property
21
+ */
22
+ const tokenWithType = z
23
+ .object({
24
+ $value: z.any(),
25
+ $type: z.string().superRefine((value, ctx) => {
26
+ if (!validTypes.includes(value)) {
27
+ ctx.addIssue({
28
+ code: 'custom',
29
+ message: schemaErrorMessage(`Invalid token $type: "${value}"`, `Must be one of the following: ${joinFriendly([...validTypes], 'or')}`),
30
+ });
31
+ }
32
+ }),
33
+ })
34
+ .required();
35
+ /**
36
+ * Recursively validates $type properties in token structure
37
+ * Allows group-level properties ($description, $extensions) per W3C Design Tokens spec
38
+ */
19
39
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
20
40
  // @ts-ignore: TODO: fix this
21
- export const validateType = z.record(z.string(), z.lazy(() => {
22
- return z.union([
23
- z
24
- .object({
25
- $value: z.any(),
26
- $type: z.string().superRefine((value, ctx) => {
27
- if (!validTypes.includes(value)) {
28
- ctx.addIssue({
29
- code: 'custom',
30
- message: schemaErrorMessage(`Invalid token $type: "${value}"`, `Must be one of the following: ${joinFriendly([...validTypes], 'or')}`),
31
- });
41
+ export const validateType = z.record(z.string(), z.unknown()).superRefine((obj, ctx) => {
42
+ for (const [key, value] of Object.entries(obj)) {
43
+ if (key === '$description') {
44
+ // Group-level $description must be a string
45
+ if (typeof value !== 'string') {
46
+ ctx.addIssue({
47
+ code: z.ZodIssueCode.custom,
48
+ message: `$description must be a string`,
49
+ path: [key],
50
+ });
51
+ }
52
+ }
53
+ else if (key === '$extensions') {
54
+ // Group-level $extensions must be an object
55
+ if (typeof value !== 'object' || value === null) {
56
+ ctx.addIssue({
57
+ code: z.ZodIssueCode.custom,
58
+ message: `$extensions must be an object`,
59
+ path: [key],
60
+ });
61
+ }
62
+ }
63
+ else if (key.startsWith('$')) {
64
+ // Unknown $-prefixed keys are not allowed
65
+ ctx.addIssue({
66
+ code: z.ZodIssueCode.custom,
67
+ message: `Unknown group property: ${key}`,
68
+ path: [key],
69
+ });
70
+ }
71
+ else if (typeof value === 'object' && value !== null) {
72
+ // Check if it's a token (has $type) or a nested group
73
+ if ('$type' in value) {
74
+ const result = tokenWithType.safeParse(value);
75
+ if (!result.success) {
76
+ for (const issue of result.error.issues) {
77
+ ctx.addIssue(Object.assign(Object.assign({}, issue), { path: [key, ...issue.path] }));
78
+ }
32
79
  }
33
- }),
34
- })
35
- .required(),
36
- validateType,
37
- ]);
38
- }));
80
+ }
81
+ else {
82
+ // Recursively validate nested group
83
+ const result = validateType.safeParse(value);
84
+ if (!result.success) {
85
+ for (const issue of result.error.issues) {
86
+ ctx.addIssue(Object.assign(Object.assign({}, issue), { path: [key, ...issue.path] }));
87
+ }
88
+ }
89
+ }
90
+ }
91
+ }
92
+ });
@@ -4,4 +4,10 @@ export declare const viewportRangeToken: z.ZodObject<{
4
4
  $deprecated: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodBoolean]>>;
5
5
  $value: z.ZodUnion<readonly [z.ZodString, z.ZodString]>;
6
6
  $type: z.ZodLiteral<"string" | "number" | "border" | "color" | "fontFamily" | "fontWeight" | "transition" | "dimension" | "duration" | "gradient" | "shadow" | "typography" | "cubicBezier" | "custom-viewportRange">;
7
+ $extensions: z.ZodOptional<z.ZodObject<{
8
+ 'org.primer.llm': z.ZodOptional<z.ZodObject<{
9
+ usage: z.ZodOptional<z.ZodArray<z.ZodString>>;
10
+ rules: z.ZodOptional<z.ZodString>;
11
+ }, z.core.$strip>>;
12
+ }, z.core.$strip>>;
7
13
  }, z.core.$strict>;
@@ -2,9 +2,15 @@ import { z } from 'zod';
2
2
  import { baseToken } from './baseToken.js';
3
3
  import { referenceValue } from './referenceValue.js';
4
4
  import { tokenType } from './tokenType.js';
5
+ import { llmExtension } from './llmExtension.js';
5
6
  export const viewportRangeToken = baseToken
6
7
  .extend({
7
8
  $value: z.union([z.string(), referenceValue]),
8
9
  $type: tokenType('custom-viewportRange'),
10
+ $extensions: z
11
+ .object({
12
+ 'org.primer.llm': llmExtension,
13
+ })
14
+ .optional(),
9
15
  })
10
16
  .strict();
@@ -1,8 +1,9 @@
1
1
  import type { Transform } from 'style-dictionary/types';
2
2
  /**
3
- * @description converts dimension tokens value to pixel value without unit, ignores `em` as they are relative to the font size of the parent element
3
+ * @description converts dimension tokens value to pixel value without unit
4
4
  * @type value transformer — [StyleDictionary.ValueTransform](https://github.com/amzn/style-dictionary/blob/main/types/Transform.d.ts)
5
5
  * @matcher matches all tokens of $type `dimension`
6
- * @transformer returns a float number
6
+ * @transformer returns a number for px/rem values, or a string with unit for em values (cannot convert to unitless)
7
+ * @note Expects W3C DTCG format { value: number, unit: "px" | "rem" | "em" }
7
8
  */
8
9
  export declare const dimensionToPixelUnitless: Transform;
@@ -1,4 +1,5 @@
1
1
  import { isDimension } from '../filters/index.js';
2
+ import { parseDimension } from './utilities/parseDimension.js';
2
3
  /**
3
4
  * @description base font size from options or 16
4
5
  * @param options
@@ -6,22 +7,11 @@ import { isDimension } from '../filters/index.js';
6
7
  */
7
8
  const getBasePxFontSize = (options) => (options && options.basePxFontSize) || 16;
8
9
  /**
9
- * @description checks if token value has a specific unit
10
- * @param value token value
11
- * @param unit unit string like px or value
12
- * @returns boolean
13
- */
14
- const hasUnit = (value, unit) => {
15
- if (typeof value === 'number') {
16
- return false;
17
- }
18
- return value.indexOf(unit) > -1;
19
- };
20
- /**
21
- * @description converts dimension tokens value to pixel value without unit, ignores `em` as they are relative to the font size of the parent element
10
+ * @description converts dimension tokens value to pixel value without unit
22
11
  * @type value transformer — [StyleDictionary.ValueTransform](https://github.com/amzn/style-dictionary/blob/main/types/Transform.d.ts)
23
12
  * @matcher matches all tokens of $type `dimension`
24
- * @transformer returns a float number
13
+ * @transformer returns a number for px/rem values, or a string with unit for em values (cannot convert to unitless)
14
+ * @note Expects W3C DTCG format { value: number, unit: "px" | "rem" | "em" }
25
15
  */
26
16
  export const dimensionToPixelUnitless = {
27
17
  name: 'dimension/pixelUnitless',
@@ -31,19 +21,25 @@ export const dimensionToPixelUnitless = {
31
21
  transform: (token, config, options) => {
32
22
  const valueProp = options.usesDtcg ? '$value' : 'value';
33
23
  const baseFont = getBasePxFontSize(config);
34
- const floatVal = parseFloat(token[valueProp]);
35
- if (isNaN(floatVal)) {
36
- throw new Error(`Invalid dimension token: '${token.path.join('.')}: ${token[valueProp]}' is not valid and cannot be transform to 'float' \n`);
37
- }
38
- if (floatVal === 0) {
39
- return 0;
40
- }
41
- if (hasUnit(token[valueProp], 'rem')) {
42
- return floatVal * baseFont;
24
+ try {
25
+ const { value, unit } = parseDimension(token[valueProp]);
26
+ if (value === 0) {
27
+ return 0;
28
+ }
29
+ // rem values convert to px
30
+ if (unit === 'rem') {
31
+ return value * baseFont;
32
+ }
33
+ // em values pass through as string (relative to parent, cannot convert to unitless px)
34
+ if (unit === 'em') {
35
+ return `${value}em`;
36
+ }
37
+ // px values return the number directly
38
+ return value;
43
39
  }
44
- if (hasUnit(token[valueProp], 'px')) {
45
- return floatVal;
40
+ catch (error) {
41
+ const originalMessage = error instanceof Error ? error.message : String(error);
42
+ throw new Error(`Invalid dimension token: '${token.path.join('.')}: ${JSON.stringify(token[valueProp])}' - ${originalMessage}\n`);
46
43
  }
47
- return token[valueProp];
48
44
  },
49
45
  };
@@ -1,8 +1,9 @@
1
1
  import type { Transform } from 'style-dictionary/types';
2
2
  /**
3
- * @description converts dimension tokens value to `rem`, ignores `em` as they are relative to the font size of the parent element
3
+ * @description converts dimension tokens value to `rem`
4
4
  * @type value transformer — [StyleDictionary.ValueTransform](https://github.com/amzn/style-dictionary/blob/main/types/Transform.d.ts)
5
5
  * @matcher matches all tokens of $type `dimension`
6
6
  * @transformer returns a `rem` string
7
+ * @note Expects W3C DTCG format { value: number, unit: "px" | "rem" | "em" }
7
8
  */
8
9
  export declare const dimensionToRem: Transform;
@@ -1,4 +1,5 @@
1
1
  import { isDimension } from '../filters/index.js';
2
+ import { parseDimension } from './utilities/parseDimension.js';
2
3
  /**
3
4
  * @description base font size from options or 16
4
5
  * @param options
@@ -6,22 +7,11 @@ import { isDimension } from '../filters/index.js';
6
7
  */
7
8
  const getBasePxFontSize = (options) => (options && options.basePxFontSize) || 16;
8
9
  /**
9
- * @description checks if token value has a specific unit
10
- * @param value token value
11
- * @param unit unit string like px or value
12
- * @returns boolean
13
- */
14
- const hasUnit = (value, unit) => {
15
- if (typeof value === 'number') {
16
- return false;
17
- }
18
- return value.indexOf(unit) > -1;
19
- };
20
- /**
21
- * @description converts dimension tokens value to `rem`, ignores `em` as they are relative to the font size of the parent element
10
+ * @description converts dimension tokens value to `rem`
22
11
  * @type value transformer — [StyleDictionary.ValueTransform](https://github.com/amzn/style-dictionary/blob/main/types/Transform.d.ts)
23
12
  * @matcher matches all tokens of $type `dimension`
24
13
  * @transformer returns a `rem` string
14
+ * @note Expects W3C DTCG format { value: number, unit: "px" | "rem" | "em" }
25
15
  */
26
16
  export const dimensionToRem = {
27
17
  name: 'dimension/rem',
@@ -31,16 +21,25 @@ export const dimensionToRem = {
31
21
  transform: (token, config, options) => {
32
22
  const valueProp = options.usesDtcg ? '$value' : 'value';
33
23
  const baseFont = getBasePxFontSize(config);
34
- const floatVal = parseFloat(token[valueProp]);
35
- if (isNaN(floatVal)) {
36
- throw new Error(`Invalid dimension token: '${token.name}: ${token[valueProp]}' is not valid and cannot be transform to 'rem' \n`);
37
- }
38
- if (floatVal === 0) {
39
- return '0';
24
+ try {
25
+ const { value, unit } = parseDimension(token[valueProp]);
26
+ if (value === 0) {
27
+ return '0';
28
+ }
29
+ // rem values pass through unchanged
30
+ if (unit === 'rem') {
31
+ return `${value}rem`;
32
+ }
33
+ // em values pass through unchanged (relative to parent, cannot convert)
34
+ if (unit === 'em') {
35
+ return `${value}em`;
36
+ }
37
+ // px values convert to rem
38
+ return `${value / baseFont}rem`;
40
39
  }
41
- if (hasUnit(token[valueProp], 'rem') || hasUnit(token[valueProp], 'em')) {
42
- return token[valueProp];
40
+ catch (error) {
41
+ const details = error instanceof Error && error.message ? ` - ${error.message}` : error ? ` - ${String(error)}` : '';
42
+ throw new Error(`Invalid dimension token: '${token.name}: ${JSON.stringify(token[valueProp])}' is not valid and cannot be transformed to 'rem'${details}\n`);
43
43
  }
44
- return `${floatVal / baseFont}rem`;
45
44
  },
46
45
  };
@@ -1,8 +1,9 @@
1
1
  import type { Transform } from 'style-dictionary/types';
2
2
  /**
3
- * @description converts dimension tokens value to `rem`, ignores `em` as they are relative to the font size of the parent element
3
+ * @description converts dimension tokens value to an array with both `rem` and `px` values
4
4
  * @type value transformer — [StyleDictionary.ValueTransform](https://github.com/amzn/style-dictionary/blob/main/types/Transform.d.ts)
5
5
  * @matcher matches all tokens of $type `dimension`
6
6
  * @transformer returns an array with the `rem` and `pixel` string
7
+ * @note Expects W3C DTCG format { value: number, unit: "px" | "rem" | "em" }
7
8
  */
8
9
  export declare const dimensionToRemPxArray: Transform;
@@ -1,4 +1,5 @@
1
1
  import { isDimension } from '../filters/index.js';
2
+ import { parseDimension } from './utilities/parseDimension.js';
2
3
  /**
3
4
  * @description base font size from options or 16
4
5
  * @param options
@@ -6,22 +7,11 @@ import { isDimension } from '../filters/index.js';
6
7
  */
7
8
  const getBasePxFontSize = (options) => (options && options.basePxFontSize) || 16;
8
9
  /**
9
- * @description checks if token value has a specific unit
10
- * @param value token value
11
- * @param unit unit string like px or value
12
- * @returns boolean
13
- */
14
- const hasUnit = (value, unit) => {
15
- if (typeof value === 'number') {
16
- return false;
17
- }
18
- return value.indexOf(unit) > -1;
19
- };
20
- /**
21
- * @description converts dimension tokens value to `rem`, ignores `em` as they are relative to the font size of the parent element
10
+ * @description converts dimension tokens value to an array with both `rem` and `px` values
22
11
  * @type value transformer — [StyleDictionary.ValueTransform](https://github.com/amzn/style-dictionary/blob/main/types/Transform.d.ts)
23
12
  * @matcher matches all tokens of $type `dimension`
24
13
  * @transformer returns an array with the `rem` and `pixel` string
14
+ * @note Expects W3C DTCG format { value: number, unit: "px" | "rem" | "em" }
25
15
  */
26
16
  export const dimensionToRemPxArray = {
27
17
  name: 'dimension/remPxArray',
@@ -31,16 +21,25 @@ export const dimensionToRemPxArray = {
31
21
  transform: (token, config, options) => {
32
22
  const valueProp = options.usesDtcg ? '$value' : 'value';
33
23
  const baseFont = getBasePxFontSize(config);
34
- const floatVal = parseFloat(token[valueProp]);
35
- if (isNaN(floatVal)) {
36
- throw new Error(`Invalid dimension token: '${token.name}: ${token[valueProp]}' is not valid and cannot be transform to 'rem' \n`);
37
- }
38
- if (floatVal === 0) {
39
- return ['0', '0'];
24
+ try {
25
+ const { value, unit } = parseDimension(token[valueProp]);
26
+ if (value === 0) {
27
+ return ['0', '0'];
28
+ }
29
+ // em values pass through unchanged (relative to parent, cannot convert)
30
+ if (unit === 'em') {
31
+ return [`${value}em`, `${value}em`];
32
+ }
33
+ // rem values pass through, convert to px for second value
34
+ if (unit === 'rem') {
35
+ return [`${value}rem`, `${value * baseFont}px`];
36
+ }
37
+ // px values convert to rem for first value
38
+ return [`${value / baseFont}rem`, `${value}px`];
40
39
  }
41
- if (hasUnit(token[valueProp], 'rem') || hasUnit(token[valueProp], 'em')) {
42
- return [token.value, `${floatVal * baseFont}px`];
40
+ catch (error) {
41
+ const errorMessage = error instanceof Error ? error.message : String(error);
42
+ throw new Error(`Invalid dimension token: '${token.name}: ${JSON.stringify(token[valueProp])}' is not valid and cannot be transformed to 'rem' - ${errorMessage}\n`);
43
43
  }
44
- return [`${floatVal / baseFont}rem`, `${floatVal}px`];
45
44
  },
46
45
  };
@@ -1,8 +1,9 @@
1
1
  import type { Transform } from 'style-dictionary/types';
2
2
  /**
3
- * @description converts duration tokens string value to number with `ms` unit
3
+ * @description converts duration tokens to css duration string
4
4
  * @type value transformer — [StyleDictionary.ValueTransform](https://github.com/amzn/style-dictionary/blob/main/types/Transform.d.ts)
5
5
  * @matcher matches all tokens of $type `duration`
6
6
  * @transformer returns a css duration
7
+ * @note W3C DTCG format: { value: number, unit: "ms" | "s" }
7
8
  */
8
9
  export declare const durationToCss: Transform;
@@ -1,9 +1,10 @@
1
1
  import { isDuration } from '../filters/index.js';
2
2
  /**
3
- * @description converts duration tokens string value to number with `ms` unit
3
+ * @description converts duration tokens to css duration string
4
4
  * @type value transformer — [StyleDictionary.ValueTransform](https://github.com/amzn/style-dictionary/blob/main/types/Transform.d.ts)
5
5
  * @matcher matches all tokens of $type `duration`
6
6
  * @transformer returns a css duration
7
+ * @note W3C DTCG format: { value: number, unit: "ms" | "s" }
7
8
  */
8
9
  export const durationToCss = {
9
10
  name: 'duration/css',
@@ -12,18 +13,24 @@ export const durationToCss = {
12
13
  filter: isDuration,
13
14
  transform: (token, _config, options) => {
14
15
  const valueProp = options.usesDtcg ? '$value' : 'value';
15
- // throw an error if token value is not a string or does not end with `ms`
16
- if (typeof token[valueProp] !== `string` || !(token[valueProp].endsWith(`ms`) || token[valueProp].endsWith(`s`))) {
17
- throw new Error(`duration token value must be a string with an "ms" || "s" unit, invalid token: ${token.name} with value: ${token[valueProp]}`);
16
+ const tokenValue = token[valueProp];
17
+ // Validate W3C DTCG object format: { value: number, unit: "ms" | "s" }
18
+ if (typeof tokenValue !== 'object' || tokenValue === null || !('value' in tokenValue) || !('unit' in tokenValue)) {
19
+ throw new Error(`duration token value must be an object with "value" and "unit" properties (W3C DTCG format). Invalid token: ${token.name} with value: ${JSON.stringify(tokenValue)}`);
18
20
  }
19
- // get value
20
- let value = parseInt(token[valueProp].replace('ms', ''));
21
- let unit = `ms`;
22
- if (value >= 1000) {
23
- value = value / 1000;
24
- unit = `s`;
21
+ const { value, unit } = tokenValue;
22
+ // Validate unit
23
+ if (unit !== 'ms' && unit !== 's') {
24
+ throw new Error(`duration token unit must be "ms" or "s", invalid token: ${token.name} with unit: ${unit}`);
25
+ }
26
+ // Validate value is a finite, non-negative number
27
+ if (typeof value !== 'number' || !Number.isFinite(value) || value < 0) {
28
+ throw new Error(`duration token value must be a finite, non-negative number, invalid token: ${token.name} with value: ${value}`);
29
+ }
30
+ // Convert ms >= 1000 to seconds for cleaner output
31
+ if (unit === 'ms' && value >= 1000) {
32
+ return `${value / 1000}s`;
25
33
  }
26
- // return value
27
34
  return `${value}${unit}`;
28
35
  },
29
36
  };
@@ -0,0 +1,12 @@
1
+ import type { DimensionTokenValue } from '../../types/dimensionTokenValue.js';
2
+ /**
3
+ * @description Parses and validates a dimension value in W3C DTCG object format
4
+ * @param input - The dimension value in W3C object format { value: number, unit: "px" | "rem" | "em" }
5
+ * @returns Validated DimensionTokenValue
6
+ * @throws Error if the input is not a valid W3C dimension object
7
+ *
8
+ * W3C DTCG format: { value: 16, unit: "px" }
9
+ * @note `em` is not in the W3C spec but is supported for practical use
10
+ * @link https://www.designtokens.org/tr/drafts/format/#dimension
11
+ */
12
+ export declare const parseDimension: (input: DimensionTokenValue) => DimensionTokenValue;