raft-ui 0.0.10 → 0.0.12

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,15 +1,18 @@
1
1
  import { cn } from "./cn.mjs";
2
- 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-jUlaK4eN.mjs";
2
+ import { a as tv, i as ThemeStateContext, n as useThemeFamily, r as ThemeContext, t as useTheme } from "./use-theme-Y_h1DKll.mjs";
3
3
  import { Dialog as Dialog$1 } from "@base-ui/react/dialog";
4
4
  import { AlertTriangle, Check, CheckCircle2, ChevronDown, Copy, Info, Minus, X } from "lucide-react";
5
- import { cloneElement, createContext, isValidElement, use, useCallback, useContext, useEffect, useId, useMemo, useState, useSyncExternalStore } from "react";
5
+ import { Children, Fragment, cloneElement, createContext, isValidElement, use, useCallback, useContext, useEffect, useId, useMemo, useRef, useState, useSyncExternalStore } from "react";
6
+ import { Button as Button$1 } from "@base-ui/react/button";
6
7
  import { mergeProps } from "@base-ui/react/merge-props";
7
8
  import { useRender } from "@base-ui/react/use-render";
8
9
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
10
+ import { Drawer } from "vaul";
9
11
  import { useClipboard } from "foxact/use-clipboard";
10
12
  import { Checkbox as Checkbox$1 } from "@base-ui/react/checkbox";
11
13
  import { Avatar as Avatar$1, ContextMenu as ContextMenu$1 } from "@base-ui/react";
12
14
  import { Menu } from "@base-ui/react/menu";
15
+ import { useHotkey } from "@tanstack/react-hotkeys";
13
16
  import { Tooltip as Tooltip$1 } from "@base-ui/react/tooltip";
14
17
  import { Popover as Popover$1 } from "@base-ui/react/popover";
15
18
  import { PreviewCard as PreviewCard$1 } from "@base-ui/react/preview-card";
@@ -26,6 +29,690 @@ import { Tabs as Tabs$1 } from "@base-ui/react/tabs";
26
29
  import { DndContext, PointerSensor, TouchSensor, closestCenter, useSensor, useSensors } from "@dnd-kit/core";
27
30
  import { SortableContext, arrayMove, horizontalListSortingStrategy, useSortable } from "@dnd-kit/sortable";
28
31
  import { Separator as Separator$1 } from "@base-ui/react/separator";
