@spree/dashboard-ui 6.0.1 → 6.0.3
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.
- package/package.json +3 -7
- package/src/shadcn.css +640 -0
- package/src/spree/browser-icon.tsx +36 -0
- package/src/spree/icons.ts +3 -0
- package/src/styles.css +1 -1
- package/src/ui/badge.tsx +3 -0
- package/src/ui/command.tsx +134 -35
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@spree/dashboard-ui",
|
|
3
3
|
"license": "MIT",
|
|
4
|
-
"version": "6.0.
|
|
4
|
+
"version": "6.0.3",
|
|
5
5
|
"description": "Spree Dashboard design system — shadcn primitives, headless composed components, and design tokens. Source-only package; consumers compile via their own Vite/Tailwind setup.",
|
|
6
6
|
"author": "Vendo Connect Inc.",
|
|
7
7
|
"homepage": "https://spreecommerce.org",
|
|
@@ -61,11 +61,9 @@
|
|
|
61
61
|
"@dnd-kit/utilities": "3.2.2",
|
|
62
62
|
"@fontsource-variable/geist": "5.3.0",
|
|
63
63
|
"@fontsource-variable/geist-mono": "5.3.0",
|
|
64
|
-
"@tanstack/react-hotkeys": "
|
|
64
|
+
"@tanstack/react-hotkeys": "0.16.0",
|
|
65
65
|
"@tanstack/react-table": "9.3.1",
|
|
66
66
|
"@tiptap/core": "3.32.0",
|
|
67
|
-
"@tiptap/extension-bubble-menu": "3.32.0",
|
|
68
|
-
"@tiptap/extension-floating-menu": "3.32.0",
|
|
69
67
|
"@tiptap/extension-image": "3.32.0",
|
|
70
68
|
"@tiptap/extension-link": "3.32.0",
|
|
71
69
|
"@tiptap/extension-placeholder": "3.32.0",
|
|
@@ -75,7 +73,6 @@
|
|
|
75
73
|
"@uiw/react-json-view": "1.12.2",
|
|
76
74
|
"class-variance-authority": "0.7.1",
|
|
77
75
|
"clsx": "2.1.1",
|
|
78
|
-
"cmdk": "1.1.1",
|
|
79
76
|
"date-fns": "4.4.0",
|
|
80
77
|
"date-fns-tz": "3.2.0",
|
|
81
78
|
"flag-icons": "7.6.0",
|
|
@@ -83,10 +80,9 @@
|
|
|
83
80
|
"react-colorful": "5.8.1",
|
|
84
81
|
"react-day-picker": "10.0.2",
|
|
85
82
|
"recharts": "3.10.1",
|
|
86
|
-
"shadcn": "4.22.1",
|
|
87
83
|
"tailwind-merge": "3.7.0",
|
|
88
84
|
"tw-animate-css": "1.4.0",
|
|
89
|
-
"@spree/core": "^6.0.
|
|
85
|
+
"@spree/core": "^6.0.3"
|
|
90
86
|
},
|
|
91
87
|
"devDependencies": {
|
|
92
88
|
"@tanstack/react-router": "^1.170.45",
|
package/src/shadcn.css
ADDED
|
@@ -0,0 +1,640 @@
|
|
|
1
|
+
/* Vendored from shadcn@4.22.1 (dist/tailwind.css, MIT) so host apps do not
|
|
2
|
+
* install the shadcn CLI to get these variants and keyframes. */
|
|
3
|
+
|
|
4
|
+
@theme inline {
|
|
5
|
+
@keyframes accordion-down {
|
|
6
|
+
from {
|
|
7
|
+
height: 0;
|
|
8
|
+
}
|
|
9
|
+
to {
|
|
10
|
+
height: var(
|
|
11
|
+
--radix-accordion-content-height,
|
|
12
|
+
var(--accordion-panel-height, auto)
|
|
13
|
+
);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
@keyframes accordion-up {
|
|
18
|
+
from {
|
|
19
|
+
height: var(
|
|
20
|
+
--radix-accordion-content-height,
|
|
21
|
+
var(--accordion-panel-height, auto)
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
to {
|
|
25
|
+
height: 0;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/* Custom variants */
|
|
31
|
+
@custom-variant data-open {
|
|
32
|
+
&:where([data-state="open"]),
|
|
33
|
+
&:where([data-open]:not([data-open="false"])) {
|
|
34
|
+
@slot;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
@custom-variant data-closed {
|
|
39
|
+
&:where([data-state="closed"]),
|
|
40
|
+
&:where([data-closed]:not([data-closed="false"])) {
|
|
41
|
+
@slot;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
@custom-variant data-checked {
|
|
46
|
+
&:where([data-state="checked"]),
|
|
47
|
+
&:where([data-checked]:not([data-checked="false"])) {
|
|
48
|
+
@slot;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
@custom-variant data-unchecked {
|
|
53
|
+
&:where([data-state="unchecked"]),
|
|
54
|
+
&:where([data-unchecked]:not([data-unchecked="false"])) {
|
|
55
|
+
@slot;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
@custom-variant data-selected {
|
|
60
|
+
&:where([data-selected="true"]) {
|
|
61
|
+
@slot;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
@custom-variant data-disabled {
|
|
66
|
+
&:where([data-disabled="true"]),
|
|
67
|
+
&:where([data-disabled]:not([data-disabled="false"])) {
|
|
68
|
+
@slot;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
@custom-variant data-active {
|
|
73
|
+
&:where([data-state="active"]),
|
|
74
|
+
&:where([data-active]:not([data-active="false"])) {
|
|
75
|
+
@slot;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
@custom-variant data-horizontal {
|
|
80
|
+
&:where([data-orientation="horizontal"]) {
|
|
81
|
+
@slot;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
@custom-variant data-vertical {
|
|
86
|
+
&:where([data-orientation="vertical"]) {
|
|
87
|
+
@slot;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
@utility no-scrollbar {
|
|
92
|
+
-ms-overflow-style: none;
|
|
93
|
+
scrollbar-width: none;
|
|
94
|
+
|
|
95
|
+
&::-webkit-scrollbar {
|
|
96
|
+
display: none;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/* scroll-fade */
|
|
101
|
+
@property --scroll-fade-t {
|
|
102
|
+
syntax: "<length-percentage>";
|
|
103
|
+
inherits: false;
|
|
104
|
+
initial-value: 0px;
|
|
105
|
+
}
|
|
106
|
+
@property --scroll-fade-b {
|
|
107
|
+
syntax: "<length-percentage>";
|
|
108
|
+
inherits: false;
|
|
109
|
+
initial-value: 0px;
|
|
110
|
+
}
|
|
111
|
+
@property --scroll-fade-s {
|
|
112
|
+
syntax: "<length-percentage>";
|
|
113
|
+
inherits: false;
|
|
114
|
+
initial-value: 0px;
|
|
115
|
+
}
|
|
116
|
+
@property --scroll-fade-e {
|
|
117
|
+
syntax: "<length-percentage>";
|
|
118
|
+
inherits: false;
|
|
119
|
+
initial-value: 0px;
|
|
120
|
+
}
|
|
121
|
+
@property --scroll-fade-mask {
|
|
122
|
+
syntax: "*";
|
|
123
|
+
inherits: false;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
@theme inline {
|
|
127
|
+
@keyframes scroll-fade-reveal-t {
|
|
128
|
+
from {
|
|
129
|
+
--scroll-fade-t: 0px;
|
|
130
|
+
}
|
|
131
|
+
to {
|
|
132
|
+
--scroll-fade-t: var(--_scroll-fade-size-t, var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10))));
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
@keyframes scroll-fade-reveal-b {
|
|
136
|
+
from {
|
|
137
|
+
--scroll-fade-b: var(--_scroll-fade-size-b, var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10))));
|
|
138
|
+
}
|
|
139
|
+
to {
|
|
140
|
+
--scroll-fade-b: 0px;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
@keyframes scroll-fade-reveal-s {
|
|
144
|
+
from {
|
|
145
|
+
--scroll-fade-s: 0px;
|
|
146
|
+
}
|
|
147
|
+
to {
|
|
148
|
+
--scroll-fade-s: var(--_scroll-fade-size-s, var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10))));
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
@keyframes scroll-fade-reveal-e {
|
|
152
|
+
from {
|
|
153
|
+
--scroll-fade-e: var(--_scroll-fade-size-e, var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10))));
|
|
154
|
+
}
|
|
155
|
+
to {
|
|
156
|
+
--scroll-fade-e: 0px;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
@utility scroll-fade {
|
|
162
|
+
--_scroll-fade-size-t: var(
|
|
163
|
+
--scroll-fade-t-size,
|
|
164
|
+
var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10)))
|
|
165
|
+
);
|
|
166
|
+
--_scroll-fade-size-b: var(
|
|
167
|
+
--scroll-fade-b-size,
|
|
168
|
+
var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10)))
|
|
169
|
+
);
|
|
170
|
+
--scroll-fade-block: linear-gradient(
|
|
171
|
+
to bottom,
|
|
172
|
+
transparent 0,
|
|
173
|
+
#000 var(--scroll-fade-t, 0px),
|
|
174
|
+
#000 calc(100% - var(--scroll-fade-b, 0px)),
|
|
175
|
+
transparent 100%
|
|
176
|
+
);
|
|
177
|
+
-webkit-mask-image: var(--scroll-fade-mask, var(--scroll-fade-block));
|
|
178
|
+
mask-image: var(--scroll-fade-mask, var(--scroll-fade-block));
|
|
179
|
+
-webkit-mask-composite: source-in;
|
|
180
|
+
mask-composite: intersect;
|
|
181
|
+
-webkit-mask-repeat: no-repeat;
|
|
182
|
+
mask-repeat: no-repeat;
|
|
183
|
+
|
|
184
|
+
@supports (animation-timeline: scroll()) {
|
|
185
|
+
animation:
|
|
186
|
+
scroll-fade-reveal-t 1ms ease-in-out,
|
|
187
|
+
scroll-fade-reveal-b 1ms ease-in-out;
|
|
188
|
+
animation-timeline: scroll(self y), scroll(self y);
|
|
189
|
+
animation-range:
|
|
190
|
+
0 var(--scroll-fade-reveal, calc(var(--spacing) * 24)),
|
|
191
|
+
calc(100% - var(--scroll-fade-reveal, calc(var(--spacing) * 24))) 100%;
|
|
192
|
+
animation-fill-mode: both;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
@supports not (animation-timeline: scroll()) {
|
|
196
|
+
--scroll-fade-t: var(--_scroll-fade-size-t);
|
|
197
|
+
--scroll-fade-b: var(--_scroll-fade-size-b);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
@utility scroll-fade-y {
|
|
202
|
+
--_scroll-fade-size-t: var(
|
|
203
|
+
--scroll-fade-t-size,
|
|
204
|
+
var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10)))
|
|
205
|
+
);
|
|
206
|
+
--_scroll-fade-size-b: var(
|
|
207
|
+
--scroll-fade-b-size,
|
|
208
|
+
var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10)))
|
|
209
|
+
);
|
|
210
|
+
--scroll-fade-block: linear-gradient(
|
|
211
|
+
to bottom,
|
|
212
|
+
transparent 0,
|
|
213
|
+
#000 var(--scroll-fade-t, 0px),
|
|
214
|
+
#000 calc(100% - var(--scroll-fade-b, 0px)),
|
|
215
|
+
transparent 100%
|
|
216
|
+
);
|
|
217
|
+
-webkit-mask-image: var(--scroll-fade-mask, var(--scroll-fade-block));
|
|
218
|
+
mask-image: var(--scroll-fade-mask, var(--scroll-fade-block));
|
|
219
|
+
-webkit-mask-composite: source-in;
|
|
220
|
+
mask-composite: intersect;
|
|
221
|
+
-webkit-mask-repeat: no-repeat;
|
|
222
|
+
mask-repeat: no-repeat;
|
|
223
|
+
|
|
224
|
+
@supports (animation-timeline: scroll()) {
|
|
225
|
+
animation:
|
|
226
|
+
scroll-fade-reveal-t 1ms ease-in-out,
|
|
227
|
+
scroll-fade-reveal-b 1ms ease-in-out;
|
|
228
|
+
animation-timeline: scroll(self y), scroll(self y);
|
|
229
|
+
animation-range:
|
|
230
|
+
0 var(--scroll-fade-reveal, calc(var(--spacing) * 24)),
|
|
231
|
+
calc(100% - var(--scroll-fade-reveal, calc(var(--spacing) * 24))) 100%;
|
|
232
|
+
animation-fill-mode: both;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
@supports not (animation-timeline: scroll()) {
|
|
236
|
+
--scroll-fade-t: var(--_scroll-fade-size-t);
|
|
237
|
+
--scroll-fade-b: var(--_scroll-fade-size-b);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
@utility scroll-fade-x {
|
|
242
|
+
--_scroll-fade-size-s: var(
|
|
243
|
+
--scroll-fade-s-size,
|
|
244
|
+
var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10)))
|
|
245
|
+
);
|
|
246
|
+
--_scroll-fade-size-e: var(
|
|
247
|
+
--scroll-fade-e-size,
|
|
248
|
+
var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10)))
|
|
249
|
+
);
|
|
250
|
+
--scroll-fade-inline: linear-gradient(
|
|
251
|
+
to right,
|
|
252
|
+
transparent 0,
|
|
253
|
+
#000 var(--scroll-fade-s, 0px),
|
|
254
|
+
#000 calc(100% - var(--scroll-fade-e, 0px)),
|
|
255
|
+
transparent 100%
|
|
256
|
+
);
|
|
257
|
+
&:where([dir="rtl"], [dir="rtl"] *) {
|
|
258
|
+
--scroll-fade-inline: linear-gradient(
|
|
259
|
+
to left,
|
|
260
|
+
transparent 0,
|
|
261
|
+
#000 var(--scroll-fade-s, 0px),
|
|
262
|
+
#000 calc(100% - var(--scroll-fade-e, 0px)),
|
|
263
|
+
transparent 100%
|
|
264
|
+
);
|
|
265
|
+
}
|
|
266
|
+
-webkit-mask-image: var(--scroll-fade-mask, var(--scroll-fade-inline));
|
|
267
|
+
mask-image: var(--scroll-fade-mask, var(--scroll-fade-inline));
|
|
268
|
+
-webkit-mask-composite: source-in;
|
|
269
|
+
mask-composite: intersect;
|
|
270
|
+
-webkit-mask-repeat: no-repeat;
|
|
271
|
+
mask-repeat: no-repeat;
|
|
272
|
+
|
|
273
|
+
@supports (animation-timeline: scroll()) {
|
|
274
|
+
animation:
|
|
275
|
+
scroll-fade-reveal-s 1ms ease-in-out,
|
|
276
|
+
scroll-fade-reveal-e 1ms ease-in-out;
|
|
277
|
+
animation-timeline: scroll(self inline), scroll(self inline);
|
|
278
|
+
animation-range:
|
|
279
|
+
0 var(--scroll-fade-reveal, calc(var(--spacing) * 24)),
|
|
280
|
+
calc(100% - var(--scroll-fade-reveal, calc(var(--spacing) * 24))) 100%;
|
|
281
|
+
animation-fill-mode: both;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
@supports not (animation-timeline: scroll()) {
|
|
285
|
+
--scroll-fade-s: var(--_scroll-fade-size-s);
|
|
286
|
+
--scroll-fade-e: var(--_scroll-fade-size-e);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
@utility scroll-fade-t {
|
|
291
|
+
--_scroll-fade-size-t: var(
|
|
292
|
+
--scroll-fade-t-size,
|
|
293
|
+
var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10)))
|
|
294
|
+
);
|
|
295
|
+
--scroll-fade-mask: linear-gradient(
|
|
296
|
+
to bottom,
|
|
297
|
+
transparent 0,
|
|
298
|
+
#000 var(--scroll-fade-t, 0px),
|
|
299
|
+
#000 100%
|
|
300
|
+
);
|
|
301
|
+
-webkit-mask-image: var(--scroll-fade-mask);
|
|
302
|
+
mask-image: var(--scroll-fade-mask);
|
|
303
|
+
-webkit-mask-composite: source-in;
|
|
304
|
+
mask-composite: intersect;
|
|
305
|
+
-webkit-mask-repeat: no-repeat;
|
|
306
|
+
mask-repeat: no-repeat;
|
|
307
|
+
|
|
308
|
+
@supports (animation-timeline: scroll()) {
|
|
309
|
+
animation: scroll-fade-reveal-t 1ms ease-in-out;
|
|
310
|
+
animation-timeline: scroll(self y);
|
|
311
|
+
animation-range: 0 var(--scroll-fade-reveal, calc(var(--spacing) * 24));
|
|
312
|
+
animation-fill-mode: both;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
@supports not (animation-timeline: scroll()) {
|
|
316
|
+
--scroll-fade-t: var(--_scroll-fade-size-t);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
@utility scroll-fade-b {
|
|
321
|
+
--_scroll-fade-size-b: var(
|
|
322
|
+
--scroll-fade-b-size,
|
|
323
|
+
var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10)))
|
|
324
|
+
);
|
|
325
|
+
--scroll-fade-mask: linear-gradient(
|
|
326
|
+
to bottom,
|
|
327
|
+
#000 0,
|
|
328
|
+
#000 calc(100% - var(--scroll-fade-b, 0px)),
|
|
329
|
+
transparent 100%
|
|
330
|
+
);
|
|
331
|
+
-webkit-mask-image: var(--scroll-fade-mask);
|
|
332
|
+
mask-image: var(--scroll-fade-mask);
|
|
333
|
+
-webkit-mask-composite: source-in;
|
|
334
|
+
mask-composite: intersect;
|
|
335
|
+
-webkit-mask-repeat: no-repeat;
|
|
336
|
+
mask-repeat: no-repeat;
|
|
337
|
+
|
|
338
|
+
@supports (animation-timeline: scroll()) {
|
|
339
|
+
animation: scroll-fade-reveal-b 1ms ease-in-out;
|
|
340
|
+
animation-timeline: scroll(self y);
|
|
341
|
+
animation-range: calc(
|
|
342
|
+
100% - var(--scroll-fade-reveal, calc(var(--spacing) * 24))
|
|
343
|
+
)
|
|
344
|
+
100%;
|
|
345
|
+
animation-fill-mode: both;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
@supports not (animation-timeline: scroll()) {
|
|
349
|
+
--scroll-fade-b: var(--_scroll-fade-size-b);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
@utility scroll-fade-l {
|
|
354
|
+
--_scroll-fade-size-s: var(
|
|
355
|
+
--scroll-fade-s-size,
|
|
356
|
+
var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10)))
|
|
357
|
+
);
|
|
358
|
+
--scroll-fade-mask: linear-gradient(
|
|
359
|
+
to right,
|
|
360
|
+
transparent 0,
|
|
361
|
+
#000 var(--scroll-fade-s, 0px),
|
|
362
|
+
#000 100%
|
|
363
|
+
);
|
|
364
|
+
-webkit-mask-image: var(--scroll-fade-mask);
|
|
365
|
+
mask-image: var(--scroll-fade-mask);
|
|
366
|
+
-webkit-mask-composite: source-in;
|
|
367
|
+
mask-composite: intersect;
|
|
368
|
+
-webkit-mask-repeat: no-repeat;
|
|
369
|
+
mask-repeat: no-repeat;
|
|
370
|
+
|
|
371
|
+
@supports (animation-timeline: scroll()) {
|
|
372
|
+
animation: scroll-fade-reveal-s 1ms ease-in-out;
|
|
373
|
+
animation-timeline: scroll(self x);
|
|
374
|
+
animation-range: 0 var(--scroll-fade-reveal, calc(var(--spacing) * 24));
|
|
375
|
+
animation-fill-mode: both;
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
@supports not (animation-timeline: scroll()) {
|
|
379
|
+
--scroll-fade-s: var(--_scroll-fade-size-s);
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
@utility scroll-fade-r {
|
|
384
|
+
--_scroll-fade-size-e: var(
|
|
385
|
+
--scroll-fade-e-size,
|
|
386
|
+
var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10)))
|
|
387
|
+
);
|
|
388
|
+
--scroll-fade-mask: linear-gradient(
|
|
389
|
+
to right,
|
|
390
|
+
#000 0,
|
|
391
|
+
#000 calc(100% - var(--scroll-fade-e, 0px)),
|
|
392
|
+
transparent 100%
|
|
393
|
+
);
|
|
394
|
+
-webkit-mask-image: var(--scroll-fade-mask);
|
|
395
|
+
mask-image: var(--scroll-fade-mask);
|
|
396
|
+
-webkit-mask-composite: source-in;
|
|
397
|
+
mask-composite: intersect;
|
|
398
|
+
-webkit-mask-repeat: no-repeat;
|
|
399
|
+
mask-repeat: no-repeat;
|
|
400
|
+
|
|
401
|
+
@supports (animation-timeline: scroll()) {
|
|
402
|
+
animation: scroll-fade-reveal-e 1ms ease-in-out;
|
|
403
|
+
animation-timeline: scroll(self x);
|
|
404
|
+
animation-range: calc(
|
|
405
|
+
100% - var(--scroll-fade-reveal, calc(var(--spacing) * 24))
|
|
406
|
+
)
|
|
407
|
+
100%;
|
|
408
|
+
animation-fill-mode: both;
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
@supports not (animation-timeline: scroll()) {
|
|
412
|
+
--scroll-fade-e: var(--_scroll-fade-size-e);
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
@utility scroll-fade-s {
|
|
417
|
+
--_scroll-fade-size-s: var(
|
|
418
|
+
--scroll-fade-s-size,
|
|
419
|
+
var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10)))
|
|
420
|
+
);
|
|
421
|
+
--scroll-fade-mask: linear-gradient(
|
|
422
|
+
to right,
|
|
423
|
+
transparent 0,
|
|
424
|
+
#000 var(--scroll-fade-s, 0px),
|
|
425
|
+
#000 100%
|
|
426
|
+
);
|
|
427
|
+
&:where([dir="rtl"], [dir="rtl"] *) {
|
|
428
|
+
--scroll-fade-mask: linear-gradient(
|
|
429
|
+
to left,
|
|
430
|
+
transparent 0,
|
|
431
|
+
#000 var(--scroll-fade-s, 0px),
|
|
432
|
+
#000 100%
|
|
433
|
+
);
|
|
434
|
+
}
|
|
435
|
+
-webkit-mask-image: var(--scroll-fade-mask);
|
|
436
|
+
mask-image: var(--scroll-fade-mask);
|
|
437
|
+
-webkit-mask-composite: source-in;
|
|
438
|
+
mask-composite: intersect;
|
|
439
|
+
-webkit-mask-repeat: no-repeat;
|
|
440
|
+
mask-repeat: no-repeat;
|
|
441
|
+
|
|
442
|
+
@supports (animation-timeline: scroll()) {
|
|
443
|
+
animation: scroll-fade-reveal-s 1ms ease-in-out;
|
|
444
|
+
animation-timeline: scroll(self inline);
|
|
445
|
+
animation-range: 0 var(--scroll-fade-reveal, calc(var(--spacing) * 24));
|
|
446
|
+
animation-fill-mode: both;
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
@supports not (animation-timeline: scroll()) {
|
|
450
|
+
--scroll-fade-s: var(--_scroll-fade-size-s);
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
@utility scroll-fade-e {
|
|
455
|
+
--_scroll-fade-size-e: var(
|
|
456
|
+
--scroll-fade-e-size,
|
|
457
|
+
var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10)))
|
|
458
|
+
);
|
|
459
|
+
--scroll-fade-mask: linear-gradient(
|
|
460
|
+
to right,
|
|
461
|
+
#000 0,
|
|
462
|
+
#000 calc(100% - var(--scroll-fade-e, 0px)),
|
|
463
|
+
transparent 100%
|
|
464
|
+
);
|
|
465
|
+
&:where([dir="rtl"], [dir="rtl"] *) {
|
|
466
|
+
--scroll-fade-mask: linear-gradient(
|
|
467
|
+
to left,
|
|
468
|
+
#000 0,
|
|
469
|
+
#000 calc(100% - var(--scroll-fade-e, 0px)),
|
|
470
|
+
transparent 100%
|
|
471
|
+
);
|
|
472
|
+
}
|
|
473
|
+
-webkit-mask-image: var(--scroll-fade-mask);
|
|
474
|
+
mask-image: var(--scroll-fade-mask);
|
|
475
|
+
-webkit-mask-composite: source-in;
|
|
476
|
+
mask-composite: intersect;
|
|
477
|
+
-webkit-mask-repeat: no-repeat;
|
|
478
|
+
mask-repeat: no-repeat;
|
|
479
|
+
|
|
480
|
+
@supports (animation-timeline: scroll()) {
|
|
481
|
+
animation: scroll-fade-reveal-e 1ms ease-in-out;
|
|
482
|
+
animation-timeline: scroll(self inline);
|
|
483
|
+
animation-range: calc(
|
|
484
|
+
100% - var(--scroll-fade-reveal, calc(var(--spacing) * 24))
|
|
485
|
+
)
|
|
486
|
+
100%;
|
|
487
|
+
animation-fill-mode: both;
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
@supports not (animation-timeline: scroll()) {
|
|
491
|
+
--scroll-fade-e: var(--_scroll-fade-size-e);
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
@utility scroll-fade-* {
|
|
496
|
+
--scroll-fade-size: calc(var(--spacing) * --value(integer));
|
|
497
|
+
--scroll-fade-size: --value([length], [percentage]);
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
@utility scroll-fade-t-* {
|
|
501
|
+
--scroll-fade-t-size: calc(var(--spacing) * --value(integer));
|
|
502
|
+
--scroll-fade-t-size: --value([length], [percentage]);
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
@utility scroll-fade-b-* {
|
|
506
|
+
--scroll-fade-b-size: calc(var(--spacing) * --value(integer));
|
|
507
|
+
--scroll-fade-b-size: --value([length], [percentage]);
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
@utility scroll-fade-s-* {
|
|
511
|
+
--scroll-fade-s-size: calc(var(--spacing) * --value(integer));
|
|
512
|
+
--scroll-fade-s-size: --value([length], [percentage]);
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
@utility scroll-fade-e-* {
|
|
516
|
+
--scroll-fade-e-size: calc(var(--spacing) * --value(integer));
|
|
517
|
+
--scroll-fade-e-size: --value([length], [percentage]);
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
@utility scroll-fade-none {
|
|
521
|
+
--scroll-fade-mask: none;
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
/* shimmer */
|
|
525
|
+
@property --shimmer-angle {
|
|
526
|
+
syntax: "<angle>";
|
|
527
|
+
inherits: true;
|
|
528
|
+
initial-value: 20deg;
|
|
529
|
+
}
|
|
530
|
+
@property --shimmer-image {
|
|
531
|
+
syntax: "*";
|
|
532
|
+
inherits: false;
|
|
533
|
+
}
|
|
534
|
+
@property --shimmer-text-fill {
|
|
535
|
+
syntax: "*";
|
|
536
|
+
inherits: false;
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
@theme inline {
|
|
540
|
+
@keyframes tw-shimmer {
|
|
541
|
+
from {
|
|
542
|
+
background-position: 100% 0;
|
|
543
|
+
}
|
|
544
|
+
to {
|
|
545
|
+
background-position: 0 0;
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
@utility shimmer {
|
|
551
|
+
--_spread: var(--shimmer-spread, calc(3ch + 40px));
|
|
552
|
+
--_base: currentColor;
|
|
553
|
+
--_highlight: var(
|
|
554
|
+
--shimmer-color,
|
|
555
|
+
oklch(from currentColor l c h / calc(alpha* 0.2))
|
|
556
|
+
);
|
|
557
|
+
|
|
558
|
+
background-image: var(
|
|
559
|
+
--shimmer-image,
|
|
560
|
+
linear-gradient(
|
|
561
|
+
calc(90deg + var(--shimmer-angle)),
|
|
562
|
+
var(--_base) calc(50% - var(--_spread)),
|
|
563
|
+
color-mix(in oklch, var(--_highlight), var(--_base) 50%)
|
|
564
|
+
calc(50% - var(--_spread) * 0.5),
|
|
565
|
+
var(--_highlight) 50%,
|
|
566
|
+
color-mix(in oklch, var(--_highlight), var(--_base) 50%)
|
|
567
|
+
calc(50% + var(--_spread) * 0.5),
|
|
568
|
+
var(--_base) calc(50% + var(--_spread))
|
|
569
|
+
)
|
|
570
|
+
);
|
|
571
|
+
background-repeat: no-repeat;
|
|
572
|
+
background-size: calc(200% + var(--_spread) * 2) 100%;
|
|
573
|
+
background-position: 0 0;
|
|
574
|
+
background-clip: text;
|
|
575
|
+
-webkit-background-clip: text;
|
|
576
|
+
-webkit-text-fill-color: var(--shimmer-text-fill, transparent);
|
|
577
|
+
animation: tw-shimmer var(--shimmer-duration, 2s) linear infinite;
|
|
578
|
+
|
|
579
|
+
@variant dark {
|
|
580
|
+
--_highlight: var(
|
|
581
|
+
--shimmer-color,
|
|
582
|
+
oklch(from currentColor max(0.8, calc(l + 0.4)) c h / calc(alpha + 0.4))
|
|
583
|
+
);
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
&:where([dir="rtl"], [dir="rtl"] *) {
|
|
587
|
+
animation-direction: reverse;
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
@media (prefers-reduced-motion: reduce) {
|
|
591
|
+
animation: none;
|
|
592
|
+
background-image: none;
|
|
593
|
+
-webkit-text-fill-color: currentColor;
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
@utility shimmer-once {
|
|
598
|
+
animation-iteration-count: 1;
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
@utility shimmer-reverse {
|
|
602
|
+
animation-direction: reverse;
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
@utility shimmer-none {
|
|
606
|
+
--shimmer-image: none;
|
|
607
|
+
--shimmer-text-fill: currentColor;
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
@utility shimmer-color-* {
|
|
611
|
+
--shimmer-color: --value(--color, [color]);
|
|
612
|
+
--shimmer-color: color-mix(
|
|
613
|
+
in oklch,
|
|
614
|
+
--value(--color, [color]) calc(--modifier(integer) * 1%),
|
|
615
|
+
transparent
|
|
616
|
+
);
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
@utility shimmer-duration-* {
|
|
620
|
+
--shimmer-duration: calc(--value(integer) * 1ms);
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
@utility shimmer-spread-* {
|
|
624
|
+
--shimmer-spread: calc(var(--spacing) * --value(integer));
|
|
625
|
+
--shimmer-spread: --value([length], [percentage]);
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
@utility shimmer-angle-* {
|
|
629
|
+
--shimmer-angle: calc(--value(integer) * 1deg);
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
/* Kept for backwards compatibility. Unlayered, so it still wins over other
|
|
633
|
+
utilities on a plain .shimmer element. Variants are handled in the utility. */
|
|
634
|
+
@media (prefers-reduced-motion: reduce) {
|
|
635
|
+
.shimmer {
|
|
636
|
+
animation: none;
|
|
637
|
+
background-image: none;
|
|
638
|
+
-webkit-text-fill-color: currentColor;
|
|
639
|
+
}
|
|
640
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { cn } from '../lib/utils'
|
|
2
|
+
|
|
3
|
+
/** A browser with a logo in `BrowserIcon`. */
|
|
4
|
+
export type BrowserName = 'chrome' | 'firefox' | 'opera' | 'safari'
|
|
5
|
+
|
|
6
|
+
// Path data from Simple Icons (https://simpleicons.org, CC0), copied rather
|
|
7
|
+
// than depended on: the package is a single 5 MB module. Microsoft's logos,
|
|
8
|
+
// Edge's among them, are no longer in Simple Icons.
|
|
9
|
+
const LOGOS: Record<BrowserName, { color: string; path: string }> = {
|
|
10
|
+
chrome: {
|
|
11
|
+
color: '#4285F4',
|
|
12
|
+
path: 'M12 0C8.21 0 4.831 1.757 2.632 4.501l3.953 6.848A5.454 5.454 0 0 1 12 6.545h10.691A12 12 0 0 0 12 0zM1.931 5.47A11.943 11.943 0 0 0 0 12c0 6.012 4.42 10.991 10.189 11.864l3.953-6.847a5.45 5.45 0 0 1-6.865-2.29zm13.342 2.166a5.446 5.446 0 0 1 1.45 7.09l.002.001h-.002l-5.344 9.257c.206.01.413.016.621.016 6.627 0 12-5.373 12-12 0-1.54-.29-3.011-.818-4.364zM12 16.364a4.364 4.364 0 1 1 0-8.728 4.364 4.364 0 0 1 0 8.728Z',
|
|
13
|
+
},
|
|
14
|
+
firefox: {
|
|
15
|
+
color: '#FF7139',
|
|
16
|
+
path: 'M8.824 7.287c.008 0 .004 0 0 0zm-2.8-1.4c.006 0 .003 0 0 0zm16.754 2.161c-.505-1.215-1.53-2.528-2.333-2.943.654 1.283 1.033 2.57 1.177 3.53l.002.02c-1.314-3.278-3.544-4.6-5.366-7.477-.091-.147-.184-.292-.273-.446a3.545 3.545 0 01-.13-.24 2.118 2.118 0 01-.172-.46.03.03 0 00-.027-.03.038.038 0 00-.021 0l-.006.001a.037.037 0 00-.01.005L15.624 0c-2.585 1.515-3.657 4.168-3.932 5.856a6.197 6.197 0 00-2.305.587.297.297 0 00-.147.37c.057.162.24.24.396.17a5.622 5.622 0 012.008-.523l.067-.005a5.847 5.847 0 011.957.222l.095.03a5.816 5.816 0 01.616.228c.08.036.16.073.238.112l.107.055a5.835 5.835 0 01.368.211 5.953 5.953 0 012.034 2.104c-.62-.437-1.733-.868-2.803-.681 4.183 2.09 3.06 9.292-2.737 9.02a5.164 5.164 0 01-1.513-.292 4.42 4.42 0 01-.538-.232c-1.42-.735-2.593-2.121-2.74-3.806 0 0 .537-2 3.845-2 .357 0 1.38-.998 1.398-1.287-.005-.095-2.029-.9-2.817-1.677-.422-.416-.622-.616-.8-.767a3.47 3.47 0 00-.301-.227 5.388 5.388 0 01-.032-2.842c-1.195.544-2.124 1.403-2.8 2.163h-.006c-.46-.584-.428-2.51-.402-2.913-.006-.025-.343.176-.389.206-.406.29-.787.616-1.136.974-.397.403-.76.839-1.085 1.303a9.816 9.816 0 00-1.562 3.52c-.003.013-.11.487-.19 1.073-.013.09-.026.181-.037.272a7.8 7.8 0 00-.069.667l-.002.034-.023.387-.001.06C.386 18.795 5.593 24 12.016 24c5.752 0 10.527-4.176 11.463-9.661.02-.149.035-.298.052-.448.232-1.994-.025-4.09-.753-5.844z',
|
|
17
|
+
},
|
|
18
|
+
opera: {
|
|
19
|
+
color: '#FF1B2D',
|
|
20
|
+
path: 'M8.051 5.238c-1.328 1.566-2.186 3.883-2.246 6.48v.564c.061 2.598.918 4.912 2.246 6.479 1.721 2.236 4.279 3.654 7.139 3.654 1.756 0 3.4-.537 4.807-1.471C17.879 22.846 15.074 24 12 24c-.192 0-.383-.004-.57-.014C5.064 23.689 0 18.436 0 12 0 5.371 5.373 0 12 0h.045c3.055.012 5.84 1.166 7.953 3.055-1.408-.93-3.051-1.471-4.81-1.471-2.858 0-5.417 1.42-7.14 3.654h.003zM24 12c0 3.556-1.545 6.748-4.002 8.945-3.078 1.5-5.946.451-6.896-.205 3.023-.664 5.307-4.32 5.307-8.74 0-4.422-2.283-8.075-5.307-8.74.949-.654 3.818-1.703 6.896-.205C22.455 5.25 24 8.445 24 12z',
|
|
21
|
+
},
|
|
22
|
+
safari: {
|
|
23
|
+
color: '#006CFF',
|
|
24
|
+
path: 'M12 0A12 12 0 0 0 0 12a12 12 0 0 0 12 12 12 12 0 0 0 12-12A12 12 0 0 0 12 0zm-.004.953h.006c.063 0 .113.05.113.113v1.842c0 .063-.05.113-.113.113h-.006a.112.112 0 0 1-.113-.113V1.066c0-.063.05-.113.113-.113zm-.941.041c.056.001.104.046.11.104l.077.918a.112.112 0 0 1-.101.12h-.01a.11.11 0 0 1-.12-.1l-.08-.919a.112.112 0 0 1 .102-.12h.01l.012-.003zm1.892 0H12.965a.113.113 0 0 1 .103.121l-.08.92a.111.111 0 0 1-.12.102h-.009a.111.111 0 0 1-.101-.121l.078-.92a.112.112 0 0 1 .111-.102zm-2.838.123a.11.11 0 0 1 .106.092l.32 1.818c.01.06-.03.119-.09.13l-.01.001a.111.111 0 0 1-.128-.09l-.32-1.818a.111.111 0 0 1 .09-.129l.01-.002a.103.103 0 0 1 .022-.002zm3.784.002h.021l.008.002c.061.01.102.07.092.131l-.32 1.814c-.011.062-.07.101-.132.09h-.005a.113.113 0 0 1-.092-.13l.32-1.815a.111.111 0 0 1 .108-.092zm-4.715.203c.048.002.09.035.103.084l.239.893a.112.112 0 0 1-.079.139l-.005.001a.114.114 0 0 1-.14-.08l-.237-.894a.11.11 0 0 1 .078-.137l.006-.002a.123.123 0 0 1 .035-.004zm5.644 0a.11.11 0 0 1 .033.004l.006.002c.06.016.097.079.08.139l-.24.892a.112.112 0 0 1-.137.08l-.005-.002a.114.114 0 0 1-.08-.138l.24-.893a.112.112 0 0 1 .103-.084zm-6.562.285a.11.11 0 0 1 .107.073L9 3.42a.107.107 0 0 1-.064.139l-.012.005a.11.11 0 0 1-.14-.066L8.15 1.76a.11.11 0 0 1 .065-.14l.014-.005a.106.106 0 0 1 .03-.008zm7.469.002c.014 0 .028.001.042.006l.012.006c.057.02.087.082.067.139l-.633 1.738a.11.11 0 0 1-.14.066l-.013-.003A.11.11 0 0 1 15 3.42l.633-1.738a.108.108 0 0 1 .096-.073zm-8.352.366a.112.112 0 0 1 .105.064l.393.838a.112.112 0 0 1-.055.148l-.008.004a.11.11 0 0 1-.146-.054l-.395-.838a.112.112 0 0 1 .055-.149l.008-.004a.11.11 0 0 1 .043-.01zm9.246 0a.11.11 0 0 1 .043.01l.006.003a.11.11 0 0 1 .053.149l-.391.838a.112.112 0 0 1-.148.054l-.006-.002a.112.112 0 0 1-.055-.148l.393-.84a.112.112 0 0 1 .105-.064zm-10.092.44c.04-.002.08.018.102.056l.922 1.597a.113.113 0 0 1-.041.155l-.006.002a.113.113 0 0 1-.154-.041l-.922-1.598a.113.113 0 0 1 .04-.154l.007-.002a.11.11 0 0 1 .052-.016zm10.94.001c.018 0 .035.004.052.014l.004.002a.114.114 0 0 1 .041.156l-.923 1.596a.114.114 0 0 1-.157.04l-.004-.001a.112.112 0 0 1-.04-.155l.925-1.595a.113.113 0 0 1 .102-.057zM5.729 2.93a.11.11 0 0 1 .093.047l.532.753a.114.114 0 0 1-.028.159l-.004.002a.114.114 0 0 1-.158-.028l-.531-.752a.114.114 0 0 1 .027-.158l.006-.002a.113.113 0 0 1 .063-.021zm12.542 0a.11.11 0 0 1 .063.02l.006.003a.112.112 0 0 1 .027.156l-.531.756a.112.112 0 0 1-.156.028l-.006-.004a.112.112 0 0 1-.028-.157l.532-.755a.11.11 0 0 1 .093-.047zm.747.578a.11.11 0 0 1 .08.027l.006.004c.047.04.053.111.013.158L17.932 5.11a.11.11 0 0 1-.157.016l-.005-.006a.11.11 0 0 1-.014-.156l1.185-1.414a.114.114 0 0 1 .077-.041zM4.984 3.51a.11.11 0 0 1 .077.039L6.244 4.96a.112.112 0 0 1-.014.158l-.003.004a.112.112 0 0 1-.159-.014L4.883 3.697a.112.112 0 0 1 .013-.158l.006-.004a.111.111 0 0 1 .082-.025zm-.714.64c.027 0 .055.01.076.032l.658.66a.107.107 0 0 1 0 .152l-.01.01a.107.107 0 0 1-.152 0l-.66-.658a.11.11 0 0 1 0-.155l.01-.01a.111.111 0 0 1 .078-.03zm15.462 0c.028 0 .055.01.077.032l.007.007a.109.109 0 0 1 0 .155l-.658.66a.109.109 0 0 1-.154 0l-.008-.008a.109.109 0 0 1 0-.154l.658-.66a.11.11 0 0 1 .078-.032zm.707.66c.038 0 .071.02.092.075a.112.112 0 0 1-.023.117l-7.606 8.08c-3.084 2.024-6.149 4.04-9.222 6.05-.078.051-.17.082-.211-.028a.112.112 0 0 1 .023-.118l7.594-8.08c3.084-2.023 6.161-4.039 9.234-6.049a.247.247 0 0 1 .12-.046zm-16.824.045a.109.109 0 0 1 .08.026l1.416 1.187a.11.11 0 0 1 .014.157l-.006.005a.11.11 0 0 1-.156.014L3.549 5.057a.109.109 0 0 1-.014-.155l.006-.007a.108.108 0 0 1 .074-.04zm17.336.756c.036 0 .072.017.094.05l.004.003a.114.114 0 0 1-.028.158l-.753.53a.112.112 0 0 1-.157-.028l-.004-.004a.114.114 0 0 1 .028-.158l.754-.53a.113.113 0 0 1 .062-.02zm-17.904.002c.02 0 .042.007.06.02l.76.531c.05.035.06.103.026.152l-.006.01a.109.109 0 0 1-.153.026l-.76-.532a.109.109 0 0 1-.025-.152l.006-.01a.108.108 0 0 1 .092-.045zm-.512.803c.018 0 .036.006.053.016l1.596.923a.111.111 0 0 1 .04.153l-.003.006a.111.111 0 0 1-.153.04L2.473 6.63a.111.111 0 0 1-.041-.152l.004-.006a.11.11 0 0 1 .1-.055zm18.932 0a.11.11 0 0 1 .1.055l.001.004a.113.113 0 0 1-.04.154l-1.596.926a.113.113 0 0 1-.155-.041l-.002-.004a.113.113 0 0 1 .041-.155l1.596-.925a.115.115 0 0 1 .055-.014zm-19.373.846c.014 0 .029.003.043.01l.838.392a.11.11 0 0 1 .052.147l-.004.01a.11.11 0 0 1-.146.052l-.838-.393a.11.11 0 0 1-.053-.146l.004-.01a.109.109 0 0 1 .104-.062zm19.81.002a.11.11 0 0 1 .106.062l.002.008a.11.11 0 0 1-.053.146l-.838.393a.11.11 0 0 1-.146-.053l-.004-.008a.11.11 0 0 1 .052-.146l.838-.393a.11.11 0 0 1 .043-.01zm-20.183.88c.014 0 .028.001.043.006l1.732.631a.112.112 0 0 1 .067.145l-.002.006a.11.11 0 0 1-.143.066l-1.732-.63a.113.113 0 0 1-.069-.145l.002-.004a.115.115 0 0 1 .102-.074zm20.549 0a.113.113 0 0 1 .11.075l.003.004a.115.115 0 0 1-.069.146l-1.732.629a.112.112 0 0 1-.145-.066l-.001-.006a.113.113 0 0 1 .068-.145l1.732-.63a.11.11 0 0 1 .034-.006zm-20.836.909a.11.11 0 0 1 .033.004l.892.24c.06.016.096.077.08.137l-.002.007a.11.11 0 0 1-.136.079l-.895-.239a.113.113 0 0 1-.078-.138l.002-.006a.113.113 0 0 1 .104-.084zm21.13.002a.115.115 0 0 1 .106.084v.004a.112.112 0 0 1-.078.138l-.893.239a.112.112 0 0 1-.138-.079v-.005a.112.112 0 0 1 .078-.14l.892-.237a.11.11 0 0 1 .033-.004zm-21.335.93.023.001 1.814.323c.062.01.101.069.09.13v.006a.111.111 0 0 1-.13.09l-1.815-.322a.113.113 0 0 1-.092-.131l.002-.006a.11.11 0 0 1 .108-.092zm21.519.001h.022c.052.002.1.038.109.092v.006c.01.062-.03.12-.092.13l-1.814.321a.113.113 0 0 1-.131-.092v-.005a.113.113 0 0 1 .092-.131l1.814-.32zm-21.644.944h.011l.922.084a.11.11 0 0 1 .102.119l-.002.01a.11.11 0 0 1-.121.1l-.922-.083a.11.11 0 0 1-.1-.12v-.009a.111.111 0 0 1 .11-.101zm21.779.002h.012c.056 0 .106.043.11.101v.008a.111.111 0 0 1-.1.121l-.923.08a.111.111 0 0 1-.12-.101v-.008a.111.111 0 0 1 .1-.121l.92-.08zm-11.82.73L6.091 16.95c2.02-1.324 4.039-2.646 6.066-3.976l-1.095-1.31zm11.87.219c.063 0 .114.05.114.113v.004c0 .063-.05.113-.113.113l-1.844.004a.113.113 0 0 1-.113-.113v-.004c0-.063.05-.113.113-.113l1.844-.004zm-21.869.002h1.844c.062 0 .112.05.112.111v.008c0 .062-.05.111-.112.111H1.064a.111.111 0 0 1-.11-.111v-.008c0-.061.049-.111.11-.111zm.952.875h.011a.11.11 0 0 1 .11.101v.006a.111.111 0 0 1-.102.121l-.922.08a.11.11 0 0 1-.119-.101l-.002-.006a.111.111 0 0 1 .102-.121l.922-.08zm19.955 0h.011l.922.08a.11.11 0 0 1 .102.119v.008a.112.112 0 0 1-.121.101l-.922-.08a.11.11 0 0 1-.102-.119v-.008a.111.111 0 0 1 .11-.101zm-18.924.705c.053.001.098.04.107.094l.002.004c.011.061-.03.12-.092.13l-1.812.32a.113.113 0 0 1-.13-.091v-.004a.115.115 0 0 1 .09-.133l1.811-.318a.117.117 0 0 1 .024-.002zm17.902 0c.008 0 .016 0 .024.002l1.816.32c.061.011.1.07.09.131v.004a.113.113 0 0 1-.131.092l-1.816-.32a.112.112 0 0 1-.09-.131v-.004a.113.113 0 0 1 .107-.094zM2.332 14.477a.11.11 0 0 1 .104.082l.002.005c.016.06-.02.121-.08.137l-.891.24a.112.112 0 0 1-.137-.08l-.002-.006a.112.112 0 0 1 .08-.136l.89-.239a.112.112 0 0 1 .034-.003zm19.332 0c.011 0 .024 0 .035.003l.893.239c.06.016.096.077.08.136l-.002.006a.111.111 0 0 1-.137.078l-.894-.238a.111.111 0 0 1-.078-.137l.002-.005a.109.109 0 0 1 .101-.082zm-18.213.517a.11.11 0 0 1 .11.074l.002.004a.112.112 0 0 1-.067.145l-1.732.63a.113.113 0 0 1-.145-.068l-.002-.004a.113.113 0 0 1 .069-.144L3.418 15a.11.11 0 0 1 .033-.006zm17.086 0c.015 0 .029 0 .043.006l1.734.63a.111.111 0 0 1 .067.143l-.002.008a.111.111 0 0 1-.143.067l-1.734-.631a.111.111 0 0 1-.066-.143l.002-.008a.111.111 0 0 1 .1-.072zM2.92 16.117a.109.109 0 0 1 .103.063l.004.01a.108.108 0 0 1-.052.144l-.838.393a.11.11 0 0 1-.147-.055l-.004-.008a.11.11 0 0 1 .053-.146l.838-.391a.112.112 0 0 1 .043-.01zm18.158 0a.11.11 0 0 1 .043.01l.838.39c.056.027.08.093.055.149l-.002.004a.112.112 0 0 1-.149.055l-.838-.391a.112.112 0 0 1-.054-.148l.002-.004a.112.112 0 0 1 .105-.065zm-16.957.315c.04-.001.078.02.1.056l.004.004a.11.11 0 0 1-.041.153l-1.596.921a.113.113 0 0 1-.154-.04l-.002-.005a.113.113 0 0 1 .04-.154l1.596-.922a.109.109 0 0 1 .053-.013zm15.756 0c.018 0 .036.004.053.013l1.597.924a.11.11 0 0 1 .041.152l-.002.004a.11.11 0 0 1-.152.041l-1.598-.921a.113.113 0 0 1-.04-.155l.001-.002a.111.111 0 0 1 .1-.056zm.328 1.193a.11.11 0 0 1 .06.021l.758.534c.05.035.061.102.026.152l-.004.008a.111.111 0 0 1-.154.027l-.756-.535a.109.109 0 0 1-.028-.152l.006-.008a.11.11 0 0 1 .092-.047zm-16.412.002c.035 0 .072.016.094.047l.004.008a.109.109 0 0 1-.028.152l-.756.531a.108.108 0 0 1-.152-.025l-.006-.008a.109.109 0 0 1 .028-.152l.755-.534a.107.107 0 0 1 .061-.019zm15.162.102a.112.112 0 0 1 .082.025l1.414 1.187a.11.11 0 0 1 .014.157l-.004.004a.113.113 0 0 1-.158.013L18.89 17.93a.11.11 0 0 1-.014-.157l.004-.005a.108.108 0 0 1 .074-.04zm-12.812 1.12a.11.11 0 0 1 .08.026l.007.008a.11.11 0 0 1 .014.154L5.06 20.451a.11.11 0 0 1-.155.012l-.008-.006a.11.11 0 0 1-.013-.154l1.185-1.414a.11.11 0 0 1 .075-.04zm11.703 0c.032 0 .065.015.088.042l1.181 1.41c.04.048.035.12-.013.16l-.002.002a.114.114 0 0 1-.16-.014l-1.182-1.41a.114.114 0 0 1 .013-.16l.002-.002a.115.115 0 0 1 .073-.027zm-12.928.114c.027 0 .054.01.074.031l.014.012a.107.107 0 0 1 0 .15l-.662.66a.105.105 0 0 1-.149 0l-.011-.011a.105.105 0 0 1 0-.149l.66-.662a.105.105 0 0 1 .074-.031zm14.164 0c.027 0 .053.01.074.031l.66.662a.106.106 0 0 1 0 .15l-.011.012a.106.106 0 0 1-.15-.002l-.66-.66a.106.106 0 0 1 .001-.15l.01-.012a.108.108 0 0 1 .076-.031zm-11.627.797c.018 0 .034.006.05.015l.007.004a.11.11 0 0 1 .04.15l-.921 1.598a.11.11 0 0 1-.15.041l-.008-.004a.111.111 0 0 1-.04-.152l.922-1.596a.113.113 0 0 1 .1-.056zm9.088.002a.11.11 0 0 1 .1.054l.925 1.596a.113.113 0 0 1-.04.154h-.005a.11.11 0 0 1-.152-.039l-.926-1.595a.113.113 0 0 1 .041-.155l.004-.002a.108.108 0 0 1 .053-.013zm-10.285.324c.021 0 .043.008.062.021l.004.002c.051.036.063.106.028.157l-.53.755a.112.112 0 0 1-.156.028l-.004-.002a.112.112 0 0 1-.027-.156l.53-.756a.113.113 0 0 1 .093-.05zm11.484.002c.036 0 .072.015.094.047l.53.756c.035.05.023.12-.028.156l-.004.002a.112.112 0 0 1-.156-.028l-.53-.755a.112.112 0 0 1 .028-.157l.004-.002a.112.112 0 0 1 .062-.02zm-8.863.342a.11.11 0 0 1 .043.006l.012.005c.056.02.084.081.064.137l-.633 1.74a.105.105 0 0 1-.136.063l-.014-.004a.106.106 0 0 1-.065-.137l.633-1.74a.107.107 0 0 1 .096-.07zm6.232 0a.107.107 0 0 1 .106.07l.633 1.738a.107.107 0 0 1-.065.137l-.015.006a.107.107 0 0 1-.137-.065L15 20.578a.107.107 0 0 1 .064-.137l.014-.005a.117.117 0 0 1 .033-.006zm-4.695.41c.008 0 .014 0 .021.002l.006.002c.062.01.101.067.09.129l-.318 1.812a.113.113 0 0 1-.131.092l-.004-.002a.111.111 0 0 1-.092-.129l.32-1.812a.113.113 0 0 1 .108-.094zm3.146.002c.008-.002.015 0 .022 0a.111.111 0 0 1 .107.092l.32 1.812c.012.061-.03.12-.091.131l-.004.002a.113.113 0 0 1-.13-.092l-.321-1.812a.113.113 0 0 1 .092-.131l.005-.002zm-5.79.119a.11.11 0 0 1 .042.01l.004.002a.114.114 0 0 1 .055.15l-.393.834a.112.112 0 0 1-.148.055l-.004-.002a.112.112 0 0 1-.055-.149l.393-.836a.112.112 0 0 1 .105-.064zm8.458 0a.108.108 0 0 1 .104.062l.39.84a.11.11 0 0 1-.052.147l-.008.004a.11.11 0 0 1-.146-.055l-.391-.838a.11.11 0 0 1 .053-.146l.008-.004a.11.11 0 0 1 .042-.01zm-4.236.018H12c.063 0 .115.05.115.113l.002 1.84c0 .063-.05.113-.113.113h-.006a.113.113 0 0 1-.113-.113l-.004-1.838c0-.063.05-.115.113-.115zm-2.592.578c.011 0 .022 0 .034.004l.005.002c.06.016.095.077.079.136l-.24.893a.111.111 0 0 1-.137.078l-.006-.002a.111.111 0 0 1-.078-.137l.24-.89a.113.113 0 0 1 .103-.084zm5.196.002a.11.11 0 0 1 .103.082l.24.89a.11.11 0 0 1-.078.137l-.006.002a.11.11 0 0 1-.136-.078l-.24-.89a.11.11 0 0 1 .078-.138l.005-.002a.112.112 0 0 1 .034-.003zm-3.475.302h.01l.008.002c.061.006.107.06.101.121l-.08.92a.112.112 0 0 1-.121.102h-.008a.11.11 0 0 1-.1-.121l.08-.922a.111.111 0 0 1 .11-.102zm1.736 0h.02a.11.11 0 0 1 .107.102l.08.924a.11.11 0 0 1-.101.119l-.008.002a.11.11 0 0 1-.12-.102l-.08-.924a.112.112 0 0 1 .102-.12z',
|
|
25
|
+
},
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** A browser's logo in its brand colour. Decorative: pair it with a label. */
|
|
29
|
+
export function BrowserIcon({ browser, className }: { browser: BrowserName; className?: string }) {
|
|
30
|
+
const { color, path } = LOGOS[browser]
|
|
31
|
+
return (
|
|
32
|
+
<svg viewBox="0 0 24 24" fill={color} aria-hidden className={cn('size-4', className)}>
|
|
33
|
+
<path d={path} />
|
|
34
|
+
</svg>
|
|
35
|
+
)
|
|
36
|
+
}
|
package/src/spree/icons.ts
CHANGED
|
@@ -149,8 +149,10 @@ export {
|
|
|
149
149
|
SunIcon,
|
|
150
150
|
SwatchBookIcon,
|
|
151
151
|
TableIcon,
|
|
152
|
+
TabletIcon,
|
|
152
153
|
TagIcon,
|
|
153
154
|
TagsIcon,
|
|
155
|
+
TerminalIcon,
|
|
154
156
|
TicketPercentIcon,
|
|
155
157
|
Trash2Icon,
|
|
156
158
|
TrashIcon,
|
|
@@ -175,3 +177,4 @@ export {
|
|
|
175
177
|
XIcon,
|
|
176
178
|
ZapIcon,
|
|
177
179
|
} from 'lucide-react'
|
|
180
|
+
export { BrowserIcon, type BrowserName } from './browser-icon'
|
package/src/styles.css
CHANGED
package/src/ui/badge.tsx
CHANGED
|
@@ -78,6 +78,9 @@ type StatusTone = 'success' | 'warning' | 'destructive' | 'info' | 'neutral'
|
|
|
78
78
|
*/
|
|
79
79
|
const statusToneMap: Record<string, StatusTone> = {
|
|
80
80
|
active: 'success',
|
|
81
|
+
// Staff accounts: locked after too many failed sign-ins, deactivated by an admin.
|
|
82
|
+
locked: 'warning',
|
|
83
|
+
deactivated: 'neutral',
|
|
81
84
|
authorized: 'info',
|
|
82
85
|
complete: 'success',
|
|
83
86
|
completed: 'success',
|
package/src/ui/command.tsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Autocomplete as AutocompletePrimitive } from '@base-ui/react'
|
|
2
2
|
import i18n from 'i18next'
|
|
3
3
|
import * as React from 'react'
|
|
4
4
|
import { cn } from '../lib/utils'
|
|
@@ -12,16 +12,67 @@ import {
|
|
|
12
12
|
} from '../spree/icons'
|
|
13
13
|
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from './dialog'
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
const CommandContext = React.createContext<{
|
|
16
|
+
query: string
|
|
17
|
+
setQuery: (query: string) => void
|
|
18
|
+
shouldFilter: boolean
|
|
19
|
+
onInputChange: React.RefObject<((value: string) => void) | undefined>
|
|
20
|
+
}>({ query: '', setQuery: () => {}, shouldFilter: false, onInputChange: { current: undefined } })
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* A search field over a list of actions, on Base UI's Autocomplete rendered
|
|
24
|
+
* inline. The query lives on `CommandInput`. Rows whose `value` or text does not
|
|
25
|
+
* contain the query are hidden unless `shouldFilter` is false.
|
|
26
|
+
*/
|
|
27
|
+
function Command({
|
|
28
|
+
className,
|
|
29
|
+
children,
|
|
30
|
+
shouldFilter = true,
|
|
31
|
+
...props
|
|
32
|
+
}: React.ComponentProps<'div'> & { shouldFilter?: boolean }) {
|
|
33
|
+
const [query, setQuery] = React.useState('')
|
|
34
|
+
const onInputChange = React.useRef<((value: string) => void) | undefined>(undefined)
|
|
35
|
+
|
|
36
|
+
const context = React.useMemo(
|
|
37
|
+
() => ({ query, setQuery, shouldFilter, onInputChange }),
|
|
38
|
+
[query, shouldFilter],
|
|
39
|
+
)
|
|
40
|
+
|
|
16
41
|
return (
|
|
17
|
-
<
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
{
|
|
24
|
-
|
|
42
|
+
<AutocompletePrimitive.Root
|
|
43
|
+
inline
|
|
44
|
+
open
|
|
45
|
+
autoHighlight="always"
|
|
46
|
+
keepHighlight
|
|
47
|
+
filter={null}
|
|
48
|
+
value={query}
|
|
49
|
+
onValueChange={(next, eventDetails) => {
|
|
50
|
+
// Choosing a row would otherwise write that row's value into the field.
|
|
51
|
+
if (eventDetails.reason === 'item-press') return
|
|
52
|
+
setQuery(next)
|
|
53
|
+
onInputChange.current?.(next)
|
|
54
|
+
}}
|
|
55
|
+
onOpenChange={(_open, eventDetails) => {
|
|
56
|
+
// The list is always shown, so Escape belongs to the dialog around it.
|
|
57
|
+
if (eventDetails.reason === 'escape-key') {
|
|
58
|
+
eventDetails.cancel()
|
|
59
|
+
eventDetails.allowPropagation()
|
|
60
|
+
}
|
|
61
|
+
}}
|
|
62
|
+
>
|
|
63
|
+
<CommandContext.Provider value={context}>
|
|
64
|
+
<div
|
|
65
|
+
data-slot="command"
|
|
66
|
+
className={cn(
|
|
67
|
+
'flex size-full flex-col overflow-hidden rounded-2xl! bg-popover text-popover-foreground',
|
|
68
|
+
className,
|
|
69
|
+
)}
|
|
70
|
+
{...props}
|
|
71
|
+
>
|
|
72
|
+
{children}
|
|
73
|
+
</div>
|
|
74
|
+
</CommandContext.Provider>
|
|
75
|
+
</AutocompletePrimitive.Root>
|
|
25
76
|
)
|
|
26
77
|
}
|
|
27
78
|
|
|
@@ -72,18 +123,32 @@ function CommandDialog({
|
|
|
72
123
|
function CommandInput({
|
|
73
124
|
className,
|
|
74
125
|
loading = false,
|
|
126
|
+
value,
|
|
127
|
+
onValueChange,
|
|
75
128
|
...props
|
|
76
|
-
}:
|
|
129
|
+
}: Omit<AutocompletePrimitive.Input.Props, 'value'> & {
|
|
130
|
+
value?: string
|
|
131
|
+
onValueChange?: (value: string) => void
|
|
77
132
|
/** Shows a spinner at the end of the field while results are in flight. */
|
|
78
133
|
loading?: boolean
|
|
79
134
|
}) {
|
|
135
|
+
const { query, setQuery, onInputChange } = React.useContext(CommandContext)
|
|
136
|
+
React.useLayoutEffect(() => {
|
|
137
|
+
onInputChange.current = onValueChange
|
|
138
|
+
}, [onInputChange, onValueChange])
|
|
139
|
+
// A controlled field shows only what its owner accepts: a reset from outside,
|
|
140
|
+
// or the previous text when an edit is rejected.
|
|
141
|
+
React.useLayoutEffect(() => {
|
|
142
|
+
if (value !== undefined && value !== query) setQuery(value)
|
|
143
|
+
}, [value, query, setQuery])
|
|
144
|
+
|
|
80
145
|
return (
|
|
81
146
|
<div
|
|
82
147
|
data-slot="command-input-wrapper"
|
|
83
148
|
className="flex h-14 shrink-0 items-center gap-3 border-b border-border px-5"
|
|
84
149
|
>
|
|
85
150
|
<SearchIcon className="size-5 shrink-0 text-muted-foreground" />
|
|
86
|
-
<
|
|
151
|
+
<AutocompletePrimitive.Input
|
|
87
152
|
data-slot="command-input"
|
|
88
153
|
aria-busy={loading || undefined}
|
|
89
154
|
className={cn(
|
|
@@ -115,12 +180,12 @@ function CommandInput({
|
|
|
115
180
|
* every keystroke. Pass `className="h-…"` to change it, or `h-auto max-h-…`
|
|
116
181
|
* for the shrink-to-fit behaviour a short static menu wants.
|
|
117
182
|
*/
|
|
118
|
-
function CommandList({ className, ...props }:
|
|
183
|
+
function CommandList({ className, ...props }: AutocompletePrimitive.List.Props) {
|
|
119
184
|
return (
|
|
120
|
-
<
|
|
185
|
+
<AutocompletePrimitive.List
|
|
121
186
|
data-slot="command-list"
|
|
122
187
|
className={cn(
|
|
123
|
-
'h-80 min-h-0 scroll-py-2 overflow-x-hidden overflow-y-auto p-2 outline-none',
|
|
188
|
+
'group/command-list h-80 min-h-0 scroll-py-2 overflow-x-hidden overflow-y-auto p-2 outline-none',
|
|
124
189
|
className,
|
|
125
190
|
)}
|
|
126
191
|
{...props}
|
|
@@ -128,14 +193,15 @@ function CommandList({ className, ...props }: React.ComponentProps<typeof Comman
|
|
|
128
193
|
)
|
|
129
194
|
}
|
|
130
195
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
...props
|
|
134
|
-
}: React.ComponentProps<typeof CommandPrimitive.Empty>) {
|
|
196
|
+
/** The message for an empty list. Hidden while the list has any rows. */
|
|
197
|
+
function CommandEmpty({ className, ...props }: React.ComponentProps<'div'>) {
|
|
135
198
|
return (
|
|
136
|
-
<
|
|
199
|
+
<div
|
|
137
200
|
data-slot="command-empty"
|
|
138
|
-
className={cn(
|
|
201
|
+
className={cn(
|
|
202
|
+
'py-10 text-center text-sm text-muted-foreground group-has-[[data-slot=command-item]]/command-list:hidden',
|
|
203
|
+
className,
|
|
204
|
+
)}
|
|
139
205
|
{...props}
|
|
140
206
|
/>
|
|
141
207
|
)
|
|
@@ -143,26 +209,35 @@ function CommandEmpty({
|
|
|
143
209
|
|
|
144
210
|
function CommandGroup({
|
|
145
211
|
className,
|
|
212
|
+
heading,
|
|
213
|
+
children,
|
|
146
214
|
...props
|
|
147
|
-
}: React.
|
|
215
|
+
}: AutocompletePrimitive.Group.Props & { heading?: React.ReactNode }) {
|
|
148
216
|
return (
|
|
149
|
-
<
|
|
217
|
+
<AutocompletePrimitive.Group
|
|
150
218
|
data-slot="command-group"
|
|
151
219
|
className={cn(
|
|
152
|
-
'overflow-hidden text-foreground not-last:pb-2
|
|
220
|
+
'overflow-hidden text-foreground not-last:pb-2 not-has-[[data-slot=command-item]]:hidden',
|
|
153
221
|
className,
|
|
154
222
|
)}
|
|
155
223
|
{...props}
|
|
156
|
-
|
|
224
|
+
>
|
|
225
|
+
{heading && (
|
|
226
|
+
<AutocompletePrimitive.GroupLabel
|
|
227
|
+
data-slot="command-group-heading"
|
|
228
|
+
className="px-3 pt-2 pb-1.5 text-xs font-medium text-muted-foreground"
|
|
229
|
+
>
|
|
230
|
+
{heading}
|
|
231
|
+
</AutocompletePrimitive.GroupLabel>
|
|
232
|
+
)}
|
|
233
|
+
{children}
|
|
234
|
+
</AutocompletePrimitive.Group>
|
|
157
235
|
)
|
|
158
236
|
}
|
|
159
237
|
|
|
160
|
-
function CommandSeparator({
|
|
161
|
-
className,
|
|
162
|
-
...props
|
|
163
|
-
}: React.ComponentProps<typeof CommandPrimitive.Separator>) {
|
|
238
|
+
function CommandSeparator({ className, ...props }: AutocompletePrimitive.Separator.Props) {
|
|
164
239
|
return (
|
|
165
|
-
<
|
|
240
|
+
<AutocompletePrimitive.Separator
|
|
166
241
|
data-slot="command-separator"
|
|
167
242
|
className={cn('-mx-2 my-1 h-px bg-border-subtle', className)}
|
|
168
243
|
{...props}
|
|
@@ -170,23 +245,47 @@ function CommandSeparator({
|
|
|
170
245
|
)
|
|
171
246
|
}
|
|
172
247
|
|
|
248
|
+
/**
|
|
249
|
+
* One row. `onSelect` runs on click and on Enter while the row is highlighted,
|
|
250
|
+
* and receives the row's `value`.
|
|
251
|
+
*/
|
|
173
252
|
function CommandItem({
|
|
174
253
|
className,
|
|
175
254
|
children,
|
|
255
|
+
value,
|
|
256
|
+
keywords,
|
|
257
|
+
onSelect,
|
|
176
258
|
...props
|
|
177
|
-
}:
|
|
259
|
+
}: Omit<AutocompletePrimitive.Item.Props, 'onClick' | 'onSelect' | 'value'> & {
|
|
260
|
+
value?: string
|
|
261
|
+
keywords?: string[]
|
|
262
|
+
onSelect?: (value: string) => void
|
|
263
|
+
}) {
|
|
264
|
+
const { query, shouldFilter } = React.useContext(CommandContext)
|
|
265
|
+
const text = value ?? (typeof children === 'string' ? children : '')
|
|
266
|
+
const needle = query.trim().toLowerCase()
|
|
267
|
+
if (
|
|
268
|
+
shouldFilter &&
|
|
269
|
+
needle &&
|
|
270
|
+
![text, ...(keywords ?? [])].some((term) => term.toLowerCase().includes(needle))
|
|
271
|
+
) {
|
|
272
|
+
return null
|
|
273
|
+
}
|
|
274
|
+
|
|
178
275
|
return (
|
|
179
|
-
<
|
|
276
|
+
<AutocompletePrimitive.Item
|
|
180
277
|
data-slot="command-item"
|
|
278
|
+
value={value}
|
|
279
|
+
onClick={() => onSelect?.(text)}
|
|
181
280
|
className={cn(
|
|
182
|
-
"group/command-item relative flex cursor-pointer items-center gap-3 rounded-md px-3 py-2.5 text-sm outline-hidden select-none data-
|
|
281
|
+
"group/command-item relative flex cursor-pointer items-center gap-3 rounded-md px-3 py-2.5 text-sm outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 data-highlighted:bg-accent-strong data-highlighted:text-accent-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground data-highlighted:*:[svg]:text-foreground",
|
|
183
282
|
className,
|
|
184
283
|
)}
|
|
185
284
|
{...props}
|
|
186
285
|
>
|
|
187
286
|
{children}
|
|
188
287
|
<CheckIcon className="ml-auto opacity-0 group-has-data-[slot=command-shortcut]/command-item:hidden group-data-[checked=true]/command-item:opacity-100" />
|
|
189
|
-
</
|
|
288
|
+
</AutocompletePrimitive.Item>
|
|
190
289
|
)
|
|
191
290
|
}
|
|
192
291
|
|
|
@@ -195,7 +294,7 @@ function CommandShortcut({ className, ...props }: React.ComponentProps<'span'>)
|
|
|
195
294
|
<span
|
|
196
295
|
data-slot="command-shortcut"
|
|
197
296
|
className={cn(
|
|
198
|
-
'ml-auto text-xs tracking-widest text-muted-foreground group-data-
|
|
297
|
+
'ml-auto text-xs tracking-widest text-muted-foreground group-data-highlighted/command-item:text-foreground',
|
|
199
298
|
className,
|
|
200
299
|
)}
|
|
201
300
|
{...props}
|