raft-ui 0.0.7 → 0.0.8

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/dist/index.mjs CHANGED
@@ -1,11 +1,14 @@
1
- import { a as useThemeFamily, c as tv, i as useTheme, n as buttonVariants, o as ThemeContext, r as Spinner, s as ThemeStateContext, t as Button } from "./button-CJqMhTPQ.mjs";
2
1
  import { cn } from "./cn.mjs";
3
- import { createContext, use, useCallback, useEffect, useId, useMemo, useState, useSyncExternalStore } from "react";
2
+ import { a as tv, i as ThemeStateContext, n as useThemeFamily, r as ThemeContext, t as useTheme } from "./use-theme-Y_h1DKll.mjs";
3
+ import { Dialog as Dialog$1 } from "@base-ui/react/dialog";
4
+ import { AlertTriangle, Check, CheckCircle2, ChevronDown, Copy, Info, Minus, X } from "lucide-react";
5
+ import { createContext, use, useCallback, useContext, useEffect, useId, useMemo, useState, useSyncExternalStore } from "react";
6
+ import { Button as Button$1 } from "@base-ui/react/button";
4
7
  import { mergeProps } from "@base-ui/react/merge-props";
5
8
  import { useRender } from "@base-ui/react/use-render";
6
- import { jsx, jsxs } from "react/jsx-runtime";
9
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
10
+ import { useClipboard } from "foxact/use-clipboard";
7
11
  import { Checkbox as Checkbox$1 } from "@base-ui/react/checkbox";
8
- import { AlertTriangle, Check, CheckCircle2, ChevronDown, Info, Minus, X } from "lucide-react";
9
12
  import { Avatar as Avatar$1, ContextMenu as ContextMenu$1 } from "@base-ui/react";
10
13
  import { Menu } from "@base-ui/react/menu";
11
14
  import { Tooltip as Tooltip$1 } from "@base-ui/react/tooltip";
@@ -16,10 +19,1083 @@ import { Combobox as Combobox$1 } from "@base-ui/react/combobox";
16
19
  import { Select as Select$1 } from "@base-ui/react/select";
17
20
  import { Radio } from "@base-ui/react/radio";
18
21
  import { RadioGroup as RadioGroup$1 } from "@base-ui/react/radio-group";
22
+ import { Switch as Switch$1 } from "@base-ui/react/switch";
19
23
  import { Tabs as Tabs$1 } from "@base-ui/react/tabs";
20
24
  import { DndContext, PointerSensor, TouchSensor, closestCenter, useSensor, useSensors } from "@dnd-kit/core";
21
25
  import { SortableContext, arrayMove, horizontalListSortingStrategy, useSortable } from "@dnd-kit/sortable";
22
26
  import { Separator as Separator$1 } from "@base-ui/react/separator";