32
+ //#region src/components/spinner/spinner.tsx
33
+ const SPINNER_STYLE = `
34
+ @keyframes raft-braille-spinner {
35
+ 0%,
36
+ 9.99% {
37
+ content: "⠋";
38
+ }
39
+ 10%,
40
+ 19.99% {
41
+ content: "⠙";
42
+ }
43
+ 20%,
44
+ 29.99% {
45
+ content: "⠹";
46
+ }
47
+ 30%,
48
+ 39.99% {
49
+ content: "⠸";
50
+ }
51
+ 40%,
52
+ 49.99% {
53
+ content: "⠼";
54
+ }
55
+ 50%,
56
+ 59.99% {
57
+ content: "⠴";
58
+ }
59
+ 60%,
60
+ 69.99% {
61
+ content: "⠦";
62
+ }
63
+ 70%,
64
+ 79.99% {
65
+ content: "⠧";
66
+ }
67
+ 80%,
68
+ 89.99% {
69
+ content: "⠇";
70
+ }
71
+ 90%,
72
+ 100% {
73
+ content: "⠏";
74
+ }
75
+ }
76
+
77
+ [data-slot="spinner"] [data-spinner-glyph]::before {
78
+ content: "⠋";
79
+ animation: raft-braille-spinner 800ms steps(1, end) infinite;
80
+ }
81
+
82
+ @media (prefers-reduced-motion: reduce) {
83
+ [data-slot="spinner"] [data-spinner-glyph]::before {
84
+ animation-duration: 1600ms;
85
+ }
86
+ }
87
+
88
+ @keyframes raft-elegant-spinner-spin {
89
+ to {
90
+ transform: rotate(360deg);
91
+ }
92
+ }
93
+
94
+ @keyframes raft-elegant-spinner-dash {
95
+ 0% {
96
+ stroke-dasharray: 1 150;
97
+ stroke-dashoffset: 0;
98
+ }
99
+ 50% {
100
+ stroke-dasharray: 90 150;
101
+ stroke-dashoffset: -35;
102
+ }
103
+ 100% {
104
+ stroke-dasharray: 90 150;
105
+ stroke-dashoffset: -124;
106
+ }
107
+ }
108
+
109
+ [data-slot="spinner"] [data-spinner-ring] {
110
+ animation: raft-elegant-spinner-spin 1600ms linear infinite;
111
+ transform-box: fill-box;
112
+ transform-origin: center;
113
+ will-change: transform;
114
+ }
115
+
116
+ [data-slot="spinner"] [data-spinner-arc] {
117
+ animation: raft-elegant-spinner-dash 1400ms cubic-bezier(0.42, 0, 0.58, 1) infinite;
118
+ stroke-dasharray: 1 150;
119
+ stroke-dashoffset: 0;
120
+ }
121
+
122
+ @media (prefers-reduced-motion: reduce) {
123
+ [data-slot="spinner"] [data-spinner-ring] {
124
+ animation-duration: 2400ms;
125
+ will-change: auto;
126
+ }
127
+
128
+ [data-slot="spinner"] [data-spinner-arc] {
129
+ animation: none;
130
+ stroke-dasharray: 72 150;
131
+ stroke-dashoffset: -30;
132
+ }
133
+ }
134
+ `;
135
+ const spinner = tv({
136
+ slots: {
137
+ root: ["relative inline-flex shrink-0 items-center justify-center", "leading-none text-current"],
138
+ glyph: "inline-block min-w-[1ch] font-mono tabular-nums",
139
+ ring: "block size-full shrink-0"
140
+ },
141
+ variants: {
142
+ theme: {
143
+ brutal: {},
144
+ elegant: {}
145
+ },
146
+ size: {
147
+ sm: {},
148
+ lg: {}
149
+ }
150
+ },
151
+ defaultVariants: { size: "sm" },
152
+ compoundVariants: [
153
+ {
154
+ theme: "brutal",
155
+ size: "sm",
156
+ class: { root: "h-4 text-base" }
157
+ },
158
+ {
159
+ theme: "brutal",
160
+ size: "lg",
161
+ class: { root: "h-6 text-xl" }
162
+ },
163
+ {
164
+ theme: "elegant",
165
+ size: "sm",
166
+ class: { root: "size-3.5" }
167
+ },
168
+ {
169
+ theme: "elegant",
170
+ size: "lg",
171
+ class: { root: "size-[18px]" }
172
+ }
173
+ ]
174
+ });
175
+ const spinnerStyle = /* @__PURE__ */ jsx("style", {
176
+ href: "raft-ui-spinner",
177
+ precedence: "default",
178
+ children: SPINNER_STYLE
179
+ });
180
+ function Spinner({ size = "sm", className, render, ...props }) {
181
+ const theme = useThemeFamily();
182
+ const { root, glyph, ring } = spinner({
183
+ theme,
184
+ size
185
+ });
186
+ const children = theme === "elegant" ? /* @__PURE__ */ jsxs(Fragment$1, { children: [spinnerStyle, /* @__PURE__ */ jsxs("svg", {
187
+ "data-spinner-ring": "",
188
+ "aria-hidden": "true",
189
+ className: ring(),
190
+ xmlns: "http://www.w3.org/2000/svg",
191
+ fill: "none",
192
+ viewBox: "0 0 24 24",
193
+ children: [/* @__PURE__ */ jsx("circle", {
194
+ className: "opacity-20",
195
+ cx: "12",
196
+ cy: "12",
197
+ r: "10",
198
+ stroke: "currentColor",
199
+ strokeWidth: "2.5"
200
+ }), /* @__PURE__ */ jsx("circle", {
201
+ "data-spinner-arc": "",
202
+ className: "opacity-80",
203
+ cx: "12",
204
+ cy: "12",
205
+ r: "10",
206
+ fill: "none",
207
+ pathLength: "150",
208
+ stroke: "currentColor",
209
+ strokeLinecap: "round",
210
+ strokeWidth: "2.5"
211
+ })]
212
+ })] }) : /* @__PURE__ */ jsxs(Fragment$1, { children: [spinnerStyle, /* @__PURE__ */ jsx("span", {
213
+ "data-spinner-glyph": "",
214
+ "aria-hidden": "true",
215
+ className: glyph()
216
+ })] });
217
+ return useRender({
218
+ defaultTagName: "span",
219
+ render,
220
+ props: mergeProps({
221
+ role: "status",
222
+ "aria-label": "Loading",
223
+ className: root({ className }),
224
+ children
225
+ }, props),
226
+ state: {
227
+ slot: "spinner",
228
+ size
229
+ }
230
+ });
231
+ }
232
+ //#endregion
233
+ //#region src/components/button/button.tsx
234
+ const buttonVariants = tv({
235
+ slots: {
236
+ root: [
237
+ "relative inline-flex shrink-0 items-center justify-center",
238
+ "font-heading leading-none whitespace-nowrap select-none",
239
+ "border-line rounded-none",
240
+ "shadow-sm transition-all duration-100",
241
+ "outline outline-[1px] outline-offset-2 outline-transparent",
242
+ "data-[loading=true]:cursor-wait",
243
+ "disabled:pointer-events-none disabled:opacity-40 data-[loading=true]:opacity-100",
244
+ "disabled:transform-none",
245
+ "[&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4"
246
+ ],
247
+ content: "relative z-10 inline-flex items-center justify-center gap-[inherit] data-[loading=true]:invisible",
248
+ loadingIndicator: "pointer-events-none absolute inset-0 z-10 flex items-center justify-center"
249
+ },
250
+ variants: {
251
+ theme: {
252
+ brutal: { root: ["border-2 font-bold focus-visible:outline-transparent"] },
253
+ elegant: { root: [
254
+ "overflow-clip border-0 font-sans font-medium antialiased",
255
+ "focus-visible:outline-[var(--button-focus-outline,transparent)]",
256
+ "shadow-[inset_0_1px_0.5px_oklch(1_0_0_/_0.05),0_0_0_1px_var(--line-subtle)]",
257
+ "before:pointer-events-none before:absolute before:inset-0 before:z-0 before:rounded-[inherit]",
258
+ "active:not-aria-[haspopup]:scale-[0.985]"
259
+ ] }
260
+ },
261
+ variant: {
262
+ primary: { root: ["border-line-strong bg-primary-400 text-primary-950", "hover:bg-primary-500"] },
263
+ default: { root: ["border-line-strong bg-layer-panel text-foreground-strong", "hover:bg-layer-panel"] },
264
+ information: { root: ["border-line-strong bg-info-base text-foreground-inverse", "hover:bg-info-base"] },
265
+ muted: { root: ["border-line-strong bg-secondary-400 text-secondary-950", "hover:border-line-strong hover:bg-secondary-400"] },
266
+ accent: { root: ["border-line-strong bg-accent-400 text-accent-950", "hover:bg-accent-500"] },
267
+ warning: { root: ["border-line-strong bg-warning-base text-foreground-inverse", "hover:bg-warning-base"] },
268
+ outline: { root: [
269
+ "border-line-strong bg-transparent text-foreground-strong",
270
+ "hover:bg-layer-muted",
271
+ "shadow-none"
272
+ ] },
273
+ ghost: { root: ["border-transparent bg-transparent text-foreground shadow-none", "hover:border-line-strong hover:bg-layer-muted"] },
274
+ link: { root: ["border-transparent bg-transparent text-foreground-strong shadow-none underline-offset-4", "hover:underline"] },
275
+ "danger-secondary": { root: ["border-line-strong bg-danger-lighter text-danger-base", "hover:bg-danger-lighter"] },
276
+ 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)]"] },
277
+ "danger-outline": { root: [
278
+ "border-line-strong bg-transparent text-danger-base",
279
+ "hover:bg-layer-muted",
280
+ "shadow-none"
281
+ ] }
282
+ },
283
+ size: {
284
+ xs: { root: [
285
+ "gap-1 px-2 py-[5px] text-[11px]",
286
+ "has-data-[icon=inline-start]:pl-1.5 has-data-[icon=inline-end]:pr-1.5",
287
+ "[&_[data-icon]]:size-[1em]",
288
+ "[&_svg:not([class*='size-'])]:size-3"
289
+ ] },
290
+ sm: { root: [
291
+ "gap-[5px] px-2.5 py-[6px] text-xs",
292
+ "has-data-[icon=inline-start]:pl-2 has-data-[icon=inline-end]:pr-2",
293
+ "[&_[data-icon]]:size-[1em]",
294
+ "[&_svg:not([class*='size-'])]:size-3.5"
295
+ ] },
296
+ md: { root: [
297
+ "gap-[5.5px] px-3 py-[7px] text-sm",
298
+ "has-data-[icon=inline-start]:pl-2.5 has-data-[icon=inline-end]:pr-2.5",
299
+ "[&_[data-icon]]:size-[1em]"
300
+ ] },
301
+ lg: { root: [
302
+ "gap-[6px] px-3.5 py-2 text-base",
303
+ "has-data-[icon=inline-start]:pl-3 has-data-[icon=inline-end]:pr-3",
304
+ "[&_[data-icon]]:size-[1em]",
305
+ "[&_svg:not([class*='size-'])]:size-4"
306
+ ] },
307
+ "icon-xs": { root: ["p-[5px] text-[11px]", "[&_svg:not([class*='size-'])]:size-3"] },
308
+ "icon-sm": { root: ["p-[6px] text-xs", "[&_svg:not([class*='size-'])]:size-3.5"] },
309
+ "icon-md": { root: ["p-2 text-sm", "[&_svg:not([class*='size-'])]:size-4"] },
310
+ "icon-lg": { root: ["p-3 text-sm", "[&_svg:not([class*='size-'])]:size-4"] }
311
+ }
312
+ },
313
+ defaultVariants: {
314
+ variant: "default",
315
+ size: "md"
316
+ },
317
+ compoundVariants: [
318
+ {
319
+ theme: "elegant",
320
+ size: ["xs", "icon-xs"],
321
+ class: { root: "rounded-sm" }
322
+ },
323
+ {
324
+ theme: "elegant",
325
+ size: ["sm", "icon-sm"],
326
+ class: { root: "rounded" }
327
+ },
328
+ {
329
+ theme: "elegant",
330
+ size: ["md", "icon-md"],
331
+ class: { root: "rounded-md" }
332
+ },
333
+ {
334
+ theme: "elegant",
335
+ size: "md",
336
+ class: { root: "py-1.5" }
337
+ },
338
+ {
339
+ theme: "elegant",
340
+ size: ["lg", "icon-lg"],
341
+ class: { root: "rounded-md" }
342
+ },
343
+ {
344
+ theme: "elegant",
345
+ size: "lg",
346
+ class: { root: "py-[7px]" }
347
+ },
348
+ {
349
+ theme: "elegant",
350
+ variant: ["outline", "danger-outline"],
351
+ size: "xs",
352
+ class: { root: "py-[6px]" }
353
+ },
354
+ {
355
+ theme: "elegant",
356
+ variant: ["outline", "danger-outline"],
357
+ size: "sm",
358
+ class: { root: "py-[6.75px]" }
359
+ },
360
+ {
361
+ theme: "elegant",
362
+ variant: ["outline", "danger-outline"],
363
+ size: "md",
364
+ class: { root: "py-[7.25px]" }
365
+ },
366
+ {
367
+ theme: "elegant",
368
+ variant: ["outline", "danger-outline"],
369
+ size: "lg",
370
+ class: { root: "py-[7.75px]" }
371
+ },
372
+ {
373
+ theme: "elegant",
374
+ variant: [
375
+ "primary",
376
+ "default",
377
+ "information",
378
+ "muted",
379
+ "accent",
380
+ "warning",
381
+ "danger-secondary",
382
+ "danger"
383
+ ],
384
+ size: "xs",
385
+ class: { root: "py-[5.75px]" }
386
+ },
387
+ {
388
+ theme: "elegant",
389
+ variant: [
390
+ "primary",
391
+ "default",
392
+ "information",
393
+ "muted",
394
+ "accent",
395
+ "warning",
396
+ "danger-secondary",
397
+ "danger"
398
+ ],
399
+ size: "sm",
400
+ class: { root: "py-[6.75px]" }
401
+ },
402
+ {
403
+ theme: "elegant",
404
+ variant: [
405
+ "primary",
406
+ "default",
407
+ "information",
408
+ "muted",
409
+ "accent",
410
+ "warning",
411
+ "danger-secondary",
412
+ "danger"
413
+ ],
414
+ size: "md",
415
+ class: { root: "py-[6.75px]" }
416
+ },
417
+ {
418
+ theme: "elegant",
419
+ variant: [
420
+ "primary",
421
+ "default",
422
+ "information",
423
+ "muted",
424
+ "accent",
425
+ "warning",
426
+ "danger-secondary",
427
+ "danger"
428
+ ],
429
+ size: "lg",
430
+ class: { root: "py-[7.75px]" }
431
+ },
432
+ {
433
+ theme: "brutal",
434
+ variant: "primary",
435
+ class: { root: "bg-brutal-yellow text-black hover:bg-brutal-yellow" }
436
+ },
437
+ {
438
+ theme: "brutal",
439
+ variant: "default",
440
+ class: { root: "bg-white text-black hover:bg-white" }
441
+ },
442
+ {
443
+ theme: "brutal",
444
+ variant: "outline",
445
+ class: { root: "bg-white text-black shadow-sm hover:bg-white" }
446
+ },
447
+ {
448
+ theme: "brutal",
449
+ variant: "information",
450
+ class: { root: "bg-brutal-cyan text-black hover:bg-brutal-cyan" }
451
+ },
452
+ {
453
+ theme: "brutal",
454
+ variant: "muted",
455
+ class: { root: "bg-brutal-stone text-black hover:bg-brutal-stone" }
456
+ },
457
+ {
458
+ theme: "brutal",
459
+ variant: "accent",
460
+ class: { root: "bg-brutal-pink text-black hover:bg-brutal-pink" }
461
+ },
462
+ {
463
+ theme: "brutal",
464
+ variant: "danger",
465
+ class: { root: "bg-brutal-red text-black hover:bg-brutal-red" }
466
+ },
467
+ {
468
+ theme: "brutal",
469
+ variant: "warning",
470
+ class: { root: "bg-[oklch(0.785_0.123_50.11)] text-black hover:bg-[oklch(0.785_0.123_50.11)]" }
471
+ },
472
+ {
473
+ theme: "brutal",
474
+ size: "xs",
475
+ class: { root: ["h-6 px-2 py-0 text-[11px]", "has-data-[icon=inline-start]:pl-1.5 has-data-[icon=inline-end]:pr-1.5"] }
476
+ },
477
+ {
478
+ theme: "brutal",
479
+ size: "sm",
480
+ class: { root: ["h-7 px-2.5 py-0 text-xs", "has-data-[icon=inline-start]:pl-2 has-data-[icon=inline-end]:pr-2"] }
481
+ },
482
+ {
483
+ theme: "brutal",
484
+ size: "md",
485
+ class: { root: ["h-8 px-3 py-0 text-sm", "has-data-[icon=inline-start]:pl-2.5 has-data-[icon=inline-end]:pr-2.5"] }
486
+ },
487
+ {
488
+ theme: "brutal",
489
+ size: "lg",
490
+ class: { root: ["h-10 px-4 py-0 text-sm", "has-data-[icon=inline-start]:pl-3.5 has-data-[icon=inline-end]:pr-3.5"] }
491
+ },
492
+ {
493
+ theme: "brutal",
494
+ size: "icon-xs",
495
+ class: { root: "size-6 p-0 text-[11px]" }
496
+ },
497
+ {
498
+ theme: "brutal",
499
+ size: "icon-sm",
500
+ class: { root: "size-7 p-0 text-xs" }
501
+ },
502
+ {
503
+ theme: "brutal",
504
+ size: "icon-md",
505
+ class: { root: "size-8 p-0 text-sm" }
506
+ },
507
+ {
508
+ theme: "brutal",
509
+ size: "icon-lg",
510
+ class: { root: "size-10 p-0 text-sm" }
511
+ },
512
+ {
513
+ theme: "elegant",
514
+ variant: "default",
515
+ class: { root: [
516
+ "bg-foreground-strong text-foreground-inverse",
517
+ "[--button-focus-outline:var(--foreground-strong)]",
518
+ "shadow-[inset_0_1px_0.5px_oklch(1_0_0_/_0.12),0_0_0_1px_var(--foreground-strong)]",
519
+ "before:bg-[linear-gradient(in_oklab_180deg,oklab(100%_0_0_/_8%)_0%,oklab(0%_0_0_/_0%)_100%)]",
520
+ "hover:bg-[oklch(0.31_0.006_285)]"
521
+ ] }
522
+ },
523
+ {
524
+ theme: "elegant",
525
+ variant: "primary",
526
+ class: { root: [
527
+ "bg-primary-400 text-primary-950",
528
+ "[--button-focus-outline:var(--primary-400)]",
529
+ "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)]",
530
+ "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%)]",
531
+ "hover:bg-[oklch(0.86_0.15_91.89)]"
532
+ ] }
533
+ },
534
+ {
535
+ theme: "elegant",
536
+ variant: "outline",
537
+ class: { root: [
538
+ "bg-layer-panel text-foreground-strong",
539
+ "[--button-focus-outline:var(--layer-panel)]",
540
+ "shadow-[inset_0_1px_0.5px_oklch(1_0_0_/_0.05),0_0_0_1px_var(--line-subtle)]",
541
+ "before:bg-[linear-gradient(in_oklab_180deg,oklab(0%_0_0_/_0%)_30%,oklab(0%_0_0_/_1%)_100%)]",
542
+ "hover:bg-layer-muted"
543
+ ] }
544
+ },
545
+ {
546
+ theme: "elegant",
547
+ variant: "ghost",
548
+ class: { root: [
549
+ "bg-transparent text-foreground-muted shadow-none",
550
+ "[--button-focus-outline:var(--line-muted)]",
551
+ "before:bg-transparent hover:bg-line-muted"
552
+ ] }
553
+ },
554
+ {
555
+ theme: "elegant",
556
+ variant: "danger-secondary",
557
+ class: { root: [
558
+ "bg-danger-lighter text-danger-base",
559
+ "[--button-focus-outline:var(--state-danger-lighter)]",
560
+ "shadow-[inset_0_1px_0.5px_oklch(1_0_0_/_0.18),0_0_0_1px_var(--state-danger-light)]",
561
+ "before:bg-[linear-gradient(in_oklab_180deg,oklab(100%_0_0_/_9%)_0%,oklab(0%_0_0_/_1%)_100%)]",
562
+ "hover:bg-danger-light"
563
+ ] }
564
+ },
565
+ {
566
+ theme: "elegant",
567
+ variant: "danger",
568
+ class: { root: [
569
+ "bg-danger-base text-foreground-inverse",
570
+ "[--button-focus-outline:var(--state-danger-base)]",
571
+ "shadow-[inset_0_1px_0.5px_oklch(1_0_0_/_0.12),0_0_0_1px_var(--state-danger-base)]",
572
+ "before:bg-[linear-gradient(in_oklab_180deg,oklab(100%_0_0_/_10%)_0%,oklab(0%_0_0_/_0%)_100%)]",
573
+ "hover:bg-[oklch(0.56_0.23_26.758)]"
574
+ ] }
575
+ },
576
+ {
577
+ theme: "brutal",
578
+ variant: "danger",
579
+ class: { root: [
580
+ "border-line-strong bg-brutal-red text-black",
581
+ "shadow-sm",
582
+ "hover:border-line-strong hover:bg-brutal-red",
583
+ "hover:-translate-y-px hover:shadow-md",
584
+ "active:not-aria-[haspopup]:translate-x-px active:not-aria-[haspopup]:translate-y-px",
585
+ "active:shadow-xs"
586
+ ] }
587
+ },
588
+ {
589
+ theme: "brutal",
590
+ variant: "danger-secondary",
591
+ class: { root: [
592
+ "border-line-strong bg-danger-lighter text-[color-mix(in_oklab,var(--state-danger-base)_72%,transparent)]",
593
+ "shadow-sm",
594
+ "hover:border-line-strong hover:bg-danger-lighter",
595
+ "hover:-translate-y-px hover:shadow-md",
596
+ "active:not-aria-[haspopup]:translate-x-px active:not-aria-[haspopup]:translate-y-px",
597
+ "active:shadow-xs"
598
+ ] }
599
+ },
600
+ {
601
+ theme: "elegant",
602
+ variant: "danger-outline",
603
+ class: { root: [
604
+ "bg-layer-panel text-danger-base",
605
+ "[--button-focus-outline:var(--layer-panel)]",
606
+ "shadow-[inset_0_1px_0.5px_oklch(1_0_0_/_0.05),0_0_0_1px_var(--state-danger-light)]",
607
+ "before:bg-[linear-gradient(in_oklab_180deg,oklab(0%_0_0_/_0%)_30%,oklab(0%_0_0_/_1%)_100%)]",
608
+ "hover:bg-danger-lighter"
609
+ ] }
610
+ },
611
+ {
612
+ theme: "elegant",
613
+ variant: "accent",
614
+ class: { root: [
615
+ "bg-accent-400 text-white",
616
+ "[--button-focus-outline:var(--accent-400)]",
617
+ "shadow-[inset_0_1px_0.5px_oklch(1_0_0_/_0.12),0_0_0_1px_var(--accent-400)]",
618
+ "before:bg-[linear-gradient(in_oklab_180deg,oklab(100%_0_0_/_8%)_0%,oklab(0%_0_0_/_0%)_100%)]",
619
+ "hover:bg-[oklch(0.72_0.15_0.71)]"
620
+ ] }
621
+ },
622
+ {
623
+ theme: "elegant",
624
+ variant: "warning",
625
+ class: { root: [
626
+ "bg-warning-base text-foreground-inverse",
627
+ "[--button-focus-outline:var(--state-warning-base)]",
628
+ "shadow-[inset_0_1px_0.5px_oklch(1_0_0_/_0.14),0_0_0_1px_var(--state-warning-base)]",
629
+ "before:bg-[linear-gradient(in_oklab_180deg,oklab(100%_0_0_/_10%)_0%,oklab(0%_0_0_/_0%)_100%)]",
630
+ "hover:bg-[oklch(0.65_0.19_44.441)]"
631
+ ] }
632
+ },
633
+ {
634
+ theme: "elegant",
635
+ variant: "link",
636
+ class: { root: [
637
+ "bg-transparent text-foreground-muted shadow-none",
638
+ "[--button-focus-outline:transparent]",
639
+ "before:bg-transparent hover:bg-transparent hover:text-foreground-muted"
640
+ ] }
641
+ },
642
+ {
643
+ theme: "elegant",
644
+ variant: "information",
645
+ class: { root: [
646
+ "bg-info-base text-foreground-inverse",
647
+ "[--button-focus-outline:var(--state-info-base)]",
648
+ "shadow-[inset_0_1px_0.5px_oklch(1_0_0_/_0.12),0_0_0_1px_var(--state-info-base)]",
649
+ "before:bg-[linear-gradient(in_oklab_180deg,oklab(100%_0_0_/_8%)_0%,oklab(0%_0_0_/_0%)_100%)]",
650
+ "hover:bg-[oklch(0.74_0.13_219.2)]"
651
+ ] }
652
+ },
653
+ {
654
+ theme: "elegant",
655
+ variant: "muted",
656
+ class: { root: [
657
+ "bg-layer-muted text-foreground-placeholder",
658
+ "[--button-focus-outline:var(--layer-muted)]",
659
+ "shadow-[inset_0_1px_0.5px_oklch(1_0_0_/_0.05),0_0_0_1px_var(--line-subtle)]",
660
+ "before:bg-[linear-gradient(in_oklab_180deg,oklab(100%_0_0_/_5%)_0%,oklab(0%_0_0_/_1%)_100%)]",
661
+ "hover:bg-line-subtle"
662
+ ] }
663
+ },
664
+ {
665
+ theme: "brutal",
666
+ variant: [
667
+ "primary",
668
+ "default",
669
+ "information",
670
+ "muted",
671
+ "accent",
672
+ "warning",
673
+ "outline"
674
+ ],
675
+ class: { root: [
676
+ "hover:-translate-y-px hover:shadow-md",
677
+ "active:not-aria-[haspopup]:translate-x-px active:not-aria-[haspopup]:translate-y-px",
678
+ "active:shadow-xs"
679
+ ] }
680
+ }
681
+ ]
682
+ });
683
+ function defaultNativeButton(render) {
684
+ if (!render || typeof render !== "object" || !("type" in render)) return;
685
+ const element = render;
686
+ if (typeof element.type === "string") return element.type === "button";
687
+ }
688
+ function Button({ variant, size, loading = false, loadingLabel = "Loading", disabled, className, children, render, nativeButton, ...props }) {
689
+ const { root, content, loadingIndicator } = buttonVariants({
690
+ theme: useThemeFamily(),
691
+ variant,
692
+ size
693
+ });
694
+ return /* @__PURE__ */ jsxs(Button$1, {
695
+ ...props,
696
+ render,
697
+ nativeButton: nativeButton ?? defaultNativeButton(render),
698
+ "data-slot": "button",
699
+ className: root({ className }),
700
+ "data-loading": loading ? "true" : void 0,
701
+ disabled: disabled || loading,
702
+ "aria-disabled": loading || void 0,
703
+ children: [loading ? /* @__PURE__ */ jsx("span", {
704
+ "data-slot": "button-loading-indicator",
705
+ className: loadingIndicator(),
706
+ children: /* @__PURE__ */ jsx(Spinner, { "aria-label": loadingLabel })
707
+ }) : null, /* @__PURE__ */ jsx("span", {
708
+ "data-slot": "button-content",
709
+ "data-loading": loading ? "true" : void 0,
710
+ className: content(),
711
+ children
712
+ })]
713
+ });
714
+ }
715
+ //#endregion
29
716
  //#region src/components/alert-dialog/alert-dialog.tsx
