@nationaldesignstudio/react 0.0.15 → 0.0.16

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 (164) hide show
  1. package/package.json +3 -2
  2. package/src/App.css +0 -0
  3. package/src/App.tsx +7 -0
  4. package/src/assets/fonts/PPNeueMontreal-Variable.woff2 +0 -0
  5. package/src/assets/react.svg +1 -0
  6. package/src/components/atoms/accordion/accordion.stories.tsx +228 -0
  7. package/src/components/atoms/accordion/accordion.tsx +219 -0
  8. package/src/components/atoms/accordion/index.ts +6 -0
  9. package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-charcoal-chromium-darwin.png +0 -0
  10. package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-charcoal-chromium-linux.png +0 -0
  11. package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-charcoal-outline-chromium-darwin.png +0 -0
  12. package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-charcoal-outline-chromium-linux.png +0 -0
  13. package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-charcoal-outline-quiet-chromium-darwin.png +0 -0
  14. package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-charcoal-outline-quiet-chromium-linux.png +0 -0
  15. package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-disabled-chromium-darwin.png +0 -0
  16. package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-disabled-chromium-linux.png +0 -0
  17. package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-ivory-chromium-darwin.png +0 -0
  18. package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-ivory-chromium-linux.png +0 -0
  19. package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-ivory-outline-chromium-darwin.png +0 -0
  20. package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-ivory-outline-chromium-linux.png +0 -0
  21. package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-ivory-outline-quiet-chromium-darwin.png +0 -0
  22. package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-ivory-outline-quiet-chromium-linux.png +0 -0
  23. package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-size-large-chromium-darwin.png +0 -0
  24. package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-size-large-chromium-linux.png +0 -0
  25. package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-size-medium-chromium-darwin.png +0 -0
  26. package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-size-medium-chromium-linux.png +0 -0
  27. package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-size-small-chromium-darwin.png +0 -0
  28. package/src/components/atoms/button/__screenshots__/button.visual.test.tsx/button-size-small-chromium-linux.png +0 -0
  29. package/src/components/atoms/button/button.stories.tsx +102 -0
  30. package/src/components/atoms/button/button.test.tsx +135 -0
  31. package/src/components/atoms/button/button.tsx +139 -0
  32. package/src/components/atoms/button/button.visual.test.tsx +102 -0
  33. package/src/components/atoms/button/icon-button.stories.tsx +166 -0
  34. package/src/components/atoms/button/icon-button.tsx +120 -0
  35. package/src/components/atoms/button/index.ts +6 -0
  36. package/src/components/atoms/ndstudio-footer/index.ts +1 -0
  37. package/src/components/atoms/ndstudio-footer/ndstudio-footer.tsx +55 -0
  38. package/src/components/atoms/pager-control/index.ts +5 -0
  39. package/src/components/atoms/pager-control/pager-control.stories.tsx +209 -0
  40. package/src/components/atoms/pager-control/pager-control.test.tsx +130 -0
  41. package/src/components/atoms/pager-control/pager-control.tsx +329 -0
  42. package/src/components/dev-tools/dev-toolbar/dev-toolbar.stories.tsx +82 -0
  43. package/src/components/dev-tools/dev-toolbar/dev-toolbar.tsx +196 -0
  44. package/src/components/dev-tools/dev-toolbar/index.ts +1 -0
  45. package/src/components/dev-tools/grid-overlay/grid-overlay.tsx +41 -0
  46. package/src/components/dev-tools/grid-overlay/index.ts +1 -0
  47. package/src/components/dev-tools/index.ts +2 -0
  48. package/src/components/organisms/card/__screenshots__/card.visual.test.tsx/card-default-vertical-chromium-darwin.png +0 -0
  49. package/src/components/organisms/card/__screenshots__/card.visual.test.tsx/card-default-vertical-chromium-linux.png +0 -0
  50. package/src/components/organisms/card/__screenshots__/card.visual.test.tsx/card-horizontal-chromium-darwin.png +0 -0
  51. package/src/components/organisms/card/__screenshots__/card.visual.test.tsx/card-horizontal-chromium-linux.png +0 -0
  52. package/src/components/organisms/card/__screenshots__/card.visual.test.tsx/card-minimal-chromium-darwin.png +0 -0
  53. package/src/components/organisms/card/__screenshots__/card.visual.test.tsx/card-minimal-chromium-linux.png +0 -0
  54. package/src/components/organisms/card/__screenshots__/card.visual.test.tsx/card-without-actions-chromium-darwin.png +0 -0
  55. package/src/components/organisms/card/__screenshots__/card.visual.test.tsx/card-without-actions-chromium-linux.png +0 -0
  56. package/src/components/organisms/card/__screenshots__/card.visual.test.tsx/card-without-eyebrow-chromium-darwin.png +0 -0
  57. package/src/components/organisms/card/__screenshots__/card.visual.test.tsx/card-without-eyebrow-chromium-linux.png +0 -0
  58. package/src/components/organisms/card/__screenshots__/card.visual.test.tsx/card-without-image-chromium-darwin.png +0 -0
  59. package/src/components/organisms/card/__screenshots__/card.visual.test.tsx/card-without-image-chromium-linux.png +0 -0
  60. package/src/components/organisms/card/card.stories.tsx +293 -0
  61. package/src/components/organisms/card/card.test.tsx +245 -0
  62. package/src/components/organisms/card/card.tsx +225 -0
  63. package/src/components/organisms/card/card.visual.test.tsx +197 -0
  64. package/src/components/organisms/card/index.ts +19 -0
  65. package/src/components/organisms/navbar/__screenshots__/navbar.visual.test.tsx/navbar-active-link-chromium-darwin.png +0 -0
  66. package/src/components/organisms/navbar/__screenshots__/navbar.visual.test.tsx/navbar-active-link-chromium-linux.png +0 -0
  67. package/src/components/organisms/navbar/__screenshots__/navbar.visual.test.tsx/navbar-brand-only-chromium-darwin.png +0 -0
  68. package/src/components/organisms/navbar/__screenshots__/navbar.visual.test.tsx/navbar-brand-only-chromium-linux.png +0 -0
  69. package/src/components/organisms/navbar/__screenshots__/navbar.visual.test.tsx/navbar-default-chromium-darwin.png +0 -0
  70. package/src/components/organisms/navbar/__screenshots__/navbar.visual.test.tsx/navbar-default-chromium-linux.png +0 -0
  71. package/src/components/organisms/navbar/index.ts +18 -0
  72. package/src/components/organisms/navbar/navbar.stories.tsx +313 -0
  73. package/src/components/organisms/navbar/navbar.test.tsx +190 -0
  74. package/src/components/organisms/navbar/navbar.tsx +323 -0
  75. package/src/components/organisms/navbar/navbar.visual.test.tsx +85 -0
  76. package/src/components/organisms/us-gov-banner/__screenshots__/us-gov-banner.visual.test.tsx/us-gov-banner-custom-icon-chromium-darwin.png +0 -0
  77. package/src/components/organisms/us-gov-banner/__screenshots__/us-gov-banner.visual.test.tsx/us-gov-banner-custom-icon-chromium-linux.png +0 -0
  78. package/src/components/organisms/us-gov-banner/__screenshots__/us-gov-banner.visual.test.tsx/us-gov-banner-custom-text-chromium-darwin.png +0 -0
  79. package/src/components/organisms/us-gov-banner/__screenshots__/us-gov-banner.visual.test.tsx/us-gov-banner-custom-text-chromium-linux.png +0 -0
  80. package/src/components/organisms/us-gov-banner/__screenshots__/us-gov-banner.visual.test.tsx/us-gov-banner-default-chromium-darwin.png +0 -0
  81. package/src/components/organisms/us-gov-banner/__screenshots__/us-gov-banner.visual.test.tsx/us-gov-banner-default-chromium-linux.png +0 -0
  82. package/src/components/organisms/us-gov-banner/index.ts +1 -0
  83. package/src/components/organisms/us-gov-banner/us-gov-banner.stories.tsx +35 -0
  84. package/src/components/organisms/us-gov-banner/us-gov-banner.test.tsx +107 -0
  85. package/src/components/organisms/us-gov-banner/us-gov-banner.tsx +73 -0
  86. package/src/components/organisms/us-gov-banner/us-gov-banner.visual.test.tsx +46 -0
  87. package/src/components/sections/banner/banner.stories.tsx +150 -0
  88. package/src/components/sections/banner/banner.test.tsx +185 -0
  89. package/src/components/sections/banner/banner.tsx +130 -0
  90. package/src/components/sections/banner/index.ts +2 -0
  91. package/src/components/sections/card-grid/card-grid.stories.tsx +351 -0
  92. package/src/components/sections/card-grid/card-grid.tsx +116 -0
  93. package/src/components/sections/card-grid/index.ts +1 -0
  94. package/src/components/sections/faq-section/faq-section.stories.tsx +453 -0
  95. package/src/components/sections/faq-section/faq-section.tsx +84 -0
  96. package/src/components/sections/faq-section/index.ts +2 -0
  97. package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a1-desktop-chromium-darwin.png +0 -0
  98. package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a1-desktop-chromium-linux.png +0 -0
  99. package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a1-mobile-chromium-darwin.png +0 -0
  100. package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a1-mobile-chromium-linux.png +0 -0
  101. package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a1-tablet-chromium-darwin.png +0 -0
  102. package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a1-tablet-chromium-linux.png +0 -0
  103. package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a2-desktop-chromium-darwin.png +0 -0
  104. package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a2-desktop-chromium-linux.png +0 -0
  105. package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a2-mobile-chromium-darwin.png +0 -0
  106. package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a2-mobile-chromium-linux.png +0 -0
  107. package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a2-tablet-chromium-darwin.png +0 -0
  108. package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a2-tablet-chromium-linux.png +0 -0
  109. package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a3-desktop-chromium-darwin.png +0 -0
  110. package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a3-desktop-chromium-linux.png +0 -0
  111. package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a3-mobile-chromium-darwin.png +0 -0
  112. package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a3-mobile-chromium-linux.png +0 -0
  113. package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a3-tablet-chromium-darwin.png +0 -0
  114. package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-a3-tablet-chromium-linux.png +0 -0
  115. package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-custom-class-chromium-darwin.png +0 -0
  116. package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-custom-class-chromium-linux.png +0 -0
  117. package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-default-chromium-linux.png +0 -0
  118. package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-long-title-chromium-darwin.png +0 -0
  119. package/src/components/sections/hero/__screenshots__/hero.visual.test.tsx/hero-long-title-chromium-linux.png +0 -0
  120. package/src/components/sections/hero/hero.stories.tsx +274 -0
  121. package/src/components/sections/hero/hero.test.tsx +135 -0
  122. package/src/components/sections/hero/hero.tsx +453 -0
  123. package/src/components/sections/hero/hero.visual.test.tsx +140 -0
  124. package/src/components/sections/hero/index.ts +10 -0
  125. package/src/components/sections/prose/__screenshots__/prose.visual.test.tsx/prose-h3-heading-chromium-darwin.png +0 -0
  126. package/src/components/sections/prose/__screenshots__/prose.visual.test.tsx/prose-h3-heading-chromium-linux.png +0 -0
  127. package/src/components/sections/prose/__screenshots__/prose.visual.test.tsx/prose-multiple-paragraphs-chromium-darwin.png +0 -0
  128. package/src/components/sections/prose/__screenshots__/prose.visual.test.tsx/prose-multiple-paragraphs-chromium-linux.png +0 -0
  129. package/src/components/sections/prose/__screenshots__/prose.visual.test.tsx/prose-multiple-sections-chromium-darwin.png +0 -0
  130. package/src/components/sections/prose/__screenshots__/prose.visual.test.tsx/prose-multiple-sections-chromium-linux.png +0 -0
  131. package/src/components/sections/prose/__screenshots__/prose.visual.test.tsx/prose-single-section-chromium-darwin.png +0 -0
  132. package/src/components/sections/prose/__screenshots__/prose.visual.test.tsx/prose-single-section-chromium-linux.png +0 -0
  133. package/src/components/sections/prose/index.ts +6 -0
  134. package/src/components/sections/prose/prose.stories.tsx +144 -0
  135. package/src/components/sections/prose/prose.test.tsx +178 -0
  136. package/src/components/sections/prose/prose.tsx +88 -0
  137. package/src/components/sections/prose/prose.visual.test.tsx +105 -0
  138. package/src/components/sections/river/index.ts +1 -0
  139. package/src/components/sections/river/river.stories.tsx +237 -0
  140. package/src/components/sections/river/river.test.tsx +268 -0
  141. package/src/components/sections/river/river.tsx +173 -0
  142. package/src/components/sections/tout/index.ts +1 -0
  143. package/src/components/sections/tout/tout.stories.tsx +171 -0
  144. package/src/components/sections/tout/tout.test.tsx +242 -0
  145. package/src/components/sections/tout/tout.tsx +270 -0
  146. package/src/components/sections/two-column-section/index.ts +5 -0
  147. package/src/components/sections/two-column-section/two-column-section.stories.tsx +285 -0
  148. package/src/components/sections/two-column-section/two-column-section.tsx +162 -0
  149. package/src/hooks/index.ts +1 -0
  150. package/src/hooks/use-event-listener.ts +73 -0
  151. package/src/index.ts +155 -0
  152. package/src/lib/theme.ts +1000 -0
  153. package/src/lib/utils.ts +6 -0
  154. package/src/main.tsx +13 -0
  155. package/src/stories/GridSystem.stories.tsx +84 -0
  156. package/src/stories/Introduction.mdx +114 -0
  157. package/src/stories/ThemeProvider.stories.tsx +357 -0
  158. package/src/stories/TokenShowcase.stories.tsx +92 -0
  159. package/src/stories/TokenShowcase.tsx +1429 -0
  160. package/src/styles.css +11 -0
  161. package/src/theme/ThemeProvider.tsx +297 -0
  162. package/src/theme/hooks.ts +40 -0
  163. package/src/theme/index.ts +43 -0
  164. package/src/theme/utils.ts +104 -0