27
+ //#region src/components/spinner/spinner.tsx
28
+ const SPINNER_STYLE = `
29
+ @keyframes raft-braille-spinner {
30
+ 0%,
31
+ 9.99% {
32
+ content: "⠋";
33
+ }
34
+ 10%,
35
+ 19.99% {
36
+ content: "⠙";
37
+ }
38
+ 20%,
39
+ 29.99% {
40
+ content: "⠹";
41
+ }
42
+ 30%,
43
+ 39.99% {
44
+ content: "⠸";
45
+ }
46
+ 40%,
47
+ 49.99% {
48
+ content: "⠼";
49
+ }
50
+ 50%,
51
+ 59.99% {
52
+ content: "⠴";
53
+ }
54
+ 60%,
55
+ 69.99% {
56
+ content: "⠦";
57
+ }
58
+ 70%,
59
+ 79.99% {
60
+ content: "⠧";
61
+ }
62
+ 80%,
63
+ 89.99% {
64
+ content: "⠇";
65
+ }
66
+ 90%,
67
+ 100% {
68
+ content: "⠏";
69
+ }
70
+ }
71
+
72
+ [data-slot="spinner"] [data-spinner-glyph]::before {
73
+ content: "⠋";
74
+ animation: raft-braille-spinner 800ms steps(1, end) infinite;
75
+ }
76
+
77
+ @media (prefers-reduced-motion: reduce) {
78
+ [data-slot="spinner"] [data-spinner-glyph]::before {
79
+ animation-duration: 1600ms;
80
+ }
81
+ }
82
+
83
+ @keyframes raft-elegant-spinner-spin {
84
+ to {
85
+ transform: rotate(360deg);
86
+ }
87
+ }
88
+
89
+ @keyframes raft-elegant-spinner-dash {
90
+ 0% {
91
+ stroke-dasharray: 1 150;
92
+ stroke-dashoffset: 0;
93
+ }
94
+ 50% {
95
+ stroke-dasharray: 90 150;
96
+ stroke-dashoffset: -35;
97
+ }
98
+ 100% {
99
+ stroke-dasharray: 90 150;
100
+ stroke-dashoffset: -124;
101
+ }
102
+ }
103
+
104
+ [data-slot="spinner"] [data-spinner-ring] {
105
+ animation: raft-elegant-spinner-spin 1600ms linear infinite;
106
+ transform-box: fill-box;
107
+ transform-origin: center;
108
+ will-change: transform;
109
+ }
110
+
111
+ [data-slot="spinner"] [data-spinner-arc] {
112
+ animation: raft-elegant-spinner-dash 1400ms cubic-bezier(0.42, 0, 0.58, 1) infinite;
113
+ stroke-dasharray: 1 150;
114
+ stroke-dashoffset: 0;
115
+ }
116
+
117
+ @media (prefers-reduced-motion: reduce) {
118
+ [data-slot="spinner"] [data-spinner-ring] {
119
+ animation-duration: 2400ms;
120
+ will-change: auto;
121
+ }
122
+
123
+ [data-slot="spinner"] [data-spinner-arc] {
124
+ animation: none;
125
+ stroke-dasharray: 72 150;
126
+ stroke-dashoffset: -30;
127
+ }
128
+ }
129
+ `;
130
+ const spinner = tv({
131
+ slots: {
132
+ root: ["relative inline-flex shrink-0 items-center justify-center", "leading-none text-current"],
133
+ glyph: "inline-block min-w-[1ch] font-mono tabular-nums",
134
+ ring: "block size-full shrink-0"
135
+ },
136
+ variants: {
137
+ theme: {
138
+ brutal: {},
139
+ elegant: {}
140
+ },
141
+ size: {
142
+ sm: {},
143
+ lg: {}
144
+ }
145
+ },
146
+ defaultVariants: { size: "sm" },
147
+ compoundVariants: [
148
+ {
149
+ theme: "brutal",
150
+ size: "sm",
151
+ class: { root: "h-4 text-base" }
152
+ },
153
+ {
154
+ theme: "brutal",
155
+ size: "lg",
156
+ class: { root: "h-6 text-xl" }
157
+ },
158
+ {
159
+ theme: "elegant",
160
+ size: "sm",
161
+ class: { root: "size-3.5" }
162
+ },
163
+ {
164
+ theme: "elegant",
165
+ size: "lg",
166
+ class: { root: "size-[18px]" }
167
+ }
168
+ ]
169
+ });
170
+ const spinnerStyle = /* @__PURE__ */ jsx("style", {
171
+ href: "raft-ui-spinner",
172
+ precedence: "default",
173
+ children: SPINNER_STYLE
174
+ });
175
+ function Spinner({ size = "sm", className, render, ...props }) {
176
+ const theme = useThemeFamily();
177
+ const { root, glyph, ring } = spinner({
178
+ theme,
179
+ size
180
+ });
181
+ const children = theme === "elegant" ? /* @__PURE__ */ jsxs(Fragment, { children: [spinnerStyle, /* @__PURE__ */ jsxs("svg", {
182
+ "data-spinner-ring": "",
183
+ "aria-hidden": "true",
184
+ className: ring(),
185
+ xmlns: "http://www.w3.org/2000/svg",
186
+ fill: "none",
187
+ viewBox: "0 0 24 24",
188
+ children: [/* @__PURE__ */ jsx("circle", {
189
+ className: "opacity-20",
190
+ cx: "12",
191
+ cy: "12",
192
+ r: "10",
193
+ stroke: "currentColor",
194
+ strokeWidth: "2.5"
195
+ }), /* @__PURE__ */ jsx("circle", {
196
+ "data-spinner-arc": "",
197
+ className: "opacity-80",
198
+ cx: "12",
199
+ cy: "12",
200
+ r: "10",
201
+ fill: "none",
202
+ pathLength: "150",
203
+ stroke: "currentColor",
204
+ strokeLinecap: "round",
205
+ strokeWidth: "2.5"
206
+ })]
207
+ })] }) : /* @__PURE__ */ jsxs(Fragment, { children: [spinnerStyle, /* @__PURE__ */ jsx("span", {
208
+ "data-spinner-glyph": "",
209
+ "aria-hidden": "true",
210
+ className: glyph()
211
+ })] });
212
+ return useRender({
213
+ defaultTagName: "span",
214
+ render,
215
+ props: mergeProps({
216
+ role: "status",
217
+ "aria-label": "Loading",
218
+ className: root({ className }),
219
+ children
220
+ }, props),
221
+ state: {
222
+ slot: "spinner",
223
+ size
224
+ }
225
+ });
226
+ }
227
+ //#endregion
228
+ //#region src/components/button/button.tsx
229
+ const buttonVariants = tv({
230
+ slots: {
231
+ root: [
232
+ "relative inline-flex shrink-0 items-center justify-center",
233
+ "font-heading leading-none whitespace-nowrap select-none",
234
+ "border-line rounded-none",
235
+ "shadow-sm transition-all duration-100",
236
+ "outline outline-[1px] outline-offset-2 outline-transparent",
237
+ "data-[loading=true]:cursor-wait",
238
+ "disabled:pointer-events-none disabled:opacity-40 data-[loading=true]:opacity-100",
239
+ "disabled:transform-none",
240
+ "[&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4"
241
+ ],
242
+ content: "relative z-10 inline-flex items-center justify-center gap-[inherit] data-[loading=true]:invisible",
243
+ loadingIndicator: "pointer-events-none absolute inset-0 z-10 flex items-center justify-center"
244
+ },
245
+ variants: {
246
+ theme: {
247
+ brutal: { root: ["border-2 font-bold focus-visible:outline-transparent"] },
248
+ elegant: { root: [
249
+ "overflow-clip border-0 font-sans font-medium antialiased",
250
+ "focus-visible:outline-[var(--button-focus-outline,transparent)]",
251
+ "shadow-[inset_0_1px_0.5px_oklch(1_0_0_/_0.05),0_0_0_1px_var(--line-subtle)]",
252
+ "before:pointer-events-none before:absolute before:inset-0 before:z-0 before:rounded-[inherit]",
253
+ "active:not-aria-[haspopup]:scale-[0.985]"
254
+ ] }
255
+ },
256
+ variant: {
257
+ primary: { root: ["border-line-strong bg-primary-400 text-primary-950", "hover:bg-primary-500"] },
258
+ default: { root: ["border-line-strong bg-layer-panel text-foreground-strong", "hover:bg-layer-panel"] },
259
+ information: { root: ["border-line-strong bg-info-base text-foreground-inverse", "hover:bg-info-base"] },
260
+ muted: { root: ["border-line-strong bg-secondary-400 text-secondary-950", "hover:border-line-strong hover:bg-secondary-400"] },
261
+ accent: { root: ["border-line-strong bg-accent-400 text-accent-950", "hover:bg-accent-500"] },
262
+ warning: { root: ["border-line-strong bg-warning-base text-foreground-inverse", "hover:bg-warning-base"] },
263
+ outline: { root: [
264
+ "border-line-strong bg-transparent text-foreground-strong",
265
+ "hover:bg-layer-muted",
266
+ "shadow-none"
267
+ ] },
268
+ ghost: { root: ["border-transparent bg-transparent text-foreground shadow-none", "hover:border-line-strong hover:bg-layer-muted"] },
269
+ link: { root: ["border-transparent bg-transparent text-foreground-strong shadow-none underline-offset-4", "hover:underline"] },
270
+ "danger-secondary": { root: ["border-line-strong bg-danger-lighter text-danger-base", "hover:bg-danger-lighter"] },
271
+ danger: { root: ["border-line-strong bg-danger-base text-foreground-inverse", "hover:border-[oklch(0.595_0.241_26.758)] hover:bg-[oklch(0.595_0.241_26.758)]"] },
272
+ "danger-outline": { root: [
273
+ "border-line-strong bg-transparent text-danger-base",
274
+ "hover:bg-layer-muted",
275
+ "shadow-none"
276
+ ] }
277
+ },
278
+ size: {
279
+ xs: { root: [
280
+ "gap-1 px-2 py-[5px] text-[11px]",
281
+ "has-data-[icon=inline-start]:pl-1.5 has-data-[icon=inline-end]:pr-1.5",
282
+ "[&_svg:not([class*='size-'])]:size-3"
283
+ ] },
284
+ sm: { root: [
285
+ "gap-1.5 px-2.5 py-[6px] text-xs",
286
+ "has-data-[icon=inline-start]:pl-2 has-data-[icon=inline-end]:pr-2",
287
+ "[&_svg:not([class*='size-'])]:size-3.5"
288
+ ] },
289
+ md: { root: ["gap-2 px-3 py-[7px] text-sm", "has-data-[icon=inline-start]:pl-2.5 has-data-[icon=inline-end]:pr-2.5"] },
290
+ lg: { root: [
291
+ "gap-2 px-3.5 py-2 text-base",
292
+ "has-data-[icon=inline-start]:pl-3 has-data-[icon=inline-end]:pr-3",
293
+ "[&_svg:not([class*='size-'])]:size-4"
294
+ ] },
295
+ "icon-xs": { root: ["p-[5px] text-[11px]", "[&_svg:not([class*='size-'])]:size-3"] },
296
+ "icon-sm": { root: ["p-[6px] text-xs", "[&_svg:not([class*='size-'])]:size-3.5"] },
297
+ "icon-md": { root: ["p-2 text-sm", "[&_svg:not([class*='size-'])]:size-4"] },
298
+ "icon-lg": { root: ["p-3 text-sm", "[&_svg:not([class*='size-'])]:size-4"] }
299
+ }
300
+ },
301
+ defaultVariants: {
302
+ variant: "default",
303
+ size: "md"
304
+ },
305
+ compoundVariants: [
306
+ {
307
+ theme: "elegant",
308
+ size: ["xs", "icon-xs"],
309
+ class: { root: "rounded-sm" }
310
+ },
311
+ {
312
+ theme: "elegant",
313
+ size: ["sm", "icon-sm"],
314
+ class: { root: "rounded" }
315
+ },
316
+ {
317
+ theme: "elegant",
318
+ size: ["md", "icon-md"],
319
+ class: { root: "rounded-md" }
320
+ },
321
+ {
322
+ theme: "elegant",
323
+ size: "md",
324
+ class: { root: "py-1.5" }
325
+ },
326
+ {
327
+ theme: "elegant",
328
+ size: ["lg", "icon-lg"],
329
+ class: { root: "rounded-md" }
330
+ },
331
+ {
332
+ theme: "elegant",
333
+ size: "lg",
334
+ class: { root: "py-[7px]" }
335
+ },
336
+ {
337
+ theme: "brutal",
338
+ variant: "primary",
339
+ class: { root: "bg-brutal-yellow text-black hover:bg-brutal-yellow" }
340
+ },
341
+ {
342
+ theme: "brutal",
343
+ variant: "default",
344
+ class: { root: "bg-white text-black hover:bg-white" }
345
+ },
346
+ {
347
+ theme: "brutal",
348
+ variant: "outline",
349
+ class: { root: "bg-white text-black shadow-sm hover:bg-white" }
350
+ },
351
+ {
352
+ theme: "brutal",
353
+ variant: "information",
354
+ class: { root: "bg-brutal-cyan text-black hover:bg-brutal-cyan" }
355
+ },
356
+ {
357
+ theme: "brutal",
358
+ variant: "muted",
359
+ class: { root: "bg-brutal-stone text-black hover:bg-brutal-stone" }
360
+ },
361
+ {
362
+ theme: "brutal",
363
+ variant: "accent",
364
+ class: { root: "bg-brutal-pink text-black hover:bg-brutal-pink" }
365
+ },
366
+ {
367
+ theme: "brutal",
368
+ variant: "danger",
369
+ class: { root: "bg-brutal-red text-black hover:bg-brutal-red" }
370
+ },
371
+ {
372
+ theme: "brutal",
373
+ variant: "warning",
374
+ class: { root: "bg-[oklch(0.785_0.123_50.11)] text-black hover:bg-[oklch(0.785_0.123_50.11)]" }
375
+ },
376
+ {
377
+ theme: "brutal",
378
+ size: "xs",
379
+ class: { root: "h-6 px-2 py-0 text-[11px]" }
380
+ },
381
+ {
382
+ theme: "brutal",
383
+ size: "sm",
384
+ class: { root: "h-7 px-2.5 py-0 text-xs" }
385
+ },
386
+ {
387
+ theme: "brutal",
388
+ size: "md",
389
+ class: { root: "h-8 px-3 py-0 text-sm" }
390
+ },
391
+ {
392
+ theme: "brutal",
393
+ size: "lg",
394
+ class: { root: "h-10 px-4 py-0 text-sm" }
395
+ },
396
+ {
397
+ theme: "brutal",
398
+ size: "icon-xs",
399
+ class: { root: "size-6 p-0 text-[11px]" }
400
+ },
401
+ {
402
+ theme: "brutal",
403
+ size: "icon-sm",
404
+ class: { root: "size-7 p-0 text-xs" }
405
+ },
406
+ {
407
+ theme: "brutal",
408
+ size: "icon-md",
409
+ class: { root: "size-8 p-0 text-sm" }
410
+ },
411
+ {
412
+ theme: "brutal",
413
+ size: "icon-lg",
414
+ class: { root: "size-10 p-0 text-sm" }
415
+ },
416
+ {
417
+ theme: "elegant",
418
+ variant: "default",
419
+ class: { root: [
420
+ "bg-foreground-strong text-foreground-inverse",
421
+ "[--button-focus-outline:var(--foreground-strong)]",
422
+ "shadow-[inset_0_1px_0.5px_oklch(1_0_0_/_0.12),0_0_0_1px_var(--foreground-strong)]",
423
+ "before:bg-[linear-gradient(in_oklab_180deg,oklab(100%_0_0_/_8%)_0%,oklab(0%_0_0_/_0%)_100%)]",
424
+ "hover:bg-[oklch(0.31_0.006_285)]"
425
+ ] }
426
+ },
427
+ {
428
+ theme: "elegant",
429
+ variant: "primary",
430
+ class: { root: [
431
+ "bg-primary-400 text-primary-950",
432
+ "[--button-focus-outline:var(--primary-400)]",
433
+ "shadow-[inset_0_1px_0.5px_oklch(1_0_0_/_0.15),0_0_0_1px_oklch(0.83_0.14_91.89_/_0.83)]",
434
+ "before:bg-[linear-gradient(in_oklab_180deg,oklab(100%_0_0_/_11%)_0%,oklab(100%_0_0_/_0%)_0%,oklab(0%_0_0_/_0%)_100%)]",
435
+ "hover:bg-[oklch(0.86_0.15_91.89)]"
436
+ ] }
437
+ },
438
+ {
439
+ theme: "elegant",
440
+ variant: "outline",
441
+ class: { root: [
442
+ "bg-layer-panel text-foreground-strong",
443
+ "[--button-focus-outline:var(--layer-panel)]",
444
+ "shadow-[inset_0_1px_0.5px_oklch(1_0_0_/_0.05),0_0_0_1px_var(--line-subtle)]",
445
+ "before:bg-[linear-gradient(in_oklab_180deg,oklab(0%_0_0_/_0%)_30%,oklab(0%_0_0_/_1%)_100%)]",
446
+ "hover:bg-layer-muted"
447
+ ] }
448
+ },
449
+ {
450
+ theme: "elegant",
451
+ variant: "ghost",
452
+ class: { root: [
453
+ "bg-transparent text-foreground-muted shadow-none",
454
+ "[--button-focus-outline:var(--line-muted)]",
455
+ "before:bg-transparent hover:bg-line-muted"
456
+ ] }
457
+ },
458
+ {
459
+ theme: "elegant",
460
+ variant: "danger-secondary",
461
+ class: { root: [
462
+ "bg-danger-lighter text-danger-base",
463
+ "[--button-focus-outline:var(--state-danger-lighter)]",
464
+ "shadow-[inset_0_1px_0.5px_oklch(1_0_0_/_0.18),0_0_0_1px_var(--state-danger-light)]",
465
+ "before:bg-[linear-gradient(in_oklab_180deg,oklab(100%_0_0_/_9%)_0%,oklab(0%_0_0_/_1%)_100%)]",
466
+ "hover:bg-danger-light"
467
+ ] }
468
+ },
469
+ {
470
+ theme: "elegant",
471
+ variant: "danger",
472
+ class: { root: [
473
+ "bg-danger-base text-foreground-inverse",
474
+ "[--button-focus-outline:var(--state-danger-base)]",
475
+ "shadow-[inset_0_1px_0.5px_oklch(1_0_0_/_0.12),0_0_0_1px_var(--state-danger-base)]",
476
+ "before:bg-[linear-gradient(in_oklab_180deg,oklab(100%_0_0_/_10%)_0%,oklab(0%_0_0_/_0%)_100%)]",
477
+ "hover:bg-[oklch(0.56_0.23_26.758)]"
478
+ ] }
479
+ },
480
+ {
481
+ theme: "brutal",
482
+ variant: "danger",
483
+ class: { root: [
484
+ "border-line-strong bg-brutal-red text-black",
485
+ "shadow-sm",
486
+ "hover:border-line-strong hover:bg-brutal-red",
487
+ "hover:-translate-y-px hover:shadow-md",
488
+ "active:not-aria-[haspopup]:translate-x-px active:not-aria-[haspopup]:translate-y-px",
489
+ "active:shadow-xs"
490
+ ] }
491
+ },
492
+ {
493
+ theme: "brutal",
494
+ variant: "danger-secondary",
495
+ class: { root: [
496
+ "border-line-strong bg-danger-lighter text-[color-mix(in_oklab,var(--state-danger-base)_72%,transparent)]",
497
+ "shadow-sm",
498
+ "hover:border-line-strong hover:bg-danger-lighter",
499
+ "hover:-translate-y-px hover:shadow-md",
500
+ "active:not-aria-[haspopup]:translate-x-px active:not-aria-[haspopup]:translate-y-px",
501
+ "active:shadow-xs"
502
+ ] }
503
+ },
504
+ {
505
+ theme: "elegant",
506
+ variant: "danger-outline",
507
+ class: { root: [
508
+ "bg-layer-panel text-danger-base",
509
+ "[--button-focus-outline:var(--layer-panel)]",
510
+ "shadow-[inset_0_1px_0.5px_oklch(1_0_0_/_0.05),0_0_0_1px_var(--state-danger-light)]",
511
+ "before:bg-[linear-gradient(in_oklab_180deg,oklab(0%_0_0_/_0%)_30%,oklab(0%_0_0_/_1%)_100%)]",
512
+ "hover:bg-danger-lighter"
513
+ ] }
514
+ },
515
+ {
516
+ theme: "elegant",
517
+ variant: "accent",
518
+ class: { root: [
519
+ "bg-accent-400 text-white",
520
+ "[--button-focus-outline:var(--accent-400)]",
521
+ "shadow-[inset_0_1px_0.5px_oklch(1_0_0_/_0.12),0_0_0_1px_var(--accent-400)]",
522
+ "before:bg-[linear-gradient(in_oklab_180deg,oklab(100%_0_0_/_8%)_0%,oklab(0%_0_0_/_0%)_100%)]",
523
+ "hover:bg-[oklch(0.72_0.15_0.71)]"
524
+ ] }
525
+ },
526
+ {
527
+ theme: "elegant",
528
+ variant: "warning",
529
+ class: { root: [
530
+ "bg-warning-base text-foreground-inverse",
531
+ "[--button-focus-outline:var(--state-warning-base)]",
532
+ "shadow-[inset_0_1px_0.5px_oklch(1_0_0_/_0.14),0_0_0_1px_var(--state-warning-base)]",
533
+ "before:bg-[linear-gradient(in_oklab_180deg,oklab(100%_0_0_/_10%)_0%,oklab(0%_0_0_/_0%)_100%)]",
534
+ "hover:bg-[oklch(0.65_0.19_44.441)]"
535
+ ] }
536
+ },
537
+ {
538
+ theme: "elegant",
539
+ variant: "link",
540
+ class: { root: [
541
+ "bg-transparent text-foreground-muted shadow-none",
542
+ "[--button-focus-outline:transparent]",
543
+ "before:bg-transparent hover:bg-transparent hover:text-foreground-muted"
544
+ ] }
545
+ },
546
+ {
547
+ theme: "elegant",
548
+ variant: "information",
549
+ class: { root: [
550
+ "bg-info-base text-foreground-inverse",
551
+ "[--button-focus-outline:var(--state-info-base)]",
552
+ "shadow-[inset_0_1px_0.5px_oklch(1_0_0_/_0.12),0_0_0_1px_var(--state-info-base)]",
553
+ "before:bg-[linear-gradient(in_oklab_180deg,oklab(100%_0_0_/_8%)_0%,oklab(0%_0_0_/_0%)_100%)]",
554
+ "hover:bg-[oklch(0.74_0.13_219.2)]"
555
+ ] }
556
+ },
557
+ {
558
+ theme: "elegant",
559
+ variant: "muted",
560
+ class: { root: [
561
+ "bg-layer-muted text-foreground-placeholder",
562
+ "[--button-focus-outline:var(--layer-muted)]",
563
+ "shadow-[inset_0_1px_0.5px_oklch(1_0_0_/_0.05),0_0_0_1px_var(--line-subtle)]",
564
+ "before:bg-[linear-gradient(in_oklab_180deg,oklab(100%_0_0_/_5%)_0%,oklab(0%_0_0_/_1%)_100%)]",
565
+ "hover:bg-line-subtle"
566
+ ] }
567
+ },
568
+ {
569
+ theme: "brutal",
570
+ variant: [
571
+ "primary",
572
+ "default",
573
+ "information",
574
+ "muted",
575
+ "accent",
576
+ "warning",
577
+ "outline"
578
+ ],
579
+ class: { root: [
580
+ "hover:-translate-y-px hover:shadow-md",
581
+ "active:not-aria-[haspopup]:translate-x-px active:not-aria-[haspopup]:translate-y-px",
582
+ "active:shadow-xs"
583
+ ] }
584
+ }
585
+ ]
586
+ });
587
+ function defaultNativeButton(render) {
588
+ if (!render || typeof render !== "object" || !("type" in render)) return;
589
+ const element = render;
590
+ if (typeof element.type === "string") return element.type === "button";
591
+ }
592
+ function Button({ variant, size, loading = false, loadingLabel = "Loading", disabled, className, children, render, nativeButton, ...props }) {
593
+ const { root, content, loadingIndicator } = buttonVariants({
594
+ theme: useThemeFamily(),
595
+ variant,
596
+ size
597
+ });
598
+ return /* @__PURE__ */ jsxs(Button$1, {
599
+ ...props,
600
+ render,
601
+ nativeButton: nativeButton ?? defaultNativeButton(render),
602
+ "data-slot": "button",
603
+ className: root({ className }),
604
+ "data-loading": loading ? "true" : void 0,
605
+ disabled: disabled || loading,
606
+ "aria-disabled": loading || void 0,
607
+ children: [loading ? /* @__PURE__ */ jsx("span", {
608
+ "data-slot": "button-loading-indicator",
609
+ className: loadingIndicator(),
610
+ children: /* @__PURE__ */ jsx(Spinner, { "aria-label": loadingLabel })
611
+ }) : null, /* @__PURE__ */ jsx("span", {
612
+ "data-slot": "button-content",
613
+ "data-loading": loading ? "true" : void 0,
614
+ className: content(),
615
+ children
616
+ })]
617
+ });
618
+ }
619
+ //#endregion
620
+ //#region src/components/alert-dialog/alert-dialog.tsx
621
+ const alertDialog = tv({
622
+ slots: {
623
+ overlay: [
624
+ "fixed inset-0 z-50",
625
+ "transition-opacity duration-100",
626
+ "data-[starting-style]:opacity-0 data-[ending-style]:opacity-0"
627
+ ],
628
+ content: [
629
+ "fixed top-1/2 left-1/2 z-50 grid w-[calc(100%-2rem)] max-w-[408px] -translate-x-1/2 -translate-y-1/2",
630
+ "outline-none transition-[opacity,transform] duration-100",
631
+ "data-[starting-style]:scale-95 data-[starting-style]:opacity-0",
632
+ "data-[ending-style]:scale-95 data-[ending-style]:opacity-0"
633
+ ],
634
+ header: ["grid grid-cols-[minmax(0,1fr)_max-content] items-center gap-3 min-w-0"],
635
+ body: ["min-w-0"],
636
+ footer: ["flex items-center justify-end gap-3"],
637
+ title: ["m-0 min-w-0 text-foreground-strong"],
638
+ description: ["m-0 text-foreground-muted"]
639
+ },
640
+ variants: { theme: {
641
+ brutal: {
642
+ overlay: ["bg-black/60"],
643
+ content: ["gap-4 border-2 border-line-strong bg-layer-panel px-6 py-4 shadow-xl"],
644
+ body: ["py-2 font-medium"],
645
+ title: ["font-heading text-lg leading-none font-bold uppercase"],
646
+ description: ["font-sans text-sm leading-5 text-foreground/60"]
647
+ },
648
+ elegant: {
649
+ overlay: ["bg-black/20"],
650
+ content: ["overflow-clip rounded-lg bg-layer-popover shadow-xl"],
651
+ header: ["border-b border-line-subtle bg-black/[0.02] px-6 py-2"],
652
+ body: ["px-6 py-5"],
653
+ footer: ["border-t border-line-subtle bg-black/[0.015] px-6 py-3"],
654
+ title: ["font-sans text-sm leading-5 font-medium tracking-[-0.005em]"],
655
+ description: ["font-sans text-sm leading-5 text-[oklch(0.48_0_0)] dark:text-[oklch(0.76_0_0)]"]
656
+ }
657
+ } }
658
+ });
659
+ function AlertDialog(props) {
660
+ return /* @__PURE__ */ jsx(Dialog$1.Root, {
661
+ "data-slot": "alert-dialog",
662
+ ...props
663
+ });
664
+ }
665
+ function AlertDialogTrigger(props) {
666
+ return /* @__PURE__ */ jsx(Dialog$1.Trigger, {
667
+ "data-slot": "alert-dialog-trigger",
668
+ ...props
669
+ });
670
+ }
671
+ function AlertDialogPortal(props) {
672
+ return /* @__PURE__ */ jsx(Dialog$1.Portal, {
673
+ "data-slot": "alert-dialog-portal",
674
+ ...props
675
+ });
676
+ }
677
+ function AlertDialogClose({ className, variant, size, children, ...props }) {
678
+ const isBrutal = useThemeFamily() === "brutal";
679
+ return /* @__PURE__ */ jsx(Dialog$1.Close, {
680
+ "data-slot": "alert-dialog-close",
681
+ render: /* @__PURE__ */ jsx(Button, {
682
+ variant: variant ?? (isBrutal ? "outline" : "ghost"),
683
+ size: size ?? (isBrutal ? "icon-md" : "icon-sm"),
684
+ "aria-label": "Close",
685
+ className: isBrutal ? className : cn("text-foreground-placeholder hover:text-foreground", className)
686
+ }),
687
+ ...props,
688
+ children: children ?? /* @__PURE__ */ jsx(X, { className: isBrutal ? "size-5" : "size-4" })
689
+ });
690
+ }
691
+ function AlertDialogOverlay({ className, ...props }) {
692
+ const { overlay } = alertDialog({ theme: useThemeFamily() });
693
+ return /* @__PURE__ */ jsx(Dialog$1.Backdrop, {
694
+ "data-slot": "alert-dialog-overlay",
695
+ className: overlay({ className }),
696
+ ...props
697
+ });
698
+ }
699
+ function AlertDialogContent({ className, children, portalProps, overlay, ...props }) {
700
+ const { content } = alertDialog({ theme: useThemeFamily() });
701
+ return /* @__PURE__ */ jsxs(AlertDialogPortal, {
702
+ ...portalProps,
703
+ children: [overlay === false ? null : /* @__PURE__ */ jsx(AlertDialogOverlay, { ...overlay }), /* @__PURE__ */ jsx(Dialog$1.Popup, {
704
+ "data-slot": "alert-dialog-content",
705
+ className: content({ className }),
706
+ ...props,
707
+ role: "alertdialog",
708
+ children
709
+ })]
710
+ });
711
+ }
712
+ function AlertDialogHeader({ className, ...props }) {
713
+ const { header } = alertDialog({ theme: useThemeFamily() });
714
+ return /* @__PURE__ */ jsx("div", {
715
+ "data-slot": "alert-dialog-header",
716
+ className: header({ className }),
717
+ ...props
718
+ });
719
+ }
720
+ function AlertDialogBody({ className, ...props }) {
721
+ const { body } = alertDialog({ theme: useThemeFamily() });
722
+ return /* @__PURE__ */ jsx("div", {
723
+ "data-slot": "alert-dialog-body",
724
+ className: body({ className }),
725
+ ...props
726
+ });
727
+ }
728
+ function AlertDialogFooter({ className, ...props }) {
729
+ const { footer } = alertDialog({ theme: useThemeFamily() });
730
+ return /* @__PURE__ */ jsx("div", {
731
+ "data-slot": "alert-dialog-footer",
732
+ className: footer({ className }),
733
+ ...props
734
+ });
735
+ }
736
+ function AlertDialogTitle({ className, ...props }) {
737
+ const { title } = alertDialog({ theme: useThemeFamily() });
738
+ return /* @__PURE__ */ jsx(Dialog$1.Title, {
739
+ "data-slot": "alert-dialog-title",
740
+ className: title({ className }),
741
+ ...props
742
+ });
743
+ }
744
+ function AlertDialogDescription({ className, ...props }) {
745
+ const { description } = alertDialog({ theme: useThemeFamily() });
746
+ return /* @__PURE__ */ jsx(Dialog$1.Description, {
747
+ "data-slot": "alert-dialog-description",
748
+ className: description({ className }),
749
+ ...props
750
+ });
751
+ }
752
+ function AlertDialogAction(props) {
753
+ return /* @__PURE__ */ jsx(Button, {
754
+ "data-slot": "alert-dialog-action",
755
+ ...props
756
+ });
757
+ }
758
+ function AlertDialogCancel({ className, variant = "outline", size = "sm", ...props }) {
759
+ return /* @__PURE__ */ jsx(Dialog$1.Close, {
760
+ "data-slot": "alert-dialog-cancel",
761
+ render: /* @__PURE__ */ jsx(Button, {
762
+ className,
763
+ variant,
764
+ size
765
+ }),
766
+ ...props
767
+ });
768
+ }
769
+ //#endregion
770
+ //#region src/components/dialog/dialog.tsx
771
+ const dialog = tv({
772
+ slots: {
773
+ overlay: [
774
+ "fixed inset-0 z-50",
775
+ "transition-opacity duration-100",
776
+ "data-[starting-style]:opacity-0 data-[ending-style]:opacity-0"
777
+ ],
778
+ content: [
779
+ "fixed top-1/2 left-1/2 z-50 grid w-[calc(100%-2rem)] max-w-md -translate-x-1/2 -translate-y-1/2",
780
+ "outline-none transition-[opacity,transform] duration-100",
781
+ "data-[starting-style]:scale-95 data-[starting-style]:opacity-0",
782
+ "data-[ending-style]:scale-95 data-[ending-style]:opacity-0"
783
+ ],
784
+ header: ["grid grid-cols-[minmax(0,1fr)_max-content] items-center gap-3 min-w-0"],
785
+ body: ["min-w-0"],
786
+ footer: ["flex items-center justify-end gap-3"],
787
+ title: ["m-0 min-w-0 text-foreground-strong"],
788
+ description: ["m-0 text-foreground-muted"]
789
+ },
790
+ variants: { theme: {
791
+ brutal: {
792
+ overlay: ["bg-black/60"],
793
+ content: ["gap-4 border-2 border-line-strong bg-layer-panel px-6 py-4 shadow-xl"],
794
+ body: ["py-2 font-medium"],
795
+ title: ["font-heading text-lg leading-none font-bold uppercase"],
796
+ description: ["font-sans text-sm leading-5 text-foreground/60"]
797
+ },
798
+ elegant: {
799
+ overlay: ["bg-black/20"],
800
+ content: ["overflow-clip rounded-lg bg-layer-popover shadow-xl"],
801
+ header: ["border-b border-line-subtle bg-black/[0.02] px-6 py-2"],
802
+ body: ["px-6 py-5"],
803
+ footer: ["border-t border-line-subtle bg-black/[0.015] px-6 py-3"],
804
+ title: ["font-sans text-sm leading-5 font-medium tracking-[-0.005em]"],
805
+ description: ["font-sans text-sm leading-5 text-[oklch(0.48_0_0)] dark:text-[oklch(0.76_0_0)]"]
806
+ }
807
+ } }
808
+ });
809
+ function Dialog(props) {
810
+ return /* @__PURE__ */ jsx(Dialog$1.Root, {
811
+ "data-slot": "dialog",
812
+ ...props
813
+ });
814
+ }
815
+ function DialogTrigger(props) {
816
+ return /* @__PURE__ */ jsx(Dialog$1.Trigger, {
817
+ "data-slot": "dialog-trigger",
818
+ ...props
819
+ });
820
+ }
821
+ function DialogPortal(props) {
822
+ return /* @__PURE__ */ jsx(Dialog$1.Portal, {
823
+ "data-slot": "dialog-portal",
824
+ ...props
825
+ });
826
+ }
827
+ function DialogOverlay({ className, ...props }) {
828
+ const { overlay } = dialog({ theme: useThemeFamily() });
829
+ return /* @__PURE__ */ jsx(Dialog$1.Backdrop, {
830
+ "data-slot": "dialog-overlay",
831
+ className: overlay({ className }),
832
+ ...props
833
+ });
834
+ }
835
+ function DialogContent({ className, children, portalProps, overlay, ...props }) {
836
+ const { content } = dialog({ theme: useThemeFamily() });
837
+ return /* @__PURE__ */ jsxs(DialogPortal, {
838
+ ...portalProps,
839
+ children: [overlay === false ? null : /* @__PURE__ */ jsx(DialogOverlay, { ...overlay }), /* @__PURE__ */ jsx(Dialog$1.Popup, {
840
+ "data-slot": "dialog-content",
841
+ className: content({ className }),
842
+ ...props,
843
+ children
844
+ })]
845
+ });
846
+ }
847
+ function DialogClose({ className, variant, size, children, render, ...props }) {
848
+ const isBrutal = useThemeFamily() === "brutal";
849
+ if (render) return /* @__PURE__ */ jsx(Dialog$1.Close, {
850
+ "data-slot": "dialog-close",
851
+ render,
852
+ ...props,
853
+ children
854
+ });
855
+ return /* @__PURE__ */ jsx(Dialog$1.Close, {
856
+ "data-slot": "dialog-close",
857
+ render: /* @__PURE__ */ jsx(Button, {
858
+ variant: variant ?? (isBrutal ? "outline" : "ghost"),
859
+ size: size ?? (isBrutal ? "icon-md" : "icon-sm"),
860
+ "aria-label": "Close",
861
+ className: isBrutal ? className : cn("text-foreground-placeholder hover:text-foreground", className)
862
+ }),
863
+ ...props,
864
+ children: children ?? /* @__PURE__ */ jsx(X, { className: isBrutal ? "size-5" : "size-4" })
865
+ });
866
+ }
867
+ function DialogHeader({ className, ...props }) {
868
+ const { header } = dialog({ theme: useThemeFamily() });
869
+ return /* @__PURE__ */ jsx("div", {
870
+ "data-slot": "dialog-header",
871
+ className: header({ className }),
872
+ ...props
873
+ });
874
+ }
875
+ function DialogBody({ className, ...props }) {
876
+ const { body } = dialog({ theme: useThemeFamily() });
877
+ return /* @__PURE__ */ jsx("div", {
878
+ "data-slot": "dialog-body",
879
+ className: body({ className }),
880
+ ...props
881
+ });
882
+ }
883
+ function DialogFooter({ className, ...props }) {
884
+ const { footer } = dialog({ theme: useThemeFamily() });
885
+ return /* @__PURE__ */ jsx("div", {
886
+ "data-slot": "dialog-footer",
887
+ className: footer({ className }),
888
+ ...props
889
+ });
890
+ }
891
+ function DialogTitle({ className, ...props }) {
892
+ const { title } = dialog({ theme: useThemeFamily() });
893
+ return /* @__PURE__ */ jsx(Dialog$1.Title, {
894
+ "data-slot": "dialog-title",
895
+ className: title({ className }),
896
+ ...props
897
+ });
898
+ }
899
+ function DialogDescription({ className, ...props }) {
900
+ const { description } = dialog({ theme: useThemeFamily() });
901
+ return /* @__PURE__ */ jsx(Dialog$1.Description, {
902
+ "data-slot": "dialog-description",
903
+ className: description({ className }),
904
+ ...props
905
+ });
906
+ }
907
+ //#endregion
908
+ //#region src/components/copyable-code/copyable-code.tsx
909
+ const copyableCode = tv({
910
+ slots: {
911
+ root: ["group/copyable-code flex w-full min-w-0 items-center gap-2"],
912
+ code: ["min-w-0 flex-1 font-mono text-xs"],
913
+ codeInner: ["block w-full min-w-0 max-w-full break-all"],
914
+ action: [
915
+ "shrink-0",
916
+ "[&_[data-slot=button]]:transition-[color,background-color,box-shadow]",
917
+ "[&_[data-slot=button]]:duration-150 [&_[data-slot=button]]:ease-out"
918
+ ],
919
+ iconSwap: [
920
+ "relative inline-grid size-3",
921
+ "[&_[data-slot=copyable-code-icon]]:col-start-1 [&_[data-slot=copyable-code-icon]]:row-start-1",
922
+ "[&_[data-slot=copyable-code-icon]]:origin-center",
923
+ "[&_[data-slot=copyable-code-icon]]:transition-[opacity,filter,scale]",
924
+ "[&_[data-slot=copyable-code-icon]]:duration-[170ms]",
925
+ "[&_[data-slot=copyable-code-icon]]:ease-[cubic-bezier(0.16,1,0.3,1)]",
926
+ "[&_[data-slot=copyable-code-icon]]:will-change-[opacity,filter,scale]",
927
+ "motion-reduce:[&_[data-slot=copyable-code-icon]]:transition-none",
928
+ "data-[state=idle]:[&_[data-icon=copy]]:scale-100 data-[state=idle]:[&_[data-icon=copy]]:opacity-100 data-[state=idle]:[&_[data-icon=copy]]:blur-0",
929
+ "data-[state=idle]:[&_[data-icon=check]]:scale-[0.72] data-[state=idle]:[&_[data-icon=check]]:opacity-0 data-[state=idle]:[&_[data-icon=check]]:blur-[1px]",
930
+ "data-[state=copied]:[&_[data-icon=check]]:scale-100 data-[state=copied]:[&_[data-icon=check]]:opacity-100 data-[state=copied]:[&_[data-icon=check]]:blur-0",
931
+ "data-[state=copied]:[&_[data-icon=copy]]:scale-[0.72] data-[state=copied]:[&_[data-icon=copy]]:opacity-0 data-[state=copied]:[&_[data-icon=copy]]:blur-[1px]"
932
+ ]
933
+ },
934
+ variants: {
935
+ theme: {
936
+ brutal: {
937
+ code: ["border-2 border-line-strong bg-black text-[oklch(0.88_0.18_132)] shadow-sm"],
938
+ codeInner: "break-all"
939
+ },
940
+ elegant: {
941
+ code: [
942
+ "bg-[oklch(0.988_0.002_286)] text-[oklch(0.45_0.04_74)]",
943
+ "shadow-[0_0_0_0.5px_oklch(0_0_0_/_0.22)]",
944
+ "dark:bg-layer-panel dark:text-[oklch(0.82_0.06_90)] dark:shadow-[0_0_0_0.5px_oklch(1_0_0_/_0.16)]"
945
+ ],
946
+ codeInner: ["border-x border-dashed border-[oklch(0_0_0_/_0.12)] bg-white px-1", "dark:border-[oklch(1_0_0_/_0.14)] dark:bg-layer-popover"],
947
+ action: [
948
+ "[&_[data-slot=button]]:text-foreground-muted",
949
+ "[&_[data-slot=button]]:shadow-none",
950
+ "[&_[data-slot=button]]:hover:bg-transparent [&_[data-slot=button]]:hover:text-foreground-strong [&_[data-slot=button]]:hover:before:bg-transparent"
951
+ ]
952
+ }
953
+ },
954
+ size: {
955
+ sm: { code: "px-3 py-1.5 leading-5" },
956
+ md: { code: "px-3 py-2 leading-5" }
957
+ }
958
+ },
959
+ defaultVariants: { size: "md" },
960
+ compoundVariants: [{
961
+ theme: "elegant",
962
+ size: "sm",
963
+ class: {
964
+ code: "px-2 py-0",
965
+ codeInner: "py-1.5 leading-5"
966
+ }
967
+ }, {
968
+ theme: "elegant",
969
+ size: "md",
970
+ class: {
971
+ code: "px-2 py-0",
972
+ codeInner: "py-2 leading-5"
973
+ }
974
+ }]
975
+ });
976
+ const CopyableCodeContext = createContext(null);
977
+ function useCopyableCode(part) {
978
+ const context = useContext(CopyableCodeContext);
979
+ if (!context) throw new Error(`${part} must be used inside CopyableCode.Root.`);
980
+ return context;
981
+ }
982
+ function CopyableCodeRoot({ copied, onCopy, size = "md", className, ...props }) {
983
+ const { root } = copyableCode({
984
+ theme: useThemeFamily(),
985
+ size
986
+ });
987
+ const { copied: clipboardCopied, copy } = useClipboard({ timeout: 1400 });
988
+ const effectiveCopied = copied ?? clipboardCopied;
989
+ const copyValue = useCallback(async (value) => {
990
+ await copy(value);
991
+ await onCopy?.(value);
992
+ }, [copy, onCopy]);
993
+ const context = useMemo(() => ({
994
+ copied: effectiveCopied,
995
+ copyValue,
996
+ size
997
+ }), [
998
+ copyValue,
999
+ effectiveCopied,
1000
+ size
1001
+ ]);
1002
+ return /* @__PURE__ */ jsx(CopyableCodeContext.Provider, {
1003
+ value: context,
1004
+ children: /* @__PURE__ */ jsx("div", {
1005
+ "data-slot": "copyable-code",
1006
+ "data-size": size,
1007
+ "data-state": effectiveCopied ? "copied" : "idle",
1008
+ className: root({ className }),
1009
+ ...props
1010
+ })
1011
+ });
1012
+ }
1013
+ function CopyableCodeCode({ children, className, truncate, ...props }) {
1014
+ const { size } = useCopyableCode("CopyableCode.Code");
1015
+ const { code, codeInner } = copyableCode({
1016
+ theme: useThemeFamily(),
1017
+ size
1018
+ });
1019
+ const scrollClassName = "overflow-x-auto overflow-y-hidden break-normal whitespace-nowrap text-clip [scrollbar-width:none] [&::-webkit-scrollbar]:hidden";
1020
+ return /* @__PURE__ */ jsx("code", {
1021
+ "data-slot": "copyable-code-code",
1022
+ "data-truncate": truncate ? "true" : void 0,
1023
+ className: code({ className }),
1024
+ ...props,
1025
+ children: /* @__PURE__ */ jsx("span", {
1026
+ "data-slot": "copyable-code-code-inner",
1027
+ className: codeInner({ className: [truncate && scrollClassName] }),
1028
+ children
1029
+ })
1030
+ });
1031
+ }
1032
+ function CopyableCodeAction({ ariaLabel = "Copy code", children, buttonClassName, className, copiedAriaLabel = "Copied code", onClick, size, variant, ...props }) {
1033
+ const { copied, copyValue } = useCopyableCode("CopyableCode.Action");
1034
+ const theme = useThemeFamily();
1035
+ const { action } = copyableCode({ theme });
1036
+ const accessibleLabel = copied ? copiedAriaLabel : ariaLabel;
1037
+ const buttonSize = size ?? (theme === "elegant" ? "icon-xs" : "icon-sm");
1038
+ const buttonVariant = variant ?? (theme === "elegant" ? "ghost" : "outline");
1039
+ const handleClick = async (event) => {
1040
+ await copyValue(event.currentTarget.closest("[data-slot=\"copyable-code\"]")?.querySelector("[data-slot=\"copyable-code-code\"]")?.textContent ?? "");
1041
+ onClick?.(event);
1042
+ };
1043
+ return /* @__PURE__ */ jsx("span", {
1044
+ "data-slot": "copyable-code-action",
1045
+ className: action({ className }),
1046
+ children: /* @__PURE__ */ jsx(Button, {
1047
+ type: "button",
1048
+ variant: buttonVariant,
1049
+ size: buttonSize,
1050
+ "aria-label": accessibleLabel,
1051
+ "aria-live": "polite",
1052
+ onClick: handleClick,
1053
+ className: buttonClassName,
1054
+ ...props,
1055
+ children: typeof children === "function" ? children({ copied }) : children ?? /* @__PURE__ */ jsx(CopyableCodeActionIcon, { copied })
1056
+ })
1057
+ });
1058
+ }
1059
+ function CopyableCodeActionIcon({ copied }) {
1060
+ const { iconSwap } = copyableCode();
1061
+ return /* @__PURE__ */ jsxs("span", {
1062
+ "data-slot": "copyable-code-icon-swap",
1063
+ "data-state": copied ? "copied" : "idle",
1064
+ className: iconSwap(),
1065
+ "aria-hidden": true,
1066
+ children: [/* @__PURE__ */ jsx(Copy, {
1067
+ "data-slot": "copyable-code-icon",
1068
+ "data-icon": "copy",
1069
+ className: "size-3",
1070
+ strokeWidth: 1.75
1071
+ }), /* @__PURE__ */ jsx(Check, {
1072
+ "data-slot": "copyable-code-icon",
1073
+ "data-icon": "check",
1074
+ className: "size-3",
1075
+ strokeWidth: 1.75
1076
+ })]
1077
+ });
1078
+ }
1079
+ function CopyableCodePreset({ actionClassName, ariaLabel, codeClassName, children, copiedAriaLabel, truncate, ...props }) {
1080
+ return /* @__PURE__ */ jsxs(CopyableCodeRoot, {
1081
+ ...props,
1082
+ children: [/* @__PURE__ */ jsx(CopyableCodeCode, {
1083
+ className: codeClassName,
1084
+ truncate,
1085
+ children
1086
+ }), /* @__PURE__ */ jsx(CopyableCodeAction, {
1087
+ ariaLabel,
1088
+ className: actionClassName,
1089
+ copiedAriaLabel
1090
+ })]
1091
+ });
1092
+ }
1093
+ const CopyableCode = Object.assign(CopyableCodePreset, {
1094
+ Action: CopyableCodeAction,
1095
+ Code: CopyableCodeCode,
1096
+ Root: CopyableCodeRoot
1097
+ });
1098
+ //#endregion
23
1099
  //#region src/components/checkbox/checkbox-indicator.tsx
