@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
@@ -1,3 +1,4 @@
1
+ export { llmGuidelines } from './llmGuidelines.js';
1
2
  export { css } from './css.js';
2
3
  export { deprecatedJson } from './deprecatedJson.js';
3
4
  export { docJson } from './docJson.js';
@@ -1,3 +1,4 @@
1
+ export { llmGuidelines } from './llmGuidelines.js';
1
2
  export { css } from './css.js';
2
3
  export { deprecatedJson } from './deprecatedJson.js';
3
4
  export { docJson } from './docJson.js';
@@ -0,0 +1,2 @@
1
+ import type { PlatformInitializer } from '../types/platformInitializer.js';
2
+ export declare const llmGuidelines: PlatformInitializer;
@@ -0,0 +1,17 @@
1
+ import { hasLlmExtensions } from '../filters/index.js';
2
+ export const llmGuidelines = (outputFile, prefix, buildPath) => ({
3
+ prefix,
4
+ buildPath,
5
+ preprocessors: ['inheritGroupProperties'],
6
+ transforms: ['name/pathToKebabCase'],
7
+ files: [
8
+ {
9
+ destination: outputFile,
10
+ format: 'json/llm-guidelines',
11
+ filter: hasLlmExtensions,
12
+ options: {
13
+ outputReferences: false,
14
+ },
15
+ },
16
+ ],
17
+ });
@@ -0,0 +1,7 @@
1
+ import type { Preprocessor } from 'style-dictionary/types';
2
+ /**
3
+ * Preprocessor that inherits group-level $description and $extensions to child tokens.
4
+ * This enables W3C Design Tokens group properties to be available on individual tokens
5
+ * during formatting.
6
+ */
7
+ export declare const inheritGroupProperties: Preprocessor;
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Recursively walks tokens and inherits group-level properties to child tokens.
3
+ * Group properties ($description, $extensions at group level) are merged into child tokens
4
+ * that don't have their own values for those properties.
5
+ *
6
+ * Per W3C Design Tokens spec: https://www.designtokens.org/tr/drafts/format/#group-properties
7
+ */
8
+ function inheritProperties(tokens, inheritedProps = {}) {
9
+ var _a;
10
+ const result = {};
11
+ // Extract group-level properties from current level
12
+ const currentGroupProps = {};
13
+ if (typeof tokens.$description === 'string') {
14
+ currentGroupProps.$description = tokens.$description;
15
+ }
16
+ if (tokens.$extensions && typeof tokens.$extensions === 'object') {
17
+ currentGroupProps.$extensions = tokens.$extensions;
18
+ }
19
+ // Merge inherited with current (current takes precedence)
20
+ const mergedProps = Object.assign(Object.assign({}, inheritedProps), currentGroupProps);
21
+ // Merge $extensions deeply
22
+ if (inheritedProps.$extensions || currentGroupProps.$extensions) {
23
+ mergedProps.$extensions = Object.assign(Object.assign({}, inheritedProps.$extensions), currentGroupProps.$extensions);
24
+ }
25
+ for (const [key, value] of Object.entries(tokens)) {
26
+ // Skip group-level properties (they're inherited, not copied)
27
+ if (key === '$description' || key === '$extensions') {
28
+ continue;
29
+ }
30
+ if (typeof value !== 'object' || value === null) {
31
+ result[key] = value;
32
+ continue;
33
+ }
34
+ const tokenValue = value;
35
+ // Check if this is a design token (has $value or value)
36
+ if ('$value' in tokenValue || 'value' in tokenValue) {
37
+ // It's a token - merge inherited properties
38
+ const token = tokenValue;
39
+ // Only inherit $description if token doesn't have its own
40
+ const inheritedDescription = !token.$description && mergedProps.$description ? mergedProps.$description : undefined;
41
+ // Merge $extensions (token-level takes precedence over inherited)
42
+ let mergedExtensions = token.$extensions;
43
+ if (mergedProps.$extensions) {
44
+ const inheritedLlm = mergedProps.$extensions['org.primer.llm'];
45
+ const tokenLlm = (_a = token.$extensions) === null || _a === void 0 ? void 0 : _a['org.primer.llm'];
46
+ if (inheritedLlm && !tokenLlm) {
47
+ // Token has no LLM extension, inherit from group
48
+ mergedExtensions = Object.assign(Object.assign({}, token.$extensions), { 'org.primer.llm': inheritedLlm });
49
+ }
50
+ }
51
+ result[key] = Object.assign(Object.assign(Object.assign({}, token), (inheritedDescription ? { $description: inheritedDescription } : {})), (mergedExtensions ? { $extensions: mergedExtensions } : {}));
52
+ }
53
+ else {
54
+ // It's a nested group - recurse with merged properties
55
+ result[key] = inheritProperties(tokenValue, mergedProps);
56
+ }
57
+ }
58
+ return result;
59
+ }
60
+ /**
61
+ * Preprocessor that inherits group-level $description and $extensions to child tokens.
62
+ * This enables W3C Design Tokens group properties to be available on individual tokens
63
+ * during formatting.
64
+ */
65
+ export const inheritGroupProperties = {
66
+ name: 'inheritGroupProperties',
67
+ preprocessor: (dictionary) => {
68
+ return inheritProperties(dictionary);
69
+ },
70
+ };
@@ -1,7 +1,8 @@
1
1
  import StyleDictionary from 'style-dictionary';