@@ -0,0 +1,1000 @@
1
+ /**
2
+ * Component-level theming interface
3
+ *
4
+ * This interface defines all the customizable design tokens that can be
5
+ * overridden at the component level. Components accepting a `theme` prop
6
+ * will apply these values as CSS custom properties, allowing fine-grained
7
+ * control over appearance without creating new variants.
8
+ *
9
+ * All values use primitive token names (e.g., "gray-100", "spacing-40")
10
+ * which are converted to CSS variable references internally.
11
+ */
12
+
13
+ // =============================================================================
14
+ // Token Name Types
15
+ // =============================================================================
16
+
17
+ /**
18
+ * Color token names - maps to `--color-{name}` CSS variables
19
+ * @example "gray-100", "ember-v300", "alpha-black-10"
20
+ */
21
+ export type ColorToken =
22
+ // Grayscale
23
+ | "gray-50"
24
+ | "gray-100"
25
+ | "gray-200"
26
+ | "gray-300"
27
+ | "gray-400"
28
+ | "gray-500"
29
+ | "gray-600"
30
+ | "gray-700"
31
+ | "gray-800"
32
+ | "gray-900"
33
+ | "gray-1000"
34
+ | "gray-1100"
35
+ | "gray-1200"
36
+ // Steel
37
+ | "steel-50"
38
+ | "steel-100"
39
+ | "steel-200"
40
+ | "steel-300"
41
+ | "steel-400"
42
+ | "steel-500"
43
+ | "steel-600"
44
+ | "steel-700"
45
+ | "steel-800"
46
+ | "steel-900"
47
+ | "steel-1000"
48
+ | "steel-1100"
49
+ | "steel-1200"
50
+ // Brown
51
+ | "brown-50"
52
+ | "brown-100"
53
+ | "brown-200"
54
+ | "brown-300"
55
+ | "brown-400"
56
+ | "brown-500"
57
+ | "brown-600"
58
+ | "brown-700"
59
+ | "brown-800"
60
+ | "brown-900"
61
+ | "brown-1000"
62
+ | "brown-1100"
63
+ | "brown-1200"
64
+ // Ember
65
+ | "ember-50"
66
+ | "ember-100"
67
+ | "ember-200"
68
+ | "ember-300"
69
+ | "ember-400"
70
+ | "ember-500"
71
+ | "ember-600"
72
+ | "ember-700"
73
+ | "ember-800"
74
+ | "ember-900"
75
+ | "ember-v100"
76
+ | "ember-v200"
77
+ | "ember-v300"
78
+ | "ember-v400"
79
+ // Orange
80
+ | "orange-50"
81
+ | "orange-100"
82
+ | "orange-200"
83
+ | "orange-300"
84
+ | "orange-400"
85
+ | "orange-500"
86
+ | "orange-600"
87
+ | "orange-700"
88
+ | "orange-800"
89
+ | "orange-900"
90
+ | "orange-v100"
91
+ | "orange-v200"
92
+ | "orange-v300"
93
+ | "orange-v400"
94
+ // Amber
95
+ | "amber-50"
96
+ | "amber-100"
97
+ | "amber-200"
98
+ | "amber-300"
99
+ | "amber-400"
100
+ | "amber-500"
101
+ | "amber-600"
102
+ | "amber-700"
103
+ | "amber-800"
104
+ | "amber-900"
105
+ | "amber-v100"
106
+ | "amber-v200"
107
+ | "amber-v300"
108
+ | "amber-v400"
109
+ // Yellow
110
+ | "yellow-50"
111
+ | "yellow-100"
112
+ | "yellow-200"
113
+ | "yellow-300"
114
+ | "yellow-400"
115
+ | "yellow-500"
116
+ | "yellow-600"
117
+ | "yellow-700"
118
+ | "yellow-800"
119
+ | "yellow-900"
120
+ | "yellow-v100"
121
+ | "yellow-v200"
122
+ | "yellow-v300"
123
+ | "yellow-v400"
124
+ // Lime
125
+ | "lime-50"
126
+ | "lime-100"
127
+ | "lime-200"
128
+ | "lime-300"
129
+ | "lime-400"
130
+ | "lime-500"
131
+ | "lime-600"
132
+ | "lime-700"
133
+ | "lime-800"
134
+ | "lime-900"
135
+ | "lime-v100"
136
+ | "lime-v200"
137
+ | "lime-v300"
138
+ | "lime-v400"
139
+ // Green
140
+ | "green-50"
141
+ | "green-100"
142
+ | "green-200"
143
+ | "green-300"
144
+ | "green-400"
145
+ | "green-500"
146
+ | "green-600"
147
+ | "green-700"
148
+ | "green-800"
149
+ | "green-900"
150
+ | "green-v100"
151
+ | "green-v200"
152
+ | "green-v300"
153
+ | "green-v400"
154
+ // Sage
155
+ | "sage-50"
156
+ | "sage-100"
157
+ | "sage-200"
158
+ | "sage-300"
159
+ | "sage-400"
160
+ | "sage-500"
161
+ | "sage-600"
162
+ | "sage-700"
163
+ | "sage-800"
164
+ | "sage-900"
165
+ | "sage-v100"
166
+ | "sage-v200"
167
+ | "sage-v300"
168
+ | "sage-v400"
169
+ // Teal
170
+ | "teal-50"
171
+ | "teal-100"
172
+ | "teal-200"
173
+ | "teal-300"
174
+ | "teal-400"
175
+ | "teal-500"
176
+ | "teal-600"
177
+ | "teal-700"
178
+ | "teal-800"
179
+ | "teal-900"
180
+ | "teal-v100"
181
+ | "teal-v200"
182
+ | "teal-v300"
183
+ | "teal-v400"
184
+ // Cyan
185
+ | "cyan-50"
186
+ | "cyan-100"
187
+ | "cyan-200"
188
+ | "cyan-300"
189
+ | "cyan-400"
190
+ | "cyan-500"
191
+ | "cyan-600"
192
+ | "cyan-700"
193
+ | "cyan-800"
194
+ | "cyan-900"
195
+ | "cyan-v100"
196
+ | "cyan-v200"
197
+ | "cyan-v300"
198
+ | "cyan-v400"
199
+ // Ice
200
+ | "ice-50"
201
+ | "ice-100"
202
+ | "ice-200"
203
+ | "ice-300"
204
+ | "ice-400"
205
+ | "ice-500"
206
+ | "ice-600"
207
+ | "ice-700"
208
+ | "ice-800"
209
+ | "ice-900"
210
+ | "ice-v100"
211
+ | "ice-v200"
212
+ | "ice-v300"
213
+ | "ice-v400"
214
+ // Blue
215
+ | "blue-50"
216
+ | "blue-100"
217
+ | "blue-200"
218
+ | "blue-300"
219
+ | "blue-400"
220
+ | "blue-500"
221
+ | "blue-600"
222
+ | "blue-700"
223
+ | "blue-800"
224
+ | "blue-900"
225
+ | "blue-v100"
226
+ | "blue-v200"
227
+ | "blue-v300"
228
+ | "blue-v400"
229
+ // Indigo
230
+ | "indigo-50"
231
+ | "indigo-100"
232
+ | "indigo-200"
233
+ | "indigo-300"
234
+ | "indigo-400"
235
+ | "indigo-500"
236
+ | "indigo-600"
237
+ | "indigo-700"
238
+ | "indigo-800"
239
+ | "indigo-900"
240
+ | "indigo-v100"
241
+ | "indigo-v200"
242
+ | "indigo-v300"
243
+ | "indigo-v400"
244
+ // Iris
245
+ | "iris-50"
246
+ | "iris-100"
247
+ | "iris-200"
248
+ | "iris-300"
249
+ | "iris-400"
250
+ | "iris-500"
251
+ | "iris-600"
252
+ | "iris-700"
253
+ | "iris-800"
254
+ | "iris-900"
255
+ | "iris-v100"
256
+ | "iris-v200"
257
+ | "iris-v300"
258
+ | "iris-v400"
259
+ // Purple
260
+ | "purple-50"
261
+ | "purple-100"
262
+ | "purple-200"
263
+ | "purple-300"
264
+ | "purple-400"
265
+ | "purple-500"
266
+ | "purple-600"
267
+ | "purple-700"
268
+ | "purple-800"
269
+ | "purple-900"
270
+ | "purple-v100"
271
+ | "purple-v200"
272
+ | "purple-v300"
273
+ | "purple-v400"
274
+ // Pink
275
+ | "pink-50"
276
+ | "pink-100"
277
+ | "pink-200"
278
+ | "pink-300"
279
+ | "pink-400"
280
+ | "pink-500"
281
+ | "pink-600"
282
+ | "pink-700"
283
+ | "pink-800"
284
+ | "pink-900"
285
+ | "pink-v100"
286
+ | "pink-v200"
287
+ | "pink-v300"
288
+ | "pink-v400"
289
+ // Red
290
+ | "red-50"
291
+ | "red-100"
292
+ | "red-200"
293
+ | "red-300"
294
+ | "red-400"
295
+ | "red-500"
296
+ | "red-600"
297
+ | "red-700"
298
+ | "red-800"
299
+ | "red-900"
300
+ | "red-v100"
301
+ | "red-v200"
302
+ | "red-v300"
303
+ | "red-v400"
304
+ // Alpha
305
+ | "alpha-black-5"
306
+ | "alpha-black-10"
307
+ | "alpha-black-20"
308
+ | "alpha-black-30"
309
+ | "alpha-black-40"
310
+ | "alpha-black-50"
311
+ | "alpha-black-60"
312
+ | "alpha-black-70"
313
+ | "alpha-black-80"
314
+ | "alpha-black-90"
315
+ | "alpha-black-95"
316
+ | "alpha-white-5"
317
+ | "alpha-white-10"
318
+ | "alpha-white-20"
319
+ | "alpha-white-30"
320
+ | "alpha-white-40"
321
+ | "alpha-white-50"
322
+ | "alpha-white-60"
323
+ | "alpha-white-70"
324
+ | "alpha-white-80"
325
+ | "alpha-white-90"
326
+ | "alpha-white-95"
327
+ // Special
328
+ | "white"
329
+ | "black";
330
+
331
+ /**
332
+ * Spacing token names - maps to `--spacing-{name}` CSS variables
333
+ * @example "spacing-40", "spacing-72"
334
+ */
335
+ export type SpacingToken =
336
+ | "spacing-0"
337
+ | "spacing-2"
338
+ | "spacing-4"
339
+ | "spacing-6"
340
+ | "spacing-8"
341
+ | "spacing-10"
342
+ | "spacing-11"
343
+ | "spacing-12"
344
+ | "spacing-16"
345
+ | "spacing-20"
346
+ | "spacing-24"
347
+ | "spacing-28"
348
+ | "spacing-32"
349
+ | "spacing-36"
350
+ | "spacing-40"
351
+ | "spacing-48"
352
+ | "spacing-56"
353
+ | "spacing-64"
354
+ | "spacing-72"
355
+ | "spacing-80"
356
+ | "spacing-96"
357
+ | "spacing-112"
358
+ | "spacing-128"
359
+ | "spacing-144"
360
+ | "spacing-160"
361
+ | "spacing-176"
362
+ | "spacing-192"
363
+ | "spacing-208"
364
+ | "spacing-224"
365
+ | "spacing-240"
366
+ | "spacing-256"
367
+ | "spacing-288"
368
+ | "spacing-320"
369
+ | "spacing-352"
370
+ | "spacing-384"
371
+ | "spacing-400";
372
+
373
+ /**
374
+ * Radius token names - maps to `--radii-{name}` CSS variables
375
+ * @example "radii-4", "radii-6"
376
+ */
377
+ export type RadiusToken =
378
+ | "radii-0"
379
+ | "radii-2"
380
+ | "radii-4"
381
+ | "radii-6"
382
+ | "radii-8"
383
+ | "radii-10"
384
+ | "radii-11"
385
+ | "radii-12"
386
+ | "radii-16"
387
+ | "radii-20"
388
+ | "radii-24"
389
+ | "radii-28"
390
+ | "radii-32"
391
+ | "radii-36"
392
+ | "radii-40"
393
+ | "radii-48"
394
+ | "radii-56"
395
+ | "radii-64"
396
+ | "radii-72"
397
+ | "radii-80"
398
+ | "radii-96"
399
+ | "radii-112"
400
+ | "radii-128"
401
+ | "radii-144"
402
+ | "radii-160"
403
+ | "radii-176"
404
+ | "radii-192"
405
+ | "radii-208"
406
+ | "radii-224"
407
+ | "radii-240"
408
+ | "radii-256"
409
+ | "radii-288"
410
+ | "radii-320"
411
+ | "radii-352"
412
+ | "radii-384"
413
+ | "radii-400";
414
+
415
+ /**
416
+ * Font size token values - primitive font sizes available in the design system
417
+ * These correspond to Tailwind classes like `text-64`, `text-128`, etc.
418
+ * @example 64, 128, 192
419
+ */
420
+ export type FontSizeToken =
421
+ | 9
422
+ | 11
423
+ | 12
424
+ | 14
425
+ | 16
426
+ | 18
427
+ | 21
428
+ | 24
429
+ | 28
430
+ | 32
431
+ | 36
432
+ | 42
433
+ | 48
434
+ | 56
435
+ | 64
436
+ | 72
437
+ | 84
438
+ | 88
439
+ | 96
440
+ | 112
441
+ | 128
442
+ | 148
443
+ | 168
444
+ | 192
445
+ | 224
446
+ | 256
447
+ | 280;
448
+
449
+ /**
450
+ * Array of all available font sizes for use in UI selectors/dropdowns
451
+ */
452
+ export const FONT_SIZES: FontSizeToken[] = [
453
+ 9, 11, 12, 14, 16, 18, 21, 24, 28, 32, 36, 42, 48, 56, 64, 72, 84, 88, 96,
454
+ 112, 128, 148, 168, 192, 224, 256, 280,
455
+ ];
456
+
457
+ /**
458
+ * Helper to generate typography class string from font size
459
+ * @example fontSizeToClass(128) => "text-128 leading-128 tracking-128"
460
+ */
461
+ export function fontSizeToClass(size: FontSizeToken): string {
462
+ return `text-${size} leading-${size} tracking-${size}`;
463
+ }
464
+
465
+ /**
466
+ * Helper to generate responsive typography class string
467
+ * @example responsiveTypographyClass(64, 128, 192) => "text-64 leading-64 tracking-64 md:text-128 md:leading-128 md:tracking-128 xl:text-192 xl:leading-192 xl:tracking-192"
468
+ */
469
+ export function responsiveTypographyClass(
470
+ mobile: FontSizeToken,
471
+ tablet: FontSizeToken,
472
+ desktop: FontSizeToken,
473
+ ): string {
474
+ return [
475
+ fontSizeToClass(mobile),
476
+ `md:${fontSizeToClass(tablet).split(" ").join(" md:")}`,
477
+ `xl:${fontSizeToClass(desktop).split(" ").join(" xl:")}`,
478
+ ].join(" ");
479
+ }
480
+
481
+ // =============================================================================
482
+ // Color Tokens
483
+ // =============================================================================
484
+
485
+ export interface ComponentThemeColors {
486
+ /**
487
+ * Background color for sections
488
+ * @example "gray-100"
489
+ */
490
+ bgSection?: ColorToken;
491
+
492
+ /**
493
+ * Background color for cards
494
+ * @example "white"
495
+ */
496
+ cardBackground?: ColorToken;
497
+
498
+ /**
499
+ * Muted background color
500
+ * @example "gray-50"
501
+ */
502
+ bgMuted?: ColorToken;
503
+
504
+ /**
505
+ * Primary text color
506
+ * @example "gray-1100"
507
+ */
508
+ textPrimary?: ColorToken;
509
+
510
+ /**
511
+ * Secondary text color
512
+ * @example "gray-800"
513
+ */
514
+ textSecondary?: ColorToken;
515
+
516
+ /**
517
+ * Muted text color
518
+ * @example "gray-600"
519
+ */
520
+ textMuted?: ColorToken;
521
+
522
+ /**
523
+ * Inverted text color (for dark backgrounds)
524
+ * @example "gray-100"
525
+ */
526
+ textInverted?: ColorToken;
527
+
528
+ /**
529
+ * Link text color
530
+ * @example "gray-1100"
531
+ */
532
+ textLink?: ColorToken;
533
+
534
+ /**
535
+ * Link hover text color
536
+ * @example "gray-700"
537
+ */
538
+ textLinkHover?: ColorToken;
539
+
540
+ /**
541
+ * Brand accent color
542
+ * @example "ember-v300"
543
+ */
544
+ accentBrand?: ColorToken;
545
+
546
+ /**
547
+ * Soft brand accent color
548
+ * @example "ember-100"
549
+ */
550
+ accentBrandSoft?: ColorToken;
551
+
552
+ /**
553
+ * Subtle border color
554
+ * @example "alpha-black-10"
555
+ */
556
+ borderSubtle?: ColorToken;
557
+
558
+ /**
559
+ * Strong border color
560
+ * @example "alpha-black-20"
561
+ */
562
+ borderStrong?: ColorToken;
563
+
564
+ /**
565
+ * Focus border color (uses accentBrand by default)
566
+ * @example "ember-v300"
567
+ */
568
+ borderFocus?: ColorToken;
569
+
570
+ /**
571
+ * Divider border color
572
+ * @example "alpha-black-10"
573
+ */
574
+ borderDivider?: ColorToken;
575
+
576
+ /**
577
+ * Primary button background color
578
+ * @example "gray-1100"
579
+ */
580
+ buttonPrimaryBg?: ColorToken;
581
+
582
+ /**
583
+ * Primary button hover background color
584
+ * @example "gray-600"
585
+ */
586
+ buttonPrimaryBgHover?: ColorToken;
587
+
588
+ /**
589
+ * Secondary button background color
590
+ * @example "white"
591
+ */
592
+ buttonSecondaryBg?: ColorToken;
593
+
594
+ /**
595
+ * Secondary button hover background color
596
+ * @example "gray-100"
597
+ */
598
+ buttonSecondaryBgHover?: ColorToken;
599
+ }
600
+
601
+ // =============================================================================
602
+ // Spatial Tokens
603
+ // =============================================================================
604
+
605
+ export interface ComponentThemeSpatial {
606
+ /**
607
+ * Grid margin for large breakpoint
608
+ * @example "spacing-72"
609
+ */
610
+ gridLargeMargin?: SpacingToken;
611
+
612
+ /**
613
+ * Grid gutter for large breakpoint
614
+ * @example "spacing-24"
615
+ */
616
+ gridLargeGutter?: SpacingToken;
617
+
618
+ /**
619
+ * Number of grid columns for large breakpoint
620
+ */
621
+ gridLargeColumns?: number;
622
+
623
+ /**
624
+ * Grid margin for medium breakpoint
625
+ * @example "spacing-56"
626
+ */
627
+ gridMediumMargin?: SpacingToken;
628
+
629
+ /**
630
+ * Grid gutter for medium breakpoint
631
+ * @example "spacing-20"
632
+ */
633
+ gridMediumGutter?: SpacingToken;
634
+
635
+ /**
636
+ * Number of grid columns for medium breakpoint
637
+ */
638
+ gridMediumColumns?: number;
639
+
640
+ /**
641
+ * Grid margin for small breakpoint
642
+ * @example "spacing-24"
643
+ */
644
+ gridSmallMargin?: SpacingToken;
645
+
646
+ /**
647
+ * Grid gutter for small breakpoint
648
+ * @example "spacing-12"
649
+ */
650
+ gridSmallGutter?: SpacingToken;
651
+
652
+ /**
653
+ * Number of grid columns for small breakpoint
654
+ */
655
+ gridSmallColumns?: number;
656
+
657
+ /**
658
+ * Section gap for large breakpoint
659
+ * @example "spacing-64"
660
+ */
661
+ sectionLargeGap?: SpacingToken;
662
+
663
+ /**
664
+ * Section padding for large breakpoint
665
+ * @example "spacing-128"
666
+ */
667
+ sectionLargePadding?: SpacingToken;
668
+
669
+ /**
670
+ * Section gap for medium breakpoint
671
+ * @example "spacing-56"
672
+ */
673
+ sectionMediumGap?: SpacingToken;
674
+
675
+ /**
676
+ * Section padding for medium breakpoint
677
+ * @example "spacing-96"
678
+ */
679
+ sectionMediumPadding?: SpacingToken;
680
+
681
+ /**
682
+ * Section gap for small breakpoint
683
+ * @example "spacing-32"
684
+ */
685
+ sectionSmallGap?: SpacingToken;
686
+
687
+ /**
688
+ * Section padding for small breakpoint
689
+ * @example "spacing-64"
690
+ */
691
+ sectionSmallPadding?: SpacingToken;
692
+
693
+ /**
694
+ * Card gap for large size
695
+ * @example "spacing-10"
696
+ */
697
+ cardLargeGap?: SpacingToken;
698
+
699
+ /**
700
+ * Card padding for large size
701
+ * @example "spacing-24"
702
+ */
703
+ cardLargePadding?: SpacingToken;
704
+
705
+ /**
706
+ * Card gap for small size
707
+ * @example "spacing-12"
708
+ */
709
+ cardSmallGap?: SpacingToken;
710
+
711
+ /**
712
+ * Card padding for small size
713
+ * @example "spacing-16"
714
+ */
715
+ cardSmallPadding?: SpacingToken;
716
+ }
717
+
718
+ // =============================================================================
719
+ // Surface Tokens
720
+ // =============================================================================
721
+
722
+ export interface ComponentThemeSurface {
723
+ /**
724
+ * Card border radius
725
+ * @example "radii-4"
726
+ */
727
+ cardRadius?: RadiusToken;
728
+
729
+ /**
730
+ * Card stroke/border width in pixels
731
+ * @example 1
732
+ */
733
+ cardStroke?: number;
734
+
735
+ /**
736
+ * Button border radius
737
+ * @example "radii-6"
738
+ */
739
+ buttonRadius?: RadiusToken;
740
+
741
+ /**
742
+ * Button stroke/border weight in pixels
743
+ * @example 1
744
+ */
745
+ buttonStrokeWeight?: number;
746
+ }
747
+
748
+ // =============================================================================
749
+ // Combined Theme Interface
750
+ // =============================================================================
751
+
752
+ /**
753
+ * Complete component theme interface combining colors, spatial, and surface tokens.
754
+ *
755
+ * @example
756
+ * ```tsx
757
+ * const customTheme: ComponentTheme = {
758
+ * colors: {
759
+ * textPrimary: "gray-100",
760
+ * accentBrand: "ember-500",
761
+ * },
762
+ * spatial: {
763
+ * sectionLargePadding: "spacing-96",
764
+ * },
765
+ * surface: {
766
+ * cardRadius: "radii-8",
767
+ * },
768
+ * };
769
+ *
770
+ * <Tout theme={customTheme} ... />
771
+ * ```
772
+ */
773
+ export interface ComponentTheme {
774
+ colors?: ComponentThemeColors;
775
+ spatial?: ComponentThemeSpatial;
776
+ surface?: ComponentThemeSurface;
777
+ }
778
+
779
+ // =============================================================================
780
+ // Button Theme Interface
781
+ // =============================================================================
782
+
783
+ /**
784
+ * Button-specific theme interface for customizing individual button appearance.
785
+ *
786
+ * @example
787
+ * ```tsx
788
+ * const buttonTheme: ButtonTheme = {
789
+ * bg: "ember-500",
790
+ * bgHover: "ember-600",
791
+ * text: "white",
792
+ * radius: "radii-8",
793
+ * };
794
+ *
795
+ * <Button theme={buttonTheme}>Themed Button</Button>
796
+ * ```
797
+ */
798
+ export interface ButtonTheme {
799
+ /** Background color */
800
+ bg?: ColorToken;
801
+ /** Background color on hover */
802
+ bgHover?: ColorToken;
803
+ /** Background color on active/press */
804
+ bgActive?: ColorToken;
805
+ /** Text color */
806
+ text?: ColorToken;
807
+ /** Border color (if using border) */
808
+ borderColor?: ColorToken;
809
+ /** Border width in pixels (0 for no border) */
810
+ borderWidth?: number;
811
+ /** Border radius */
812
+ radius?: RadiusToken;
813
+ }
814
+
815
+ // =============================================================================
816
+ // Utility Functions
817
+ // =============================================================================
818
+
819
+ /**
820
+ * Converts a color token name to a CSS variable reference
821
+ */
822
+ function colorToVar(token: ColorToken): string {
823
+ return `var(--color-${token})`;
824
+ }
825
+
826
+ /**
827
+ * Converts a spacing token name to a CSS variable reference
828
+ */
829
+ function spacingToVar(token: SpacingToken): string {
830
+ return `var(--${token})`;
831
+ }
832
+
833
+ /**
834
+ * Converts a radius token name to a CSS variable reference
835
+ */
836
+ function radiusToVar(token: RadiusToken): string {
837
+ return `var(--${token})`;
838
+ }
839
+
840
+ /**
841
+ * Converts a ComponentTheme object to CSS custom properties (inline style object)
842
+ *
843
+ * @param theme - The theme object to convert
844
+ * @returns An object suitable for use as React inline styles
845
+ */
846
+ export function themeToStyleVars(
847
+ theme: ComponentTheme | undefined,
848
+ ): React.CSSProperties {
849
+ if (!theme) return {};
850
+
851
+ const vars: Record<string, string> = {};
852
+
853
+ // Colors
854
+ if (theme.colors) {
855
+ const { colors } = theme;
856
+ if (colors.bgSection)
857
+ vars["--theme-bg-section"] = colorToVar(colors.bgSection);
858
+ if (colors.cardBackground)
859
+ vars["--theme-card-background"] = colorToVar(colors.cardBackground);
860
+ if (colors.bgMuted) vars["--theme-bg-muted"] = colorToVar(colors.bgMuted);
861
+ if (colors.textPrimary)
862
+ vars["--theme-text-primary"] = colorToVar(colors.textPrimary);
863
+ if (colors.textSecondary)
864
+ vars["--theme-text-secondary"] = colorToVar(colors.textSecondary);
865
+ if (colors.textMuted)
866
+ vars["--theme-text-muted"] = colorToVar(colors.textMuted);
867
+ if (colors.textInverted)
868
+ vars["--theme-text-inverted"] = colorToVar(colors.textInverted);
869
+ if (colors.textLink)
870
+ vars["--theme-text-link"] = colorToVar(colors.textLink);
871
+ if (colors.textLinkHover)
872
+ vars["--theme-text-link-hover"] = colorToVar(colors.textLinkHover);
873
+ if (colors.accentBrand)
874
+ vars["--theme-accent-brand"] = colorToVar(colors.accentBrand);
875
+ if (colors.accentBrandSoft)
876
+ vars["--theme-accent-brand-soft"] = colorToVar(colors.accentBrandSoft);
877
+ if (colors.borderSubtle)
878
+ vars["--theme-border-subtle"] = colorToVar(colors.borderSubtle);
879
+ if (colors.borderStrong)
880
+ vars["--theme-border-strong"] = colorToVar(colors.borderStrong);
881
+ if (colors.borderFocus)
882
+ vars["--theme-border-focus"] = colorToVar(colors.borderFocus);
883
+ if (colors.borderDivider)
884
+ vars["--theme-border-divider"] = colorToVar(colors.borderDivider);
885
+ if (colors.buttonPrimaryBg)
886
+ vars["--theme-button-primary-bg"] = colorToVar(colors.buttonPrimaryBg);
887
+ if (colors.buttonPrimaryBgHover)
888
+ vars["--theme-button-primary-bg-hover"] = colorToVar(
889
+ colors.buttonPrimaryBgHover,
890
+ );
891
+ if (colors.buttonSecondaryBg)
892
+ vars["--theme-button-secondary-bg"] = colorToVar(
893
+ colors.buttonSecondaryBg,
894
+ );
895
+ if (colors.buttonSecondaryBgHover)
896
+ vars["--theme-button-secondary-bg-hover"] = colorToVar(
897
+ colors.buttonSecondaryBgHover,
898
+ );
899
+ }
900
+
901
+ // Spatial
902
+ if (theme.spatial) {
903
+ const { spatial } = theme;
904
+ if (spatial.gridLargeMargin)
905
+ vars["--theme-grid-large-margin"] = spacingToVar(spatial.gridLargeMargin);
906
+ if (spatial.gridLargeGutter)
907
+ vars["--theme-grid-large-gutter"] = spacingToVar(spatial.gridLargeGutter);
908
+ if (spatial.gridLargeColumns)
909
+ vars["--theme-grid-large-columns"] = String(spatial.gridLargeColumns);
910
+ if (spatial.gridMediumMargin)
911
+ vars["--theme-grid-medium-margin"] = spacingToVar(
912
+ spatial.gridMediumMargin,
913
+ );
914
+ if (spatial.gridMediumGutter)
915
+ vars["--theme-grid-medium-gutter"] = spacingToVar(
916
+ spatial.gridMediumGutter,
917
+ );
918
+ if (spatial.gridMediumColumns)
919
+ vars["--theme-grid-medium-columns"] = String(spatial.gridMediumColumns);
920
+ if (spatial.gridSmallMargin)
921
+ vars["--theme-grid-small-margin"] = spacingToVar(spatial.gridSmallMargin);
922
+ if (spatial.gridSmallGutter)
923
+ vars["--theme-grid-small-gutter"] = spacingToVar(spatial.gridSmallGutter);
924
+ if (spatial.gridSmallColumns)
925
+ vars["--theme-grid-small-columns"] = String(spatial.gridSmallColumns);
926
+ if (spatial.sectionLargeGap)
927
+ vars["--theme-section-large-gap"] = spacingToVar(spatial.sectionLargeGap);
928
+ if (spatial.sectionLargePadding)
929
+ vars["--theme-section-large-padding"] = spacingToVar(
930
+ spatial.sectionLargePadding,
931
+ );
932
+ if (spatial.sectionMediumGap)
933
+ vars["--theme-section-medium-gap"] = spacingToVar(
934
+ spatial.sectionMediumGap,
935
+ );
936
+ if (spatial.sectionMediumPadding)
937
+ vars["--theme-section-medium-padding"] = spacingToVar(
938
+ spatial.sectionMediumPadding,
939
+ );
940
+ if (spatial.sectionSmallGap)
941
+ vars["--theme-section-small-gap"] = spacingToVar(spatial.sectionSmallGap);
942
+ if (spatial.sectionSmallPadding)
943
+ vars["--theme-section-small-padding"] = spacingToVar(
944
+ spatial.sectionSmallPadding,
945
+ );
946
+ if (spatial.cardLargeGap)
947
+ vars["--theme-card-large-gap"] = spacingToVar(spatial.cardLargeGap);
948
+ if (spatial.cardLargePadding)
949
+ vars["--theme-card-large-padding"] = spacingToVar(
950
+ spatial.cardLargePadding,
951
+ );
952
+ if (spatial.cardSmallGap)
953
+ vars["--theme-card-small-gap"] = spacingToVar(spatial.cardSmallGap);
954
+ if (spatial.cardSmallPadding)
955
+ vars["--theme-card-small-padding"] = spacingToVar(
956
+ spatial.cardSmallPadding,
957
+ );
958
+ }
959
+
960
+ // Surface
961
+ if (theme.surface) {
962
+ const { surface } = theme;
963
+ if (surface.cardRadius)
964
+ vars["--theme-card-radius"] = radiusToVar(surface.cardRadius);
965
+ if (surface.cardStroke)
966
+ vars["--theme-card-stroke"] = `${surface.cardStroke}px`;
967
+ if (surface.buttonRadius)
968
+ vars["--theme-button-radius"] = radiusToVar(surface.buttonRadius);
969
+ if (surface.buttonStrokeWeight)
970
+ vars["--theme-button-stroke-weight"] = `${surface.buttonStrokeWeight}px`;
971
+ }
972
+
973
+ return vars as React.CSSProperties;
974
+ }
975
+
976
+ /**
977
+ * Converts a ButtonTheme object to CSS custom properties (inline style object)
978
+ *
979
+ * @param theme - The button theme object to convert
980
+ * @returns An object suitable for use as React inline styles
981
+ */
982
+ export function buttonThemeToStyleVars(
983
+ theme: ButtonTheme | undefined,
984
+ ): React.CSSProperties {
985
+ if (!theme) return {};
986
+
987
+ const vars: Record<string, string> = {};
988
+
989
+ if (theme.bg) vars["--btn-bg"] = colorToVar(theme.bg);
990
+ if (theme.bgHover) vars["--btn-bg-hover"] = colorToVar(theme.bgHover);
991
+ if (theme.bgActive) vars["--btn-bg-active"] = colorToVar(theme.bgActive);
992
+ if (theme.text) vars["--btn-text"] = colorToVar(theme.text);
993
+ if (theme.borderColor)
994
+ vars["--btn-border-color"] = colorToVar(theme.borderColor);
995
+ if (theme.borderWidth !== undefined)
996
+ vars["--btn-border-width"] = `${theme.borderWidth}px`;
997
+ if (theme.radius) vars["--btn-radius"] = radiusToVar(theme.radius);
998
+
999
+ return vars as React.CSSProperties;
1000
+ }