@react-spectrum/s2 3.0.0-nightly-5a0b4fabc-240924 → 3.0.0-nightly-a626c2596-240926

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 (251) hide show
  1. package/dist/Accordion.cjs +1 -1
  2. package/dist/Accordion.cjs.map +1 -1
  3. package/dist/Accordion.css.map +1 -1
  4. package/dist/Accordion.mjs +2 -2
  5. package/dist/Accordion.mjs.map +1 -1
  6. package/dist/Button.cjs +5 -1
  7. package/dist/Button.cjs.map +1 -1
  8. package/dist/Button.css.map +1 -1
  9. package/dist/Button.mjs +5 -1
  10. package/dist/Button.mjs.map +1 -1
  11. package/dist/Card.cjs +1 -1
  12. package/dist/Card.cjs.map +1 -1
  13. package/dist/Card.css.map +1 -1
  14. package/dist/Card.mjs +1 -1
  15. package/dist/Card.mjs.map +1 -1
  16. package/dist/Checkbox.cjs +4 -1
  17. package/dist/Checkbox.cjs.map +1 -1
  18. package/dist/Checkbox.css +4 -0
  19. package/dist/Checkbox.css.map +1 -1
  20. package/dist/Checkbox.mjs +4 -1
  21. package/dist/Checkbox.mjs.map +1 -1
  22. package/dist/ComboBox.cjs +3 -0
  23. package/dist/ComboBox.cjs.map +1 -1
  24. package/dist/ComboBox.css.map +1 -1
  25. package/dist/ComboBox.mjs +3 -0
  26. package/dist/ComboBox.mjs.map +1 -1
  27. package/dist/Content.cjs +0 -2
  28. package/dist/Content.cjs.map +1 -1
  29. package/dist/Content.mjs +1 -2
  30. package/dist/Content.mjs.map +1 -1
  31. package/dist/Dialog.cjs +7 -5
  32. package/dist/Dialog.cjs.map +1 -1
  33. package/dist/Dialog.css.map +1 -1
  34. package/dist/Dialog.mjs +8 -6
  35. package/dist/Dialog.mjs.map +1 -1
  36. package/dist/Disclosure.cjs +2 -2
  37. package/dist/Disclosure.cjs.map +1 -1
  38. package/dist/Disclosure.css.map +1 -1
  39. package/dist/Disclosure.mjs +3 -3
  40. package/dist/Disclosure.mjs.map +1 -1
  41. package/dist/MoveHorizontalCircleTableWidget.cjs +33 -0
  42. package/dist/MoveHorizontalCircleTableWidget.cjs.map +1 -0
  43. package/dist/MoveHorizontalCircleTableWidget.mjs +28 -0
  44. package/dist/MoveHorizontalCircleTableWidget.mjs.map +1 -0
  45. package/dist/Picker.cjs +3 -0
  46. package/dist/Picker.cjs.map +1 -1
  47. package/dist/Picker.css.map +1 -1
  48. package/dist/Picker.mjs +3 -0
  49. package/dist/Picker.mjs.map +1 -1
  50. package/dist/Popover.cjs +1 -0
  51. package/dist/Popover.cjs.map +1 -1
  52. package/dist/Popover.css +4 -0
  53. package/dist/Popover.css.map +1 -1
  54. package/dist/Popover.mjs +1 -0
  55. package/dist/Popover.mjs.map +1 -1
  56. package/dist/SegmentedControl.cjs +11 -1
  57. package/dist/SegmentedControl.cjs.map +1 -1
  58. package/dist/SegmentedControl.css +24 -0
  59. package/dist/SegmentedControl.css.map +1 -1
  60. package/dist/SegmentedControl.mjs +11 -1
  61. package/dist/SegmentedControl.mjs.map +1 -1
  62. package/dist/Table.cjs +1093 -0
  63. package/dist/Table.cjs.map +1 -0
  64. package/dist/Table.css +821 -0
  65. package/dist/Table.css.map +1 -0
  66. package/dist/Table.mjs +1083 -0
  67. package/dist/Table.mjs.map +1 -0
  68. package/dist/TagGroup.cjs +5 -3
  69. package/dist/TagGroup.cjs.map +1 -1
  70. package/dist/TagGroup.css.map +1 -1
  71. package/dist/TagGroup.mjs +5 -3
  72. package/dist/TagGroup.mjs.map +1 -1
  73. package/dist/ar-AE.cjs +5 -0
  74. package/dist/ar-AE.cjs.map +1 -1
  75. package/dist/ar-AE.mjs +5 -0
  76. package/dist/ar-AE.mjs.map +1 -1
  77. package/dist/bg-BG.cjs +5 -0
  78. package/dist/bg-BG.cjs.map +1 -1
  79. package/dist/bg-BG.mjs +5 -0
  80. package/dist/bg-BG.mjs.map +1 -1
  81. package/dist/cs-CZ.cjs +5 -0
  82. package/dist/cs-CZ.cjs.map +1 -1
  83. package/dist/cs-CZ.mjs +5 -0
  84. package/dist/cs-CZ.mjs.map +1 -1
  85. package/dist/da-DK.cjs +5 -0
  86. package/dist/da-DK.cjs.map +1 -1
  87. package/dist/da-DK.mjs +5 -0
  88. package/dist/da-DK.mjs.map +1 -1
  89. package/dist/de-DE.cjs +5 -0
  90. package/dist/de-DE.cjs.map +1 -1
  91. package/dist/de-DE.mjs +5 -0
  92. package/dist/de-DE.mjs.map +1 -1
  93. package/dist/el-GR.cjs +5 -0
  94. package/dist/el-GR.cjs.map +1 -1
  95. package/dist/el-GR.mjs +5 -0
  96. package/dist/el-GR.mjs.map +1 -1
  97. package/dist/en-US.cjs +5 -0
  98. package/dist/en-US.cjs.map +1 -1
  99. package/dist/en-US.mjs +5 -0
  100. package/dist/en-US.mjs.map +1 -1
  101. package/dist/es-ES.cjs +5 -0
  102. package/dist/es-ES.cjs.map +1 -1
  103. package/dist/es-ES.mjs +5 -0
  104. package/dist/es-ES.mjs.map +1 -1
  105. package/dist/et-EE.cjs +5 -0
  106. package/dist/et-EE.cjs.map +1 -1
  107. package/dist/et-EE.mjs +5 -0
  108. package/dist/et-EE.mjs.map +1 -1
  109. package/dist/fi-FI.cjs +5 -0
  110. package/dist/fi-FI.cjs.map +1 -1
  111. package/dist/fi-FI.mjs +5 -0
  112. package/dist/fi-FI.mjs.map +1 -1
  113. package/dist/fr-FR.cjs +5 -0
  114. package/dist/fr-FR.cjs.map +1 -1
  115. package/dist/fr-FR.mjs +5 -0
  116. package/dist/fr-FR.mjs.map +1 -1
  117. package/dist/he-IL.cjs +5 -0
  118. package/dist/he-IL.cjs.map +1 -1
  119. package/dist/he-IL.mjs +5 -0
  120. package/dist/he-IL.mjs.map +1 -1
  121. package/dist/hr-HR.cjs +5 -0
  122. package/dist/hr-HR.cjs.map +1 -1
  123. package/dist/hr-HR.mjs +5 -0
  124. package/dist/hr-HR.mjs.map +1 -1
  125. package/dist/hu-HU.cjs +5 -0
  126. package/dist/hu-HU.cjs.map +1 -1
  127. package/dist/hu-HU.mjs +5 -0
  128. package/dist/hu-HU.mjs.map +1 -1
  129. package/dist/it-IT.cjs +5 -0
  130. package/dist/it-IT.cjs.map +1 -1
  131. package/dist/it-IT.mjs +5 -0
  132. package/dist/it-IT.mjs.map +1 -1
  133. package/dist/ja-JP.cjs +5 -0
  134. package/dist/ja-JP.cjs.map +1 -1
  135. package/dist/ja-JP.mjs +5 -0
  136. package/dist/ja-JP.mjs.map +1 -1
  137. package/dist/ko-KR.cjs +5 -0
  138. package/dist/ko-KR.cjs.map +1 -1
  139. package/dist/ko-KR.mjs +5 -0
  140. package/dist/ko-KR.mjs.map +1 -1
  141. package/dist/lt-LT.cjs +5 -0
  142. package/dist/lt-LT.cjs.map +1 -1
  143. package/dist/lt-LT.mjs +5 -0
  144. package/dist/lt-LT.mjs.map +1 -1
  145. package/dist/lv-LV.cjs +5 -0
  146. package/dist/lv-LV.cjs.map +1 -1
  147. package/dist/lv-LV.mjs +5 -0
  148. package/dist/lv-LV.mjs.map +1 -1
  149. package/dist/main.cjs +8 -0
  150. package/dist/main.cjs.map +1 -1
  151. package/dist/module.mjs +3 -1
  152. package/dist/module.mjs.map +1 -1
  153. package/dist/nb-NO.cjs +5 -0
  154. package/dist/nb-NO.cjs.map +1 -1
  155. package/dist/nb-NO.mjs +5 -0
  156. package/dist/nb-NO.mjs.map +1 -1
  157. package/dist/nl-NL.cjs +5 -0
  158. package/dist/nl-NL.cjs.map +1 -1
  159. package/dist/nl-NL.mjs +5 -0
  160. package/dist/nl-NL.mjs.map +1 -1
  161. package/dist/pl-PL.cjs +5 -0
  162. package/dist/pl-PL.cjs.map +1 -1
  163. package/dist/pl-PL.mjs +5 -0
  164. package/dist/pl-PL.mjs.map +1 -1
  165. package/dist/pt-BR.cjs +5 -0
  166. package/dist/pt-BR.cjs.map +1 -1
  167. package/dist/pt-BR.mjs +5 -0
  168. package/dist/pt-BR.mjs.map +1 -1
  169. package/dist/pt-PT.cjs +5 -0
  170. package/dist/pt-PT.cjs.map +1 -1
  171. package/dist/pt-PT.mjs +5 -0
  172. package/dist/pt-PT.mjs.map +1 -1
  173. package/dist/ro-RO.cjs +5 -0
  174. package/dist/ro-RO.cjs.map +1 -1
  175. package/dist/ro-RO.mjs +5 -0
  176. package/dist/ro-RO.mjs.map +1 -1
  177. package/dist/ru-RU.cjs +5 -0
  178. package/dist/ru-RU.cjs.map +1 -1
  179. package/dist/ru-RU.mjs +5 -0
  180. package/dist/ru-RU.mjs.map +1 -1
  181. package/dist/sk-SK.cjs +5 -0
  182. package/dist/sk-SK.cjs.map +1 -1
  183. package/dist/sk-SK.mjs +5 -0
  184. package/dist/sk-SK.mjs.map +1 -1
  185. package/dist/sl-SI.cjs +5 -0
  186. package/dist/sl-SI.cjs.map +1 -1
  187. package/dist/sl-SI.mjs +5 -0
  188. package/dist/sl-SI.mjs.map +1 -1
  189. package/dist/sr-SP.cjs +5 -0
  190. package/dist/sr-SP.cjs.map +1 -1
  191. package/dist/sr-SP.mjs +5 -0
  192. package/dist/sr-SP.mjs.map +1 -1
  193. package/dist/sv-SE.cjs +5 -0
  194. package/dist/sv-SE.cjs.map +1 -1
  195. package/dist/sv-SE.mjs +5 -0
  196. package/dist/sv-SE.mjs.map +1 -1
  197. package/dist/tr-TR.cjs +5 -0
  198. package/dist/tr-TR.cjs.map +1 -1
  199. package/dist/tr-TR.mjs +5 -0
  200. package/dist/tr-TR.mjs.map +1 -1
  201. package/dist/types.d.ts +93 -4
  202. package/dist/types.d.ts.map +1 -1
  203. package/dist/uk-UA.cjs +5 -0
  204. package/dist/uk-UA.cjs.map +1 -1
  205. package/dist/uk-UA.mjs +5 -0
  206. package/dist/uk-UA.mjs.map +1 -1
  207. package/dist/utils.cjs +30 -0
  208. package/dist/utils.cjs.map +1 -0
  209. package/dist/utils.mjs +25 -0
  210. package/dist/utils.mjs.map +1 -0
  211. package/dist/zh-CN.cjs +5 -0
  212. package/dist/zh-CN.cjs.map +1 -1
  213. package/dist/zh-CN.mjs +5 -0
  214. package/dist/zh-CN.mjs.map +1 -1
  215. package/dist/zh-TW.cjs +5 -0
  216. package/dist/zh-TW.cjs.map +1 -1
  217. package/dist/zh-TW.mjs +5 -0
  218. package/dist/zh-TW.mjs.map +1 -1
  219. package/package.json +18 -16
  220. package/src/Accordion.tsx +2 -2
  221. package/src/Button.tsx +22 -14
  222. package/src/Card.tsx +1 -1
  223. package/src/Checkbox.tsx +1 -0
  224. package/src/ComboBox.tsx +3 -0
  225. package/src/Content.tsx +1 -3
  226. package/src/Dialog.tsx +3 -2
  227. package/src/Disclosure.tsx +3 -3
  228. package/src/Picker.tsx +3 -0
  229. package/src/Popover.tsx +4 -1
  230. package/src/SegmentedControl.tsx +14 -3
  231. package/src/Table.tsx +1084 -48
  232. package/src/TagGroup.tsx +3 -2
  233. package/src/index.ts +2 -0
  234. package/src/utils.ts +28 -0
  235. package/style/__tests__/mergeStyles.test.js +32 -0
  236. package/style/__tests__/style-macro.test.js +128 -0
  237. package/style/dist/main.cjs +1984 -0
  238. package/style/dist/main.cjs.map +1 -0
  239. package/style/dist/module.mjs +1973 -0
  240. package/style/dist/module.mjs.map +1 -0
  241. package/style/dist/style-macro.cjs +543 -0
  242. package/style/dist/style-macro.cjs.map +1 -0
  243. package/style/dist/style-macro.mjs +534 -0
  244. package/style/dist/style-macro.mjs.map +1 -0
  245. package/style/dist/types.d.ts +780 -0
  246. package/style/dist/types.d.ts.map +1 -0
  247. package/style/runtime.ts +103 -0
  248. package/style/spectrum-theme.ts +974 -0
  249. package/style/style-macro.ts +638 -0
  250. package/style/tokens.ts +68 -0
  251. package/style/types.ts +177 -0