30
717
  const alertDialog = tv({
31
718
  slots: {
@@ -324,6 +1011,202 @@ function DialogDescription({ className, ...props }) {
324
1011
  });
325
1012
  }
326
1013
  //#endregion
1014
+ //#region src/components/bottom-sheet/bottom-sheet.tsx
1015
+ const bottomSheet = tv({
1016
+ slots: {
1017
+ portal: [],
1018
+ overlay: ["fixed inset-0 z-50", "![animation-duration:0.2s]"],
1019
+ positioner: ["contents"],
1020
+ content: [
1021
+ "fixed z-50 flex h-auto flex-col outline-none",
1022
+ "data-[vaul-drawer-direction=bottom]:inset-x-0 data-[vaul-drawer-direction=bottom]:bottom-0 md:data-[vaul-drawer-direction=bottom]:inset-x-3",
1023
+ "data-[vaul-drawer-direction=bottom]:mx-auto data-[vaul-drawer-direction=bottom]:mt-24 data-[vaul-drawer-direction=bottom]:min-h-64 data-[vaul-drawer-direction=bottom]:max-h-[82vh] data-[vaul-drawer-direction=bottom]:max-w-lg md:data-[vaul-drawer-direction=bottom]:max-w-md",
1024
+ "data-[vaul-drawer-direction=top]:inset-x-3 data-[vaul-drawer-direction=top]:top-3",
1025
+ "data-[vaul-drawer-direction=top]:mx-auto data-[vaul-drawer-direction=top]:mb-24 data-[vaul-drawer-direction=top]:max-h-[80vh] data-[vaul-drawer-direction=top]:max-w-md",
1026
+ "data-[vaul-drawer-direction=left]:inset-y-3 data-[vaul-drawer-direction=left]:left-3 data-[vaul-drawer-direction=left]:w-3/4 data-[vaul-drawer-direction=left]:max-w-sm",
1027
+ "data-[vaul-drawer-direction=right]:inset-y-3 data-[vaul-drawer-direction=right]:right-3 data-[vaul-drawer-direction=right]:w-3/4 data-[vaul-drawer-direction=right]:max-w-sm",
1028
+ "!duration-200 ![animation-duration:0.2s]"
1029
+ ],
1030
+ header: ["flex flex-col items-center px-6 pt-8 pb-2 text-center"],
1031
+ body: ["flex flex-1 flex-col items-center px-6 pt-4 pb-6 text-center"],
1032
+ footer: ["mt-auto px-6 py-5 md:pb-11"],
1033
+ actions: ["mx-auto w-full items-center justify-center gap-2.5", "[&_[data-slot=button]]:w-full"],
1034
+ title: ["max-w-sm text-pretty text-center text-2xl leading-8 text-foreground-strong"],
1035
+ description: ["max-w-sm text-pretty text-center text-sm leading-5 text-foreground/60"]
1036
+ },
1037
+ variants: { theme: {
1038
+ brutal: {
1039
+ overlay: ["bg-layer-backdrop"],
1040
+ title: ["font-bold"],
1041
+ content: [
1042
+ "border-2 border-black bg-white text-black shadow-[var(--shadow-lg)]",
1043
+ "data-[vaul-drawer-direction=bottom]:border-x-0 md:data-[vaul-drawer-direction=bottom]:border-x-2",
1044
+ "data-[vaul-drawer-direction=bottom]:border-b-0 md:data-[vaul-drawer-direction=bottom]:border-b-2"
1045
+ ]
1046
+ },
1047
+ elegant: {
1048
+ overlay: ["bg-layer-backdrop backdrop-blur-[2px]"],
1049
+ content: [
1050
+ "overflow-clip rounded-lg bg-layer-popover text-foreground shadow-xl md:rounded-xl",
1051
+ "data-[vaul-drawer-direction=bottom]:rounded-b-none",
1052
+ "md:data-[vaul-drawer-direction=bottom]:max-w-md",
1053
+ "md:data-[vaul-drawer-direction=top]:max-w-md",
1054
+ "md:data-[vaul-drawer-direction=left]:max-w-md",
1055
+ "md:data-[vaul-drawer-direction=right]:max-w-md"
1056
+ ],
1057
+ header: ["bg-white px-8 pt-9 pb-2"],
1058
+ body: ["bg-white px-8 pt-4 pb-7"],
1059
+ footer: ["mt-0 px-8 py-5 md:pb-11"],
1060
+ actions: ["flex w-fit max-w-none flex-row justify-center", "[&_[data-slot=button]]:w-auto"],
1061
+ title: ["font-sans text-2xl leading-8 font-semibold text-[oklch(0.22_0_0)]"],
1062
+ description: ["font-sans text-sm leading-5 text-[oklch(0.48_0_0)]"]
1063
+ }
1064
+ } }
1065
+ });
1066
+ function BottomSheet({ direction = "bottom", ...props }) {
1067
+ return /* @__PURE__ */ jsx(Drawer.Root, {
1068
+ direction,
1069
+ ...props
1070
+ });
1071
+ }
1072
+ function BottomSheetTrigger({ children, render, ...props }) {
1073
+ if (render) return /* @__PURE__ */ jsx(Drawer.Trigger, {
1074
+ "data-slot": "bottom-sheet-trigger",
1075
+ asChild: true,
1076
+ ...props,
1077
+ children: cloneElement(render, void 0, children ?? render.props.children)
1078
+ });
1079
+ return /* @__PURE__ */ jsx(Drawer.Trigger, {
1080
+ "data-slot": "bottom-sheet-trigger",
1081
+ ...props,
1082
+ children
1083
+ });
1084
+ }
1085
+ function BottomSheetPortal({ className, children, ...props }) {
1086
+ const portalChildren = Children.map(children, (child) => {
1087
+ if (isValidElement(child) && child.type === BottomSheetPositioner) return Children.map(child.props.children, (positionerChild) => withPortalClassName(positionerChild, className));
1088
+ return withPortalClassName(child, className);
1089
+ });
1090
+ return /* @__PURE__ */ jsx(Drawer.Portal, {
1091
+ ...props,
1092
+ children: portalChildren
1093
+ });
1094
+ }
1095
+ function withPortalClassName(child, className) {
1096
+ if (!className || !isValidElement(child)) return child;
1097
+ return cloneElement(child, { className: cn(child.props.className, className) });
1098
+ }
1099
+ function BottomSheetPositioner({ className, ...props }) {
1100
+ const { positioner } = bottomSheet({ theme: useThemeFamily() });
1101
+ return /* @__PURE__ */ jsx("div", {
1102
+ "data-slot": "bottom-sheet-positioner",
1103
+ className: positioner({ className }),
1104
+ ...props
1105
+ });
1106
+ }
1107
+ function BottomSheetOverlay({ className, ...props }) {
1108
+ const theme = useThemeFamily();
1109
+ const { overlay } = bottomSheet({ theme });
1110
+ return /* @__PURE__ */ jsx(Drawer.Overlay, {
1111
+ "data-slot": "bottom-sheet-overlay",
1112
+ "data-theme": theme,
1113
+ className: overlay({ className }),
1114
+ ...props
1115
+ });
1116
+ }
1117
+ function BottomSheetContent({ className, ...props }) {
1118
+ const { content } = bottomSheet({ theme: useThemeFamily() });
1119
+ return /* @__PURE__ */ jsx(Drawer.Content, {
1120
+ "data-slot": "bottom-sheet-content",
1121
+ className: content({ className }),
1122
+ ...props
1123
+ });
1124
+ }
1125
+ function BottomSheetClose({ className, variant, size, children, render, ...props }) {
1126
+ const isBrutal = useThemeFamily() === "brutal";
1127
+ if (render) return /* @__PURE__ */ jsx(Drawer.Close, {
1128
+ "data-slot": "bottom-sheet-close",
1129
+ asChild: true,
1130
+ ...props,
1131
+ children: cloneElement(render, void 0, children ?? render.props.children)
1132
+ });
1133
+ return /* @__PURE__ */ jsx(Drawer.Close, {
1134
+ "data-slot": "bottom-sheet-close",
1135
+ asChild: true,
1136
+ ...props,
1137
+ children: /* @__PURE__ */ jsx(Button, {
1138
+ variant: variant ?? (isBrutal ? "outline" : "ghost"),
1139
+ size: size ?? (isBrutal ? "icon-sm" : "icon-sm"),
1140
+ "aria-label": "Close",
1141
+ className: cn(isBrutal ? "absolute top-3 right-3" : "absolute top-4 right-6", isBrutal ? "bg-white" : "p-0 text-foreground-placeholder hover:bg-transparent hover:text-foreground", className),
1142
+ children: children ?? /* @__PURE__ */ jsx(X, { className: "size-4" })
1143
+ })
1144
+ });
1145
+ }
1146
+ function BottomSheetHeader({ className, render, ...props }) {
1147
+ const { header } = bottomSheet({ theme: useThemeFamily() });
1148
+ return useRender({
1149
+ defaultTagName: "div",
1150
+ render,
1151
+ props: mergeProps({ className: header({ className }) }, props),
1152
+ state: { slot: "bottom-sheet-header" }
1153
+ });
1154
+ }
1155
+ function BottomSheetFooter({ className, render, ...props }) {
1156
+ const { footer } = bottomSheet({ theme: useThemeFamily() });
1157
+ return useRender({
1158
+ defaultTagName: "div",
1159
+ render,
1160
+ props: mergeProps({ className: footer({ className }) }, props),
1161
+ state: { slot: "bottom-sheet-footer" }
1162
+ });
1163
+ }
1164
+ function BottomSheetBody({ className, render, ...props }) {
1165
+ const { body } = bottomSheet({ theme: useThemeFamily() });
1166
+ return useRender({
1167
+ defaultTagName: "div",
1168
+ render,
1169
+ props: mergeProps({ className: body({ className }) }, props),
1170
+ state: { slot: "bottom-sheet-body" }
1171
+ });
1172
+ }
1173
+ function BottomSheetActions({ className, render, children, ...props }) {
1174
+ const theme = useThemeFamily();
1175
+ const { actions } = bottomSheet({ theme });
1176
+ const count = Math.min(3, countActionChildren(children));
1177
+ return useRender({
1178
+ defaultTagName: "div",
1179
+ render,
1180
+ props: mergeProps({
1181
+ className: actions({ className: cn(theme === "elegant" ? "flex-row" : count <= 1 ? "flex max-w-64 flex-col" : count === 2 ? "flex max-w-64 flex-col-reverse" : "grid max-w-[32rem] grid-cols-3", className) }),
1182
+ children
1183
+ }, props),
1184
+ state: { slot: "bottom-sheet-actions" }
1185
+ });
1186
+ }
1187
+ function countActionChildren(children) {
1188
+ return Children.toArray(children).reduce((count, child) => {
1189
+ if (isValidElement(child) && child.type === Fragment) return count + countActionChildren(child.props.children);
1190
+ return count + 1;
1191
+ }, 0);
1192
+ }
1193
+ function BottomSheetTitle({ className, ...props }) {
1194
+ const { title } = bottomSheet({ theme: useThemeFamily() });
1195
+ return /* @__PURE__ */ jsx(Drawer.Title, {
1196
+ "data-slot": "bottom-sheet-title",
1197
+ className: title({ className }),
1198
+ ...props
1199
+ });
1200
+ }
1201
+ function BottomSheetDescription({ className, ...props }) {
1202
+ const { description } = bottomSheet({ theme: useThemeFamily() });
1203
+ return /* @__PURE__ */ jsx(Drawer.Description, {
1204
+ "data-slot": "bottom-sheet-description",
1205
+ className: description({ className }),
1206
+ ...props
1207
+ });
1208
+ }
1209
+ //#endregion
327
1210
  //#region src/components/copyable-code/copyable-code.tsx
328
1211
  const copyableCode = tv({
329
1212
  slots: {
@@ -1565,6 +2448,11 @@ const dropdownMenu = tv({
1565
2448
  indicator: []
1566
2449
  },
1567
2450
  elegant: {
2451
+ trigger: [
2452
+ "hover:bg-[color-mix(in_oklch,var(--line-subtle)_22%,var(--layer-panel))]",
2453
+ "data-[popup-open]:[--button-focus-outline:transparent] focus-visible:[--button-focus-outline:transparent]",
2454
+ "data-[popup-open]:shadow-[0_0_0_0.5px_oklch(0.21_0.006_285_/_0.14),0_0_0_3px_color-mix(in_oklch,var(--primary-400)_35%,transparent)] focus-visible:shadow-[0_0_0_0.5px_oklch(0.21_0.006_285_/_0.14),0_0_0_3px_color-mix(in_oklch,var(--primary-400)_35%,transparent)]"
2455
+ ],
1568
2456
  content: [
1569
2457
  "gap-0.5 rounded-md bg-layer-popover p-1",
1570
2458
  "shadow-lg outline-none",
@@ -1631,10 +2519,14 @@ function DropdownMenuSubmenu(props) {
1631
2519
  ...props
1632
2520
  });
1633
2521
  }
1634
- function DropdownMenuTrigger({ className, ...props }) {
2522
+ function DropdownMenuTrigger({ className, render = /* @__PURE__ */ jsx(Button, {
2523
+ variant: "outline",
2524
+ size: "md"
2525
+ }), ...props }) {
1635
2526
  const { trigger } = dropdownMenu({ theme: useThemeFamily() });
1636
2527
  return /* @__PURE__ */ jsx(Menu.Trigger, {
1637
2528
  "data-slot": "dropdown-menu-trigger",
2529
+ render,
1638
2530
  className: trigger({ className }),
1639
2531
  ...props
1640
2532
  });
@@ -1653,8 +2545,10 @@ function DropdownMenuPopup({ className, ...props }) {
1653
2545
  ...props
1654
2546
  });
1655
2547
  }
1656
- function DropdownMenuContent({ align = "start", alignOffset = 0, anchor, arrowPadding, collisionAvoidance, collisionBoundary, collisionPadding, disableAnchorTracking = false, positionMethod = "fixed", side = "bottom", sideOffset = 4, sticky, portalProps, className, ...props }) {
1657
- const { positioner, content } = dropdownMenu({ theme: useThemeFamily() });
2548
+ function DropdownMenuContent({ align = "start", alignOffset = 0, anchor, arrowPadding, collisionAvoidance, collisionBoundary, collisionPadding, disableAnchorTracking = false, positionMethod = "fixed", side = "bottom", sideOffset, sticky, portalProps, className, ...props }) {
2549
+ const theme = useThemeFamily();
2550
+ const resolvedSideOffset = sideOffset ?? (theme === "elegant" ? 6 : 4);
2551
+ const { positioner, content } = dropdownMenu({ theme });
1658
2552
  return /* @__PURE__ */ jsx(Menu.Portal, {
1659
2553
  ...portalProps,
1660
2554
  children: /* @__PURE__ */ jsx(Menu.Positioner, {
@@ -1668,7 +2562,7 @@ function DropdownMenuContent({ align = "start", alignOffset = 0, anchor, arrowPa
1668
2562
  disableAnchorTracking,
1669
2563
  positionMethod,
1670
2564
  side,
1671
- sideOffset,
2565
+ sideOffset: resolvedSideOffset,
1672
2566
  sticky,
1673
2567
  className: positioner(),
1674
2568
  children: /* @__PURE__ */ jsx(Menu.Popup, {
@@ -1789,6 +2683,241 @@ function DropdownMenuCheckboxItemIndicator({ className, ...props }) {
1789
2683
  });
1790
2684
  }
1791
2685
  //#endregion
2686
+ //#region src/components/lightbox/lightbox.tsx
2687
+ const lightbox = tv({
2688
+ slots: {
2689
+ backdrop: ["fixed inset-0 z-[70] bg-layer-backdrop data-[closed]:hidden"],
2690
+ content: ["pointer-events-none fixed inset-0 z-[71] data-[closed]:hidden"],
2691
+ header: ["safe-top safe-left safe-right pointer-events-auto shrink-0"],
2692
+ title: ["min-w-0 flex-1 truncate font-heading text-sm font-bold"],
2693
+ actions: ["flex shrink-0 items-center gap-1.5"],
2694
+ stage: ["pointer-events-none relative flex min-h-0 flex-1 items-center justify-center overflow-hidden"],
2695
+ media: ["pointer-events-auto max-h-[80vh] max-w-[86vw] border-2"],
2696
+ navigationButton: [
2697
+ "pointer-events-auto absolute z-10 inline-flex items-center justify-center",
2698
+ "border-2 border-line-strong bg-layer-panel text-foreground-strong shadow-sm",
2699
+ "transition-[background-color,color,opacity,box-shadow,transform] duration-150",
2700
+ "outline outline-[1px] outline-offset-2 outline-transparent",
2701
+ "focus-visible:outline-foreground-strong",
2702
+ "data-[disabled=true]:cursor-default",
2703
+ "[&_svg]:pointer-events-none [&_svg]:size-6 [&_svg]:shrink-0"
2704
+ ],
2705
+ infoBar: [
2706
+ "pointer-events-auto flex min-w-0 items-center",
2707
+ "bg-layer-panel text-foreground-strong",
2708
+ "shadow-[0_12px_32px_-18px_oklch(0_0_0_/_0.55)]"
2709
+ ],
2710
+ infoTitle: ["min-w-0 flex-1 truncate font-heading text-sm font-bold"],
2711
+ infoActions: ["flex shrink-0 items-center gap-1.5"],
2712
+ close: []
2713
+ },
2714
+ variants: { theme: {
2715
+ brutal: {
2716
+ header: ["bg-transparent shadow-none"],
2717
+ title: ["text-foreground-strong"],
2718
+ media: ["border-line-strong bg-layer-panel shadow-xl"],
2719
+ navigationButton: [
2720
+ "size-8 rounded-none",
2721
+ "hover:bg-layer-panel data-[disabled=true]:text-black/35",
2722
+ "[&_svg]:size-6"
2723
+ ],
2724
+ infoBar: [
2725
+ "w-[clamp(9rem,20vw,14rem)] max-w-[calc(100vw-3rem)] min-w-[9rem]",
2726
+ "gap-2 rounded-none border-2 border-black py-0.5 pr-0.5 pl-2.5 shadow-[var(--shadow)]",
2727
+ "[&_[data-slot=button]_svg]:stroke-2"
2728
+ ],
2729
+ infoTitle: ["text-xs text-black"]
2730
+ },
2731
+ elegant: {
2732
+ backdrop: ["bg-[oklch(0_0_0_/_0.72)] backdrop-blur-[2px]"],
2733
+ header: ["bg-transparent shadow-none"],
2734
+ title: ["font-sans font-medium text-foreground-strong"],
2735
+ actions: ["gap-2"],
2736
+ media: ["border border-line-subtle bg-layer-panel shadow-none"],
2737
+ navigationButton: [
2738
+ "size-8 rounded-full border-0",
2739
+ "bg-white/75 backdrop-blur-md",
2740
+ "text-foreground-muted",
2741
+ "shadow-none",
2742
+ "hover:bg-white/85 hover:text-foreground-strong",
2743
+ "active:scale-[0.97]",
2744
+ "data-[disabled=true]:bg-white/35 data-[disabled=true]:text-black/30 data-[disabled=true]:shadow-none",
2745
+ "data-[disabled=true]:hover:bg-white/35 data-[disabled=true]:active:scale-100",
2746
+ "[&_svg]:size-5"
2747
+ ],
2748
+ infoBar: [
2749
+ "w-[clamp(9rem,20vw,14rem)] max-w-[calc(100vw-3rem)] min-w-[9rem]",
2750
+ "gap-2 rounded py-0.5 pr-0.5 pl-2.5",
2751
+ "bg-[rgba(245,245,245,0.8)] text-neutral-900 shadow-none backdrop-blur-[10px]",
2752
+ "[&_[data-slot=button]]:text-neutral-600 [&_[data-slot=button]]:hover:bg-neutral-900/10 [&_[data-slot=button]]:hover:text-neutral-800"
2753
+ ],
2754
+ infoTitle: ["font-sans text-xs font-medium text-neutral-800"],
2755
+ infoActions: ["gap-1"]
2756
+ }
2757
+ } }
2758
+ });
2759
+ function Lightbox({ closeOnModW = true, defaultOpen = false, modal = true, onOpenChange, open, children, ...props }) {
2760
+ const dialogRef = useRef(null);
2761
+ const [uncontrolledOpen, setUncontrolledOpen] = useState(defaultOpen);
2762
+ const effectiveOpen = open ?? uncontrolledOpen;
2763
+ const handleOpenChange = useCallback((nextOpen, eventDetails) => {
2764
+ if (open === void 0) setUncontrolledOpen(nextOpen);
2765
+ onOpenChange?.(nextOpen, eventDetails);
2766
+ }, [onOpenChange, open]);
2767
+ const modWClose = closeOnModW && effectiveOpen ? /* @__PURE__ */ jsx(LightboxModWClose, { dialogRef }) : null;
2768
+ return /* @__PURE__ */ jsxs(Dialog$1.Root, {
2769
+ actionsRef: dialogRef,
2770
+ defaultOpen,
2771
+ modal,
2772
+ onOpenChange: handleOpenChange,
2773
+ open,
2774
+ ...props,
2775
+ children: [modWClose, children]
2776
+ });
2777
+ }
2778
+ function LightboxModWClose({ dialogRef }) {
2779
+ useHotkey("Mod+W", (event) => {
2780
+ event.preventDefault();
2781
+ event.stopPropagation();
2782
+ dialogRef.current?.close();
2783
+ }, { meta: {
2784
+ name: "Close lightbox",
2785
+ description: "Close the active lightbox before the browser closes the tab."
2786
+ } });
2787
+ return null;
2788
+ }
2789
+ function LightboxTrigger(props) {
2790
+ return /* @__PURE__ */ jsx(Dialog$1.Trigger, {
2791
+ "data-slot": "lightbox-trigger",
2792
+ ...props
2793
+ });
2794
+ }
2795
+ function LightboxPortal(props) {
2796
+ return /* @__PURE__ */ jsx(Dialog$1.Portal, {
2797
+ "data-slot": "lightbox-portal",
2798
+ ...props
2799
+ });
2800
+ }
2801
+ function LightboxContent({ className, initialFocus = false, finalFocus = false, ...props }) {
2802
+ const theme = useThemeFamily();
2803
+ const { backdrop, content } = lightbox({ theme });
2804
+ return /* @__PURE__ */ jsxs(LightboxPortal, { children: [/* @__PURE__ */ jsx(Dialog$1.Backdrop, {
2805
+ "data-slot": "lightbox-backdrop",
2806
+ "data-theme": theme,
2807
+ className: backdrop()
2808
+ }), /* @__PURE__ */ jsx(Dialog$1.Popup, {
2809
+ "data-slot": "lightbox-content",
2810
+ "data-theme": theme,
2811
+ initialFocus,
2812
+ finalFocus,
2813
+ className: content({ className }),
2814
+ ...props
2815
+ })] });
2816
+ }
2817
+ function LightboxHeader({ render, className, ...props }) {
2818
+ const { header } = lightbox({ theme: useThemeFamily() });
2819
+ return useRender({
2820
+ defaultTagName: "div",
2821
+ render,
2822
+ props: mergeProps({ className: header({ className }) }, props),
2823
+ state: { slot: "lightbox-header" }
2824
+ });
2825
+ }
2826
+ function LightboxTitle({ render, className, ...props }) {
2827
+ const { title } = lightbox({ theme: useThemeFamily() });
2828
+ return useRender({
2829
+ defaultTagName: "div",
2830
+ render,
2831
+ props: mergeProps({ className: title({ className }) }, props),
2832
+ state: { slot: "lightbox-title" }
2833
+ });
2834
+ }
2835
+ function LightboxActions({ render, className, ...props }) {
2836
+ const { actions } = lightbox({ theme: useThemeFamily() });
2837
+ return useRender({
2838
+ defaultTagName: "div",
2839
+ render,
2840
+ props: mergeProps({ className: actions({ className }) }, props),
2841
+ state: { slot: "lightbox-actions" }
2842
+ });
2843
+ }
2844
+ function LightboxStage({ render, className, ...props }) {
2845
+ const { stage } = lightbox({ theme: useThemeFamily() });
2846
+ return useRender({
2847
+ defaultTagName: "div",
2848
+ render,
2849
+ props: mergeProps({ className: stage({ className }) }, props),
2850
+ state: { slot: "lightbox-stage" }
2851
+ });
2852
+ }
2853
+ function LightboxMedia({ render, className, ...props }) {
2854
+ const { media } = lightbox({ theme: useThemeFamily() });
2855
+ return useRender({
2856
+ defaultTagName: "div",
2857
+ render,
2858
+ props: mergeProps({ className: media({ className }) }, props),
2859
+ state: { slot: "lightbox-media" }
2860
+ });
2861
+ }
2862
+ function LightboxNavigationButton({ className, direction, disabled, onClick, type = "button", ...props }) {
2863
+ const { navigationButton } = lightbox({ theme: useThemeFamily() });
2864
+ const handleClick = useCallback((event) => {
2865
+ event.stopPropagation();
2866
+ if (disabled) {
2867
+ event.preventDefault();
2868
+ return;
2869
+ }
2870
+ onClick?.(event);
2871
+ }, [disabled, onClick]);
2872
+ return /* @__PURE__ */ jsx(Button, {
2873
+ "aria-disabled": disabled,
2874
+ className: navigationButton({ className: cn(direction === "previous" ? "left-8" : "right-8", className) }),
2875
+ "data-disabled": disabled ? "true" : void 0,
2876
+ "data-slot": "lightbox-navigation-button",
2877
+ "data-direction": direction,
2878
+ onClick: handleClick,
2879
+ size: "icon-lg",
2880
+ type,
2881
+ variant: "outline",
2882
+ ...props
2883
+ });
2884
+ }
2885
+ function LightboxInfoBar({ render, className, ...props }) {
2886
+ const { infoBar } = lightbox({ theme: useThemeFamily() });
2887
+ return useRender({
2888
+ defaultTagName: "div",
2889
+ render,
2890
+ props: mergeProps({ className: infoBar({ className }) }, props),
2891
+ state: { slot: "lightbox-info-bar" }
2892
+ });
2893
+ }
2894
+ function LightboxInfoTitle({ render, className, ...props }) {
2895
+ const { infoTitle } = lightbox({ theme: useThemeFamily() });
2896
+ return useRender({
2897
+ defaultTagName: "div",
2898
+ render,
2899
+ props: mergeProps({ className: infoTitle({ className }) }, props),
2900
+ state: { slot: "lightbox-info-title" }
2901
+ });
2902
+ }
2903
+ function LightboxInfoActions({ render, className, ...props }) {
2904
+ const { infoActions } = lightbox({ theme: useThemeFamily() });
2905
+ return useRender({
2906
+ defaultTagName: "div",
2907
+ render,
2908
+ props: mergeProps({ className: infoActions({ className }) }, props),
2909
+ state: { slot: "lightbox-info-actions" }
2910
+ });
2911
+ }
2912
+ function LightboxClose({ className, ...props }) {
2913
+ const { close } = lightbox({ theme: useThemeFamily() });
2914
+ return /* @__PURE__ */ jsx(Dialog$1.Close, {
2915
+ "data-slot": "lightbox-close",
2916
+ className: close({ className }),
2917
+ ...props
2918
+ });
2919
+ }
2920
+ //#endregion
1792
2921
  //#region src/components/tooltip/tooltip.tsx
1793
2922
  const tooltip = tv({
1794
2923
  slots: {
@@ -1831,7 +2960,7 @@ const tooltip = tv({
1831
2960
  },
1832
2961
  elegant: {
1833
2962
  content: [
1834
- "rounded-xl bg-[oklch(0.263_0.009_294.9)] text-[oklch(0.965_0.002_286)]",
2963
+ "rounded-md bg-[oklch(0.263_0.009_294.9)] text-[oklch(0.965_0.002_286)]",
1835
2964
  "font-sans text-[13px] font-medium tracking-[-0.005em]",
1836
2965
  "shadow-[0_18px_42px_-18px_oklch(0_0_0_/_0.54)]",
1837
2966
  "after:pointer-events-none after:absolute after:inset-0 after:rounded-[inherit] after:ring-1 after:ring-white/35 after:mix-blend-overlay after:content-['']",
@@ -6033,4 +7162,4 @@ function ThemeProvider({ theme, defaultTheme = "brutal", onThemeChange, mode, de
6033
7162
  });
6034
7163
  }
6035
7164
  //#endregion
6036
- 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, PreviewCard, PreviewCardArrow, PreviewCardContent, PreviewCardDescription, PreviewCardHeader, PreviewCardPopup, PreviewCardPortal, PreviewCardSeparator, PreviewCardTitle, PreviewCardTrigger, Progress, ProgressHeader, ProgressIndicator, ProgressLabel, ProgressTrack, ProgressValue, 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, Skeleton, SortableTabsList, SortableTabsTab, Spinner, Status, Switch, SwitchThumb, Tabs, TabsBackground, TabsIndicator, TabsLabel, TabsList, TabsPanel, TabsTab, Text, TextHeading, TextMono, TextSans, Textarea, TextareaCounter, TextareaGroup, ThemeProvider, ToastAction, ToastActions, ToastArrow, ToastBody, ToastClose, ToastContent, ToastDescription, ToastIcon, ToastPortal, ToastPositioner, ToastProvider, ToastRoot, ToastTitle, ToastViewport, Tooltip, TooltipContent, TooltipPortal, TooltipProvider, TooltipTrigger, buttonVariants, cn, createToastManager, toast, useOrderedTabs, useTheme, useThemeFamily, useToastManager };
7165
+ 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, BottomSheet, BottomSheetActions, BottomSheetBody, BottomSheetClose, BottomSheetContent, BottomSheetDescription, BottomSheetFooter, BottomSheetHeader, BottomSheetOverlay, BottomSheetPortal, BottomSheetPositioner, BottomSheetTitle, BottomSheetTrigger, 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, Lightbox, LightboxActions, LightboxClose, LightboxContent, LightboxHeader, LightboxInfoActions, LightboxInfoBar, LightboxInfoTitle, LightboxMedia, LightboxNavigationButton, LightboxPortal, LightboxStage, LightboxTitle, LightboxTrigger, 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, PreviewCard, PreviewCardArrow, PreviewCardContent, PreviewCardDescription, PreviewCardHeader, PreviewCardPopup, PreviewCardPortal, PreviewCardSeparator, PreviewCardTitle, PreviewCardTrigger, Progress, ProgressHeader, ProgressIndicator, ProgressLabel, ProgressTrack, ProgressValue, 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, Skeleton, SortableTabsList, SortableTabsTab, Spinner, Status, Switch, SwitchThumb, Tabs, TabsBackground, TabsIndicator, TabsLabel, TabsList, TabsPanel, TabsTab, Text, TextHeading, TextMono, TextSans, Textarea, TextareaCounter, TextareaGroup, ThemeProvider, ToastAction, ToastActions, ToastArrow, ToastBody, ToastClose, ToastContent, ToastDescription, ToastIcon, ToastPortal, ToastPositioner, ToastProvider, ToastRoot, ToastTitle, ToastViewport, Tooltip, TooltipContent, TooltipPortal, TooltipProvider, TooltipTrigger, buttonVariants, cn, createToastManager, toast, useOrderedTabs, useTheme, useThemeFamily, useToastManager };