2
2
  import { borderToCss, colorToRgbAlpha, colorToHex, colorToRgbaFloat, cubicBezierToCss, dimensionToRem, dimensionToPixelUnitless, durationToCss, figmaAttributes, fontFamilyToCss, fontFamilyToFigma, fontWeightToNumber, gradientToCss, jsonDeprecated, namePathToDotNotation, namePathToCamelCase, namePathToPascalCase, namePathToKebabCase, namePathToSlashNotation, namePathToFigma, shadowToCss, typographyToCss, dimensionToRemPxArray, floatToPixel, floatToPixelUnitless, transitionToCss, } from './transformers/index.js';
3
- import { javascriptCommonJs, javascriptEsm, typescriptExportDefinition, jsonNestedPrefixed, cssCustomMedia, jsonOneDimensional, jsonPostCssFallback, cssAdvanced, jsonFigma, } from './formats/index.js';
3
+ import { javascriptCommonJs, javascriptEsm, typescriptExportDefinition, jsonNestedPrefixed, cssCustomMedia, jsonOneDimensional, jsonPostCssFallback, cssAdvanced, jsonFigma, markdownLlmGuidelines, } from './formats/index.js';
4
4
  import { themeOverrides } from './preprocessors/themeOverrides.js';
5
+ import { inheritGroupProperties } from './preprocessors/inheritGroupProperties.js';
5
6
  import { colorAlphaToCss } from './transformers/colorAlphaToCss.js';