@@ -0,0 +1,974 @@
1
+ /*
2
+ * Copyright 2024 Adobe. All rights reserved.
3
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ * you may not use this file except in compliance with the License. You may obtain a copy
5
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ *
7
+ * Unless required by applicable law or agreed to in writing, software distributed under
8
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ * OF ANY KIND, either express or implied. See the License for the specific language
10
+ * governing permissions and limitations under the License.
11
+ */
12
+
13
+ import {Color, createArbitraryProperty, createColorProperty, createMappedProperty, createRenamedProperty, createTheme} from './style-macro';
14
+ import {colorScale, colorToken, fontSizeToken, getToken, simpleColorScale, weirdColorToken} from './tokens' with {type: 'macro'};
15
+ import type * as CSS from 'csstype';
16
+
17
+ interface MacroContext {
18
+ addAsset(asset: {type: string, content: string}): void
19
+ }
20
+
21
+ function pxToRem(px: string | number) {
22
+ if (typeof px === 'string') {
23
+ px = parseFloat(px);
24
+ }
25
+ return px / 16 + 'rem';
26
+ }
27
+
28
+ const color = {
29
+ transparent: 'transparent',
30
+ black: 'black',
31
+ white: 'white',
32
+
33
+ ...colorScale('gray'),
34
+ ...colorScale('blue'),
35
+ ...colorScale('red'),
36
+ ...colorScale('orange'),
37
+ ...colorScale('yellow'),
38
+ ...colorScale('chartreuse'),
39
+ ...colorScale('celery'),
40
+ ...colorScale('green'),
41
+ ...colorScale('seafoam'),
42
+ ...colorScale('cyan'),
43
+ ...colorScale('indigo'),
44
+ ...colorScale('purple'),
45
+ ...colorScale('fuchsia'),
46
+ ...colorScale('magenta'),
47
+ ...colorScale('pink'),
48
+ ...colorScale('turquoise'),
49
+ ...colorScale('brown'),
50
+ ...colorScale('silver'),
51
+ ...colorScale('cinnamon'),
52
+
53
+ ...colorScale('accent-color'),
54
+ ...colorScale('informative-color'),
55
+ ...colorScale('negative-color'),
56
+ ...colorScale('notice-color'),
57
+ ...colorScale('positive-color'),
58
+
59
+ ...simpleColorScale('transparent-white'),
60
+ ...simpleColorScale('transparent-black'),
61
+
62
+ // High contrast mode.
63
+ Background: 'Background',
64
+ ButtonBorder: 'ButtonBorder',
65
+ ButtonFace: 'ButtonFace',
66
+ ButtonText: 'ButtonText',
67
+ Field: 'Field',
68
+ Highlight: 'Highlight',
69
+ HighlightText: 'HighlightText',
70
+ GrayText: 'GrayText',
71
+ Mark: 'Mark',
72
+ LinkText: 'LinkText'
73
+ };
74
+
75
+ export function baseColor(base: keyof typeof color) {
76
+ let keys = Object.keys(color) as (keyof typeof color)[];
77
+ let index = keys.indexOf(base);
78
+ if (index === -1) {
79
+ throw new Error('Invalid base color ' + base);
80
+ }
81
+
82
+ return {
83
+ default: base,
84
+ isHovered: keys[index + 1],
85
+ isFocusVisible: keys[index + 1],
86
+ isPressed: keys[index + 1]
87
+ };
88
+ }
89
+
90
+ export function lightDark(light: Color<keyof typeof color>, dark: Color<keyof typeof color>): `[${string}]` {
91
+ let [lightColorValue, lightOpacity] = light.split('/');
92
+ let [darkColorValue, darkOpacity] = dark.split('/');
93
+ let lightColor = color[lightColorValue];
94
+ let darkColor = color[darkColorValue];
95
+
96
+ if (lightOpacity) {
97
+ lightColor = `rgb(from ${lightColor} r g b / ${lightOpacity}%)`;
98
+ }
99
+
100
+ if (darkOpacity) {
101
+ darkColor = `rgb(from ${darkColor} r g b / ${darkOpacity}%)`;
102
+ }
103
+
104
+ return `[light-dark(${lightColor}, ${darkColor})]`;
105
+ }
106
+
107
+ function generateSpacing<K extends number[]>(px: K): {[P in K[number]]: string} {
108
+ let res: any = {};
109
+ for (let p of px) {
110
+ res[p] = pxToRem(p);
111
+ }
112
+ return res;
113
+ }
114
+
115
+ const baseSpacing = generateSpacing([
116
+ 0,
117
+ 2, // spacing-50
118
+ 4, // spacing-75
119
+ 8, // spacing-100
120
+ 12, // spacing-200
121
+ 16, // spacing-300
122
+ 20,
123
+ 24, // spacing-400
124
+ 28,
125
+ 32, // spacing-500
126
+ 36,
127
+ 40, // spacing-600
128
+ 44,
129
+ 48, // spacing-700
130
+ 56,
131
+ // From here onward the values are mostly spaced by 1rem (16px)
132
+ 64, // spacing-800
133
+ 80, // spacing-900
134
+ 96, // spacing-1000
135
+ // TODO: should these only be available as sizes rather than spacing?
136
+ 112,
137
+ 128,
138
+ 144,
139
+ 160,
140
+ 176,
141
+ 192,
142
+ 208,
143
+ 224,
144
+ 240,
145
+ 256,
146
+ 288,
147
+ 320,
148
+ 384
149
+ ] as const);
150
+
151
+ // This should match the above, but negative. There's no way to negate a number
152
+ // type in typescript so this has to be done manually for now.
153
+ const negativeSpacing = generateSpacing([
154
+ // -2, // spacing-50 !! TODO: should we support this?
155
+ -4, // spacing-75
156
+ -8, // spacing-100
157
+ -12, // spacing-200
158
+ -16, // spacing-300
159
+ -20,
160
+ -24, // spacing-400
161
+ -28,
162
+ -32, // spacing-500
163
+ -36,
164
+ -40, // spacing-600
165
+ -44,
166
+ -48, // spacing-700
167
+ -56,
168
+ // From here onward the values are mostly spaced by 1rem (16px)
169
+ -64, // spacing-800
170
+ -80, // spacing-900
171
+ -96, // spacing-1000
172
+ // TODO: should these only be available as sizes rather than spacing?
173
+ -112,
174
+ -128,
175
+ -144,
176
+ -160,
177
+ -176,
178
+ -192,
179
+ -208,
180
+ -224,
181
+ -240,
182
+ -256,
183
+ -288,
184
+ -320,
185
+ -384
186
+ ] as const);
187
+
188
+ function arbitrary(ctx: MacroContext | void, value: string): `[${string}]` {
189
+ return ctx ? `[${value}]` : value as any;
190
+ }
191
+
192
+ export function fontRelative(this: MacroContext | void, base: number, baseFontSize = 14) {
193
+ return arbitrary(this, (base / baseFontSize) + 'em');
194
+ }
195
+
196
+ export function edgeToText(this: MacroContext | void, height: keyof typeof baseSpacing) {
197
+ return `calc(${baseSpacing[height]} * 3 / 8)`;
198
+ }
199
+
200
+ export function space(this: MacroContext | void, px: number) {
201
+ return arbitrary(this, pxToRem(px));
202
+ }
203
+
204
+ const spacing = {
205
+ ...baseSpacing,
206
+
207
+ // font-size relative values
208
+ 'text-to-control': fontRelative(10),
209
+ 'text-to-visual': {
210
+ default: fontRelative(6), // -> 5px, 5px, 6px, 7px, 8px
211
+ touch: fontRelative(8, 17) // -> 6px, 7px, 8px, 9px, 10px, should be 7px, 7px, 8px, 9px, 11px
212
+ },
213
+ // height relative values
214
+ 'edge-to-text': 'calc(self(height, self(minHeight)) * 3 / 8)',
215
+ 'pill': 'calc(self(height, self(minHeight)) / 2)'
216
+ };
217
+
218
+ export function size(this: MacroContext | void, px: number) {
219
+ return {default: arbitrary(this, pxToRem(px)), touch: arbitrary(this, pxToRem(px * 1.25))};
220
+ }
221
+
222
+ const scaledSpacing: {[key in keyof typeof baseSpacing]: {default: string, touch: string}} =
223
+ Object.fromEntries(Object.entries(baseSpacing).map(([k, v]) =>
224
+ [k, {default: v, touch: parseFloat(v) * 1.25 + v.match(/[^0-9.]+/)![0]}])
225
+ ) as any;
226
+
227
+ const sizing = {
228
+ ...scaledSpacing,
229
+ auto: 'auto',
230
+ full: '100%',
231
+ min: 'min-content',
232
+ max: 'max-content',
233
+ fit: 'fit-content',
234
+
235
+ control: {
236
+ default: size(32),
237
+ size: {
238
+ XS: size(20),
239
+ S: size(24),
240
+ L: size(40),
241
+ XL: size(48)
242
+ }
243
+ },
244
+ // With browser support for round() we could do this:
245
+ // 'control-sm': `round(${16 / 14}em, 2px)`
246
+ 'control-sm': {
247
+ default: size(16),
248
+ size: {
249
+ S: size(14),
250
+ L: size(18),
251
+ XL: size(20)
252
+ }
253
+ }
254
+ };
255
+
256
+ const height = {
257
+ ...sizing,
258
+ screen: '100vh'
259
+ };
260
+
261
+ const width = {
262
+ ...sizing,
263
+ screen: '100vw'
264
+ };
265
+
266
+ const margin = {
267
+ ...spacing,
268
+ ...negativeSpacing,
269
+ auto: 'auto'
270
+ };
271
+
272
+ const inset = {
273
+ ...baseSpacing,
274
+ auto: 'auto',
275
+ full: '100%'
276
+ };
277
+
278
+ const translate = {
279
+ ...baseSpacing,
280
+ ...negativeSpacing,
281
+ full: '100%'
282
+ };
283
+
284
+ const borderWidth = {
285
+ 0: '0px',
286
+ 1: getToken('border-width-100'),
287
+ 2: getToken('border-width-200'),
288
+ 4: getToken('border-width-400')
289
+ };
290
+
291
+ const radius = {
292
+ none: getToken('corner-radius-none'), // 0px
293
+ sm: pxToRem(getToken('corner-radius-small-default')), // 4px
294
+ default: pxToRem(getToken('corner-radius-medium-default')), // 8px
295
+ lg: pxToRem(getToken('corner-radius-large-default')), // 10px
296
+ xl: pxToRem(getToken('corner-radius-extra-large-default')), // 16px
297
+ full: '9999px',
298
+ pill: 'calc(self(height, self(minHeight, 9999px)) / 2)',
299
+ control: fontRelative(8), // automatic based on font size (e.g. t-shirt size logarithmic scale)
300
+ 'control-sm': fontRelative(4)
301
+ };
302
+
303
+ type GridTrack = 'none' | 'subgrid' | (string & {}) | readonly GridTrackSize[];
304
+ type GridTrackSize = 'auto' | 'min-content' | 'max-content' | `${number}fr` | `minmax(${string}, ${string})` | keyof typeof baseSpacing | (string & {});
305
+
306
+ let gridTrack = (value: GridTrack) => {
307
+ if (typeof value === 'string') {
308
+ return value;
309
+ }
310
+ return value.map(v => gridTrackSize(v)).join(' ');
311
+ };
312
+
313
+ let gridTrackSize = (value: GridTrackSize) => {
314
+ // @ts-ignore
315
+ return value in baseSpacing ? baseSpacing[value] : value;
316
+ };
317
+
318
+ const transitionProperty = {
319
+ default: 'color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, translate, scale, rotate, filter, backdrop-filter',
320
+ colors: 'color, background-color, border-color, text-decoration-color, fill, stroke',
321
+ opacity: 'opacity',
322
+ shadow: 'box-shadow',
323
+ transform: 'transform, translate, scale, rotate',
324
+ all: 'all',
325
+ none: 'none'
326
+ };
327
+
328
+ // TODO
329
+ const timingFunction = {
330
+ default: 'cubic-bezier(0.45, 0, 0.4, 1)',
331
+ linear: 'linear',
332
+ in: 'cubic-bezier(0.5, 0, 1, 1)',
333
+ out: 'cubic-bezier(0, 0, 0.40, 1)',
334
+ 'in-out': 'cubic-bezier(0.45, 0, 0.4, 1)'
335
+ };
336
+
337
+ // TODO: do these need tokens or are arbitrary values ok?
338
+ let durationProperty = createArbitraryProperty((value: number | string, property) => ({[property]: typeof value === 'number' ? value + 'ms' : value}));
339
+
340
+ // const colorWithAlpha = createColorProperty(color);
341
+
342
+ const fontWeightBase = {
343
+ light: '300',
344
+ // TODO: spectrum calls this "regular" but CSS calls it "normal". We also call other properties "default". What do we want to match?
345
+ normal: '400',
346
+ medium: '500',
347
+ bold: '700',
348
+ 'extra-bold': '800',
349
+ black: '900'
350
+ } as const;
351
+
352
+ const i18nFonts = {
353
+ ':lang(ar)': 'myriad-arabic, ui-sans-serif, system-ui, sans-serif',
354
+ ':lang(he)': 'myriad-hebrew, ui-sans-serif, system-ui, sans-serif',
355
+ ':lang(ja)': "adobe-clean-han-japanese, 'Hiragino Kaku Gothic ProN', 'ヒラギノ角ゴ ProN W3', Osaka, YuGothic, 'Yu Gothic', 'メイリオ', Meiryo, 'MS Pゴシック', 'MS PGothic', sans-serif",
356
+ ':lang(ko)': "adobe-clean-han-korean, source-han-korean, 'Malgun Gothic', 'Apple Gothic', sans-serif",
357
+ ':lang(zh)': "adobe-clean-han-traditional, source-han-traditional, 'MingLiu', 'Heiti TC Light', sans-serif",
358
+ // TODO: are these fallbacks supposed to be different than above?
359
+ ':lang(zh-hant)': "adobe-clean-han-traditional, source-han-traditional, 'MingLiu', 'Microsoft JhengHei UI', 'Microsoft JhengHei', 'Heiti TC Light', sans-serif",
360
+ ':lang(zh-Hans, zh-CN, zh-SG)': "adobe-clean-han-simplified-c, source-han-simplified-c, 'SimSun', 'Heiti SC Light', sans-serif"
361
+ } as const;
362
+
363
+ const fontSize = {
364
+ // The default font size scale is for use within UI components.
365
+ 'ui-xs': fontSizeToken('font-size-50'),
366
+ 'ui-sm': fontSizeToken('font-size-75'),
367
+ ui: fontSizeToken('font-size-100'),
368
+ 'ui-lg': fontSizeToken('font-size-200'),
369
+ 'ui-xl': fontSizeToken('font-size-300'),
370
+ 'ui-2xl': fontSizeToken('font-size-400'),
371
+ 'ui-3xl': fontSizeToken('font-size-500'),
372
+
373
+ control: {
374
+ default: fontSizeToken('font-size-100'),
375
+ size: {
376
+ XS: fontSizeToken('font-size-50'),
377
+ S: fontSizeToken('font-size-75'),
378
+ L: fontSizeToken('font-size-200'),
379
+ XL: fontSizeToken('font-size-300')
380
+ }
381
+ },
382
+
383
+ 'heading-2xs': fontSizeToken('heading-size-xxs'),
384
+ 'heading-xs': fontSizeToken('heading-size-xs'),
385
+ 'heading-sm': fontSizeToken('heading-size-s'),
386
+ heading: fontSizeToken('heading-size-m'),
387
+ 'heading-lg': fontSizeToken('heading-size-l'),
388
+ 'heading-xl': fontSizeToken('heading-size-xl'),
389
+ 'heading-2xl': fontSizeToken('heading-size-xxl'),
390
+ 'heading-3xl': fontSizeToken('heading-size-xxxl'),
391
+
392
+ 'title-xs': fontSizeToken('title-size-xs'),
393
+ 'title-sm': fontSizeToken('title-size-s'),
394
+ title: fontSizeToken('title-size-m'),
395
+ 'title-lg': fontSizeToken('title-size-l'),
396
+ 'title-xl': fontSizeToken('title-size-xl'),
397
+ 'title-2xl': fontSizeToken('title-size-xxl'),
398
+ 'title-3xl': fontSizeToken('title-size-xxxl'),
399
+
400
+ // Body is for large blocks of text, e.g. paragraphs, not in UI components.
401
+ 'body-2xs': fontSizeToken('font-size-50'), // TODO: seems like there is no token for this
402
+ 'body-xs': fontSizeToken('body-size-xs'),
403
+ 'body-sm': fontSizeToken('body-size-s'),
404
+ body: fontSizeToken('body-size-m'),
405
+ 'body-lg': fontSizeToken('body-size-l'),
406
+ 'body-xl': fontSizeToken('body-size-xl'),
407
+ 'body-2xl': fontSizeToken('body-size-xxl'),
408
+ 'body-3xl': fontSizeToken('body-size-xxxl'),
409
+
410
+ 'detail-sm': fontSizeToken('detail-size-s'),
411
+ detail: fontSizeToken('detail-size-m'),
412
+ 'detail-lg': fontSizeToken('detail-size-l'),
413
+ 'detail-xl': fontSizeToken('detail-size-xl'),
414
+
415
+ 'code-xs': fontSizeToken('code-size-xs'),
416
+ 'code-sm': fontSizeToken('code-size-s'),
417
+ code: fontSizeToken('code-size-m'),
418
+ 'code-lg': fontSizeToken('code-size-l'),
419
+ 'code-xl': fontSizeToken('code-size-xl')
420
+ } as const;
421
+
422
+ export const style = createTheme({
423
+ properties: {
424
+ // colors
425
+ color: createColorProperty({
426
+ ...color,
427
+ accent: {
428
+ default: colorToken('accent-content-color-default'),
429
+ isHovered: colorToken('accent-content-color-hover'),
430
+ isFocusVisible: colorToken('accent-content-color-key-focus'),
431
+ isPressed: colorToken('accent-content-color-down')
432
+ // isSelected: colorToken('accent-content-color-selected'), // same as pressed
433
+ },
434
+ neutral: {
435
+ default: colorToken('neutral-content-color-default'),
436
+ isHovered: colorToken('neutral-content-color-hover'),
437
+ isFocusVisible: colorToken('neutral-content-color-key-focus'),
438
+ isPressed: colorToken('neutral-content-color-down')
439
+ // isSelected: colorToken('neutral-subdued-content-color-selected'),
440
+ },
441
+ 'neutral-subdued': {
442
+ default: colorToken('neutral-subdued-content-color-default'),
443
+ isHovered: colorToken('neutral-subdued-content-color-hover'),
444
+ isFocusVisible: colorToken('neutral-subdued-content-color-key-focus'),
445
+ isPressed: colorToken('neutral-subdued-content-color-down')
446
+ // isSelected: colorToken('neutral-subdued-content-color-selected'),
447
+ },
448
+ negative: {
449
+ default: colorToken('negative-content-color-default'),
450
+ isHovered: colorToken('negative-content-color-hover'),
451
+ isFocusVisible: colorToken('negative-content-color-key-focus'),
452
+ isPressed: colorToken('negative-content-color-down')
453
+ },
454
+ disabled: {
455
+ default: colorToken('disabled-content-color')
456
+ // forcedColors: 'GrayText'
457
+ },
458
+ heading: colorToken('heading-color'),
459
+ title: colorToken('title-color'),
460
+ body: colorToken('body-color'),
461
+ detail: colorToken('detail-color'),
462
+ code: colorToken('code-color')
463
+ }),
464
+ backgroundColor: createColorProperty({
465
+ ...color,
466
+ accent: {
467
+ default: weirdColorToken('accent-background-color-default'),
468
+ isHovered: weirdColorToken('accent-background-color-hover'),
469
+ isFocusVisible: weirdColorToken('accent-background-color-key-focus'),
470
+ isPressed: weirdColorToken('accent-background-color-down')
471
+ },
472
+ neutral: {
473
+ default: colorToken('neutral-background-color-default'),
474
+ isHovered: colorToken('neutral-background-color-hover'),
475
+ isFocusVisible: colorToken('neutral-background-color-key-focus'),
476
+ isPressed: colorToken('neutral-background-color-down')
477
+ },
478
+ 'neutral-subdued': {
479
+ default: weirdColorToken('neutral-subdued-background-color-default'),
480
+ isHovered: weirdColorToken('neutral-subdued-background-color-hover'),
481
+ isFocusVisible: weirdColorToken('neutral-subdued-background-color-key-focus'),
482
+ isPressed: weirdColorToken('neutral-subdued-background-color-down')
483
+ },
484
+ 'neutral-subtle': colorToken('neutral-subtle-background-color-default'),
485
+ negative: {
486
+ default: weirdColorToken('negative-background-color-default'),
487
+ isHovered: weirdColorToken('negative-background-color-hover'),
488
+ isFocusVisible: weirdColorToken('negative-background-color-key-focus'),
489
+ isPressed: weirdColorToken('negative-background-color-down')
490
+ },
491
+ 'negative-subtle': colorToken('negative-subtle-background-color-default'),
492
+ informative: {
493
+ default: weirdColorToken('informative-background-color-default'),
494
+ isHovered: weirdColorToken('informative-background-color-hover'),
495
+ isFocusVisible: weirdColorToken('informative-background-color-key-focus'),
496
+ isPressed: weirdColorToken('informative-background-color-down')
497
+ },
498
+ 'informative-subtle': colorToken('informative-subtle-background-color-default'),
499
+ positive: {
500
+ default: weirdColorToken('positive-background-color-default'),
501
+ isHovered: weirdColorToken('positive-background-color-hover'),
502
+ isFocusVisible: weirdColorToken('positive-background-color-key-focus'),
503
+ isPressed: weirdColorToken('positive-background-color-down')
504
+ },
505
+ 'positive-subtle': colorToken('positive-subtle-background-color-default'),
506
+ notice: weirdColorToken('notice-background-color-default'),
507
+ 'notice-subtle': colorToken('notice-subtle-background-color-default'),
508
+ gray: weirdColorToken('gray-background-color-default'),
509
+ red: weirdColorToken('red-background-color-default'),
510
+ orange: weirdColorToken('orange-background-color-default'),
511
+ yellow: weirdColorToken('yellow-background-color-default'),
512
+ chartreuse: weirdColorToken('chartreuse-background-color-default'),
513
+ celery: weirdColorToken('celery-background-color-default'),
514
+ green: weirdColorToken('green-background-color-default'),
515
+ seafoam: weirdColorToken('seafoam-background-color-default'),
516
+ cyan: weirdColorToken('cyan-background-color-default'),
517
+ blue: weirdColorToken('blue-background-color-default'),
518
+ indigo: weirdColorToken('indigo-background-color-default'),
519
+ purple: weirdColorToken('purple-background-color-default'),
520
+ fuchsia: weirdColorToken('fuchsia-background-color-default'),
521
+ magenta: weirdColorToken('magenta-background-color-default'),
522
+ pink: weirdColorToken('pink-background-color-default'),
523
+ turquoise: weirdColorToken('turquoise-background-color-default'),
524
+ cinnamon: weirdColorToken('cinnamon-background-color-default'),
525
+ brown: weirdColorToken('brown-background-color-default'),
526
+ silver: weirdColorToken('silver-background-color-default'),
527
+ disabled: colorToken('disabled-background-color'),
528
+ base: colorToken('background-base-color'),
529
+ 'layer-1': colorToken('background-layer-1-color'),
530
+ 'layer-2': weirdColorToken('background-layer-2-color'),
531
+ pasteboard: weirdColorToken('background-pasteboard-color'),
532
+ elevated: weirdColorToken('background-elevated-color')
533
+ }),
534
+ borderColor: createColorProperty({
535
+ ...color,
536
+ negative: {
537
+ default: colorToken('negative-border-color-default'),
538
+ isHovered: colorToken('negative-border-color-hover'),
539
+ isFocusVisible: colorToken('negative-border-color-key-focus'),
540
+ isPressed: colorToken('negative-border-color-down')
541
+ },
542
+ disabled: colorToken('disabled-border-color')
543
+ // forcedColors: 'GrayText'
544
+
545
+ }),
546
+ outlineColor: createColorProperty({
547
+ ...color,
548
+ 'focus-ring': {
549
+ default: colorToken('focus-indicator-color'),
550
+ forcedColors: 'Highlight'
551
+ }
552
+ }),
553
+ // textDecorationColor: colorWithAlpha,
554
+ // accentColor: colorWithAlpha,
555
+ // caretColor: colorWithAlpha,
556
+ fill: createColorProperty({
557
+ none: 'none',
558
+ currentColor: 'currentColor',
559
+ accent: weirdColorToken('accent-visual-color'),
560
+ neutral: weirdColorToken('neutral-visual-color'),
561
+ negative: weirdColorToken('negative-visual-color'),
562
+ informative: weirdColorToken('informative-visual-color'),
563
+ positive: weirdColorToken('positive-visual-color'),
564
+ notice: weirdColorToken('notice-visual-color'),
565
+ gray: weirdColorToken('gray-visual-color'),
566
+ red: weirdColorToken('red-visual-color'),
567
+ orange: weirdColorToken('orange-visual-color'),
568
+ yellow: weirdColorToken('yellow-visual-color'),
569
+ chartreuse: weirdColorToken('chartreuse-visual-color'),
570
+ celery: weirdColorToken('celery-visual-color'),
571
+ green: weirdColorToken('green-visual-color'),
572
+ seafoam: weirdColorToken('seafoam-visual-color'),
573
+ cyan: weirdColorToken('cyan-visual-color'),
574
+ blue: weirdColorToken('blue-visual-color'),
575
+ indigo: weirdColorToken('indigo-visual-color'),
576
+ purple: weirdColorToken('purple-visual-color'),
577
+ fuchsia: weirdColorToken('fuchsia-visual-color'),
578
+ magenta: weirdColorToken('magenta-visual-color'),
579
+ pink: weirdColorToken('pink-visual-color'),
580
+ turquoise: weirdColorToken('turquoise-visual-color'),
581
+ cinnamon: weirdColorToken('cinnamon-visual-color'),
582
+ brown: weirdColorToken('brown-visual-color'),
583
+ silver: weirdColorToken('silver-visual-color'),
584
+ ...color
585
+ }),
586
+ stroke: createColorProperty({
587
+ none: 'none',
588
+ currentColor: 'currentColor',
589
+ ...color
590
+ }),
591
+
592
+ // dimensions
593
+ borderSpacing: baseSpacing, // TODO: separate x and y
594
+ flexBasis: {
595
+ auto: 'auto',
596
+ full: '100%',
597
+ ...baseSpacing
598
+ },
599
+ rowGap: spacing,
600
+ columnGap: spacing,
601
+ height,
602
+ width,
603
+ containIntrinsicWidth: width,
604
+ containIntrinsicHeight: height,
605
+ minHeight: height,
606
+ maxHeight: {
607
+ ...height,
608
+ none: 'none'
609
+ },
610
+ minWidth: width,
611
+ maxWidth: {
612
+ ...width,
613
+ none: 'none'
614
+ },
615
+ borderStartWidth: createRenamedProperty('borderInlineStartWidth', borderWidth),
616
+ borderEndWidth: createRenamedProperty('borderInlineEndWidth', borderWidth),
617
+ borderTopWidth: borderWidth,
618
+ borderBottomWidth: borderWidth,
619
+ borderStyle: ['solid', 'dashed', 'dotted', 'double', 'hidden', 'none'] as const,
620
+ strokeWidth: {
621
+ 0: '0',
622
+ 1: '1',
623
+ 2: '2'
624
+ },
625
+ marginStart: createRenamedProperty('marginInlineStart', margin),
626
+ marginEnd: createRenamedProperty('marginInlineEnd', margin),
627
+ marginTop: margin,
628
+ marginBottom: margin,
629
+ paddingStart: createRenamedProperty('paddingInlineStart', spacing),
630
+ paddingEnd: createRenamedProperty('paddingInlineEnd', spacing),
631
+ paddingTop: spacing,
632
+ paddingBottom: spacing,
633
+ scrollMarginStart: createRenamedProperty('scrollMarginInlineStart', baseSpacing),
634
+ scrollMarginEnd: createRenamedProperty('scrollMarginInlineEnd', baseSpacing),
635
+ scrollMarginTop: baseSpacing,
636
+ scrollMarginBottom: baseSpacing,
637
+ scrollPaddingStart: createRenamedProperty('scrollPaddingInlineStart', baseSpacing),
638
+ scrollPaddingEnd: createRenamedProperty('scrollPaddingInlineEnd', baseSpacing),
639
+ scrollPaddingTop: baseSpacing,
640
+ scrollPaddingBottom: baseSpacing,
641
+ textIndent: baseSpacing,
642
+ translateX: createMappedProperty(value => ({
643
+ '--translateX': value,
644
+ translate: 'var(--translateX, 0) var(--translateY, 0)'
645
+ }), translate),
646
+ translateY: createMappedProperty(value => ({
647
+ '--translateY': value,
648
+ translate: 'var(--translateX, 0) var(--translateY, 0)'
649
+ }), translate),
650
+ rotate: createArbitraryProperty((value: number | `${number}deg` | `${number}rad` | `${number}grad` | `${number}turn`, property) => ({[property]: typeof value === 'number' ? `${value}deg` : value})),
651
+ scale: createArbitraryProperty<number>(),
652
+ transform: createArbitraryProperty<string>(),
653
+ position: ['absolute', 'fixed', 'relative', 'sticky', 'static'] as const,
654
+ insetStart: createRenamedProperty('insetInlineStart', inset),
655
+ insetEnd: createRenamedProperty('insetInlineEnd', inset),
656
+ top: inset,
657
+ left: inset,
658
+ bottom: inset,
659
+ right: inset,
660
+ aspectRatio: {
661
+ auto: 'auto',
662
+ square: '1 / 1',
663
+ video: '16 / 9'
664
+ },
665
+
666
+ // text
667
+ fontFamily: {
668
+ sans: {
669
+ default: 'adobe-clean-variable, adobe-clean, ui-sans-serif, system-ui, sans-serif',
670
+ ...i18nFonts
671
+ },
672
+ serif: {
673
+ default: 'adobe-clean-serif, "Source Serif", Georgia, serif',
674
+ ...i18nFonts
675
+ },
676
+ code: 'source-code-pro, "Source Code Pro", Monaco, monospace'
677
+ },
678
+ fontSize,
679
+ fontWeight: createMappedProperty((value, property) => {
680
+ if (property === 'fontWeight') {
681
+ return {
682
+ // Set font-variation-settings in addition to font-weight to work around typekit issue.
683
+ fontVariationSettings: value === 'inherit' ? 'inherit' : `"wght" ${value}`,
684
+ fontWeight: value as any,
685
+ fontSynthesisWeight: 'none'
686
+ };
687
+ }
688
+
689
+ return {[property]: value};
690
+ }, {
691
+ ...fontWeightBase,
692
+ heading: {
693
+ default: fontWeightBase[getToken('heading-sans-serif-font-weight') as keyof typeof fontWeightBase],
694
+ ':lang(ja, ko, zh, zh-Hant, zh-Hans)': fontWeightBase[getToken('heading-cjk-font-weight') as keyof typeof fontWeightBase]
695
+ },
696
+ title: {
697
+ default: fontWeightBase[getToken('title-sans-serif-font-weight') as keyof typeof fontWeightBase],
698
+ ':lang(ja, ko, zh, zh-Hant, zh-Hans)': fontWeightBase[getToken('title-cjk-font-weight') as keyof typeof fontWeightBase]
699
+ },
700
+ detail: {
701
+ default: fontWeightBase[getToken('detail-sans-serif-font-weight') as keyof typeof fontWeightBase],
702
+ ':lang(ja, ko, zh, zh-Hant, zh-Hans)': fontWeightBase[getToken('detail-cjk-font-weight') as keyof typeof fontWeightBase]
703
+ }
704
+ }),
705
+ lineHeight: {
706
+ // See https://spectrum.corp.adobe.com/page/typography/#Line-height
707
+ ui: {
708
+ default: getToken('line-height-100'),
709
+ ':lang(ja, ko, zh, zh-Hant, zh-Hans)': getToken('line-height-200')
710
+ },
711
+ heading: {
712
+ default: getToken('heading-line-height'),
713
+ ':lang(ja, ko, zh, zh-Hant, zh-Hans)': getToken('heading-cjk-line-height')
714
+ },
715
+ title: {
716
+ default: getToken('title-line-height'),
717
+ ':lang(ja, ko, zh, zh-Hant, zh-Hans)': getToken('title-cjk-line-height')
718
+ },
719
+ body: {
720
+ default: getToken('body-line-height'),
721
+ ':lang(ja, ko, zh, zh-Hant, zh-Hans)': getToken('body-cjk-line-height')
722
+ },
723
+ detail: {
724
+ default: getToken('detail-line-height'),
725
+ ':lang(ja, ko, zh, zh-Hant, zh-Hans)': getToken('detail-cjk-line-height')
726
+ },
727
+ code: {
728
+ default: getToken('code-line-height'),
729
+ ':lang(ja, ko, zh, zh-Hant, zh-Hans)': getToken('code-cjk-line-height')
730
+ }
731
+ },
732
+ listStyleType: ['none', 'dist', 'decimal'] as const,
733
+ listStylePosition: ['inside', 'outside'] as const,
734
+ textTransform: ['uppercase', 'lowercase', 'capitalize', 'none'] as const,
735
+ textAlign: ['start', 'center', 'end', 'justify'] as const,
736
+ verticalAlign: ['baseline', 'top', 'middle', 'bottom', 'text-top', 'text-bottom', 'sub', 'super'] as const,
737
+ textDecoration: createMappedProperty((value) => ({
738
+ textDecoration: value === 'none' ? 'none' : `${value} ${getToken('text-underline-thickness')}`,
739
+ textUnderlineOffset: value === 'underline' ? getToken('text-underline-gap') : undefined
740
+ }), ['underline', 'overline', 'line-through', 'none'] as const),
741
+ textOverflow: ['ellipsis', 'clip'] as const,
742
+ lineClamp: createArbitraryProperty((value: number) => ({
743
+ overflow: 'hidden',
744
+ display: '-webkit-box',
745
+ '-webkit-box-orient': 'vertical',
746
+ '-webkit-line-clamp': value
747
+ })),
748
+ hyphens: ['none', 'manual', 'auto'] as const,
749
+ whiteSpace: ['normal', 'nowrap', 'pre', 'pre-line', 'pre-wrap', 'break-spaces'] as const,
750
+ textWrap: ['wrap', 'nowrap', 'balance', 'pretty'] as const,
751
+ wordBreak: ['normal', 'break-all', 'keep-all'] as const, // also overflowWrap??
752
+ boxDecorationBreak: ['slice', 'clone'] as const,
753
+
754
+ // effects
755
+ boxShadow: {
756
+ emphasized: `${getToken('drop-shadow-emphasized-default-x')} ${getToken('drop-shadow-emphasized-default-y')} ${getToken('drop-shadow-emphasized-default-blur')} ${colorToken('drop-shadow-emphasized-default-color')}`,
757
+ elevated: `${getToken('drop-shadow-elevated-x')} ${getToken('drop-shadow-elevated-y')} ${getToken('drop-shadow-elevated-blur')} ${colorToken('drop-shadow-elevated-color')}`,
758
+ dragged: `${getToken('drop-shadow-dragged-x')} ${getToken('drop-shadow-dragged-y')} ${getToken('drop-shadow-dragged-blur')} ${colorToken('drop-shadow-dragged-color')}`,
759
+ none: 'none'
760
+ },
761
+ filter: {
762
+ emphasized: `drop-shadow(${getToken('drop-shadow-emphasized-default-x')} ${getToken('drop-shadow-emphasized-default-y')} ${getToken('drop-shadow-emphasized-default-blur')} ${colorToken('drop-shadow-emphasized-default-color')})`,
763
+ elevated: `drop-shadow(${getToken('drop-shadow-elevated-x')} ${getToken('drop-shadow-elevated-y')} ${getToken('drop-shadow-elevated-blur')} ${colorToken('drop-shadow-elevated-color')})`,
764
+ dragged: `drop-shadow${getToken('drop-shadow-dragged-x')} ${getToken('drop-shadow-dragged-y')} ${getToken('drop-shadow-dragged-blur')} ${colorToken('drop-shadow-dragged-color')}`,
765
+ none: 'none'
766
+ },
767
+ borderTopStartRadius: createRenamedProperty('borderStartStartRadius', radius),
768
+ borderTopEndRadius: createRenamedProperty('borderStartEndRadius', radius),
769
+ borderBottomStartRadius: createRenamedProperty('borderEndStartRadius', radius),
770
+ borderBottomEndRadius: createRenamedProperty('borderEndEndRadius', radius),
771
+ forcedColorAdjust: ['auto', 'none'] as const,
772
+ colorScheme: ['light', 'dark', 'light dark'] as const,
773
+ backgroundImage: createArbitraryProperty<string>(),
774
+ // TODO: do we need separate x and y properties?
775
+ backgroundPosition: ['bottom', 'center', 'left', 'left bottom', 'left top', 'right', 'right bottom', 'right top', 'top'] as const,
776
+ backgroundSize: ['auto', 'cover', 'contain'] as const,
777
+ backgroundAttachment: ['fixed', 'local', 'scroll'] as const,
778
+ backgroundClip: ['border-box', 'padding-box', 'content-box', 'text'] as const,
779
+ backgroundRepeat: ['repeat', 'no-repeat', 'repeat-x', 'repeat-y', 'round', 'space'] as const,
780
+ backgroundOrigin: ['border-box', 'padding-box', 'content-box'] as const,
781
+ backgroundBlendMode: ['normal', 'multiply', 'screen', 'overlay', 'darken', 'lighten', 'color-dodge', 'color-burn', 'hard-light', 'soft-light', 'difference', 'exclusion', 'hue', 'saturation', 'color', 'luminosity'] as const,
782
+ mixBlendMode: ['normal', 'multiply', 'screen', 'overlay', 'darken', 'lighten', 'color-dodge', 'color-burn', 'hard-light', 'soft-light', 'difference', 'exclusion', 'hue', 'saturation', 'color', 'luminosity', 'plus-darker', 'plus-lighter'] as const,
783
+ opacity: createArbitraryProperty<number>(),
784
+
785
+ outlineStyle: ['none', 'solid', 'dashed', 'dotted', 'double', 'inset'] as const,
786
+ outlineOffset: createArbitraryProperty<number>((v, property) => ({[property]: `${v}px`})),
787
+ outlineWidth: borderWidth,
788
+
789
+ transition: createRenamedProperty('transitionProperty', transitionProperty),
790
+ transitionDelay: durationProperty,
791
+ transitionDuration: durationProperty,
792
+ transitionTimingFunction: timingFunction,
793
+ animation: createArbitraryProperty((value: string, property) => ({[property === 'animation' ? 'animationName' : property]: value})),
794
+ animationDuration: durationProperty,
795
+ animationDelay: durationProperty,
796
+ animationDirection: ['normal', 'reverse', 'alternate', 'alternate-reverse'] as const,
797
+ animationFillMode: ['none', 'forwards', 'backwards', 'both'] as const,
798
+ animationIterationCount: createArbitraryProperty<string>(),
799
+ animationTimingFunction: timingFunction,
800
+
801
+ // layout
802
+ display: ['block', 'inline-block', 'inline', 'flex', 'inline-flex', 'grid', 'inline-grid', 'contents', 'list-item', 'none'] as const, // tables?
803
+ alignContent: ['normal', 'center', 'start', 'end', 'space-between', 'space-around', 'space-evenly', 'baseline', 'stretch'] as const,
804
+ alignItems: ['start', 'end', 'center', 'baseline', 'stretch'] as const,
805
+ justifyContent: ['normal', 'start', 'end', 'center', 'space-between', 'space-around', 'space-evenly', 'stretch'] as const,
806
+ justifyItems: ['start', 'end', 'center', 'stretch'] as const,
807
+ alignSelf: ['auto', 'start', 'end', 'center', 'stretch', 'baseline'] as const,
808
+ justifySelf: ['auto', 'start', 'end', 'center', 'stretch'] as const,
809
+ flexDirection: ['row', 'column', 'row-reverse', 'column-reverse'] as const,
810
+ flexWrap: ['wrap', 'wrap-reverse', 'nowrap'] as const,
811
+ flexShrink: createArbitraryProperty<CSS.Property.FlexShrink>(),
812
+ flexGrow: createArbitraryProperty<CSS.Property.FlexGrow>(),
813
+ gridColumnStart: createArbitraryProperty<CSS.Property.GridColumnStart>(),
814
+ gridColumnEnd: createArbitraryProperty<CSS.Property.GridColumnEnd>(),
815
+ gridRowStart: createArbitraryProperty<CSS.Property.GridRowStart>(),
816
+ gridRowEnd: createArbitraryProperty<CSS.Property.GridRowEnd>(),
817
+ gridAutoFlow: ['row', 'column', 'dense', 'row dense', 'column dense'] as const,
818
+ gridAutoRows: createArbitraryProperty((value: GridTrackSize, property) => ({[property]: gridTrackSize(value)})),
819
+ gridAutoColumns: createArbitraryProperty((value: GridTrackSize, property) => ({[property]: gridTrackSize(value)})),
820
+ gridTemplateColumns: createArbitraryProperty((value: GridTrack, property) => ({[property]: gridTrack(value)})),
821
+ gridTemplateRows: createArbitraryProperty((value: GridTrack, property) => ({[property]: gridTrack(value)})),
822
+ gridTemplateAreas: createArbitraryProperty((value: readonly string[], property) => ({[property]: value.map(v => `"${v}"`).join('')})),
823
+ float: ['inline-start', 'inline-end', 'right', 'left', 'none'] as const,
824
+ clear: ['inline-start', 'inline-end', 'left', 'right', 'both', 'none'] as const,
825
+ contain: ['none', 'strict', 'content', 'size', 'inline-size', 'layout', 'style', 'paint'] as const,
826
+ boxSizing: ['border-box', 'content-box'] as const,
827
+ tableLayout: ['auto', 'fixed'] as const,
828
+ captionSide: ['top', 'bottom'] as const,
829
+ borderCollapse: ['collapse', 'separate'] as const,
830
+ columns: {
831
+ auto: 'auto',
832
+ 1: '1',
833
+ 2: '2',
834
+ 3: '3',
835
+ 4: '4',
836
+ 5: '5',
837
+ 6: '6',
838
+ 7: '7',
839
+ 8: '8',
840
+ 9: '9',
841
+ 10: '10',
842
+ 11: '11',
843
+ 12: '12',
844
+ // TODO: what should these sizes be?
845
+ '3xs': '16rem',
846
+ '2xs': '18rem',
847
+ xs: '20rem',
848
+ sm: '24rem',
849
+ md: '28rem',
850
+ lg: '32rem',
851
+ xl: '36rem',
852
+ '2xl': '42rem',
853
+ '3xl': '48rem',
854
+ '4xl': '56rem',
855
+ '5xl': '64rem',
856
+ '6xl': '72rem',
857
+ '7xl': '80rem'
858
+ },
859
+ breakBefore: ['auto', 'avoid', 'all', 'avoid-page', 'page', 'left', 'right', 'column'] as const,
860
+ breakInside: ['auto', 'avoid', 'avoid-page', 'avoid-column'] as const,
861
+ breakAfter: ['auto', 'avoid', 'all', 'avoid-page', 'page', 'left', 'right', 'column'] as const,
862
+ overflowX: ['auto', 'hidden', 'clip', 'visible', 'scroll'] as const,
863
+ overflowY: ['auto', 'hidden', 'clip', 'visible', 'scroll'] as const,
864
+ overscrollBehaviorX: ['auto', 'contain', 'none'] as const,
865
+ overscrollBehaviorY: ['auto', 'contain', 'none'] as const,
866
+ scrollBehavior: ['auto', 'smooth'] as const,
867
+ order: createArbitraryProperty<number>(),
868
+
869
+ pointerEvents: ['none', 'auto'] as const,
870
+ touchAction: ['auto', 'none', 'pan-x', 'pan-y', 'manipulation', 'pinch-zoom'] as const,
871
+ userSelect: ['none', 'text', 'all', 'auto'] as const,
872
+ visibility: ['visible', 'hidden', 'collapse'] as const,
873
+ isolation: ['isolate', 'auto'] as const,
874
+ transformOrigin: ['center', 'top', 'top right', 'right', 'bottom right', 'bottom', 'bottom left', 'left', 'top right'] as const,
875
+ cursor: ['auto', 'default', 'pointer', 'wait', 'text', 'move', 'help', 'not-allowed', 'none', 'context-menu', 'progress', 'cell', 'crosshair', 'vertical-text', 'alias', 'copy', 'no-drop', 'grab', 'grabbing', 'all-scroll', 'col-resize', 'row-resize', 'n-resize', 'e-resize', 's-resize', 'w-resize', 'ne-resize', 'nw-resize', 'se-resize', 'ew-resize', 'ns-resize', 'nesw-resize', 'nwse-resize', 'zoom-in', 'zoom-out'] as const,
876
+ resize: ['none', 'vertical', 'horizontal', 'both'] as const,
877
+ scrollSnapType: ['x', 'y', 'both', 'x mandatory', 'y mandatory', 'both mandatory'] as const,
878
+ scrollSnapAlign: ['start', 'end', 'center', 'none'] as const,
879
+ scrollSnapStop: ['normal', 'always'] as const,
880
+ appearance: ['none', 'auto'] as const,
881
+ objectFit: ['contain', 'cover', 'fill', 'none', 'scale-down'] as const,
882
+ objectPosition: ['bottom', 'center', 'left', 'left bottom', 'left top', 'right', 'right bottom', 'right top', 'top'] as const,
883
+ willChange: ['auto', 'scroll-position', 'contents', 'transform'] as const,
884
+ zIndex: createArbitraryProperty<number>(),
885
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
886
+ disableTapHighlight: createArbitraryProperty((_value: true) => ({
887
+ '-webkit-tap-highlight-color': 'rgba(0,0,0,0)'
888
+ }))
889
+ },
890
+ shorthands: {
891
+ padding: ['paddingTop', 'paddingBottom', 'paddingStart', 'paddingEnd'] as const,
892
+ paddingX: ['paddingStart', 'paddingEnd'] as const,
893
+ paddingY: ['paddingTop', 'paddingBottom'] as const,
894
+ margin: ['marginTop', 'marginBottom', 'marginStart', 'marginEnd'] as const,
895
+ marginX: ['marginStart', 'marginEnd'] as const,
896
+ marginY: ['marginTop', 'marginBottom'] as const,
897
+ scrollPadding: ['scrollPaddingTop', 'scrollPaddingBottom', 'scrollPaddingStart', 'scrollPaddingEnd'] as const,
898
+ scrollPaddingX: ['scrollPaddingStart', 'scrollPaddingEnd'] as const,
899
+ scrollPaddingY: ['scrollPaddingTop', 'scrollPaddingBottom'] as const,
900
+ scrollMargin: ['scrollMarginTop', 'scrollMarginBottom', 'scrollMarginStart', 'scrollMarginEnd'] as const,
901
+ scrollMarginX: ['scrollMarginStart', 'scrollMarginEnd'] as const,
902
+ scrollMarginY: ['scrollMarginTop', 'scrollMarginBottom'] as const,
903
+ borderWidth: ['borderTopWidth', 'borderBottomWidth', 'borderStartWidth', 'borderEndWidth'] as const,
904
+ borderXWidth: ['borderStartWidth', 'borderEndWidth'] as const,
905
+ borderYWidth: ['borderTopWidth', 'borderBottomWidth'] as const,
906
+ borderRadius: ['borderTopStartRadius', 'borderTopEndRadius', 'borderBottomStartRadius', 'borderBottomEndRadius'] as const,
907
+ borderTopRadius: ['borderTopStartRadius', 'borderTopEndRadius'] as const,
908
+ borderBottomRadius: ['borderBottomStartRadius', 'borderBottomEndRadius'] as const,
909
+ borderStartRadius: ['borderTopStartRadius', 'borderBottomStartRadius'] as const,
910
+ borderEndRadius: ['borderTopEndRadius', 'borderBottomEndRadius'] as const,
911
+ translate: ['translateX', 'translateY'] as const,
912
+ inset: ['top', 'bottom', 'insetStart', 'insetEnd'] as const,
913
+ insetX: ['insetStart', 'insetEnd'] as const,
914
+ insetY: ['top', 'bottom'] as const,
915
+ placeItems: ['alignItems', 'justifyItems'] as const,
916
+ placeContent: ['alignContent', 'justifyContent'] as const,
917
+ placeSelf: ['alignSelf', 'justifySelf'] as const,
918
+ gap: ['rowGap', 'columnGap'] as const,
919
+ size: ['width', 'height'] as const,
920
+ minSize: ['minWidth', 'minHeight'] as const,
921
+ maxSize: ['maxWidth', 'maxHeight'] as const,
922
+ overflow: ['overflowX', 'overflowY'] as const,
923
+ overscrollBehavior: ['overscrollBehaviorX', 'overscrollBehaviorY'] as const,
924
+ gridArea: ['gridColumnStart', 'gridColumnEnd', 'gridRowStart', 'gridRowEnd'] as const,
925
+ transition: (value: keyof typeof transitionProperty) => ({
926
+ transition: value,
927
+ transitionDuration: 150,
928
+ transitionTimingFunction: 'default'
929
+ }),
930
+ animation: (value: string) => ({
931
+ animation: value,
932
+ animationDuration: 150,
933
+ animationTimingFunction: 'default'
934
+ }),
935
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
936
+ truncate: (_value: true) => ({
937
+ overflowX: 'hidden',
938
+ overflowY: 'hidden',
939
+ textOverflow: 'ellipsis',
940
+ whiteSpace: 'nowrap'
941
+ }),
942
+ font: (value: keyof typeof fontSize) => {
943
+ let type = value.split('-')[0];
944
+ if (type === 'control') {
945
+ type = 'ui';
946
+ }
947
+ return {
948
+ fontFamily: type === 'code' ? 'code' : 'sans',
949
+ fontSize: value,
950
+ fontWeight: type === 'heading' || type === 'title' || type === 'detail' ? type : 'normal',
951
+ lineHeight: type,
952
+ color: type === 'ui' ? 'body' : type
953
+ };
954
+ }
955
+ },
956
+ conditions: {
957
+ forcedColors: '@media (forced-colors: active)',
958
+ // This detects touch primary devices as best as we can.
959
+ // Ideally we'd use (pointer: course) but browser/device support is inconsistent.
960
+ // Samsung Android devices claim to be mice at the hardware/OS level: (any-pointer: fine), (any-hover: hover), (hover: hover), and nothing for pointer.
961
+ // More details: https://www.ctrl.blog/entry/css-media-hover-samsung.html
962
+ // iPhone matches (any-hover: none), (hover: none), and nothing for any-pointer or pointer.
963
+ // If a trackpad or Apple Pencil is connected to iPad, it matches (any-pointer: fine), (any-hover: hover), (hover: none).
964
+ // Windows tablet matches the same as iPhone. No difference when a mouse is connected.
965
+ // Windows touch laptop matches same as macOS: (any-pointer: fine), (pointer: fine), (any-hover: hover), (hover: hover).
966
+ touch: '@media not ((hover: hover) and (pointer: fine))',
967
+ // TODO
968
+ sm: '@media (min-width: 640px)',
969
+ md: '@media (min-width: 768px)',
970
+ lg: '@media (min-width: 1024px)',
971
+ xl: '@media (min-width: 1280px)',
972
+ '2xl': '@media (min-width: 1536px)'
973
+ }
974
+ });