24
1100
  const checkboxIndicator = tv({
25
1101
  slots: { root: [
@@ -2751,6 +3827,114 @@ function RadioGroupItem({ appearance = "default", className, children, ...props
2751
3827
  });
2752
3828
  }
2753
3829
  //#endregion
3830
+ //#region src/components/switch/switch.tsx
3831
+ const switchRecipe = tv({
3832
+ slots: {
3833
+ root: [
3834
+ "group/switch relative inline-flex shrink-0 touch-manipulation items-center outline-none",
3835
+ "transition-[background-color,box-shadow,transform] duration-[180ms] ease-out",
3836
+ "motion-reduce:transition-none",
3837
+ "not-data-[disabled]:cursor-pointer",
3838
+ "data-[disabled]:cursor-not-allowed data-[disabled]:active:scale-100",
3839
+ "after:absolute after:-inset-x-3 after:-inset-y-2 after:content-['']"
3840
+ ],
3841
+ thumb: [
3842
+ "pointer-events-none block",
3843
+ "transition-transform duration-[180ms] ease-out",
3844
+ "motion-reduce:transition-none"
3845
+ ]
3846
+ },
3847
+ variants: {
3848
+ theme: {
3849
+ brutal: {
3850
+ root: [
3851
+ "rounded-none border-[2.5px] border-line-strong bg-layer-panel",
3852
+ "hover:bg-layer-panel data-[checked]:bg-primary-400",
3853
+ "data-[checked]:hover:bg-primary-400",
3854
+ "data-[disabled]:border-line-muted data-[disabled]:bg-layer-panel data-[disabled]:opacity-50 data-[disabled]:hover:bg-layer-panel",
3855
+ "data-[checked]:data-[disabled]:border-line-muted data-[checked]:data-[disabled]:bg-primary-400",
3856
+ "focus-visible:ring-2 focus-visible:ring-line-focus focus-visible:ring-offset-2 focus-visible:ring-offset-background",
3857
+ "active:scale-[0.98] motion-reduce:active:scale-100"
3858
+ ],
3859
+ thumb: [
3860
+ "rounded-none bg-line-strong shadow-none",
3861
+ "data-[checked]:bg-line-strong",
3862
+ "data-[disabled]:bg-line-muted",
3863
+ "data-[checked]:data-[disabled]:bg-line-subtle"
3864
+ ]
3865
+ },
3866
+ elegant: {
3867
+ root: [
3868
+ "rounded-full bg-foreground/[0.12]",
3869
+ "shadow-[inset_0_1px_0.5px_oklch(1_0_0_/_0.05),0_1px_1.5px_-1px_oklch(0_0_0_/_0.08)]",
3870
+ "hover:bg-foreground/[0.16]",
3871
+ "data-[checked]:bg-foreground-strong data-[checked]:shadow-[inset_0_1px_0.5px_oklch(1_0_0_/_0.12),0_1px_1.5px_-1px_oklch(0_0_0_/_0.12)]",
3872
+ "data-[checked]:hover:bg-foreground-strong",
3873
+ "data-[disabled]:bg-layer-panel data-[disabled]:shadow-[inset_0_0_0_1px_var(--line-subtle)]",
3874
+ "data-[checked]:data-[disabled]:bg-layer-panel data-[checked]:data-[disabled]:shadow-[inset_0_0_0_1px_var(--line-subtle)]",
3875
+ "focus-visible:ring-2 focus-visible:ring-line-focus focus-visible:ring-offset-2 focus-visible:ring-offset-background",
3876
+ "active:scale-[0.96] motion-reduce:active:scale-100"
3877
+ ],
3878
+ thumb: [
3879
+ "rounded-full bg-layer-popover",
3880
+ "shadow-[0_1px_1.5px_-0.5px_oklch(0_0_0_/_0.18),0_0_0_1px_oklch(0_0_0_/_0.04)]",
3881
+ "data-[disabled]:bg-[oklch(0.88_0.004_286)] data-[disabled]:shadow-none",
3882
+ "data-[checked]:data-[disabled]:bg-[oklch(0.88_0.004_286)]"
3883
+ ]
3884
+ }
3885
+ },
3886
+ size: {
3887
+ sm: {
3888
+ root: "h-4 w-7 p-0.5",
3889
+ thumb: "size-3 data-[checked]:translate-x-3"
3890
+ },
3891
+ md: {
3892
+ root: "h-5 w-9 p-0.5",
3893
+ thumb: "size-4 data-[checked]:translate-x-4"
3894
+ }
3895
+ }
3896
+ },
3897
+ compoundVariants: [{
3898
+ theme: "brutal",
3899
+ size: "sm",
3900
+ class: {
3901
+ root: "h-5 w-9 p-0",
3902
+ thumb: "size-3.5 translate-x-px data-[checked]:translate-x-4"
3903
+ }
3904
+ }, {
3905
+ theme: "brutal",
3906
+ size: "md",
3907
+ class: {
3908
+ root: "h-6 w-11 p-0",
3909
+ thumb: "size-[18px] translate-x-px data-[checked]:translate-x-5"
3910
+ }
3911
+ }],
3912
+ defaultVariants: { size: "sm" }
3913
+ });
3914
+ function Switch({ size, className, children, ...props }) {
3915
+ const { root } = switchRecipe({
3916
+ theme: useThemeFamily(),
3917
+ size
3918
+ });
3919
+ return /* @__PURE__ */ jsx(Switch$1.Root, {
3920
+ "data-slot": "switch",
3921
+ className: root({ className }),
3922
+ ...props,
3923
+ children: children ?? /* @__PURE__ */ jsx(SwitchThumb, { size })
3924
+ });
3925
+ }
3926
+ function SwitchThumb({ size, className, ...props }) {
3927
+ const { thumb } = switchRecipe({
3928
+ theme: useThemeFamily(),
3929
+ size
3930
+ });
3931
+ return /* @__PURE__ */ jsx(Switch$1.Thumb, {
3932
+ "data-slot": "switch-thumb",
3933
+ className: thumb({ className }),
3934
+ ...props
3935
+ });
3936
+ }
3937
+ //#endregion
2754
3938
  //#region src/components/segmented-control/segmented-control.tsx
2755
3939
  const segmentedControl = tv({
2756
3940
  slots: {
@@ -3494,12 +4678,15 @@ const banner = tv({
3494
4678
  "group/banner grid grid-cols-[0_minmax(0,1fr)] items-start border-2 border-line-strong",
3495
4679
  "has-[>[data-slot=banner-action]]:grid-cols-[0_minmax(0,1fr)_auto]",
3496
4680
  "has-[>svg]:grid-cols-[18px_minmax(0,1fr)]",
4681
+ "has-[>[data-slot=status]]:grid-cols-[auto_minmax(0,1fr)]",
3497
4682
  "[&:has(>svg):has(>[data-slot=banner-action])]:grid-cols-[18px_minmax(0,1fr)_auto]",
4683
+ "[&:has(>[data-slot=status]):has(>[data-slot=banner-action])]:grid-cols-[auto_minmax(0,1fr)_auto]",
3498
4684
  "[&>svg]:col-start-1 [&>svg]:row-span-2 [&>svg]:mt-0.5",
3499
- "[&>svg]:size-[18px] [&>svg]:shrink-0 [&>svg]:text-foreground-strong"
4685
+ "[&>svg]:size-[18px] [&>svg]:shrink-0 [&>svg]:text-foreground-strong",
4686
+ "[&>[data-slot=status]]:col-start-1 [&>[data-slot=status]]:row-start-1 [&>[data-slot=status]]:row-span-2 [&>[data-slot=status]]:self-center"
3500
4687
  ],
3501
4688
  title: ["col-start-2 mb-0.5 text-sm font-bold text-foreground-strong", "group-data-[size=sm]/banner:text-xs"],
3502
- description: ["col-start-2 min-w-0 text-sm text-foreground-strong", "group-data-[size=sm]/banner:text-xs"],
4689
+ description: ["col-start-2 min-w-0 text-sm font-semibold text-foreground-strong", "group-data-[size=sm]/banner:text-xs"],
3503
4690
  action: ["col-start-3 row-span-2 row-start-1 shrink-0"]
3504
4691
  },
3505
4692
  elegant: {
@@ -3508,16 +4695,20 @@ const banner = tv({
3508
4695
  "text-[0.8125rem] leading-5 tracking-[-0.005em] text-foreground-strong",
3509
4696
  "grid-cols-[minmax(0,1fr)]",
3510
4697
  "has-[>svg]:grid-cols-[auto_minmax(0,1fr)]",
4698
+ "has-[>[data-slot=status]]:grid-cols-[auto_minmax(0,1fr)]",
3511
4699
  "has-[>[data-slot=banner-action]]:grid-cols-[minmax(0,1fr)_auto]",
3512
4700
  "has-[>svg]:has-[>[data-slot=banner-action]]:grid-cols-[auto_minmax(0,1fr)_auto]",
4701
+ "has-[>[data-slot=status]]:has-[>[data-slot=banner-action]]:grid-cols-[auto_minmax(0,1fr)_auto]",
3513
4702
  "has-[>[data-slot=banner-title]]:has-[>[data-slot=banner-description]]:items-start",
3514
4703
  "has-[>[data-slot=banner-title]]:has-[>[data-slot=banner-description]]:grid-rows-[auto_auto]",
3515
4704
  "has-[>[data-slot=banner-title]]:has-[>[data-slot=banner-description]]:gap-y-1",
3516
- "[&>svg]:col-start-1 [&>svg]:row-start-1 [&>svg]:size-4 [&>svg]:shrink-0 [&>svg]:self-center"
4705
+ "[&>svg]:col-start-1 [&>svg]:row-start-1 [&>svg]:size-4 [&>svg]:shrink-0 [&>svg]:self-center",
4706
+ "[&>[data-slot=status]]:col-start-1 [&>[data-slot=status]]:row-start-1 [&>[data-slot=status]]:self-center"
3517
4707
  ],
3518
4708
  title: [
3519
4709
  "col-start-1 row-start-1 flex h-5 min-w-0 items-center text-[0.84375rem] font-medium leading-5 text-foreground-strong",
3520
4710
  "group-has-[>svg]/banner:col-start-2",
4711
+ "group-has-[>[data-slot=status]]/banner:col-start-2",
3521
4712
  "group-data-[size=sm]/banner:h-4 group-data-[size=sm]/banner:text-[0.8125rem] group-data-[size=sm]/banner:leading-4",
3522
4713
  "group-data-[size=lg]/banner:h-6 group-data-[size=lg]/banner:text-[0.90625rem] group-data-[size=lg]/banner:leading-6",
3523
4714
  "group-data-[status=warning]/banner:text-[oklch(0.476_0.114_61.907)]"
@@ -3525,6 +4716,7 @@ const banner = tv({
3525
4716
  description: [
3526
4717
  "col-start-1 row-start-1 min-w-0 font-normal leading-4 text-foreground-muted",
3527
4718
  "group-has-[>svg]/banner:col-start-2",
4719
+ "group-has-[>[data-slot=status]]/banner:col-start-2",
3528
4720
  "group-has-[>[data-slot=banner-title]]/banner:row-start-2",
3529
4721
  "group-data-[size=sm]/banner:text-xs group-data-[size=sm]/banner:leading-4",
3530
4722
  "group-data-[size=lg]/banner:text-[0.875rem] group-data-[size=lg]/banner:leading-5",
@@ -3533,6 +4725,7 @@ const banner = tv({
3533
4725
  action: [
3534
4726
  "col-start-2 row-start-1 flex h-5 shrink-0 items-center gap-2",
3535
4727
  "group-has-[>svg]/banner:col-start-3",
4728
+ "group-has-[>[data-slot=status]]/banner:col-start-3",
3536
4729
  "group-has-[>[data-slot=banner-title]+[data-slot=banner-description]]/banner:row-span-2",
3537
4730
  "[&>button:has(svg):last-child]:size-5 [&>button:has(svg):last-child]:min-h-5 [&>button:has(svg):last-child]:min-w-5",
3538
4731
  "[&>button:has(svg):last-child]:rounded-sm",
@@ -3585,7 +4778,7 @@ const banner = tv({
3585
4778
  {
3586
4779
  theme: "brutal",
3587
4780
  status: "warning",
3588
- class: { root: "bg-warning-base/20" }
4781
+ class: { root: "bg-brutal-yellow/30" }
3589
4782
  },
3590
4783
  {
3591
4784
  theme: "brutal",
@@ -3600,17 +4793,17 @@ const banner = tv({
3600
4793
  {
3601
4794
  theme: "brutal",
3602
4795
  size: "sm",
3603
- class: { root: "gap-y-0 p-2 has-[>svg]:gap-x-2 has-[>[data-slot=banner-action]]:gap-x-2" }
4796
+ class: { root: "gap-y-0 p-2 has-[>svg]:gap-x-2 has-[>[data-slot=banner-action]]:gap-x-2 has-[>[data-slot=status]]:gap-x-1.5" }
3604
4797
  },
3605
4798
  {
3606
4799
  theme: "brutal",
3607
4800
  size: "md",
3608
- class: { root: "gap-y-0 p-3 has-[>svg]:gap-x-3 has-[>[data-slot=banner-action]]:gap-x-3" }
4801
+ class: { root: "gap-y-0 p-3 has-[>svg]:gap-x-3 has-[>[data-slot=banner-action]]:gap-x-3 has-[>[data-slot=status]]:gap-x-2" }
3609
4802
  },
3610
4803
  {
3611
4804
  theme: "brutal",
3612
4805
  size: "lg",
3613
- class: { root: "gap-y-0 p-4 shadow-sm has-[>svg]:gap-x-3 has-[>[data-slot=banner-action]]:gap-x-3" }
4806
+ class: { root: "gap-y-0 p-4 shadow-sm has-[>svg]:gap-x-3 has-[>[data-slot=banner-action]]:gap-x-3 has-[>[data-slot=status]]:gap-x-2" }
3614
4807
  },
3615
4808
  {
3616
4809
  theme: "elegant",
@@ -4591,4 +5784,4 @@ function ThemeProvider({ theme, defaultTheme = "brutal", onThemeChange, mode, de
4591
5784
  });
4592
5785
  }
4593
5786
  //#endregion
4594
- export { Avatar, AvatarBadge, AvatarFallback, AvatarGroup, AvatarGroupCount, AvatarImage, Badge, Banner, BannerAction, BannerDescription, BannerTitle, Button, Checkbox, Combobox, ComboboxChip, ComboboxChipRemove, ComboboxChips, ComboboxClear, ComboboxCollection, ComboboxContent, ComboboxControl, ComboboxEmpty, ComboboxGroup, ComboboxGroupLabel, ComboboxHeader, ComboboxInput, ComboboxInputGroup, ComboboxItem, ComboboxItemIndicator, ComboboxLabel, ComboboxList, ComboboxPopup, ComboboxPortal, ComboboxRow, ComboboxSeparator, ComboboxTrigger, ComboboxTriggerIndicator, ComboboxValue, ContextMenu, ContextMenuCheckboxItem, ContextMenuCheckboxItemIndicator, ContextMenuContent, ContextMenuItem, ContextMenuLabel, ContextMenuPortal, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuRadioItemIndicator, ContextMenuSeparator, ContextMenuShortcut, ContextMenuSubmenu, ContextMenuSubmenuTrigger, ContextMenuTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuCheckboxItemIndicator, DropdownMenuContent, DropdownMenuItem, DropdownMenuItemCount, DropdownMenuLabel, DropdownMenuPopup, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuRadioItemIndicator, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSubmenu, DropdownMenuSubmenuTrigger, DropdownMenuTrigger, EmptyState, EmptyStateActions, EmptyStateContent, EmptyStateDescription, EmptyStateIcon, EmptyStateTitle, Field, FieldControl, FieldDescription, FieldError, FieldItem, FieldLabel, FieldValidity, InlineCode, Input, InputGroup, InputGroupAddon, InputGroupInput, Kbd, KbdGroup, Label, LabelAsterisk, LabelOptional, LabelSub, NotificationCenter, NotificationCenterActionButton, NotificationCenterCount, NotificationCenterEmptyState, NotificationCenterHeader, NotificationCenterItem, NotificationCenterItemActions, NotificationCenterItemBody, NotificationCenterItemContent, NotificationCenterItemIcon, NotificationCenterItemRow, NotificationCenterItemTitle, NotificationCenterList, NotificationCenterPopup, NotificationCenterScroller, NotificationCenterTitle, NotificationCenterTrigger, Popover, PopoverArrow, PopoverBackdrop, PopoverClose, PopoverContent, PopoverDescription, PopoverHeader, PopoverPopup, PopoverPortal, PopoverSeparator, PopoverTitle, PopoverTrigger, PopoverViewport, RadioGroup, RadioGroupIndicator, RadioGroupItem, SegmentedControl, SegmentedControlCount, SegmentedControlItem, SegmentedControlLabel, Select, SelectArrow, SelectContent, SelectGroup, SelectGroupLabel, SelectIcon, SelectItem, SelectItemIndicator, SelectItemText, SelectLabel, SelectList, SelectPopup, SelectPortal, SelectScrollDownArrow, SelectScrollUpArrow, SelectSeparator, SelectTrigger, SelectValue, Separator, SortableTabsList, SortableTabsTab, Spinner, Status, Tabs, TabsBackground, TabsIndicator, TabsLabel, TabsList, TabsPanel, TabsTab, Text, TextHeading, TextMono, TextSans, Textarea, TextareaCounter, TextareaGroup, ThemeProvider, Tooltip, TooltipContent, TooltipPortal, TooltipProvider, TooltipTrigger, buttonVariants, cn, useOrderedTabs, useTheme, useThemeFamily };
5787
+ export { AlertDialog, AlertDialogAction, AlertDialogBody, AlertDialogCancel, AlertDialogClose, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, Avatar, AvatarBadge, AvatarFallback, AvatarGroup, AvatarGroupCount, AvatarImage, Badge, Banner, BannerAction, BannerDescription, BannerTitle, Button, Checkbox, Combobox, ComboboxChip, ComboboxChipRemove, ComboboxChips, ComboboxClear, ComboboxCollection, ComboboxContent, ComboboxControl, ComboboxEmpty, ComboboxGroup, ComboboxGroupLabel, ComboboxHeader, ComboboxInput, ComboboxInputGroup, ComboboxItem, ComboboxItemIndicator, ComboboxLabel, ComboboxList, ComboboxPopup, ComboboxPortal, ComboboxRow, ComboboxSeparator, ComboboxTrigger, ComboboxTriggerIndicator, ComboboxValue, ContextMenu, ContextMenuCheckboxItem, ContextMenuCheckboxItemIndicator, ContextMenuContent, ContextMenuItem, ContextMenuLabel, ContextMenuPortal, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuRadioItemIndicator, ContextMenuSeparator, ContextMenuShortcut, ContextMenuSubmenu, ContextMenuSubmenuTrigger, ContextMenuTrigger, CopyableCode, Dialog, DialogBody, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuCheckboxItemIndicator, DropdownMenuContent, DropdownMenuItem, DropdownMenuItemCount, DropdownMenuLabel, DropdownMenuPopup, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuRadioItemIndicator, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSubmenu, DropdownMenuSubmenuTrigger, DropdownMenuTrigger, EmptyState, EmptyStateActions, EmptyStateContent, EmptyStateDescription, EmptyStateIcon, EmptyStateTitle, Field, FieldControl, FieldDescription, FieldError, FieldItem, FieldLabel, FieldValidity, InlineCode, Input, InputGroup, InputGroupAddon, InputGroupInput, Kbd, KbdGroup, Label, LabelAsterisk, LabelOptional, LabelSub, NotificationCenter, NotificationCenterActionButton, NotificationCenterCount, NotificationCenterEmptyState, NotificationCenterHeader, NotificationCenterItem, NotificationCenterItemActions, NotificationCenterItemBody, NotificationCenterItemContent, NotificationCenterItemIcon, NotificationCenterItemRow, NotificationCenterItemTitle, NotificationCenterList, NotificationCenterPopup, NotificationCenterScroller, NotificationCenterTitle, NotificationCenterTrigger, Popover, PopoverArrow, PopoverBackdrop, PopoverClose, PopoverContent, PopoverDescription, PopoverHeader, PopoverPopup, PopoverPortal, PopoverSeparator, PopoverTitle, PopoverTrigger, PopoverViewport, RadioGroup, RadioGroupIndicator, RadioGroupItem, SegmentedControl, SegmentedControlCount, SegmentedControlItem, SegmentedControlLabel, Select, SelectArrow, SelectContent, SelectGroup, SelectGroupLabel, SelectIcon, SelectItem, SelectItemIndicator, SelectItemText, SelectLabel, SelectList, SelectPopup, SelectPortal, SelectScrollDownArrow, SelectScrollUpArrow, SelectSeparator, SelectTrigger, SelectValue, Separator, SortableTabsList, SortableTabsTab, Spinner, Status, Switch, SwitchThumb, Tabs, TabsBackground, TabsIndicator, TabsLabel, TabsList, TabsPanel, TabsTab, Text, TextHeading, TextMono, TextSans, Textarea, TextareaCounter, TextareaGroup, ThemeProvider, Tooltip, TooltipContent, TooltipPortal, TooltipProvider, TooltipTrigger, buttonVariants, cn, useOrderedTabs, useTheme, useThemeFamily };