6
7
  /**
7
8
  * @name {@link PrimerStyleDictionary}
@@ -55,6 +56,10 @@ PrimerStyleDictionary.registerFormat({
55
56
  name: 'json/figma',
56
57
  format: jsonFigma,
57
58
  });
59
+ PrimerStyleDictionary.registerFormat({
60
+ name: 'json/llm-guidelines',
61
+ format: markdownLlmGuidelines,
62
+ });
58
63
  /**
59
64
  * Transformers
60
65
  *
@@ -88,3 +93,4 @@ PrimerStyleDictionary.registerTransform(fontFamilyToCss);
88
93
  PrimerStyleDictionary.registerTransform(fontFamilyToFigma);
89
94
  PrimerStyleDictionary.registerTransform(gradientToCss);
90
95
  PrimerStyleDictionary.registerPreprocessor(themeOverrides);
96
+ PrimerStyleDictionary.registerPreprocessor(inheritGroupProperties);
@@ -11,7 +11,14 @@ export declare const borderValue: z.ZodObject<{
11
11
  ridge: "ridge";
12
12
  outset: "outset";
13
13
  }>;
14
- width: z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodString, z.ZodLiteral<"0">, z.ZodLiteral<0>]>, z.ZodString]>;
14
+ width: z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodObject<{
15
+ value: z.ZodNumber;
16
+ unit: z.ZodEnum<{
17
+ em: "em";
18
+ px: "px";
19
+ rem: "rem";
20
+ }>;
21
+ }, z.core.$strict>, z.ZodUnion<readonly [z.ZodString, z.ZodLiteral<"0">, z.ZodLiteral<0>]>]>, z.ZodString]>;
15
22
  }, z.core.$strip>;
16
23
  export declare const borderToken: z.ZodObject<{
17
24
  $description: z.ZodOptional<z.ZodString>;
@@ -28,7 +35,20 @@ export declare const borderToken: z.ZodObject<{
28
35
  ridge: "ridge";
29
36
  outset: "outset";
30
37
  }>;
31
- width: z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodString, z.ZodLiteral<"0">, z.ZodLiteral<0>]>, z.ZodString]>;
38
+ width: z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodObject<{
39
+ value: z.ZodNumber;
40
+ unit: z.ZodEnum<{
41
+ em: "em";
42
+ px: "px";
43
+ rem: "rem";
44
+ }>;
45
+ }, z.core.$strict>, z.ZodUnion<readonly [z.ZodString, z.ZodLiteral<"0">, z.ZodLiteral<0>]>]>, z.ZodString]>;
32
46
  }, z.core.$strip>, z.ZodString]>;
33
47
  $type: z.ZodLiteral<"string" | "number" | "border" | "color" | "fontFamily" | "fontWeight" | "transition" | "dimension" | "duration" | "gradient" | "shadow" | "typography" | "cubicBezier" | "custom-viewportRange">;
48
+ $extensions: z.ZodOptional<z.ZodObject<{
49
+ 'org.primer.llm': z.ZodOptional<z.ZodObject<{
50
+ usage: z.ZodOptional<z.ZodArray<z.ZodString>>;
51
+ rules: z.ZodOptional<z.ZodString>;
52
+ }, z.core.$strip>>;
53
+ }, z.core.$strip>>;
34
54
  }, z.core.$strict>;
@@ -4,6 +4,7 @@ import { referenceValue } from './referenceValue.js';
4
4
  import { colorHexValue } from './colorHexValue.js';
5
5
  import { dimensionValue } from './dimensionValue.js';
6
6
  import { tokenType } from './tokenType.js';
7
+ import { llmExtension } from './llmExtension.js';
7
8
  export const borderValue = z.object({
8
9
  color: z.union([colorHexValue, referenceValue]),
9
10
  style: z.enum(['solid', 'dashed', 'dotted', 'double', 'groove', 'ridge', 'outset', 'inset']),
@@ -13,5 +14,10 @@ export const borderToken = baseToken
13
14
  .extend({
14
15
  $value: z.union([borderValue, referenceValue]),
15
16
  $type: tokenType('border'),
17
+ $extensions: z
18
+ .object({
19
+ 'org.primer.llm': llmExtension,
20
+ })
21
+ .optional(),
16
22
  })
17
23
  .strict();
@@ -98,5 +98,9 @@ export declare const colorToken: z.ZodObject<{
98
98
  alpha: z.ZodOptional<z.ZodNullable<z.ZodOptional<z.ZodAny>>>;
99
99
  }, z.core.$strict>]>>;
100
100
  }, z.core.$strict>>;
101
+ 'org.primer.llm': z.ZodOptional<z.ZodObject<{
102
+ usage: z.ZodOptional<z.ZodArray<z.ZodString>>;
103
+ rules: z.ZodOptional<z.ZodString>;
104
+ }, z.core.$strip>>;
101
105
  }, z.core.$strict>>;
102
106
  }, z.core.$strict>;
@@ -6,6 +6,7 @@ import { baseToken } from './baseToken.js';
6
6
  import { collection, mode } from './collections.js';
7
7
  import { scopes } from './scopes.js';
8
8
  import { tokenType } from './tokenType.js';
9
+ import { llmExtension } from './llmExtension.js';
9
10
  const baseColorToken = baseToken.extend({
10
11
  $value: z.union([colorHexValue, referenceValue]),
11
12
  alpha: alphaValue.optional().nullable(),
@@ -75,6 +76,7 @@ export const colorToken = baseColorToken
75
76
  })
76
77
  .strict()
77
78
  .optional(),
79
+ 'org.primer.llm': llmExtension,
78
80
  })
79
81
  .strict()
80
82
  .optional(),
@@ -4,4 +4,10 @@ export declare const cubicBezierToken: z.ZodObject<{
4
4
  $deprecated: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodBoolean]>>;
5
5
  $value: z.ZodUnion<readonly [z.ZodArray<z.ZodNumber>, 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,7 +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
- export const cubicBezierToken = baseToken.extend({
5
+ import { llmExtension } from './llmExtension.js';
6
+ export const cubicBezierToken = baseToken
7
+ .extend({
6
8
  $value: z.union([z.array(z.number()).length(4), referenceValue]),
7
9
  $type: tokenType('cubicBezier'),
8
- });
10
+ $extensions: z
11
+ .object({
12
+ 'org.primer.llm': llmExtension,
13
+ })
14
+ .optional(),
15
+ })
16
+ .strict();
@@ -1,2 +1,2 @@
1
1
  import { z } from 'zod';
2
- export declare const designToken: z.ZodRecord<z.ZodString, z.ZodLazy<z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>>>;
2
+ export declare const designToken: z.ZodType<unknown>;
@@ -14,26 +14,118 @@ import { durationToken } from './durationToken.js';
14
14
  import { cubicBezierToken } from './cubicBezierToken.js';
15
15
  import { gradientToken } from './gradientToken.js';
16
16
  import { transitionToken } from './transitionToken.js';
17
+ import { llmExtension } from './llmExtension.js';
18
+ /**
19
+ * Group-level extensions schema (W3C Design Tokens spec)
20
+ * https://www.designtokens.org/tr/drafts/format/#group-properties
21
+ */
22
+ const groupExtensions = z
23
+ .object({
24
+ 'org.primer.llm': llmExtension,
25
+ })
26
+ .passthrough();
27
+ /**
28
+ * All valid token types with $type discriminator
29
+ */
30
+ const tokenTypes = z.discriminatedUnion('$type', [
31
+ colorToken,
32
+ cubicBezierToken,
33
+ dimensionToken,
34
+ shadowToken,
35
+ borderToken,
36
+ fontFamilyToken,
37
+ fontWeightToken,
38
+ gradientToken,
39
+ typographyToken,
40
+ viewportRangeToken,
41
+ numberToken,
42
+ durationToken,
43
+ stringToken,
44
+ transitionToken,
45
+ ]);
46
+ /**
47
+ * Validates a record allowing both token names and group properties ($description, $extensions)
48
+ * Recursively validates nested groups
49
+ */
50
+ const createDesignTokenSchema = () => {
51
+ return z.record(z.string(), z.unknown()).superRefine((obj, ctx) => {
52
+ for (const [key, value] of Object.entries(obj)) {
53
+ if (key === '$description') {
54
+ // Group-level $description must be a string
55
+ if (typeof value !== 'string') {
56
+ ctx.addIssue({
57
+ code: z.ZodIssueCode.custom,
58
+ message: `$description must be a string, got ${typeof value}`,
59
+ path: [key],
60
+ });
61
+ }
62
+ }
63
+ else if (key === '$extensions') {
64
+ // Group-level $extensions must be an object
65
+ if (typeof value !== 'object' || value === null) {
66
+ ctx.addIssue({
67
+ code: z.ZodIssueCode.custom,
68
+ message: `$extensions must be an object`,
69
+ path: [key],
70
+ });
71
+ }
72
+ else {
73
+ const result = groupExtensions.safeParse(value);
74
+ if (!result.success) {
75
+ for (const issue of result.error.issues) {
76
+ ctx.addIssue(Object.assign(Object.assign({}, issue), { path: [key, ...issue.path] }));
77
+ }
78
+ }
79
+ }
80
+ }
81
+ else if (key.startsWith('$')) {
82
+ // Unknown $-prefixed keys at group level are not allowed
83
+ ctx.addIssue({
84
+ code: z.ZodIssueCode.custom,
85
+ message: `Unknown group property: ${key}. Only $description and $extensions are allowed.`,
86
+ path: [key],
87
+ });
88
+ }
89
+ else {
90
+ // Validate token name
91
+ const nameResult = tokenName.safeParse(key);
92
+ if (!nameResult.success) {
93
+ for (const issue of nameResult.error.issues) {
94
+ ctx.addIssue(Object.assign(Object.assign({}, issue), { path: [key] }));
95
+ }
96
+ }
97
+ // Validate value as either a token or nested group
98
+ if (typeof value === 'object' && value !== null) {
99
+ // Check if it's a token (has $type) or a nested group
100
+ if ('$type' in value) {
101
+ const tokenResult = tokenTypes.safeParse(value);
102
+ if (!tokenResult.success) {
103
+ for (const issue of tokenResult.error.issues) {
104
+ ctx.addIssue(Object.assign(Object.assign({}, issue), { path: [key, ...issue.path] }));
105
+ }
106
+ }
107
+ }
108
+ else {
109
+ // Recursively validate nested group
110
+ const nestedResult = designToken.safeParse(value);
111
+ if (!nestedResult.success) {
112
+ for (const issue of nestedResult.error.issues) {
113
+ ctx.addIssue(Object.assign(Object.assign({}, issue), { path: [key, ...issue.path] }));
114
+ }
115
+ }
116
+ }
117
+ }
118
+ else {
119
+ ctx.addIssue({
120
+ code: z.ZodIssueCode.custom,
121
+ message: `Expected token or group object, got ${typeof value}`,
122
+ path: [key],
123
+ });
124
+ }
125
+ }
126
+ }
127
+ });
128
+ };
17
129
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
18
130
  // @ts-ignore: TODO: fix this
