@ohos-ports/dxos-react-ui-theme 0.6.7-beta.1

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 (196) hide show
  1. package/LICENSE +8 -0
  2. package/README.md +25 -0
  3. package/README.yml +1 -0
  4. package/dist/lib/browser/index.mjs +2300 -0
  5. package/dist/lib/browser/index.mjs.map +7 -0
  6. package/dist/lib/browser/meta.json +1 -0
  7. package/dist/plugin/node/chunk-G3RQ5GOB.cjs +712 -0
  8. package/dist/plugin/node/chunk-G3RQ5GOB.cjs.map +7 -0
  9. package/dist/plugin/node/esbuild-plugin.cjs +89 -0
  10. package/dist/plugin/node/esbuild-plugin.cjs.map +7 -0
  11. package/dist/plugin/node/meta.json +1 -0
  12. package/dist/plugin/node/plugin.cjs +77 -0
  13. package/dist/plugin/node/plugin.cjs.map +7 -0
  14. package/dist/plugin/node/theme.css +418 -0
  15. package/dist/plugin/node/theme.css.map +7 -0
  16. package/dist/types/src/config/colors.d.ts +109 -0
  17. package/dist/types/src/config/colors.d.ts.map +1 -0
  18. package/dist/types/src/config/index.d.ts +3 -0
  19. package/dist/types/src/config/index.d.ts.map +1 -0
  20. package/dist/types/src/config/resolveContent.d.ts +2 -0
  21. package/dist/types/src/config/resolveContent.d.ts.map +1 -0
  22. package/dist/types/src/config/tailwind.d.ts +9 -0
  23. package/dist/types/src/config/tailwind.d.ts.map +1 -0
  24. package/dist/types/src/esbuild-plugin.d.ts +9 -0
  25. package/dist/types/src/esbuild-plugin.d.ts.map +1 -0
  26. package/dist/types/src/index.d.ts +4 -0
  27. package/dist/types/src/index.d.ts.map +1 -0
  28. package/dist/types/src/plugin.d.ts +13 -0
  29. package/dist/types/src/plugin.d.ts.map +1 -0
  30. package/dist/types/src/styles/components/anchored-overflow.d.ts +6 -0
  31. package/dist/types/src/styles/components/anchored-overflow.d.ts.map +1 -0
  32. package/dist/types/src/styles/components/avatar.d.ts +21 -0
  33. package/dist/types/src/styles/components/avatar.d.ts.map +1 -0
  34. package/dist/types/src/styles/components/breadcrumb.d.ts +9 -0
  35. package/dist/types/src/styles/components/breadcrumb.d.ts.map +1 -0
  36. package/dist/types/src/styles/components/button.d.ts +19 -0
  37. package/dist/types/src/styles/components/button.d.ts.map +1 -0
  38. package/dist/types/src/styles/components/dialog.d.ts +12 -0
  39. package/dist/types/src/styles/components/dialog.d.ts.map +1 -0
  40. package/dist/types/src/styles/components/index.d.ts +22 -0
  41. package/dist/types/src/styles/components/index.d.ts.map +1 -0
  42. package/dist/types/src/styles/components/input.d.ts +103 -0
  43. package/dist/types/src/styles/components/input.d.ts.map +1 -0
  44. package/dist/types/src/styles/components/link.d.ts +7 -0
  45. package/dist/types/src/styles/components/link.d.ts.map +1 -0
  46. package/dist/types/src/styles/components/list.d.ts +14 -0
  47. package/dist/types/src/styles/components/list.d.ts.map +1 -0
  48. package/dist/types/src/styles/components/main.d.ts +25 -0
  49. package/dist/types/src/styles/components/main.d.ts.map +1 -0
  50. package/dist/types/src/styles/components/menu.d.ts +12 -0
  51. package/dist/types/src/styles/components/menu.d.ts.map +1 -0
  52. package/dist/types/src/styles/components/message.d.ts +10 -0
  53. package/dist/types/src/styles/components/message.d.ts.map +1 -0
  54. package/dist/types/src/styles/components/popover.d.ts +10 -0
  55. package/dist/types/src/styles/components/popover.d.ts.map +1 -0
  56. package/dist/types/src/styles/components/scroll-area.d.ts +9 -0
  57. package/dist/types/src/styles/components/scroll-area.d.ts.map +1 -0
  58. package/dist/types/src/styles/components/select.d.ts +13 -0
  59. package/dist/types/src/styles/components/select.d.ts.map +1 -0
  60. package/dist/types/src/styles/components/separator.d.ts +7 -0
  61. package/dist/types/src/styles/components/separator.d.ts.map +1 -0
  62. package/dist/types/src/styles/components/status.d.ts +8 -0
  63. package/dist/types/src/styles/components/status.d.ts.map +1 -0
  64. package/dist/types/src/styles/components/tag.d.ts +7 -0
  65. package/dist/types/src/styles/components/tag.d.ts.map +1 -0
  66. package/dist/types/src/styles/components/toast.d.ts +12 -0
  67. package/dist/types/src/styles/components/toast.d.ts.map +1 -0
  68. package/dist/types/src/styles/components/toolbar.d.ts +5 -0
  69. package/dist/types/src/styles/components/toolbar.d.ts.map +1 -0
  70. package/dist/types/src/styles/components/tooltip.d.ts +6 -0
  71. package/dist/types/src/styles/components/tooltip.d.ts.map +1 -0
  72. package/dist/types/src/styles/components/treegrid.d.ts +10 -0
  73. package/dist/types/src/styles/components/treegrid.d.ts.map +1 -0
  74. package/dist/types/src/styles/fragments/arrow.d.ts +6 -0
  75. package/dist/types/src/styles/fragments/arrow.d.ts.map +1 -0
  76. package/dist/types/src/styles/fragments/density.d.ts +13 -0
  77. package/dist/types/src/styles/fragments/density.d.ts.map +1 -0
  78. package/dist/types/src/styles/fragments/dimensions.d.ts +2 -0
  79. package/dist/types/src/styles/fragments/dimensions.d.ts.map +1 -0
  80. package/dist/types/src/styles/fragments/disabled.d.ts +3 -0
  81. package/dist/types/src/styles/fragments/disabled.d.ts.map +1 -0
  82. package/dist/types/src/styles/fragments/elevation.d.ts +11 -0
  83. package/dist/types/src/styles/fragments/elevation.d.ts.map +1 -0
  84. package/dist/types/src/styles/fragments/focus.d.ts +6 -0
  85. package/dist/types/src/styles/fragments/focus.d.ts.map +1 -0
  86. package/dist/types/src/styles/fragments/group.d.ts +5 -0
  87. package/dist/types/src/styles/fragments/group.d.ts.map +1 -0
  88. package/dist/types/src/styles/fragments/hover.d.ts +14 -0
  89. package/dist/types/src/styles/fragments/hover.d.ts.map +1 -0
  90. package/dist/types/src/styles/fragments/hue.d.ts +16 -0
  91. package/dist/types/src/styles/fragments/hue.d.ts.map +1 -0
  92. package/dist/types/src/styles/fragments/index.d.ts +19 -0
  93. package/dist/types/src/styles/fragments/index.d.ts.map +1 -0
  94. package/dist/types/src/styles/fragments/layout.d.ts +3 -0
  95. package/dist/types/src/styles/fragments/layout.d.ts.map +1 -0
  96. package/dist/types/src/styles/fragments/motion.d.ts +3 -0
  97. package/dist/types/src/styles/fragments/motion.d.ts.map +1 -0
  98. package/dist/types/src/styles/fragments/ornament.d.ts +4 -0
  99. package/dist/types/src/styles/fragments/ornament.d.ts.map +1 -0
  100. package/dist/types/src/styles/fragments/selected.d.ts +12 -0
  101. package/dist/types/src/styles/fragments/selected.d.ts.map +1 -0
  102. package/dist/types/src/styles/fragments/shimmer.d.ts +3 -0
  103. package/dist/types/src/styles/fragments/shimmer.d.ts.map +1 -0
  104. package/dist/types/src/styles/fragments/size.d.ts +9 -0
  105. package/dist/types/src/styles/fragments/size.d.ts.map +1 -0
  106. package/dist/types/src/styles/fragments/surface.d.ts +9 -0
  107. package/dist/types/src/styles/fragments/surface.d.ts.map +1 -0
  108. package/dist/types/src/styles/fragments/text.d.ts +6 -0
  109. package/dist/types/src/styles/fragments/text.d.ts.map +1 -0
  110. package/dist/types/src/styles/fragments/valence.d.ts +13 -0
  111. package/dist/types/src/styles/fragments/valence.d.ts.map +1 -0
  112. package/dist/types/src/styles/index.d.ts +4 -0
  113. package/dist/types/src/styles/index.d.ts.map +1 -0
  114. package/dist/types/src/styles/theme.d.ts +5 -0
  115. package/dist/types/src/styles/theme.d.ts.map +1 -0
  116. package/dist/types/src/tailwind.d.ts +1 -0
  117. package/dist/types/src/tailwind.d.ts.map +1 -0
  118. package/dist/types/src/util/index.d.ts +2 -0
  119. package/dist/types/src/util/index.d.ts.map +1 -0
  120. package/dist/types/src/util/mx.d.ts +2 -0
  121. package/dist/types/src/util/mx.d.ts.map +1 -0
  122. package/dist/types/src/util/semanticColors.d.ts +10 -0
  123. package/dist/types/src/util/semanticColors.d.ts.map +1 -0
  124. package/dist/types/src/util/withLogical.d.ts +158 -0
  125. package/dist/types/src/util/withLogical.d.ts.map +1 -0
  126. package/package.json +45 -0
  127. package/plugin.d.ts +7 -0
  128. package/plugin.js +10 -0
  129. package/src/config/colors.ts +293 -0
  130. package/src/config/index.ts +6 -0
  131. package/src/config/resolveContent.ts +50 -0
  132. package/src/config/tailwind.ts +200 -0
  133. package/src/esbuild-plugin.ts +60 -0
  134. package/src/index.ts +7 -0
  135. package/src/plugin.ts +63 -0
  136. package/src/styles/components/anchored-overflow.ts +20 -0
  137. package/src/styles/components/avatar.ts +96 -0
  138. package/src/styles/components/breadcrumb.ts +29 -0
  139. package/src/styles/components/button.ts +47 -0
  140. package/src/styles/components/dialog.ts +46 -0
  141. package/src/styles/components/index.ts +25 -0
  142. package/src/styles/components/input.ts +172 -0
  143. package/src/styles/components/link.ts +27 -0
  144. package/src/styles/components/list.ts +46 -0
  145. package/src/styles/components/main.ts +81 -0
  146. package/src/styles/components/menu.ts +52 -0
  147. package/src/styles/components/message.ts +27 -0
  148. package/src/styles/components/popover.ts +32 -0
  149. package/src/styles/components/scroll-area.ts +42 -0
  150. package/src/styles/components/select.ts +55 -0
  151. package/src/styles/components/separator.ts +19 -0
  152. package/src/styles/components/status.ts +27 -0
  153. package/src/styles/components/tag.ts +49 -0
  154. package/src/styles/components/toast.ts +53 -0
  155. package/src/styles/components/toolbar.ts +17 -0
  156. package/src/styles/components/tooltip.ts +27 -0
  157. package/src/styles/components/treegrid.ts +37 -0
  158. package/src/styles/fragments/arrow.ts +10 -0
  159. package/src/styles/fragments/density.ts +17 -0
  160. package/src/styles/fragments/dimensions.ts +5 -0
  161. package/src/styles/fragments/disabled.ts +6 -0
  162. package/src/styles/fragments/elevation.ts +14 -0
  163. package/src/styles/fragments/focus.ts +18 -0
  164. package/src/styles/fragments/group.ts +12 -0
  165. package/src/styles/fragments/hover.ts +22 -0
  166. package/src/styles/fragments/hue.ts +151 -0
  167. package/src/styles/fragments/index.ts +22 -0
  168. package/src/styles/fragments/layout.ts +7 -0
  169. package/src/styles/fragments/motion.ts +8 -0
  170. package/src/styles/fragments/ornament.ts +7 -0
  171. package/src/styles/fragments/selected.ts +39 -0
  172. package/src/styles/fragments/shimmer.ts +9 -0
  173. package/src/styles/fragments/size.ts +117 -0
  174. package/src/styles/fragments/surface.ts +29 -0
  175. package/src/styles/fragments/text.ts +11 -0
  176. package/src/styles/fragments/valence.ts +50 -0
  177. package/src/styles/index.ts +7 -0
  178. package/src/styles/layers/anchored-overflow.css +9 -0
  179. package/src/styles/layers/attention.css +50 -0
  180. package/src/styles/layers/button.css +73 -0
  181. package/src/styles/layers/can-scroll.css +26 -0
  182. package/src/styles/layers/checkbox.css +25 -0
  183. package/src/styles/layers/focus-ring.css +26 -0
  184. package/src/styles/layers/index.css +10 -0
  185. package/src/styles/layers/positioning.css +20 -0
  186. package/src/styles/layers/surfaces.css +39 -0
  187. package/src/styles/layers/tldraw.css +87 -0
  188. package/src/styles/layers/typography.css +152 -0
  189. package/src/styles/theme.ts +69 -0
  190. package/src/tailwind.ts +5 -0
  191. package/src/theme.css +52 -0
  192. package/src/typings.d.ts +7 -0
  193. package/src/util/index.ts +5 -0
  194. package/src/util/mx.ts +40 -0
  195. package/src/util/semanticColors.ts +57 -0
  196. package/src/util/withLogical.ts +110 -0