19
- export const designToken = z.record(tokenName, z.lazy(() => {
20
- return z.union([
21
- z.discriminatedUnion('$type', [
22
- colorToken,
23
- cubicBezierToken,
24
- dimensionToken,
25
- shadowToken,
26
- borderToken,
27
- fontFamilyToken,
28
- fontWeightToken,
29
- gradientToken,
30
- typographyToken,
31
- viewportRangeToken,
32
- numberToken,
33
- durationToken,
34
- stringToken,
35
- transitionToken,
36
- ]),
37
- designToken,
38
- ]);
39
- }));
131
+ export const designToken = createDesignTokenSchema();
@@ -2,13 +2,24 @@ import { z } from 'zod';
2
2
  export declare const dimensionToken: z.ZodObject<{
3
3
  $description: z.ZodOptional<z.ZodString>;
4
4
  $deprecated: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodBoolean]>>;
5
- $value: z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodString, z.ZodLiteral<"0">, z.ZodLiteral<0>]>, z.ZodString]>;
5
+ $value: z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodObject<{
6
+ value: z.ZodNumber;
7
+ unit: z.ZodEnum<{
8
+ em: "em";
9
+ px: "px";
10
+ rem: "rem";
11
+ }>;
12
+ }, z.core.$strict>, z.ZodUnion<readonly [z.ZodString, z.ZodLiteral<"0">, z.ZodLiteral<0>]>]>, z.ZodString]>;
6
13
  $type: z.ZodLiteral<"string" | "number" | "border" | "color" | "fontFamily" | "fontWeight" | "transition" | "dimension" | "duration" | "gradient" | "shadow" | "typography" | "cubicBezier" | "custom-viewportRange">;
7
14
  $extensions: z.ZodOptional<z.ZodObject<{
8
- 'org.primer.figma': z.ZodObject<{
15
+ 'org.primer.figma': z.ZodOptional<z.ZodObject<{
9
16
  collection: z.ZodString;
10
17
  scopes: z.ZodArray<z.ZodString>;
11
18
  group: z.ZodOptional<z.ZodString>;
12
- }, z.core.$strip>;
19
+ }, z.core.$strip>>;
20
+ 'org.primer.llm': z.ZodOptional<z.ZodObject<{
21
+ usage: z.ZodOptional<z.ZodArray<z.ZodString>>;
22
+ rules: z.ZodOptional<z.ZodString>;
23
+ }, z.core.$strip>>;
13
24
  }, z.core.$strip>>;
14
25
  }, z.core.$strict>;
@@ -5,13 +5,15 @@ import { collection } from './collections.js';
5
5
  import { scopes } from './scopes.js';
6
6
  import { dimensionValue } from './dimensionValue.js';
7
7
  import { tokenType } from './tokenType.js';
8
+ import { llmExtension } from './llmExtension.js';
8
9
  export const dimensionToken = baseToken
9
10
  .extend({
10
11
  $value: z.union([dimensionValue, referenceValue]),
11
12
  $type: tokenType('dimension'),
12
13
  $extensions: z
13
14
  .object({
14
- 'org.primer.figma': z.object({
15
+ 'org.primer.figma': z
16
+ .object({
15
17
  collection: collection(['base/size', 'base/typography', 'functional/size', 'pattern/size', 'typography']),
16
18
  scopes: scopes([
17
19
  'all',
@@ -28,7 +30,9 @@ export const dimensionToken = baseToken
28
30
  'paragraphIndent',
29
31
  ]),
30
32
  group: z.string().optional(),
31
- }),
33
+ })
34
+ .optional(),
35
+ 'org.primer.llm': llmExtension,
32
36
  })
33
37
  .optional(),
34
38
  })