@@ -0,0 +1,293 @@
1
+ //
2
+ // Copyright 2024 DXOS.org
3
+ //
4
+
5
+ import {
6
+ curvePathFromPalette,
7
+ paletteShadesFromCurve,
8
+ hex_to_LCH as hexToLch,
9
+ Lab_to_hex as labToHex,
10
+ } from '@ch-ui/colors';
11
+
12
+ export type PaletteConfig = {
13
+ keyColor: string;
14
+ darkCp: number;
15
+ lightCp: number;
16
+ hueTorsion: number;
17
+ };
18
+
19
+ const shadeNumbers: number[] = /* [...Array(19)].map((_, i) => 50 + i * 50); */ [
20
+ 50, 100, 150, 200, 250, 300, 350, 400, 450, 500, 550, 600, 650, 700, 750, 800, 850, 900, 950,
21
+ ];
22
+
23
+ const broadShadeNumbers: number[] = [
24
+ 12, 25, 37, 50, 75, 100, 125, 150, 200, 250, 300, 350, 400, 450, 500, 550, 600, 650, 700, 750, 800, 825, 850, 875,
25
+ 900, 925, 950, 975,
26
+ ];
27
+
28
+ const dtor = Math.PI / 180;
29
+
30
+ export type HuePalette =
31
+ | 'red'
32
+ | 'orange'
33
+ | 'amber'
34
+ | 'yellow'
35
+ | 'lime'
36
+ | 'green'
37
+ | 'emerald'
38
+ | 'teal'
39
+ | 'cyan'
40
+ | 'sky'
41
+ | 'blue'
42
+ | 'indigo'
43
+ | 'violet'
44
+ | 'purple'
45
+ | 'fuchsia'
46
+ | 'pink'
47
+ | 'rose';
48
+
49
+ export type ConfigPalette = HuePalette | 'primary' | 'neutral';
50
+
51
+ export const paletteConfigs: Record<ConfigPalette, PaletteConfig> = {
52
+ red: {
53
+ keyColor: '#ee003b',
54
+ darkCp: 1,
55
+ lightCp: 0.13,
56
+ hueTorsion: 5.5 * dtor,
57
+ },
58
+ orange: {
59
+ keyColor: '#fa6b32',
60
+ darkCp: 0.725,
61
+ lightCp: 1,
62
+ hueTorsion: 13 * dtor,
63
+ },
64
+ amber: {
65
+ keyColor: '#f08c00',
66
+ darkCp: 1,
67
+ lightCp: 1,
68
+ hueTorsion: 24 * dtor,
69
+ },
70
+ yellow: {
71
+ keyColor: '#ffd900',
72
+ darkCp: 1,
73
+ lightCp: 1,
74
+ hueTorsion: 32 * dtor,
75
+ },
76
+ lime: {
77
+ keyColor: '#99c400',
78
+ darkCp: 1,
79
+ lightCp: 1,
80
+ hueTorsion: -3.5 * dtor,
81
+ },
82
+ green: {
83
+ keyColor: '#30a908',
84
+ darkCp: 0.35,
85
+ lightCp: 0.665,
86
+ hueTorsion: -10.5 * dtor,
87
+ },
88
+ emerald: {
89
+ keyColor: '#15e066',
90
+ darkCp: 1,
91
+ lightCp: 0.735,
92
+ hueTorsion: -7 * dtor,
93
+ },
94
+ teal: {
95
+ keyColor: '#00a270',
96
+ darkCp: 1,
97
+ lightCp: 0.755,
98
+ hueTorsion: -12 * dtor,
99
+ },
100
+ cyan: {
101
+ keyColor: '#048992',
102
+ darkCp: 1,
103
+ lightCp: 0.855,
104
+ hueTorsion: -15 * dtor,
105
+ },
106
+ sky: {
107
+ keyColor: '#007bc2',
108
+ darkCp: 1,
109
+ lightCp: 0.64,
110
+ hueTorsion: 0,
111
+ },
112
+ blue: {
113
+ keyColor: '#0058cb',
114
+ darkCp: 1,
115
+ lightCp: 0.495,
116
+ hueTorsion: -7 * dtor,
117
+ },
118
+ indigo: {
119
+ keyColor: '#1b45c5',
120
+ darkCp: 0.495,
121
+ lightCp: 0.55,
122
+ hueTorsion: 0,
123
+ },
124
+ violet: {
125
+ keyColor: '#080886',
126
+ darkCp: 0.195,
127
+ lightCp: 0.635,
128
+ hueTorsion: -5 * dtor,
129
+ },
130
+ purple: {
131
+ keyColor: '#2c0073',
132
+ darkCp: 0,
133
+ lightCp: 0.63,
134
+ hueTorsion: 0,
135
+ },
136
+ fuchsia: {
137
+ keyColor: '#6d0085',
138
+ darkCp: 1,
139
+ lightCp: 0.695,
140
+ hueTorsion: 0,
141
+ },
142
+ pink: {
143
+ keyColor: '#a5006d',
144
+ darkCp: 1,
145
+ lightCp: 0.775,
146
+ hueTorsion: 0,
147
+ },
148
+ rose: {
149
+ keyColor: '#d00054',
150
+ darkCp: 1,
151
+ lightCp: 1,
152
+ hueTorsion: 0,
153
+ },
154
+ neutral: {
155
+ keyColor: '#707076',
156
+ darkCp: 0.8,
157
+ lightCp: 0.88,
158
+ hueTorsion: 0,
159
+ },
160
+ primary: {
161
+ keyColor: '#1662d9',
162
+ darkCp: 0.86,
163
+ lightCp: 1,
164
+ hueTorsion: -30 * dtor,
165
+ },
166
+ };
167
+
168
+ export const physicalColors = Object.keys(paletteConfigs).reduce(
169
+ (acc: Record<string, Record<string, string>>, palette) => {
170
+ const isBroad = palette === 'neutral' || palette === 'primary';
171
+ const paletteConfig = paletteConfigs[palette as ConfigPalette];
172
+ const curve = curvePathFromPalette({
173
+ ...paletteConfig,
174
+ keyColor: hexToLch(paletteConfig.keyColor),
175
+ });
176
+ const defaultShades = paletteShadesFromCurve(curve, 21, [0, 100 * (22 / 21)], 1, 24).reverse();
177
+ const renderCssValue = (shadeNumber: number) => {
178
+ if (shadeNumber > 999) {
179
+ return '#000000';
180
+ } else if (shadeNumber < 1) {
181
+ return '#ffffff';
182
+ } else if (shadeNumber % 50 === 0) {
183
+ return labToHex(defaultShades[shadeNumber / 50]);
184
+ } else {
185
+ const k2 = (shadeNumber % 50) / 50;
186
+ const k1 = 1 - k2;
187
+ const [l1, a1, b1] = defaultShades[Math.floor(shadeNumber / 50)];
188
+ const [l2, a2, b2] = defaultShades[Math.ceil(shadeNumber / 50)];
189
+ return labToHex([l1 * k1 + l2 * k2, a1 * k1 + a2 * k2, b1 * k1 + b2 * k2]);
190
+ }
191
+ };
192
+ acc[palette] = (isBroad ? broadShadeNumbers : shadeNumbers).reduce((acc: Record<string, string>, shadeNumber) => {
193
+ acc[shadeNumber] = renderCssValue(shadeNumber);
194
+ return acc;
195
+ }, {});
196
+
197
+ return acc;
198
+ },
199
+ {},
200
+ );
201
+
202
+ export const semanticColors = {
203
+ scrim: {
204
+ light: `${physicalColors.neutral['75']}A6`,
205
+ dark: `${physicalColors.neutral['900']}A6`,
206
+ },
207
+ attention: {
208
+ light: '#ffffff',
209
+ dark: physicalColors.neutral['900'],
210
+ },
211
+ deck: {
212
+ light: physicalColors.neutral['75'],
213
+ dark: physicalColors.neutral['875'],
214
+ },
215
+ base: {
216
+ light: physicalColors.neutral['25'],
217
+ dark: physicalColors.neutral['850'],
218
+ fg: { light: '#000000', dark: '#ffffff' },
219
+ },
220
+ fgHover: {
221
+ light: physicalColors.neutral['900'],
222
+ dark: physicalColors.neutral['100'],
223
+ },
224
+ description: {
225
+ light: physicalColors.neutral['500'],
226
+ dark: physicalColors.neutral['400'],
227
+ },
228
+ subdued: {
229
+ light: physicalColors.neutral['700'],
230
+ dark: physicalColors.neutral['300'],
231
+ },
232
+ error: {
233
+ light: physicalColors.red['700'],
234
+ dark: physicalColors.red['300'],
235
+ },
236
+ baseGlass: {
237
+ light: `${physicalColors.neutral['12']}e0`,
238
+ dark: `${physicalColors.neutral['850']}e0`,
239
+ },
240
+ input: {
241
+ light: physicalColors.neutral['50'],
242
+ dark: physicalColors.neutral['825'],
243
+ },
244
+ modal: {
245
+ light: '#ffffff',
246
+ dark: `${physicalColors.neutral['750']}`,
247
+ },
248
+ modalSelected: {
249
+ light: physicalColors.neutral['50'],
250
+ dark: physicalColors.neutral['825'],
251
+ },
252
+ hover: {
253
+ light: physicalColors.neutral['37'],
254
+ dark: physicalColors.neutral['800'],
255
+ },
256
+ accent: {
257
+ light: physicalColors.primary['550'],
258
+ dark: physicalColors.primary['550'],
259
+ fg: { light: physicalColors.primary['550'], dark: physicalColors.primary['400'] },
260
+ },
261
+ accentHover: {
262
+ light: physicalColors.primary['600'],
263
+ dark: physicalColors.primary['500'],
264
+ },
265
+ accentFocusIndicator: {
266
+ light: physicalColors.primary['350'],
267
+ dark: physicalColors.primary['450'],
268
+ },
269
+ unAccent: {
270
+ light: physicalColors.neutral['500'],
271
+ dark: physicalColors.neutral['400'],
272
+ },
273
+ unAccentHover: {
274
+ light: physicalColors.neutral['400'],
275
+ dark: physicalColors.neutral['500'],
276
+ },
277
+ separator: {
278
+ light: physicalColors.neutral['50'],
279
+ dark: physicalColors.neutral['700'],
280
+ },
281
+ inverse: {
282
+ light: '#ffffff',
283
+ dark: '#ffffff',
284
+ },
285
+ transparent: {
286
+ light: 'transparent',
287
+ dark: 'transparent',
288
+ },
289
+ unavailable: {
290
+ light: physicalColors.neutral['100'],
291
+ dark: physicalColors.neutral['600'],
292
+ },
293
+ };
@@ -0,0 +1,6 @@
1
+ //
2
+ // Copyright 2022 DXOS.org
3
+ //
4
+
5
+ export * from './colors';
6
+ export * from './tailwind';
@@ -0,0 +1,50 @@
1
+ //
2
+ // Copyright 2023 DXOS.org
3
+ //
4
+
5
+ import { glob as globCb } from 'glob';
6
+ import { promisify } from 'node:util';
7
+
8
+ const glob = promisify(globCb);
9
+
10
+ const knownIndirectPeers = [
11
+ '@dxos/react-*',
12
+ '@dxos/react-ui-*',
13
+ '@dxos/devtools',
14
+ '@dxos/shell',
15
+ // TODO(thure): glob v7 runs out of memory if we do a `**` search, and this is (hopefully) the only L3 content package; find a better solution.
16
+ '@dxos/react-ui-table/node_modules/@dxos/react-ui-searchlist',
17
+ ];
18
+
19
+ const knownDirectPeers = ['@braneframe/plugin-*', ...knownIndirectPeers];
20
+
21
+ const packageNamePattern = /.*node_modules\/(.+?)$/;
22
+ const packageName = (path: string) => path.match(packageNamePattern)?.[1];
23
+
24
+ const flatten = (acc: string[], group: string[]) => [...acc, ...group];
25
+ const dedupe = (acc: Record<string, string>, path: string) => {
26
+ const name = packageName(path);
27
+ if (name && !acc[name]) {
28
+ acc[name] = path;
29
+ }
30
+ return acc;
31
+ };
32
+
33
+ export const resolveKnownPeers = async (content: string[], cwd: string): Promise<string[]> => {
34
+ const globOptions = { cwd, absolute: true };
35
+
36
+ const directPeers = await Promise.all(knownDirectPeers.map((peer) => glob(`./node_modules/${peer}`, globOptions)));
37
+
38
+ // NOTE(thure): With glob v7, JS runs out of memory if `**` is used, so this limits the search to @braneframe/plugin-*/node_modules
39
+ const indirectPeers = await Promise.all(
40
+ knownIndirectPeers.map((peer) => glob(`./node_modules/@braneframe/plugin-*/node_modules/${peer}`, globOptions)),
41
+ );
42
+
43
+ const knownPeerContent = Object.values(
44
+ indirectPeers.reduce(flatten, []).reduce(dedupe, directPeers.reduce(flatten, []).reduce(dedupe, {})),
45
+ ).map((value) => `${value}/dist/lib/**/*.mjs`);
46
+
47
+ // console.log('[found known peer content paths]', knownPeerContent);
48
+
49
+ return [...content, ...knownPeerContent];
50
+ };
@@ -0,0 +1,200 @@
1
+ //
2
+ // Copyright 2022 DXOS.org
3
+ //
4
+
5
+ import tailwindcssForms from '@tailwindcss/forms';
6
+ import merge from 'lodash.merge';
7
+ import tailwindScrollbar from 'tailwind-scrollbar';
8
+ import tailwindColors from 'tailwindcss/colors.js';
9
+ import defaultConfig from 'tailwindcss/stubs/config.full.js';
10
+ import { type Config, type ThemeConfig } from 'tailwindcss/types/config';
11
+ import tailwindcssLogical from 'tailwindcss-logical';
12
+ import tailwindcssRadix from 'tailwindcss-radix';
13
+
14
+ import { physicalColors, semanticColors } from './colors';
15
+ import { semanticColors as semanticColorsPlugin } from '../util/semanticColors';
16
+
17
+ export type TailwindConfig = Config;
18
+ export type TailwindThemeConfig = ThemeConfig;
19
+
20
+ export const tailwindConfig = ({
21
+ env = 'production',
22
+ content = [],
23
+ extensions = [],
24
+ }: {
25
+ env?: string;
26
+ content?: string[];
27
+ extensions?: Partial<TailwindThemeConfig>[];
28
+ }): TailwindConfig => ({
29
+ darkMode: 'class',
30
+ theme: {
31
+ // Configure fonts in theme.css and package.json.
32
+ fontFamily: {
33
+ body: ['Inter Variable', ...defaultConfig.theme.fontFamily.sans],
34
+ mono: ['JetBrains Mono Variable', ...defaultConfig.theme.fontFamily.mono],
35
+ },
36
+ extend: merge(
37
+ {
38
+ screens: {
39
+ 'pointer-fine': { raw: '(pointer: fine)' },
40
+ 'hover-hover': { raw: '(hover: hover)' },
41
+ },
42
+ colors: {
43
+ ...physicalColors,
44
+ slate: tailwindColors.slate,
45
+ gray: tailwindColors.gray,
46
+ zinc: tailwindColors.zinc,
47
+ stone: tailwindColors.stone,
48
+ success: physicalColors.emerald,
49
+ warning: physicalColors.amber,
50
+ error: physicalColors.rose,
51
+ info: physicalColors.cyan,
52
+ transparent: 'transparent',
53
+ current: 'currentColor',
54
+ white: '#ffffff',
55
+ black: '#000000',
56
+ },
57
+ semanticColors,
58
+ fontSize: {
59
+ // Base size 16px
60
+ // Scale 1.125
61
+ xs: ['0.790rem', { lineHeight: '1rem' }],
62
+ sm: ['0.889rem', { lineHeight: '1.25rem' }],
63
+ base: ['1rem', { lineHeight: '1.5rem' }],
64
+ lg: ['1.125rem', { lineHeight: '1.75rem' }],
65
+ xl: ['1.266rem', { lineHeight: '1.75rem' }],
66
+ '2xl': ['1.424rem', { lineHeight: '2rem' }],
67
+ '3xl': ['1.602rem', { lineHeight: '2.25rem' }],
68
+ '4xl': ['1.802rem', { lineHeight: '2.5rem' }],
69
+ '5xl': ['2.027rem', { lineHeight: '2.5rem' }],
70
+ '6xl': ['2.281rem', { lineHeight: '2.5rem' }],
71
+ '7xl': ['2.566rem', { lineHeight: '2.75rem' }],
72
+ '8xl': ['2.887rem', { lineHeight: '3rem' }],
73
+ '9xl': ['3.247rem', { lineHeight: '3.25rem' }],
74
+ },
75
+ outlineWidth: {
76
+ 3: '3px',
77
+ },
78
+ boxShadow: {
79
+ slider: '0 0 0 5px rgba(0, 0, 0, 0.3)',
80
+ },
81
+ transitionProperty: {
82
+ 'max-height': 'max-height',
83
+ },
84
+ keyframes: {
85
+ // Popper chrome
86
+ slideDownAndFade: {
87
+ from: { opacity: 0, transform: 'translateY(-2px)' },
88
+ to: { opacity: 1, transform: 'translateY(0)' },
89
+ },
90
+ slideLeftAndFade: {
91
+ from: { opacity: 0, transform: 'translateX(2px)' },
92
+ to: { opacity: 1, transform: 'translateX(0)' },
93
+ },
94
+ slideUpAndFade: {
95
+ from: { opacity: 0, transform: 'translateY(2px)' },
96
+ to: { opacity: 1, transform: 'translateY(0)' },
97
+ },
98
+ slideRightAndFade: {
99
+ from: { opacity: 0, transform: 'translateX(-2px)' },
100
+ to: { opacity: 1, transform: 'translateX(0)' },
101
+ },
102
+
103
+ // Toast
104
+ 'toast-hide': {
105
+ '0%': { opacity: '1' },
106
+ '100%': { opacity: '0' },
107
+ },
108
+ 'toast-slide-in-right': {
109
+ '0%': { transform: 'translateX(calc(100% + 1rem))' },
110
+ '100%': { transform: 'translateX(0)' },
111
+ },
112
+ 'toast-slide-in-bottom': {
113
+ '0%': { transform: 'translateY(calc(100% + 1rem))' },
114
+ '100%': { transform: 'translateY(0)' },
115
+ },
116
+ 'toast-swipe-out': {
117
+ '0%': {
118
+ transform: 'translateX(var(--radix-toast-swipe-end-x))',
119
+ },
120
+ '100%': {
121
+ transform: 'translateX(calc(100% + 1rem))',
122
+ },
123
+ },
124
+
125
+ // Shimmer
126
+ 'shimmer-loop': {
127
+ '100%': {
128
+ transform: 'translateX(100%)',
129
+ },
130
+ },
131
+
132
+ 'halo-pulse': {
133
+ '0%': {
134
+ opacity: 0.3,
135
+ },
136
+ '5%': {
137
+ opacity: 1,
138
+ },
139
+ '100%': {
140
+ opacity: 0.3,
141
+ },
142
+ },
143
+
144
+ 'progress-indeterminate': {
145
+ '0%': {
146
+ left: 0,
147
+ width: '0%',
148
+ },
149
+ '25%': {
150
+ left: '25%',
151
+ width: '50%',
152
+ },
153
+ '75%': {
154
+ left: '50%',
155
+ width: '100%',
156
+ },
157
+ '100%': {
158
+ left: '100%',
159
+ width: '0%',
160
+ },
161
+ },
162
+ },
163
+ animation: {
164
+ // Popper chrome
165
+ slideDownAndFade: 'slideDownAndFade 400ms cubic-bezier(0.16, 1, 0.3, 1)',
166
+ slideLeftAndFade: 'slideLeftAndFade 400ms cubic-bezier(0.16, 1, 0.3, 1)',
167
+ slideUpAndFade: 'slideUpAndFade 400ms cubic-bezier(0.16, 1, 0.3, 1)',
168
+ slideRightAndFade: 'slideRightAndFade 400ms cubic-bezier(0.16, 1, 0.3, 1)',
169
+
170
+ // Toast
171
+ 'toast-hide': 'toast-hide 100ms ease-in forwards',
172
+ 'toast-slide-in-right': 'toast-slide-in-right 150ms cubic-bezier(0.16, 1, 0.3, 1)',
173
+ 'toast-slide-in-bottom': 'toast-slide-in-bottom 150ms cubic-bezier(0.16, 1, 0.3, 1)',
174
+ 'toast-swipe-out': 'toast-swipe-out 100ms ease-out forwards',
175
+
176
+ spin: 'spin 1.5s linear infinite',
177
+ 'spin-slow': 'spin 3s linear infinite',
178
+
179
+ shimmer: 'shimmer-loop 2s infinite',
180
+ 'halo-pulse': 'halo-pulse 2s ease-out infinite',
181
+ 'progress-indeterminate': 'progress-indeterminate 2s ease-out infinite',
182
+ },
183
+ },
184
+ ...extensions,
185
+ ),
186
+ },
187
+ plugins: [
188
+ semanticColorsPlugin,
189
+ tailwindcssLogical,
190
+ tailwindcssForms,
191
+ tailwindcssRadix(),
192
+ // https://adoxography.github.io/tailwind-scrollbar/utilities
193
+ tailwindScrollbar,
194
+ ],
195
+ ...(env === 'development' && { mode: 'jit' }),
196
+ content,
197
+ future: {
198
+ hoverOnlyWhenSupported: true,
199
+ },
200
+ });
@@ -0,0 +1,60 @@
1
+ //
2
+ // Copyright 2022 DXOS.org
3
+ //
4
+
5
+ import autoprefixer from 'autoprefixer';
6
+ import type { Plugin } from 'esbuild';
7
+ import stylePlugin from 'esbuild-style-plugin';
8
+ import { mkdir, cp } from 'node:fs/promises';
9
+ import { resolve, relative, join, basename } from 'node:path';
10
+ import tailwindcss from 'tailwindcss';
11
+ import type { ThemeConfig } from 'tailwindcss/types/config';
12
+
13
+ import { tailwindConfig } from './config';
14
+ import { resolveKnownPeers } from './config/resolveContent';
15
+
16
+ export const ThemePlugins = async (options: {
17
+ content: string[];
18
+ root?: string;
19
+ outdir: string;
20
+ extensions?: Partial<ThemeConfig>[];
21
+ }): Promise<Plugin[]> => {
22
+ const resolvedContent = options.root ? await resolveKnownPeers(options.content, options.root) : options.content;
23
+ return [
24
+ // TODO(thure): This really shouldn’t be this way, but after hours of searching for a reasonable way to do this I came up empty. The prior art I found was mainly this thread, though it’s only tangentially related: https://github.com/evanw/esbuild/issues/800#issuecomment-786151076
25
+ {
26
+ name: 'esbuild-plugin-dxos-ui-theme-resolvers',
27
+ setup: async (build) => {
28
+ const fontsDir = join(options.outdir, 'node_modules/@dxos/react-ui-theme/fonts');
29
+ try {
30
+ await mkdir(fontsDir);
31
+ } catch (_err) {}
32
+ build.onResolve({ filter: /\.woff2$/ }, async (args) => {
33
+ const depPath = resolve(args.resolveDir, args.path);
34
+ const destPath = join(fontsDir, basename(args.path));
35
+ try {
36
+ await cp(depPath, destPath);
37
+ } catch (_err) {}
38
+ return { path: `./${relative(options.outdir, join('fonts', basename(args.path)))}`, external: true };
39
+ });
40
+ },
41
+ },
42
+ // TODO(thure): theme.css must be part of entryPoints in order to be processed with `stylePlugin`, but this should not be necessary. ESBuild would not load theme.css using stylePlugin if referenced within index.ts(x) as with the Vite plugin.
43
+ // TODO(thure): Note also that because it is an entryPoint, the developer has to reference the built theme.css from `index.html`, which is inflexible and possibly inconvenient.
44
+ // TODO(zhenyasav): autoprefixer version misalignment with esbuild-style-plugin requires the `as any`
45
+ stylePlugin({
46
+ postcss: {
47
+ plugins: [
48
+ tailwindcss(
49
+ tailwindConfig({
50
+ env: process.env.NODE_ENV,
51
+ content: resolvedContent,
52
+ extensions: options.extensions,
53
+ }),
54
+ ),
55
+ autoprefixer as any,
56
+ ],
57
+ },
58
+ }),
59
+ ];
60
+ };
package/src/index.ts ADDED
@@ -0,0 +1,7 @@
1
+ //
2
+ // Copyright 2022 DXOS.org
3
+ //
4
+
5
+ export * from './config';
6
+ export * from './styles';
7
+ export * from './util';
package/src/plugin.ts ADDED
@@ -0,0 +1,63 @@
1
+ //
2
+ // Copyright 2022 DXOS.org
3
+ //
4
+
5
+ import autoprefixer from 'autoprefixer';
6
+ import { resolve } from 'node:path';
7
+ import tailwindcss from 'tailwindcss';
8
+ import nesting from 'tailwindcss/nesting';
9
+ import type { ThemeConfig } from 'tailwindcss/types/config';
10
+ import { type Plugin } from 'vite';
11
+
12
+ import { tailwindConfig } from './config';
13
+ import { resolveKnownPeers } from './config/resolveContent';
14
+
15
+ export interface VitePluginTailwindOptions {
16
+ jit?: boolean;
17
+ cssPath?: string;
18
+ virtualFileId?: string;
19
+ content?: string[];
20
+ root?: string;
21
+ }
22
+
23
+ // TODO(zhenyasav): Make it easy to override the tailwind config.
24
+ // TODO(zhenyasav): Make it easy to add postcss plugins?
25
+ export const ThemePlugin = (
26
+ options: Pick<VitePluginTailwindOptions, 'content' | 'root'> & { extensions?: Partial<ThemeConfig>[] },
27
+ ) => {
28
+ const config: VitePluginTailwindOptions & Pick<typeof options, 'extensions'> = {
29
+ jit: true,
30
+ cssPath: resolve(__dirname, './theme.css'),
31
+ virtualFileId: '@dxosTheme', // TODO(burdon): Rename '@dxos-theme'?
32
+ ...options,
33
+ };
34
+
35
+ return {
36
+ name: 'vite-plugin-dxos-ui-theme',
37
+ config: async ({ root }, env) => {
38
+ const content = root ? await resolveKnownPeers(config.content ?? [], root) : config.content;
39
+ return {
40
+ css: {
41
+ postcss: {
42
+ plugins: [
43
+ nesting,
44
+ tailwindcss(
45
+ tailwindConfig({
46
+ env: env.mode,
47
+ content,
48
+ extensions: config.extensions,
49
+ }),
50
+ ),
51
+ autoprefixer,
52
+ ],
53
+ },
54
+ },
55
+ };
56
+ },
57
+ resolveId: (id) => {
58
+ if (id === config.virtualFileId) {
59
+ return config.cssPath;
60
+ }
61
+ },
62
+ } as Plugin;
63
+ };
@@ -0,0 +1,20 @@
1
+ //
2
+ // Copyright 2023 DXOS.org
3
+ //
4
+
5
+ import { type ComponentFunction, type Theme } from '@dxos/react-ui-types';
6
+
7
+ import { mx } from '../../util';
8
+
9
+ export type AnchoredOverflowStyleProps = {};
10
+
11
+ export const anchoredOverflowRoot: ComponentFunction<AnchoredOverflowStyleProps> = (_props, ...etc) =>
12
+ mx('overflow-anchored overflow-auto', ...etc);
13
+
14
+ export const anchoredOverflowAnchor: ComponentFunction<AnchoredOverflowStyleProps> = (_props, ...etc) =>
15
+ mx('overflow-anchor is-px bs-px', ...etc);
16
+
17
+ export const anchoredOverflowTheme: Theme<AnchoredOverflowStyleProps> = {
18
+ root: anchoredOverflowRoot,
19
+ anchor: anchoredOverflowAnchor,
20
+ };