@@ -1,2 +1,25 @@
1
1
  import { z } from 'zod';
2
- export declare const dimensionValue: z.ZodUnion<readonly [z.ZodString, z.ZodLiteral<"0">, z.ZodLiteral<0>]>;
2
+ /**
3
+ * W3C DTCG dimension value format
4
+ * @link https://www.designtokens.org/tr/drafts/format/#dimension
5
+ */
6
+ export declare const dimensionValueObject: z.ZodObject<{
7
+ value: z.ZodNumber;
8
+ unit: z.ZodEnum<{
9
+ em: "em";
10
+ px: "px";
11
+ rem: "rem";
12
+ }>;
13
+ }, z.core.$strict>;
14
+ /**
15
+ * Dimension value - supports both W3C DTCG object format and legacy string format
16
+ * Note: Transformers only accept W3C format, but schema validates both for migration period
17
+ */
18
+ export declare const dimensionValue: z.ZodUnion<readonly [z.ZodObject<{
19
+ value: z.ZodNumber;
20
+ unit: z.ZodEnum<{
21
+ em: "em";
22
+ px: "px";
23
+ rem: "rem";
24
+ }>;
25
+ }, z.core.$strict>, z.ZodUnion<readonly [z.ZodString, z.ZodLiteral<"0">, z.ZodLiteral<0>]>]>;
@@ -1,6 +1,20 @@
1
1
  import { z } from 'zod';
2
2
  import { schemaErrorMessage } from '../utilities/index.js';
3
- export const dimensionValue = z.union([
3
+ /**
4
+ * W3C DTCG dimension value format
5
+ * @link https://www.designtokens.org/tr/drafts/format/#dimension
6
+ */
7
+ export const dimensionValueObject = z
8
+ .object({
9
+ value: z.number(),
10
+ unit: z.enum(['px', 'rem', 'em']),
11
+ })
12
+ .strict();
13
+ /**
14
+ * Legacy dimension value format (string with unit)
15
+ * @deprecated Use W3C DTCG object format instead
16
+ */
17
+ const dimensionValueLegacy = z.union([
4
18
  z.string().superRefine((dim, ctx) => {
5
19
  if (!/(^-?[0-9]+\.?[0-9]*(px|rem)$|^-?[0-9]+\.?[0-9]*em$)/.test(dim)) {
6
20
  ctx.addIssue({
@@ -12,3 +26,8 @@ export const dimensionValue = z.union([
12
26
  z.literal('0'),
13
27
  z.literal(0),
14
28
  ]);
29
+ /**
30
+ * Dimension value - supports both W3C DTCG object format and legacy string format
31
+ * Note: Transformers only accept W3C format, but schema validates both for migration period
32
+ */
33
+ export const dimensionValue = z.union([dimensionValueObject, dimensionValueLegacy]);
@@ -2,6 +2,18 @@ import { z } from 'zod';
2
2
  export declare const durationToken: z.ZodObject<{
3
3
  $description: z.ZodOptional<z.ZodString>;
4
4
  $deprecated: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodBoolean]>>;
5
- $value: z.ZodUnion<readonly [z.ZodString, z.ZodString]>;
5
+ $value: z.ZodUnion<readonly [z.ZodObject<{
6
+ value: z.ZodNumber;
7
+ unit: z.ZodEnum<{
8
+ s: "s";
9
+ ms: "ms";
10
+ }>;
11
+ }, z.core.$strict>, z.ZodString]>;
6
12
  $type: z.ZodLiteral<"string" | "number" | "border" | "color" | "fontFamily" | "fontWeight" | "transition" | "dimension" | "duration" | "gradient" | "shadow" | "typography" | "cubicBezier" | "custom-viewportRange">;
13
+ $extensions: z.ZodOptional<z.ZodObject<{
14
+ 'org.primer.llm': z.ZodOptional<z.ZodObject<{
15
+ usage: z.ZodOptional<z.ZodArray<z.ZodString>>;
16
+ rules: z.ZodOptional<z.ZodString>;
17
+ }, z.core.$strip>>;
18
+ }, z.core.$strip>>;
7
19
  }, z.core.$strict>;
@@ -3,9 +3,15 @@ import { baseToken } from './baseToken.js';
3
3
  import { referenceValue } from './referenceValue.js';
4
4
  import { durationValue } from './durationValue.js';
5
5
  import { tokenType } from './tokenType.js';
6
+ import { llmExtension } from './llmExtension.js';
6
7
  export const durationToken = baseToken
7
8
  .extend({
8
9
  $value: z.union([durationValue, referenceValue]),
9
10
  $type: tokenType('duration'),
11
+ $extensions: z
12
+ .object({
13
+ 'org.primer.llm': llmExtension,
14
+ })
15
+ .optional(),
10
16
  })
11
17
  .strict();
@@ -1,2 +1,12 @@
1
1
  import { z } from 'zod';
2
- export declare const durationValue: z.ZodString;
2
+ /**
3
+ * W3C DTCG duration value format
4
+ * @see https://www.designtokens.org/tr/2025.10/format/#duration
5
+ */
6
+ export declare const durationValue: z.ZodObject<{
7
+ value: z.ZodNumber;
8
+ unit: z.ZodEnum<{
9
+ s: "s";
10
+ ms: "ms";
11
+ }>;
12
+ }, z.core.$strict>;
@@ -1,10 +1,20 @@
1
1
  import { z } from 'zod';
2
2
  import { schemaErrorMessage } from '../utilities/index.js';
3
- export const durationValue = z.string().superRefine((duration, ctx) => {
4
- if (!/^[0-9]+ms$/.test(duration)) {
3
+ /**
4
+ * W3C DTCG duration value format
5
+ * @see https://www.designtokens.org/tr/2025.10/format/#duration
6
+ */
7
+ export const durationValue = z
8
+ .object({
9
+ value: z.number(),
10
+ unit: z.enum(['ms', 's']),
11
+ })
12
+ .strict()
13
+ .superRefine((duration, ctx) => {
14
+ if (typeof duration.value !== 'number') {
5
15
  ctx.addIssue({
6
16
  code: 'custom',
7
- message: schemaErrorMessage(`Invalid duration: "${duration}"`, `A duration must be a string with an "ms"`),
17
+ message: schemaErrorMessage(`Invalid duration value: "${duration.value}"`, `Duration value must be a number`),
8
18
  });
9
19
  }
10
20
  });
@@ -9,5 +9,9 @@ export declare const fontFamilyToken: z.ZodObject<{
9
9
  collection: z.ZodOptional<z.ZodString>;
10
10
  scopes: z.ZodOptional<z.ZodArray<z.ZodString>>;
11
11
  }, z.core.$strip>;
12
+ 'org.primer.llm': z.ZodOptional<z.ZodObject<{
13
+ usage: z.ZodOptional<z.ZodArray<z.ZodString>>;
14
+ rules: z.ZodOptional<z.ZodString>;
15
+ }, z.core.$strip>>;
12
16
  }, z.core.$strip>>;
13
17
  }, z.core.$strict>;
@@ -4,6 +4,7 @@ import { baseToken } from './baseToken.js';
4
4
  import { tokenType } from './tokenType.js';
5
5
  import { collection } from './collections.js';
6
6
  import { scopes } from './scopes.js';
7
+ import { llmExtension } from './llmExtension.js';
7
8
  export const fontFamilyToken = baseToken
8
9
  .extend({
9
10
  $value: z.union([z.string(), referenceValue]),
@@ -14,6 +15,7 @@ export const fontFamilyToken = baseToken
14
15
  collection: collection(['base/typography', 'typography']).optional(),
15
16
  scopes: scopes(['fontFamily']).optional(),
16
17
  }),
18
+ 'org.primer.llm': llmExtension,
17
19
  })
18
20
  .optional(),
19
21
  })
@@ -9,5 +9,9 @@ export declare const fontWeightToken: z.ZodObject<{
9
9
  collection: z.ZodOptional<z.ZodString>;
10
10
  scopes: z.ZodOptional<z.ZodArray<z.ZodString>>;
11
11
  }, z.core.$strip>;
12
+ 'org.primer.llm': z.ZodOptional<z.ZodObject<{
13
+ usage: z.ZodOptional<z.ZodArray<z.ZodString>>;
14
+ rules: z.ZodOptional<z.ZodString>;
15
+ }, z.core.$strip>>;
12
16
  }, z.core.$strip>>;
13
17
  }, z.core.$strict>;
@@ -5,6 +5,7 @@ import { baseToken } from './baseToken.js';
5
5
  import { tokenType } from './tokenType.js';
6
6
  import { collection } from './collections.js';
7
7
  import { scopes } from './scopes.js';
8
+ import { llmExtension } from './llmExtension.js';
8
9
  export const fontWeightToken = baseToken
9
10
  .extend({
10
11
  $type: tokenType('fontWeight'),
@@ -15,6 +16,7 @@ export const fontWeightToken = baseToken
15
16
  collection: collection(['base/typography', 'typography']).optional(),
16
17
  scopes: scopes(['fontWeight']).optional(),
17
18
  }),
19
+ 'org.primer.llm': llmExtension,
18
20
  })
19
21
  .optional(),
20
22
  })