@json-render/shadcn 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs ADDED
@@ -0,0 +1,2520 @@
1
+ import {
2
+ shadcnComponentDefinitions
3
+ } from "./chunk-VZQBPEYT.mjs";
4
+
5
+ // src/components.tsx
6
+ import { useState as useState2 } from "react";
7
+ import {
8
+ useBoundProp,
9
+ useStateBinding,
10
+ useFieldValidation
11
+ } from "@json-render/react";
12
+
13
+ // src/ui/button.tsx
14
+ import { cva } from "class-variance-authority";
15
+ import { Slot } from "radix-ui";
16
+
17
+ // src/lib/utils.ts
18
+ import { clsx } from "clsx";
19
+ import { twMerge } from "tailwind-merge";
20
+ function cn(...inputs) {
21
+ return twMerge(clsx(inputs));
22
+ }
23
+
24
+ // src/ui/button.tsx
25
+ import { jsx } from "react/jsx-runtime";
26
+ var buttonVariants = cva(
27
+ "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
28
+ {
29
+ variants: {
30
+ variant: {
31
+ default: "bg-primary text-primary-foreground hover:bg-primary/90",
32
+ destructive: "bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
33
+ outline: "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50",
34
+ secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
35
+ ghost: "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
36
+ link: "text-primary underline-offset-4 hover:underline"
37
+ },
38
+ size: {
39
+ default: "h-9 px-4 py-2 has-[>svg]:px-3",
40
+ xs: "h-6 gap-1 rounded-md px-2 text-xs has-[>svg]:px-1.5 [&_svg:not([class*='size-'])]:size-3",
41
+ sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",
42
+ lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
43
+ icon: "size-9",
44
+ "icon-xs": "size-6 rounded-md [&_svg:not([class*='size-'])]:size-3",
45
+ "icon-sm": "size-8",
46
+ "icon-lg": "size-10"
47
+ }
48
+ },
49
+ defaultVariants: {
50
+ variant: "default",
51
+ size: "default"
52
+ }
53
+ }
54
+ );
55
+ function Button({
56
+ className,
57
+ variant = "default",
58
+ size = "default",
59
+ asChild = false,
60
+ ...props
61
+ }) {
62
+ const Comp = asChild ? Slot.Root : "button";
63
+ return /* @__PURE__ */ jsx(
64
+ Comp,
65
+ {
66
+ "data-slot": "button",
67
+ "data-variant": variant,
68
+ "data-size": size,
69
+ className: cn(buttonVariants({ variant, size, className })),
70
+ ...props
71
+ }
72
+ );
73
+ }
74
+
75
+ // src/ui/card.tsx
76
+ import { jsx as jsx2 } from "react/jsx-runtime";
77
+ function Card({ className, ...props }) {
78
+ return /* @__PURE__ */ jsx2(
79
+ "div",
80
+ {
81
+ "data-slot": "card",
82
+ className: cn(
83
+ "bg-card text-card-foreground flex flex-col gap-6 rounded-xl border py-6 shadow-sm",
84
+ className
85
+ ),
86
+ ...props
87
+ }
88
+ );
89
+ }
90
+ function CardHeader({ className, ...props }) {
91
+ return /* @__PURE__ */ jsx2(
92
+ "div",
93
+ {
94
+ "data-slot": "card-header",
95
+ className: cn(
96
+ "@container/card-header grid auto-rows-min grid-rows-[auto_auto] items-start gap-2 px-6 has-data-[slot=card-action]:grid-cols-[1fr_auto] [.border-b]:pb-6",
97
+ className
98
+ ),
99
+ ...props
100
+ }
101
+ );
102
+ }
103
+ function CardTitle({ className, ...props }) {
104
+ return /* @__PURE__ */ jsx2(
105
+ "div",
106
+ {
107
+ "data-slot": "card-title",
108
+ className: cn("leading-none font-semibold", className),
109
+ ...props
110
+ }
111
+ );
112
+ }
113
+ function CardDescription({ className, ...props }) {
114
+ return /* @__PURE__ */ jsx2(
115
+ "div",
116
+ {
117
+ "data-slot": "card-description",
118
+ className: cn("text-muted-foreground text-sm", className),
119
+ ...props
120
+ }
121
+ );
122
+ }
123
+ function CardContent({ className, ...props }) {
124
+ return /* @__PURE__ */ jsx2(
125
+ "div",
126
+ {
127
+ "data-slot": "card-content",
128
+ className: cn("px-6", className),
129
+ ...props
130
+ }
131
+ );
132
+ }
133
+
134
+ // src/ui/input.tsx
135
+ import { jsx as jsx3 } from "react/jsx-runtime";
136
+ function Input({ className, type, ...props }) {
137
+ return /* @__PURE__ */ jsx3(
138
+ "input",
139
+ {
140
+ type,
141
+ "data-slot": "input",
142
+ className: cn(
143
+ "file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
144
+ "focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
145
+ "aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
146
+ className
147
+ ),
148
+ ...props
149
+ }
150
+ );
151
+ }
152
+
153
+ // src/ui/label.tsx
154
+ import { Label as LabelPrimitive } from "radix-ui";
155
+ import { jsx as jsx4 } from "react/jsx-runtime";
156
+ function Label({
157
+ className,
158
+ ...props
159
+ }) {
160
+ return /* @__PURE__ */ jsx4(
161
+ LabelPrimitive.Root,
162
+ {
163
+ "data-slot": "label",
164
+ className: cn(
165
+ "flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50",
166
+ className
167
+ ),
168
+ ...props
169
+ }
170
+ );
171
+ }
172
+
173
+ // src/ui/textarea.tsx
174
+ import { jsx as jsx5 } from "react/jsx-runtime";
175
+ function Textarea({ className, ...props }) {
176
+ return /* @__PURE__ */ jsx5(
177
+ "textarea",
178
+ {
179
+ "data-slot": "textarea",
180
+ className: cn(
181
+ "border-input placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 flex field-sizing-content min-h-16 w-full rounded-md border bg-transparent px-3 py-2 text-base shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
182
+ className
183
+ ),
184
+ ...props
185
+ }
186
+ );
187
+ }
188
+
189
+ // src/ui/checkbox.tsx
190
+ import { CheckIcon } from "lucide-react";
191
+ import { Checkbox as CheckboxPrimitive } from "radix-ui";
192
+ import { jsx as jsx6 } from "react/jsx-runtime";
193
+ function Checkbox({
194
+ className,
195
+ ...props
196
+ }) {
197
+ return /* @__PURE__ */ jsx6(
198
+ CheckboxPrimitive.Root,
199
+ {
200
+ "data-slot": "checkbox",
201
+ className: cn(
202
+ "peer border-input dark:bg-input/30 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground dark:data-[state=checked]:bg-primary data-[state=checked]:border-primary focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive size-4 shrink-0 rounded-[4px] border shadow-xs transition-shadow outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50",
203
+ className
204
+ ),
205
+ ...props,
206
+ children: /* @__PURE__ */ jsx6(
207
+ CheckboxPrimitive.Indicator,
208
+ {
209
+ "data-slot": "checkbox-indicator",
210
+ className: "grid place-content-center text-current transition-none",
211
+ children: /* @__PURE__ */ jsx6(CheckIcon, { className: "size-3.5" })
212
+ }
213
+ )
214
+ }
215
+ );
216
+ }
217
+
218
+ // src/ui/switch.tsx
219
+ import { Switch as SwitchPrimitive } from "radix-ui";
220
+ import { jsx as jsx7 } from "react/jsx-runtime";
221
+ function Switch({
222
+ className,
223
+ size = "default",
224
+ ...props
225
+ }) {
226
+ return /* @__PURE__ */ jsx7(
227
+ SwitchPrimitive.Root,
228
+ {
229
+ "data-slot": "switch",
230
+ "data-size": size,
231
+ className: cn(
232
+ "peer data-[state=checked]:bg-primary data-[state=unchecked]:bg-input focus-visible:border-ring focus-visible:ring-ring/50 dark:data-[state=unchecked]:bg-input/80 group/switch inline-flex shrink-0 items-center rounded-full border border-transparent shadow-xs transition-all outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 data-[size=default]:h-[1.15rem] data-[size=default]:w-8 data-[size=sm]:h-3.5 data-[size=sm]:w-6",
233
+ className
234
+ ),
235
+ ...props,
236
+ children: /* @__PURE__ */ jsx7(
237
+ SwitchPrimitive.Thumb,
238
+ {
239
+ "data-slot": "switch-thumb",
240
+ className: cn(
241
+ "bg-background dark:data-[state=unchecked]:bg-foreground dark:data-[state=checked]:bg-primary-foreground pointer-events-none block rounded-full ring-0 transition-transform group-data-[size=default]/switch:size-4 group-data-[size=sm]/switch:size-3 data-[state=checked]:translate-x-[calc(100%-2px)] data-[state=unchecked]:translate-x-0"
242
+ )
243
+ }
244
+ )
245
+ }
246
+ );
247
+ }
248
+
249
+ // src/ui/progress.tsx
250
+ import { Progress as ProgressPrimitive } from "radix-ui";
251
+ import { jsx as jsx8 } from "react/jsx-runtime";
252
+ function Progress({
253
+ className,
254
+ value,
255
+ ...props
256
+ }) {
257
+ return /* @__PURE__ */ jsx8(
258
+ ProgressPrimitive.Root,
259
+ {
260
+ "data-slot": "progress",
261
+ className: cn(
262
+ "bg-primary/20 relative h-2 w-full overflow-hidden rounded-full",
263
+ className
264
+ ),
265
+ ...props,
266
+ children: /* @__PURE__ */ jsx8(
267
+ ProgressPrimitive.Indicator,
268
+ {
269
+ "data-slot": "progress-indicator",
270
+ className: "bg-primary h-full w-full flex-1 transition-all",
271
+ style: { transform: `translateX(-${100 - (value || 0)}%)` }
272
+ }
273
+ )
274
+ }
275
+ );
276
+ }
277
+
278
+ // src/ui/separator.tsx
279
+ import { Separator as SeparatorPrimitive } from "radix-ui";
280
+ import { jsx as jsx9 } from "react/jsx-runtime";
281
+ function Separator({
282
+ className,
283
+ orientation = "horizontal",
284
+ decorative = true,
285
+ ...props
286
+ }) {
287
+ return /* @__PURE__ */ jsx9(
288
+ SeparatorPrimitive.Root,
289
+ {
290
+ "data-slot": "separator",
291
+ decorative,
292
+ orientation,
293
+ className: cn(
294
+ "bg-border shrink-0 data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px",
295
+ className
296
+ ),
297
+ ...props
298
+ }
299
+ );
300
+ }
301
+
302
+ // src/ui/alert.tsx
303
+ import { cva as cva2 } from "class-variance-authority";
304
+ import { jsx as jsx10 } from "react/jsx-runtime";
305
+ var alertVariants = cva2(
306
+ "relative w-full rounded-lg border px-4 py-3 text-sm grid has-[>svg]:grid-cols-[calc(var(--spacing)*4)_1fr] grid-cols-[0_1fr] has-[>svg]:gap-x-3 gap-y-0.5 items-start [&>svg]:size-4 [&>svg]:translate-y-0.5 [&>svg]:text-current",
307
+ {
308
+ variants: {
309
+ variant: {
310
+ default: "bg-card text-card-foreground",
311
+ destructive: "text-destructive bg-card [&>svg]:text-current *:data-[slot=alert-description]:text-destructive/90"
312
+ }
313
+ },
314
+ defaultVariants: {
315
+ variant: "default"
316
+ }
317
+ }
318
+ );
319
+ function Alert({
320
+ className,
321
+ variant,
322
+ ...props
323
+ }) {
324
+ return /* @__PURE__ */ jsx10(
325
+ "div",
326
+ {
327
+ "data-slot": "alert",
328
+ role: "alert",
329
+ className: cn(alertVariants({ variant }), className),
330
+ ...props
331
+ }
332
+ );
333
+ }
334
+ function AlertTitle({ className, ...props }) {
335
+ return /* @__PURE__ */ jsx10(
336
+ "div",
337
+ {
338
+ "data-slot": "alert-title",
339
+ className: cn(
340
+ "col-start-2 line-clamp-1 min-h-4 font-medium tracking-tight",
341
+ className
342
+ ),
343
+ ...props
344
+ }
345
+ );
346
+ }
347
+ function AlertDescription({
348
+ className,
349
+ ...props
350
+ }) {
351
+ return /* @__PURE__ */ jsx10(
352
+ "div",
353
+ {
354
+ "data-slot": "alert-description",
355
+ className: cn(
356
+ "text-muted-foreground col-start-2 grid justify-items-start gap-1 text-sm [&_p]:leading-relaxed",
357
+ className
358
+ ),
359
+ ...props
360
+ }
361
+ );
362
+ }
363
+
364
+ // src/ui/dialog.tsx
365
+ import { XIcon } from "lucide-react";
366
+ import { Dialog as DialogPrimitive } from "radix-ui";
367
+ import { jsx as jsx11, jsxs } from "react/jsx-runtime";
368
+ function Dialog({
369
+ ...props
370
+ }) {
371
+ return /* @__PURE__ */ jsx11(DialogPrimitive.Root, { "data-slot": "dialog", ...props });
372
+ }
373
+ function DialogPortal({
374
+ ...props
375
+ }) {
376
+ return /* @__PURE__ */ jsx11(DialogPrimitive.Portal, { "data-slot": "dialog-portal", ...props });
377
+ }
378
+ function DialogOverlay({
379
+ className,
380
+ ...props
381
+ }) {
382
+ return /* @__PURE__ */ jsx11(
383
+ DialogPrimitive.Overlay,
384
+ {
385
+ "data-slot": "dialog-overlay",
386
+ className: cn(
387
+ "data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50",
388
+ className
389
+ ),
390
+ ...props
391
+ }
392
+ );
393
+ }
394
+ function DialogContent({
395
+ className,
396
+ children,
397
+ showCloseButton = true,
398
+ ...props
399
+ }) {
400
+ return /* @__PURE__ */ jsxs(DialogPortal, { "data-slot": "dialog-portal", children: [
401
+ /* @__PURE__ */ jsx11(DialogOverlay, {}),
402
+ /* @__PURE__ */ jsxs(
403
+ DialogPrimitive.Content,
404
+ {
405
+ "data-slot": "dialog-content",
406
+ className: cn(
407
+ "bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 outline-none sm:max-w-lg",
408
+ className
409
+ ),
410
+ ...props,
411
+ children: [
412
+ children,
413
+ showCloseButton && /* @__PURE__ */ jsxs(
414
+ DialogPrimitive.Close,
415
+ {
416
+ "data-slot": "dialog-close",
417
+ className: "ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
418
+ children: [
419
+ /* @__PURE__ */ jsx11(XIcon, {}),
420
+ /* @__PURE__ */ jsx11("span", { className: "sr-only", children: "Close" })
421
+ ]
422
+ }
423
+ )
424
+ ]
425
+ }
426
+ )
427
+ ] });
428
+ }
429
+ function DialogHeader({ className, ...props }) {
430
+ return /* @__PURE__ */ jsx11(
431
+ "div",
432
+ {
433
+ "data-slot": "dialog-header",
434
+ className: cn("flex flex-col gap-2 text-center sm:text-left", className),
435
+ ...props
436
+ }
437
+ );
438
+ }
439
+ function DialogTitle({
440
+ className,
441
+ ...props
442
+ }) {
443
+ return /* @__PURE__ */ jsx11(
444
+ DialogPrimitive.Title,
445
+ {
446
+ "data-slot": "dialog-title",
447
+ className: cn("text-lg leading-none font-semibold", className),
448
+ ...props
449
+ }
450
+ );
451
+ }
452
+ function DialogDescription({
453
+ className,
454
+ ...props
455
+ }) {
456
+ return /* @__PURE__ */ jsx11(
457
+ DialogPrimitive.Description,
458
+ {
459
+ "data-slot": "dialog-description",
460
+ className: cn("text-muted-foreground text-sm", className),
461
+ ...props
462
+ }
463
+ );
464
+ }
465
+
466
+ // src/ui/accordion.tsx
467
+ import { ChevronDownIcon } from "lucide-react";
468
+ import { Accordion as AccordionPrimitive } from "radix-ui";
469
+ import { jsx as jsx12, jsxs as jsxs2 } from "react/jsx-runtime";
470
+ function Accordion({
471
+ ...props
472
+ }) {
473
+ return /* @__PURE__ */ jsx12(AccordionPrimitive.Root, { "data-slot": "accordion", ...props });
474
+ }
475
+ function AccordionItem({
476
+ className,
477
+ ...props
478
+ }) {
479
+ return /* @__PURE__ */ jsx12(
480
+ AccordionPrimitive.Item,
481
+ {
482
+ "data-slot": "accordion-item",
483
+ className: cn("border-b last:border-b-0", className),
484
+ ...props
485
+ }
486
+ );
487
+ }
488
+ function AccordionTrigger({
489
+ className,
490
+ children,
491
+ ...props
492
+ }) {
493
+ return /* @__PURE__ */ jsx12(AccordionPrimitive.Header, { className: "flex", children: /* @__PURE__ */ jsxs2(
494
+ AccordionPrimitive.Trigger,
495
+ {
496
+ "data-slot": "accordion-trigger",
497
+ className: cn(
498
+ "focus-visible:border-ring focus-visible:ring-ring/50 flex flex-1 items-start justify-between gap-4 rounded-md py-4 text-left text-sm font-medium transition-all outline-none hover:underline focus-visible:ring-[3px] disabled:pointer-events-none disabled:opacity-50 [&[data-state=open]>svg]:rotate-180",
499
+ className
500
+ ),
501
+ ...props,
502
+ children: [
503
+ children,
504
+ /* @__PURE__ */ jsx12(ChevronDownIcon, { className: "text-muted-foreground pointer-events-none size-4 shrink-0 translate-y-0.5 transition-transform duration-200" })
505
+ ]
506
+ }
507
+ ) });
508
+ }
509
+ function AccordionContent({
510
+ className,
511
+ children,
512
+ ...props
513
+ }) {
514
+ return /* @__PURE__ */ jsx12(
515
+ AccordionPrimitive.Content,
516
+ {
517
+ "data-slot": "accordion-content",
518
+ className: "data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down overflow-hidden text-sm",
519
+ ...props,
520
+ children: /* @__PURE__ */ jsx12("div", { className: cn("pt-0 pb-4", className), children })
521
+ }
522
+ );
523
+ }
524
+
525
+ // src/ui/avatar.tsx
526
+ import { Avatar as AvatarPrimitive } from "radix-ui";
527
+ import { jsx as jsx13 } from "react/jsx-runtime";
528
+ function Avatar({
529
+ className,
530
+ ...props
531
+ }) {
532
+ return /* @__PURE__ */ jsx13(
533
+ AvatarPrimitive.Root,
534
+ {
535
+ "data-slot": "avatar",
536
+ className: cn(
537
+ "relative flex size-10 shrink-0 overflow-hidden rounded-full",
538
+ className
539
+ ),
540
+ ...props
541
+ }
542
+ );
543
+ }
544
+ function AvatarImage({
545
+ className,
546
+ ...props
547
+ }) {
548
+ return /* @__PURE__ */ jsx13(
549
+ AvatarPrimitive.Image,
550
+ {
551
+ "data-slot": "avatar-image",
552
+ className: cn("aspect-square size-full", className),
553
+ ...props
554
+ }
555
+ );
556
+ }
557
+ function AvatarFallback({
558
+ className,
559
+ ...props
560
+ }) {
561
+ return /* @__PURE__ */ jsx13(
562
+ AvatarPrimitive.Fallback,
563
+ {
564
+ "data-slot": "avatar-fallback",
565
+ className: cn(
566
+ "bg-muted flex size-full items-center justify-center rounded-full",
567
+ className
568
+ ),
569
+ ...props
570
+ }
571
+ );
572
+ }
573
+
574
+ // src/ui/badge.tsx
575
+ import { cva as cva3 } from "class-variance-authority";
576
+ import { Slot as Slot2 } from "radix-ui";
577
+ import { jsx as jsx14 } from "react/jsx-runtime";
578
+ var badgeVariants = cva3(
579
+ "inline-flex items-center justify-center rounded-full border border-transparent px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden",
580
+ {
581
+ variants: {
582
+ variant: {
583
+ default: "bg-primary text-primary-foreground [a&]:hover:bg-primary/90",
584
+ secondary: "bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90",
585
+ destructive: "bg-destructive text-white [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
586
+ outline: "border-border text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground"
587
+ }
588
+ },
589
+ defaultVariants: {
590
+ variant: "default"
591
+ }
592
+ }
593
+ );
594
+ function Badge({
595
+ className,
596
+ variant = "default",
597
+ asChild = false,
598
+ ...props
599
+ }) {
600
+ const Comp = asChild ? Slot2.Root : "span";
601
+ return /* @__PURE__ */ jsx14(
602
+ Comp,
603
+ {
604
+ "data-slot": "badge",
605
+ "data-variant": variant,
606
+ className: cn(badgeVariants({ variant }), className),
607
+ ...props
608
+ }
609
+ );
610
+ }
611
+
612
+ // src/ui/radio-group.tsx
613
+ import { CircleIcon } from "lucide-react";
614
+ import { RadioGroup as RadioGroupPrimitive } from "radix-ui";
615
+ import { jsx as jsx15 } from "react/jsx-runtime";
616
+ function RadioGroup({
617
+ className,
618
+ ...props
619
+ }) {
620
+ return /* @__PURE__ */ jsx15(
621
+ RadioGroupPrimitive.Root,
622
+ {
623
+ "data-slot": "radio-group",
624
+ className: cn("grid gap-3", className),
625
+ ...props
626
+ }
627
+ );
628
+ }
629
+ function RadioGroupItem({
630
+ className,
631
+ ...props
632
+ }) {
633
+ return /* @__PURE__ */ jsx15(
634
+ RadioGroupPrimitive.Item,
635
+ {
636
+ "data-slot": "radio-group-item",
637
+ className: cn(
638
+ "border-input text-primary focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 aspect-square size-4 shrink-0 rounded-full border shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50",
639
+ className
640
+ ),
641
+ ...props,
642
+ children: /* @__PURE__ */ jsx15(
643
+ RadioGroupPrimitive.Indicator,
644
+ {
645
+ "data-slot": "radio-group-indicator",
646
+ className: "relative flex items-center justify-center",
647
+ children: /* @__PURE__ */ jsx15(CircleIcon, { className: "fill-primary absolute top-1/2 left-1/2 size-2 -translate-x-1/2 -translate-y-1/2" })
648
+ }
649
+ )
650
+ }
651
+ );
652
+ }
653
+
654
+ // src/ui/select.tsx
655
+ import { CheckIcon as CheckIcon2, ChevronDownIcon as ChevronDownIcon2, ChevronUpIcon } from "lucide-react";
656
+ import { Select as SelectPrimitive } from "radix-ui";
657
+ import { jsx as jsx16, jsxs as jsxs3 } from "react/jsx-runtime";
658
+ function Select({
659
+ ...props
660
+ }) {
661
+ return /* @__PURE__ */ jsx16(SelectPrimitive.Root, { "data-slot": "select", ...props });
662
+ }
663
+ function SelectValue({
664
+ ...props
665
+ }) {
666
+ return /* @__PURE__ */ jsx16(SelectPrimitive.Value, { "data-slot": "select-value", ...props });
667
+ }
668
+ function SelectTrigger({
669
+ className,
670
+ size = "default",
671
+ children,
672
+ ...props
673
+ }) {
674
+ return /* @__PURE__ */ jsxs3(
675
+ SelectPrimitive.Trigger,
676
+ {
677
+ "data-slot": "select-trigger",
678
+ "data-size": size,
679
+ className: cn(
680
+ "border-input data-[placeholder]:text-muted-foreground [&_svg:not([class*='text-'])]:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 dark:hover:bg-input/50 flex w-fit items-center justify-between gap-2 rounded-md border bg-transparent px-3 py-2 text-sm whitespace-nowrap shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 data-[size=default]:h-9 data-[size=sm]:h-8 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
681
+ className
682
+ ),
683
+ ...props,
684
+ children: [
685
+ children,
686
+ /* @__PURE__ */ jsx16(SelectPrimitive.Icon, { asChild: true, children: /* @__PURE__ */ jsx16(ChevronDownIcon2, { className: "size-4 opacity-50" }) })
687
+ ]
688
+ }
689
+ );
690
+ }
691
+ function SelectContent({
692
+ className,
693
+ children,
694
+ position = "item-aligned",
695
+ align = "center",
696
+ ...props
697
+ }) {
698
+ return /* @__PURE__ */ jsx16(SelectPrimitive.Portal, { children: /* @__PURE__ */ jsxs3(
699
+ SelectPrimitive.Content,
700
+ {
701
+ "data-slot": "select-content",
702
+ className: cn(
703
+ "bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 relative z-50 max-h-(--radix-select-content-available-height) min-w-[8rem] origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border shadow-md",
704
+ position === "popper" && "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
705
+ className
706
+ ),
707
+ position,
708
+ align,
709
+ ...props,
710
+ children: [
711
+ /* @__PURE__ */ jsx16(SelectScrollUpButton, {}),
712
+ /* @__PURE__ */ jsx16(
713
+ SelectPrimitive.Viewport,
714
+ {
715
+ className: cn(
716
+ "p-1",
717
+ position === "popper" && "h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)] scroll-my-1"
718
+ ),
719
+ children
720
+ }
721
+ ),
722
+ /* @__PURE__ */ jsx16(SelectScrollDownButton, {})
723
+ ]
724
+ }
725
+ ) });
726
+ }
727
+ function SelectItem({
728
+ className,
729
+ children,
730
+ ...props
731
+ }) {
732
+ return /* @__PURE__ */ jsxs3(
733
+ SelectPrimitive.Item,
734
+ {
735
+ "data-slot": "select-item",
736
+ className: cn(
737
+ "focus:bg-accent focus:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground relative flex w-full cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2",
738
+ className
739
+ ),
740
+ ...props,
741
+ children: [
742
+ /* @__PURE__ */ jsx16(
743
+ "span",
744
+ {
745
+ "data-slot": "select-item-indicator",
746
+ className: "absolute right-2 flex size-3.5 items-center justify-center",
747
+ children: /* @__PURE__ */ jsx16(SelectPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx16(CheckIcon2, { className: "size-4" }) })
748
+ }
749
+ ),
750
+ /* @__PURE__ */ jsx16(SelectPrimitive.ItemText, { children })
751
+ ]
752
+ }
753
+ );
754
+ }
755
+ function SelectScrollUpButton({
756
+ className,
757
+ ...props
758
+ }) {
759
+ return /* @__PURE__ */ jsx16(
760
+ SelectPrimitive.ScrollUpButton,
761
+ {
762
+ "data-slot": "select-scroll-up-button",
763
+ className: cn(
764
+ "flex cursor-default items-center justify-center py-1",
765
+ className
766
+ ),
767
+ ...props,
768
+ children: /* @__PURE__ */ jsx16(ChevronUpIcon, { className: "size-4" })
769
+ }
770
+ );
771
+ }
772
+ function SelectScrollDownButton({
773
+ className,
774
+ ...props
775
+ }) {
776
+ return /* @__PURE__ */ jsx16(
777
+ SelectPrimitive.ScrollDownButton,
778
+ {
779
+ "data-slot": "select-scroll-down-button",
780
+ className: cn(
781
+ "flex cursor-default items-center justify-center py-1",
782
+ className
783
+ ),
784
+ ...props,
785
+ children: /* @__PURE__ */ jsx16(ChevronDownIcon2, { className: "size-4" })
786
+ }
787
+ );
788
+ }
789
+
790
+ // src/ui/carousel.tsx
791
+ import * as React from "react";
792
+ import useEmblaCarousel from "embla-carousel-react";
793
+ import { ArrowLeft, ArrowRight } from "lucide-react";
794
+ import { jsx as jsx17, jsxs as jsxs4 } from "react/jsx-runtime";
795
+ var CarouselContext = React.createContext(null);
796
+ function useCarousel() {
797
+ const context = React.useContext(CarouselContext);
798
+ if (!context) {
799
+ throw new Error("useCarousel must be used within a <Carousel />");
800
+ }
801
+ return context;
802
+ }
803
+ function Carousel({
804
+ orientation = "horizontal",
805
+ opts,
806
+ setApi,
807
+ plugins,
808
+ className,
809
+ children,
810
+ ...props
811
+ }) {
812
+ const [carouselRef, api] = useEmblaCarousel(
813
+ {
814
+ ...opts,
815
+ axis: orientation === "horizontal" ? "x" : "y"
816
+ },
817
+ plugins
818
+ );
819
+ const [canScrollPrev, setCanScrollPrev] = React.useState(false);
820
+ const [canScrollNext, setCanScrollNext] = React.useState(false);
821
+ const onSelect = React.useCallback((api2) => {
822
+ if (!api2) return;
823
+ setCanScrollPrev(api2.canScrollPrev());
824
+ setCanScrollNext(api2.canScrollNext());
825
+ }, []);
826
+ const scrollPrev = React.useCallback(() => {
827
+ api?.scrollPrev();
828
+ }, [api]);
829
+ const scrollNext = React.useCallback(() => {
830
+ api?.scrollNext();
831
+ }, [api]);
832
+ const handleKeyDown = React.useCallback(
833
+ (event) => {
834
+ if (event.key === "ArrowLeft") {
835
+ event.preventDefault();
836
+ scrollPrev();
837
+ } else if (event.key === "ArrowRight") {
838
+ event.preventDefault();
839
+ scrollNext();
840
+ }
841
+ },
842
+ [scrollPrev, scrollNext]
843
+ );
844
+ React.useEffect(() => {
845
+ if (!api || !setApi) return;
846
+ setApi(api);
847
+ }, [api, setApi]);
848
+ React.useEffect(() => {
849
+ if (!api) return;
850
+ onSelect(api);
851
+ api.on("reInit", onSelect);
852
+ api.on("select", onSelect);
853
+ return () => {
854
+ api?.off("select", onSelect);
855
+ };
856
+ }, [api, onSelect]);
857
+ return /* @__PURE__ */ jsx17(
858
+ CarouselContext.Provider,
859
+ {
860
+ value: {
861
+ carouselRef,
862
+ api,
863
+ opts,
864
+ orientation: orientation || (opts?.axis === "y" ? "vertical" : "horizontal"),
865
+ scrollPrev,
866
+ scrollNext,
867
+ canScrollPrev,
868
+ canScrollNext
869
+ },
870
+ children: /* @__PURE__ */ jsx17(
871
+ "div",
872
+ {
873
+ onKeyDownCapture: handleKeyDown,
874
+ className: cn("relative", className),
875
+ role: "region",
876
+ "aria-roledescription": "carousel",
877
+ "data-slot": "carousel",
878
+ ...props,
879
+ children
880
+ }
881
+ )
882
+ }
883
+ );
884
+ }
885
+ function CarouselContent({ className, ...props }) {
886
+ const { carouselRef, orientation } = useCarousel();
887
+ return /* @__PURE__ */ jsx17(
888
+ "div",
889
+ {
890
+ ref: carouselRef,
891
+ className: "overflow-hidden",
892
+ "data-slot": "carousel-content",
893
+ children: /* @__PURE__ */ jsx17(
894
+ "div",
895
+ {
896
+ className: cn(
897
+ "flex",
898
+ orientation === "horizontal" ? "-ml-4" : "-mt-4 flex-col",
899
+ className
900
+ ),
901
+ ...props
902
+ }
903
+ )
904
+ }
905
+ );
906
+ }
907
+ function CarouselItem({ className, ...props }) {
908
+ const { orientation } = useCarousel();
909
+ return /* @__PURE__ */ jsx17(
910
+ "div",
911
+ {
912
+ role: "group",
913
+ "aria-roledescription": "slide",
914
+ "data-slot": "carousel-item",
915
+ className: cn(
916
+ "min-w-0 shrink-0 grow-0 basis-full",
917
+ orientation === "horizontal" ? "pl-4" : "pt-4",
918
+ className
919
+ ),
920
+ ...props
921
+ }
922
+ );
923
+ }
924
+ function CarouselPrevious({
925
+ className,
926
+ variant = "outline",
927
+ size = "icon",
928
+ ...props
929
+ }) {
930
+ const { orientation, scrollPrev, canScrollPrev } = useCarousel();
931
+ return /* @__PURE__ */ jsxs4(
932
+ Button,
933
+ {
934
+ "data-slot": "carousel-previous",
935
+ variant,
936
+ size,
937
+ className: cn(
938
+ "absolute size-8 rounded-full",
939
+ orientation === "horizontal" ? "top-1/2 -left-12 -translate-y-1/2" : "-top-12 left-1/2 -translate-x-1/2 rotate-90",
940
+ className
941
+ ),
942
+ disabled: !canScrollPrev,
943
+ onClick: scrollPrev,
944
+ ...props,
945
+ children: [
946
+ /* @__PURE__ */ jsx17(ArrowLeft, {}),
947
+ /* @__PURE__ */ jsx17("span", { className: "sr-only", children: "Previous slide" })
948
+ ]
949
+ }
950
+ );
951
+ }
952
+ function CarouselNext({
953
+ className,
954
+ variant = "outline",
955
+ size = "icon",
956
+ ...props
957
+ }) {
958
+ const { orientation, scrollNext, canScrollNext } = useCarousel();
959
+ return /* @__PURE__ */ jsxs4(
960
+ Button,
961
+ {
962
+ "data-slot": "carousel-next",
963
+ variant,
964
+ size,
965
+ className: cn(
966
+ "absolute size-8 rounded-full",
967
+ orientation === "horizontal" ? "top-1/2 -right-12 -translate-y-1/2" : "-bottom-12 left-1/2 -translate-x-1/2 rotate-90",
968
+ className
969
+ ),
970
+ disabled: !canScrollNext,
971
+ onClick: scrollNext,
972
+ ...props,
973
+ children: [
974
+ /* @__PURE__ */ jsx17(ArrowRight, {}),
975
+ /* @__PURE__ */ jsx17("span", { className: "sr-only", children: "Next slide" })
976
+ ]
977
+ }
978
+ );
979
+ }
980
+
981
+ // src/ui/collapsible.tsx
982
+ import { Collapsible as CollapsiblePrimitive } from "radix-ui";
983
+ import { jsx as jsx18 } from "react/jsx-runtime";
984
+ function Collapsible({
985
+ ...props
986
+ }) {
987
+ return /* @__PURE__ */ jsx18(CollapsiblePrimitive.Root, { "data-slot": "collapsible", ...props });
988
+ }
989
+ function CollapsibleTrigger({
990
+ ...props
991
+ }) {
992
+ return /* @__PURE__ */ jsx18(
993
+ CollapsiblePrimitive.CollapsibleTrigger,
994
+ {
995
+ "data-slot": "collapsible-trigger",
996
+ ...props
997
+ }
998
+ );
999
+ }
1000
+ function CollapsibleContent({
1001
+ ...props
1002
+ }) {
1003
+ return /* @__PURE__ */ jsx18(
1004
+ CollapsiblePrimitive.CollapsibleContent,
1005
+ {
1006
+ "data-slot": "collapsible-content",
1007
+ ...props
1008
+ }
1009
+ );
1010
+ }
1011
+
1012
+ // src/ui/table.tsx
1013
+ import { jsx as jsx19 } from "react/jsx-runtime";
1014
+ function Table({ className, ...props }) {
1015
+ return /* @__PURE__ */ jsx19(
1016
+ "div",
1017
+ {
1018
+ "data-slot": "table-container",
1019
+ className: "relative w-full overflow-x-auto",
1020
+ children: /* @__PURE__ */ jsx19(
1021
+ "table",
1022
+ {
1023
+ "data-slot": "table",
1024
+ className: cn("w-full caption-bottom text-sm", className),
1025
+ ...props
1026
+ }
1027
+ )
1028
+ }
1029
+ );
1030
+ }
1031
+ function TableHeader({ className, ...props }) {
1032
+ return /* @__PURE__ */ jsx19(
1033
+ "thead",
1034
+ {
1035
+ "data-slot": "table-header",
1036
+ className: cn("[&_tr]:border-b", className),
1037
+ ...props
1038
+ }
1039
+ );
1040
+ }
1041
+ function TableBody({ className, ...props }) {
1042
+ return /* @__PURE__ */ jsx19(
1043
+ "tbody",
1044
+ {
1045
+ "data-slot": "table-body",
1046
+ className: cn("[&_tr:last-child]:border-0", className),
1047
+ ...props
1048
+ }
1049
+ );
1050
+ }
1051
+ function TableRow({ className, ...props }) {
1052
+ return /* @__PURE__ */ jsx19(
1053
+ "tr",
1054
+ {
1055
+ "data-slot": "table-row",
1056
+ className: cn(
1057
+ "hover:bg-muted/50 data-[state=selected]:bg-muted border-b transition-colors",
1058
+ className
1059
+ ),
1060
+ ...props
1061
+ }
1062
+ );
1063
+ }
1064
+ function TableHead({ className, ...props }) {
1065
+ return /* @__PURE__ */ jsx19(
1066
+ "th",
1067
+ {
1068
+ "data-slot": "table-head",
1069
+ className: cn(
1070
+ "text-foreground h-10 px-2 text-left align-middle font-medium whitespace-nowrap [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]",
1071
+ className
1072
+ ),
1073
+ ...props
1074
+ }
1075
+ );
1076
+ }
1077
+ function TableCell({ className, ...props }) {
1078
+ return /* @__PURE__ */ jsx19(
1079
+ "td",
1080
+ {
1081
+ "data-slot": "table-cell",
1082
+ className: cn(
1083
+ "p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]",
1084
+ className
1085
+ ),
1086
+ ...props
1087
+ }
1088
+ );
1089
+ }
1090
+ function TableCaption({
1091
+ className,
1092
+ ...props
1093
+ }) {
1094
+ return /* @__PURE__ */ jsx19(
1095
+ "caption",
1096
+ {
1097
+ "data-slot": "table-caption",
1098
+ className: cn("text-muted-foreground mt-4 text-sm", className),
1099
+ ...props
1100
+ }
1101
+ );
1102
+ }
1103
+
1104
+ // src/ui/drawer.tsx
1105
+ import { Drawer as DrawerPrimitive } from "vaul";
1106
+ import { jsx as jsx20, jsxs as jsxs5 } from "react/jsx-runtime";
1107
+ function Drawer({
1108
+ ...props
1109
+ }) {
1110
+ return /* @__PURE__ */ jsx20(DrawerPrimitive.Root, { "data-slot": "drawer", ...props });
1111
+ }
1112
+ function DrawerPortal({
1113
+ ...props
1114
+ }) {
1115
+ return /* @__PURE__ */ jsx20(DrawerPrimitive.Portal, { "data-slot": "drawer-portal", ...props });
1116
+ }
1117
+ function DrawerOverlay({
1118
+ className,
1119
+ ...props
1120
+ }) {
1121
+ return /* @__PURE__ */ jsx20(
1122
+ DrawerPrimitive.Overlay,
1123
+ {
1124
+ "data-slot": "drawer-overlay",
1125
+ className: cn(
1126
+ "data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50",
1127
+ className
1128
+ ),
1129
+ ...props
1130
+ }
1131
+ );
1132
+ }
1133
+ function DrawerContent({
1134
+ className,
1135
+ children,
1136
+ ...props
1137
+ }) {
1138
+ return /* @__PURE__ */ jsxs5(DrawerPortal, { "data-slot": "drawer-portal", children: [
1139
+ /* @__PURE__ */ jsx20(DrawerOverlay, {}),
1140
+ /* @__PURE__ */ jsxs5(
1141
+ DrawerPrimitive.Content,
1142
+ {
1143
+ "data-slot": "drawer-content",
1144
+ className: cn(
1145
+ "group/drawer-content bg-background fixed z-50 flex h-auto flex-col",
1146
+ "data-[vaul-drawer-direction=top]:inset-x-0 data-[vaul-drawer-direction=top]:top-0 data-[vaul-drawer-direction=top]:mb-24 data-[vaul-drawer-direction=top]:max-h-[80vh] data-[vaul-drawer-direction=top]:rounded-b-lg data-[vaul-drawer-direction=top]:border-b",
1147
+ "data-[vaul-drawer-direction=bottom]:inset-x-0 data-[vaul-drawer-direction=bottom]:bottom-0 data-[vaul-drawer-direction=bottom]:mt-24 data-[vaul-drawer-direction=bottom]:max-h-[80vh] data-[vaul-drawer-direction=bottom]:rounded-t-lg data-[vaul-drawer-direction=bottom]:border-t",
1148
+ "data-[vaul-drawer-direction=right]:inset-y-0 data-[vaul-drawer-direction=right]:right-0 data-[vaul-drawer-direction=right]:w-3/4 data-[vaul-drawer-direction=right]:border-l data-[vaul-drawer-direction=right]:sm:max-w-sm",
1149
+ "data-[vaul-drawer-direction=left]:inset-y-0 data-[vaul-drawer-direction=left]:left-0 data-[vaul-drawer-direction=left]:w-3/4 data-[vaul-drawer-direction=left]:border-r data-[vaul-drawer-direction=left]:sm:max-w-sm",
1150
+ className
1151
+ ),
1152
+ ...props,
1153
+ children: [
1154
+ /* @__PURE__ */ jsx20("div", { className: "bg-muted mx-auto mt-4 hidden h-2 w-[100px] shrink-0 rounded-full group-data-[vaul-drawer-direction=bottom]/drawer-content:block" }),
1155
+ children
1156
+ ]
1157
+ }
1158
+ )
1159
+ ] });
1160
+ }
1161
+ function DrawerHeader({ className, ...props }) {
1162
+ return /* @__PURE__ */ jsx20(
1163
+ "div",
1164
+ {
1165
+ "data-slot": "drawer-header",
1166
+ className: cn(
1167
+ "flex flex-col gap-0.5 p-4 group-data-[vaul-drawer-direction=bottom]/drawer-content:text-center group-data-[vaul-drawer-direction=top]/drawer-content:text-center md:gap-1.5 md:text-left",
1168
+ className
1169
+ ),
1170
+ ...props
1171
+ }
1172
+ );
1173
+ }
1174
+ function DrawerTitle({
1175
+ className,
1176
+ ...props
1177
+ }) {
1178
+ return /* @__PURE__ */ jsx20(
1179
+ DrawerPrimitive.Title,
1180
+ {
1181
+ "data-slot": "drawer-title",
1182
+ className: cn("text-foreground font-semibold", className),
1183
+ ...props
1184
+ }
1185
+ );
1186
+ }
1187
+ function DrawerDescription({
1188
+ className,
1189
+ ...props
1190
+ }) {
1191
+ return /* @__PURE__ */ jsx20(
1192
+ DrawerPrimitive.Description,
1193
+ {
1194
+ "data-slot": "drawer-description",
1195
+ className: cn("text-muted-foreground text-sm", className),
1196
+ ...props
1197
+ }
1198
+ );
1199
+ }
1200
+
1201
+ // src/ui/dropdown-menu.tsx
1202
+ import { CheckIcon as CheckIcon3, ChevronRightIcon, CircleIcon as CircleIcon2 } from "lucide-react";
1203
+ import { DropdownMenu as DropdownMenuPrimitive } from "radix-ui";
1204
+ import { jsx as jsx21, jsxs as jsxs6 } from "react/jsx-runtime";
1205
+ function DropdownMenu({
1206
+ ...props
1207
+ }) {
1208
+ return /* @__PURE__ */ jsx21(DropdownMenuPrimitive.Root, { "data-slot": "dropdown-menu", ...props });
1209
+ }
1210
+ function DropdownMenuTrigger({
1211
+ ...props
1212
+ }) {
1213
+ return /* @__PURE__ */ jsx21(
1214
+ DropdownMenuPrimitive.Trigger,
1215
+ {
1216
+ "data-slot": "dropdown-menu-trigger",
1217
+ ...props
1218
+ }
1219
+ );
1220
+ }
1221
+ function DropdownMenuContent({
1222
+ className,
1223
+ sideOffset = 4,
1224
+ ...props
1225
+ }) {
1226
+ return /* @__PURE__ */ jsx21(DropdownMenuPrimitive.Portal, { children: /* @__PURE__ */ jsx21(
1227
+ DropdownMenuPrimitive.Content,
1228
+ {
1229
+ "data-slot": "dropdown-menu-content",
1230
+ sideOffset,
1231
+ className: cn(
1232
+ "bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 max-h-(--radix-dropdown-menu-content-available-height) min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border p-1 shadow-md",
1233
+ className
1234
+ ),
1235
+ ...props
1236
+ }
1237
+ ) });
1238
+ }
1239
+ function DropdownMenuItem({
1240
+ className,
1241
+ inset,
1242
+ variant = "default",
1243
+ ...props
1244
+ }) {
1245
+ return /* @__PURE__ */ jsx21(
1246
+ DropdownMenuPrimitive.Item,
1247
+ {
1248
+ "data-slot": "dropdown-menu-item",
1249
+ "data-inset": inset,
1250
+ "data-variant": variant,
1251
+ className: cn(
1252
+ "focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:!text-destructive [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
1253
+ className
1254
+ ),
1255
+ ...props
1256
+ }
1257
+ );
1258
+ }
1259
+
1260
+ // src/ui/pagination.tsx
1261
+ import {
1262
+ ChevronLeftIcon,
1263
+ ChevronRightIcon as ChevronRightIcon2,
1264
+ MoreHorizontalIcon
1265
+ } from "lucide-react";
1266
+ import { jsx as jsx22, jsxs as jsxs7 } from "react/jsx-runtime";
1267
+ function Pagination({ className, ...props }) {
1268
+ return /* @__PURE__ */ jsx22(
1269
+ "nav",
1270
+ {
1271
+ role: "navigation",
1272
+ "aria-label": "pagination",
1273
+ "data-slot": "pagination",
1274
+ className: cn("mx-auto flex w-full justify-center", className),
1275
+ ...props
1276
+ }
1277
+ );
1278
+ }
1279
+ function PaginationContent({
1280
+ className,
1281
+ ...props
1282
+ }) {
1283
+ return /* @__PURE__ */ jsx22(
1284
+ "ul",
1285
+ {
1286
+ "data-slot": "pagination-content",
1287
+ className: cn("flex flex-row items-center gap-1", className),
1288
+ ...props
1289
+ }
1290
+ );
1291
+ }
1292
+ function PaginationItem({ ...props }) {
1293
+ return /* @__PURE__ */ jsx22("li", { "data-slot": "pagination-item", ...props });
1294
+ }
1295
+ function PaginationLink({
1296
+ className,
1297
+ isActive,
1298
+ size = "icon",
1299
+ ...props
1300
+ }) {
1301
+ return /* @__PURE__ */ jsx22(
1302
+ "a",
1303
+ {
1304
+ "aria-current": isActive ? "page" : void 0,
1305
+ "data-slot": "pagination-link",
1306
+ "data-active": isActive,
1307
+ className: cn(
1308
+ buttonVariants({
1309
+ variant: isActive ? "outline" : "ghost",
1310
+ size
1311
+ }),
1312
+ className
1313
+ ),
1314
+ ...props
1315
+ }
1316
+ );
1317
+ }
1318
+ function PaginationPrevious({
1319
+ className,
1320
+ ...props
1321
+ }) {
1322
+ return /* @__PURE__ */ jsxs7(
1323
+ PaginationLink,
1324
+ {
1325
+ "aria-label": "Go to previous page",
1326
+ size: "default",
1327
+ className: cn("gap-1 px-2.5 sm:pl-2.5", className),
1328
+ ...props,
1329
+ children: [
1330
+ /* @__PURE__ */ jsx22(ChevronLeftIcon, {}),
1331
+ /* @__PURE__ */ jsx22("span", { className: "hidden sm:block", children: "Previous" })
1332
+ ]
1333
+ }
1334
+ );
1335
+ }
1336
+ function PaginationNext({
1337
+ className,
1338
+ ...props
1339
+ }) {
1340
+ return /* @__PURE__ */ jsxs7(
1341
+ PaginationLink,
1342
+ {
1343
+ "aria-label": "Go to next page",
1344
+ size: "default",
1345
+ className: cn("gap-1 px-2.5 sm:pr-2.5", className),
1346
+ ...props,
1347
+ children: [
1348
+ /* @__PURE__ */ jsx22("span", { className: "hidden sm:block", children: "Next" }),
1349
+ /* @__PURE__ */ jsx22(ChevronRightIcon2, {})
1350
+ ]
1351
+ }
1352
+ );
1353
+ }
1354
+ function PaginationEllipsis({
1355
+ className,
1356
+ ...props
1357
+ }) {
1358
+ return /* @__PURE__ */ jsxs7(
1359
+ "span",
1360
+ {
1361
+ "aria-hidden": true,
1362
+ "data-slot": "pagination-ellipsis",
1363
+ className: cn("flex size-9 items-center justify-center", className),
1364
+ ...props,
1365
+ children: [
1366
+ /* @__PURE__ */ jsx22(MoreHorizontalIcon, { className: "size-4" }),
1367
+ /* @__PURE__ */ jsx22("span", { className: "sr-only", children: "More pages" })
1368
+ ]
1369
+ }
1370
+ );
1371
+ }
1372
+
1373
+ // src/ui/popover.tsx
1374
+ import { Popover as PopoverPrimitive } from "radix-ui";
1375
+ import { jsx as jsx23 } from "react/jsx-runtime";
1376
+ function Popover({
1377
+ ...props
1378
+ }) {
1379
+ return /* @__PURE__ */ jsx23(PopoverPrimitive.Root, { "data-slot": "popover", ...props });
1380
+ }
1381
+ function PopoverTrigger({
1382
+ ...props
1383
+ }) {
1384
+ return /* @__PURE__ */ jsx23(PopoverPrimitive.Trigger, { "data-slot": "popover-trigger", ...props });
1385
+ }
1386
+ function PopoverContent({
1387
+ className,
1388
+ align = "center",
1389
+ sideOffset = 4,
1390
+ ...props
1391
+ }) {
1392
+ return /* @__PURE__ */ jsx23(PopoverPrimitive.Portal, { children: /* @__PURE__ */ jsx23(
1393
+ PopoverPrimitive.Content,
1394
+ {
1395
+ "data-slot": "popover-content",
1396
+ align,
1397
+ sideOffset,
1398
+ className: cn(
1399
+ "bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-72 origin-(--radix-popover-content-transform-origin) rounded-md border p-4 shadow-md outline-hidden",
1400
+ className
1401
+ ),
1402
+ ...props
1403
+ }
1404
+ ) });
1405
+ }
1406
+
1407
+ // src/ui/skeleton.tsx
1408
+ import { jsx as jsx24 } from "react/jsx-runtime";
1409
+ function Skeleton({ className, ...props }) {
1410
+ return /* @__PURE__ */ jsx24(
1411
+ "div",
1412
+ {
1413
+ "data-slot": "skeleton",
1414
+ className: cn("bg-accent animate-pulse rounded-md", className),
1415
+ ...props
1416
+ }
1417
+ );
1418
+ }
1419
+
1420
+ // src/ui/slider.tsx
1421
+ import * as React2 from "react";
1422
+ import { Slider as SliderPrimitive } from "radix-ui";
1423
+ import { jsx as jsx25, jsxs as jsxs8 } from "react/jsx-runtime";
1424
+ function Slider({
1425
+ className,
1426
+ defaultValue,
1427
+ value,
1428
+ min = 0,
1429
+ max = 100,
1430
+ ...props
1431
+ }) {
1432
+ const _values = React2.useMemo(
1433
+ () => Array.isArray(value) ? value : Array.isArray(defaultValue) ? defaultValue : [min, max],
1434
+ [value, defaultValue, min, max]
1435
+ );
1436
+ return /* @__PURE__ */ jsxs8(
1437
+ SliderPrimitive.Root,
1438
+ {
1439
+ "data-slot": "slider",
1440
+ defaultValue,
1441
+ value,
1442
+ min,
1443
+ max,
1444
+ className: cn(
1445
+ "relative flex w-full touch-none items-center select-none data-[disabled]:opacity-50 data-[orientation=vertical]:h-full data-[orientation=vertical]:min-h-44 data-[orientation=vertical]:w-auto data-[orientation=vertical]:flex-col",
1446
+ className
1447
+ ),
1448
+ ...props,
1449
+ children: [
1450
+ /* @__PURE__ */ jsx25(
1451
+ SliderPrimitive.Track,
1452
+ {
1453
+ "data-slot": "slider-track",
1454
+ className: cn(
1455
+ "bg-muted relative grow overflow-hidden rounded-full data-[orientation=horizontal]:h-1.5 data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-1.5"
1456
+ ),
1457
+ children: /* @__PURE__ */ jsx25(
1458
+ SliderPrimitive.Range,
1459
+ {
1460
+ "data-slot": "slider-range",
1461
+ className: cn(
1462
+ "bg-primary absolute data-[orientation=horizontal]:h-full data-[orientation=vertical]:w-full"
1463
+ )
1464
+ }
1465
+ )
1466
+ }
1467
+ ),
1468
+ Array.from({ length: _values.length }, (_, index) => /* @__PURE__ */ jsx25(
1469
+ SliderPrimitive.Thumb,
1470
+ {
1471
+ "data-slot": "slider-thumb",
1472
+ className: "border-primary ring-ring/50 block size-4 shrink-0 rounded-full border bg-white shadow-sm transition-[color,box-shadow] hover:ring-4 focus-visible:ring-4 focus-visible:outline-hidden disabled:pointer-events-none disabled:opacity-50"
1473
+ },
1474
+ index
1475
+ ))
1476
+ ]
1477
+ }
1478
+ );
1479
+ }
1480
+
1481
+ // src/ui/tabs.tsx
1482
+ import { cva as cva4 } from "class-variance-authority";
1483
+ import { Tabs as TabsPrimitive } from "radix-ui";
1484
+ import { jsx as jsx26 } from "react/jsx-runtime";
1485
+ function Tabs({
1486
+ className,
1487
+ orientation = "horizontal",
1488
+ ...props
1489
+ }) {
1490
+ return /* @__PURE__ */ jsx26(
1491
+ TabsPrimitive.Root,
1492
+ {
1493
+ "data-slot": "tabs",
1494
+ "data-orientation": orientation,
1495
+ orientation,
1496
+ className: cn(
1497
+ "group/tabs flex gap-2 data-[orientation=horizontal]:flex-col",
1498
+ className
1499
+ ),
1500
+ ...props
1501
+ }
1502
+ );
1503
+ }
1504
+ var tabsListVariants = cva4(
1505
+ "rounded-lg p-[3px] group-data-[orientation=horizontal]/tabs:h-9 data-[variant=line]:rounded-none group/tabs-list text-muted-foreground inline-flex w-fit items-center justify-center group-data-[orientation=vertical]/tabs:h-fit group-data-[orientation=vertical]/tabs:flex-col",
1506
+ {
1507
+ variants: {
1508
+ variant: {
1509
+ default: "bg-muted",
1510
+ line: "gap-1 bg-transparent"
1511
+ }
1512
+ },
1513
+ defaultVariants: {
1514
+ variant: "default"
1515
+ }
1516
+ }
1517
+ );
1518
+ function TabsList({
1519
+ className,
1520
+ variant = "default",
1521
+ ...props
1522
+ }) {
1523
+ return /* @__PURE__ */ jsx26(
1524
+ TabsPrimitive.List,
1525
+ {
1526
+ "data-slot": "tabs-list",
1527
+ "data-variant": variant,
1528
+ className: cn(tabsListVariants({ variant }), className),
1529
+ ...props
1530
+ }
1531
+ );
1532
+ }
1533
+ function TabsTrigger({
1534
+ className,
1535
+ ...props
1536
+ }) {
1537
+ return /* @__PURE__ */ jsx26(
1538
+ TabsPrimitive.Trigger,
1539
+ {
1540
+ "data-slot": "tabs-trigger",
1541
+ className: cn(
1542
+ "focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:outline-ring text-foreground/60 hover:text-foreground dark:text-muted-foreground dark:hover:text-foreground relative inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 rounded-md border border-transparent px-2 py-1 text-sm font-medium whitespace-nowrap transition-all group-data-[orientation=vertical]/tabs:w-full group-data-[orientation=vertical]/tabs:justify-start focus-visible:ring-[3px] focus-visible:outline-1 disabled:pointer-events-none disabled:opacity-50 group-data-[variant=default]/tabs-list:data-[state=active]:shadow-sm group-data-[variant=line]/tabs-list:data-[state=active]:shadow-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
1543
+ "group-data-[variant=line]/tabs-list:bg-transparent group-data-[variant=line]/tabs-list:data-[state=active]:bg-transparent dark:group-data-[variant=line]/tabs-list:data-[state=active]:border-transparent dark:group-data-[variant=line]/tabs-list:data-[state=active]:bg-transparent",
1544
+ "data-[state=active]:bg-background dark:data-[state=active]:text-foreground dark:data-[state=active]:border-input dark:data-[state=active]:bg-input/30 data-[state=active]:text-foreground",
1545
+ "after:bg-foreground after:absolute after:opacity-0 after:transition-opacity group-data-[orientation=horizontal]/tabs:after:inset-x-0 group-data-[orientation=horizontal]/tabs:after:bottom-[-5px] group-data-[orientation=horizontal]/tabs:after:h-0.5 group-data-[orientation=vertical]/tabs:after:inset-y-0 group-data-[orientation=vertical]/tabs:after:-right-1 group-data-[orientation=vertical]/tabs:after:w-0.5 group-data-[variant=line]/tabs-list:data-[state=active]:after:opacity-100",
1546
+ className
1547
+ ),
1548
+ ...props
1549
+ }
1550
+ );
1551
+ }
1552
+
1553
+ // src/ui/toggle.tsx
1554
+ import { cva as cva5 } from "class-variance-authority";
1555
+ import { Toggle as TogglePrimitive } from "radix-ui";
1556
+ import { jsx as jsx27 } from "react/jsx-runtime";
1557
+ var toggleVariants = cva5(
1558
+ "inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium hover:bg-muted hover:text-muted-foreground disabled:pointer-events-none disabled:opacity-50 data-[state=on]:bg-accent data-[state=on]:text-accent-foreground [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] outline-none transition-[color,box-shadow] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive whitespace-nowrap",
1559
+ {
1560
+ variants: {
1561
+ variant: {
1562
+ default: "bg-transparent",
1563
+ outline: "border border-input bg-transparent shadow-xs hover:bg-accent hover:text-accent-foreground"
1564
+ },
1565
+ size: {
1566
+ default: "h-9 px-2 min-w-9",
1567
+ sm: "h-8 px-1.5 min-w-8",
1568
+ lg: "h-10 px-2.5 min-w-10"
1569
+ }
1570
+ },
1571
+ defaultVariants: {
1572
+ variant: "default",
1573
+ size: "default"
1574
+ }
1575
+ }
1576
+ );
1577
+ function Toggle({
1578
+ className,
1579
+ variant,
1580
+ size,
1581
+ ...props
1582
+ }) {
1583
+ return /* @__PURE__ */ jsx27(
1584
+ TogglePrimitive.Root,
1585
+ {
1586
+ "data-slot": "toggle",
1587
+ className: cn(toggleVariants({ variant, size, className })),
1588
+ ...props
1589
+ }
1590
+ );
1591
+ }
1592
+
1593
+ // src/ui/toggle-group.tsx
1594
+ import * as React3 from "react";
1595
+ import { ToggleGroup as ToggleGroupPrimitive } from "radix-ui";
1596
+ import { jsx as jsx28 } from "react/jsx-runtime";
1597
+ var ToggleGroupContext = React3.createContext({
1598
+ size: "default",
1599
+ variant: "default",
1600
+ spacing: 0
1601
+ });
1602
+ function ToggleGroup({
1603
+ className,
1604
+ variant,
1605
+ size,
1606
+ spacing = 0,
1607
+ children,
1608
+ ...props
1609
+ }) {
1610
+ return /* @__PURE__ */ jsx28(
1611
+ ToggleGroupPrimitive.Root,
1612
+ {
1613
+ "data-slot": "toggle-group",
1614
+ "data-variant": variant,
1615
+ "data-size": size,
1616
+ "data-spacing": spacing,
1617
+ style: { "--gap": spacing },
1618
+ className: cn(
1619
+ "group/toggle-group flex w-fit items-center gap-[--spacing(var(--gap))] rounded-md data-[spacing=default]:data-[variant=outline]:shadow-xs",
1620
+ className
1621
+ ),
1622
+ ...props,
1623
+ children: /* @__PURE__ */ jsx28(ToggleGroupContext.Provider, { value: { variant, size, spacing }, children })
1624
+ }
1625
+ );
1626
+ }
1627
+ function ToggleGroupItem({
1628
+ className,
1629
+ children,
1630
+ variant,
1631
+ size,
1632
+ ...props
1633
+ }) {
1634
+ const context = React3.useContext(ToggleGroupContext);
1635
+ return /* @__PURE__ */ jsx28(
1636
+ ToggleGroupPrimitive.Item,
1637
+ {
1638
+ "data-slot": "toggle-group-item",
1639
+ "data-variant": context.variant || variant,
1640
+ "data-size": context.size || size,
1641
+ "data-spacing": context.spacing,
1642
+ className: cn(
1643
+ toggleVariants({
1644
+ variant: context.variant || variant,
1645
+ size: context.size || size
1646
+ }),
1647
+ "w-auto min-w-0 shrink-0 px-3 focus:z-10 focus-visible:z-10",
1648
+ "data-[spacing=0]:rounded-none data-[spacing=0]:shadow-none data-[spacing=0]:first:rounded-l-md data-[spacing=0]:last:rounded-r-md data-[spacing=0]:data-[variant=outline]:border-l-0 data-[spacing=0]:data-[variant=outline]:first:border-l",
1649
+ className
1650
+ ),
1651
+ ...props,
1652
+ children
1653
+ }
1654
+ );
1655
+ }
1656
+
1657
+ // src/ui/tooltip.tsx
1658
+ import { Tooltip as TooltipPrimitive } from "radix-ui";
1659
+ import { jsx as jsx29, jsxs as jsxs9 } from "react/jsx-runtime";
1660
+ function TooltipProvider({
1661
+ delayDuration = 0,
1662
+ ...props
1663
+ }) {
1664
+ return /* @__PURE__ */ jsx29(
1665
+ TooltipPrimitive.Provider,
1666
+ {
1667
+ "data-slot": "tooltip-provider",
1668
+ delayDuration,
1669
+ ...props
1670
+ }
1671
+ );
1672
+ }
1673
+ function Tooltip({
1674
+ ...props
1675
+ }) {
1676
+ return /* @__PURE__ */ jsx29(TooltipPrimitive.Root, { "data-slot": "tooltip", ...props });
1677
+ }
1678
+ function TooltipTrigger({
1679
+ ...props
1680
+ }) {
1681
+ return /* @__PURE__ */ jsx29(TooltipPrimitive.Trigger, { "data-slot": "tooltip-trigger", ...props });
1682
+ }
1683
+ function TooltipContent({
1684
+ className,
1685
+ sideOffset = 0,
1686
+ children,
1687
+ ...props
1688
+ }) {
1689
+ return /* @__PURE__ */ jsx29(TooltipPrimitive.Portal, { children: /* @__PURE__ */ jsxs9(
1690
+ TooltipPrimitive.Content,
1691
+ {
1692
+ "data-slot": "tooltip-content",
1693
+ sideOffset,
1694
+ className: cn(
1695
+ "bg-foreground text-background animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-fit origin-(--radix-tooltip-content-transform-origin) rounded-md px-3 py-1.5 text-xs text-balance",
1696
+ className
1697
+ ),
1698
+ ...props,
1699
+ children: [
1700
+ children,
1701
+ /* @__PURE__ */ jsx29(TooltipPrimitive.Arrow, { className: "bg-foreground fill-foreground z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px]" })
1702
+ ]
1703
+ }
1704
+ ) });
1705
+ }
1706
+
1707
+ // src/components.tsx
1708
+ import { jsx as jsx30, jsxs as jsxs10 } from "react/jsx-runtime";
1709
+ function getPaginationRange(current, total) {
1710
+ if (total <= 7) {
1711
+ return Array.from({ length: total }, (_, i) => i + 1);
1712
+ }
1713
+ const pages = [];
1714
+ pages.push(1);
1715
+ if (current > 3) {
1716
+ pages.push("ellipsis");
1717
+ }
1718
+ const start = Math.max(2, current - 1);
1719
+ const end = Math.min(total - 1, current + 1);
1720
+ for (let i = start; i <= end; i++) {
1721
+ pages.push(i);
1722
+ }
1723
+ if (current < total - 2) {
1724
+ pages.push("ellipsis");
1725
+ }
1726
+ pages.push(total);
1727
+ return pages;
1728
+ }
1729
+ var shadcnComponents = {
1730
+ // ── Layout ────────────────────────────────────────────────────────────
1731
+ Card: ({ props, children }) => {
1732
+ const maxWidthClass = props.maxWidth === "sm" ? "max-w-xs sm:min-w-[280px]" : props.maxWidth === "md" ? "max-w-sm sm:min-w-[320px]" : props.maxWidth === "lg" ? "max-w-md sm:min-w-[360px]" : "w-full";
1733
+ const centeredClass = props.centered ? "mx-auto" : "";
1734
+ return /* @__PURE__ */ jsxs10(Card, { className: cn(maxWidthClass, centeredClass), children: [
1735
+ (props.title || props.description) && /* @__PURE__ */ jsxs10(CardHeader, { children: [
1736
+ props.title && /* @__PURE__ */ jsx30(CardTitle, { children: props.title }),
1737
+ props.description && /* @__PURE__ */ jsx30(CardDescription, { children: props.description })
1738
+ ] }),
1739
+ /* @__PURE__ */ jsx30(CardContent, { className: "flex flex-col gap-3", children })
1740
+ ] });
1741
+ },
1742
+ Stack: ({ props, children }) => {
1743
+ const isHorizontal = props.direction === "horizontal";
1744
+ const gapMap = {
1745
+ none: "gap-0",
1746
+ sm: "gap-2",
1747
+ md: "gap-3",
1748
+ lg: "gap-4"
1749
+ };
1750
+ const alignMap = {
1751
+ start: "items-start",
1752
+ center: "items-center",
1753
+ end: "items-end",
1754
+ stretch: "items-stretch"
1755
+ };
1756
+ const justifyMap = {
1757
+ start: "",
1758
+ center: "justify-center",
1759
+ end: "justify-end",
1760
+ between: "justify-between",
1761
+ around: "justify-around"
1762
+ };
1763
+ const gapClass = gapMap[props.gap ?? "md"] ?? "gap-3";
1764
+ const alignClass = alignMap[props.align ?? "start"] ?? "items-start";
1765
+ const justifyClass = justifyMap[props.justify ?? ""] ?? "";
1766
+ return /* @__PURE__ */ jsx30(
1767
+ "div",
1768
+ {
1769
+ className: `flex ${isHorizontal ? "flex-row flex-wrap" : "flex-col"} ${gapClass} ${alignClass} ${justifyClass}`,
1770
+ children
1771
+ }
1772
+ );
1773
+ },
1774
+ Grid: ({ props, children }) => {
1775
+ const colsMap = {
1776
+ 1: "grid-cols-1",
1777
+ 2: "grid-cols-2",
1778
+ 3: "grid-cols-3",
1779
+ 4: "grid-cols-4",
1780
+ 5: "grid-cols-5",
1781
+ 6: "grid-cols-6"
1782
+ };
1783
+ const gridGapMap = {
1784
+ sm: "gap-2",
1785
+ md: "gap-3",
1786
+ lg: "gap-4"
1787
+ };
1788
+ const n = Math.max(1, Math.min(6, props.columns ?? 1));
1789
+ const cols = colsMap[n] ?? "grid-cols-1";
1790
+ const gridGap = gridGapMap[props.gap ?? "md"] ?? "gap-3";
1791
+ return /* @__PURE__ */ jsx30("div", { className: `grid ${cols} ${gridGap}`, children });
1792
+ },
1793
+ Separator: ({ props }) => {
1794
+ return /* @__PURE__ */ jsx30(
1795
+ Separator,
1796
+ {
1797
+ orientation: props.orientation ?? "horizontal",
1798
+ className: props.orientation === "vertical" ? "h-full mx-2" : "my-3"
1799
+ }
1800
+ );
1801
+ },
1802
+ Tabs: ({
1803
+ props,
1804
+ children,
1805
+ bindings,
1806
+ emit
1807
+ }) => {
1808
+ const tabs = props.tabs ?? [];
1809
+ const [boundValue, setBoundValue] = useBoundProp(
1810
+ props.value,
1811
+ bindings?.value
1812
+ );
1813
+ const [localValue, setLocalValue] = useState2(
1814
+ props.defaultValue ?? tabs[0]?.value ?? ""
1815
+ );
1816
+ const isBound = !!bindings?.value;
1817
+ const value = isBound ? boundValue ?? tabs[0]?.value ?? "" : localValue;
1818
+ const setValue = isBound ? setBoundValue : setLocalValue;
1819
+ return /* @__PURE__ */ jsxs10(
1820
+ Tabs,
1821
+ {
1822
+ value,
1823
+ onValueChange: (v) => {
1824
+ setValue(v);
1825
+ emit("change");
1826
+ },
1827
+ children: [
1828
+ /* @__PURE__ */ jsx30(TabsList, { children: tabs.map((tab) => /* @__PURE__ */ jsx30(TabsTrigger, { value: tab.value, children: tab.label }, tab.value)) }),
1829
+ children
1830
+ ]
1831
+ }
1832
+ );
1833
+ },
1834
+ Accordion: ({ props }) => {
1835
+ const items = props.items ?? [];
1836
+ const isMultiple = props.type === "multiple";
1837
+ const itemElements = items.map((item, i) => /* @__PURE__ */ jsxs10(AccordionItem, { value: `item-${i}`, children: [
1838
+ /* @__PURE__ */ jsx30(AccordionTrigger, { children: item.title }),
1839
+ /* @__PURE__ */ jsx30(AccordionContent, { children: item.content })
1840
+ ] }, i));
1841
+ if (isMultiple) {
1842
+ return /* @__PURE__ */ jsx30(Accordion, { type: "multiple", className: "w-full", children: itemElements });
1843
+ }
1844
+ return /* @__PURE__ */ jsx30(Accordion, { type: "single", collapsible: true, className: "w-full", children: itemElements });
1845
+ },
1846
+ Collapsible: ({
1847
+ props,
1848
+ children
1849
+ }) => {
1850
+ const [open, setOpen] = useState2(props.defaultOpen ?? false);
1851
+ return /* @__PURE__ */ jsxs10(Collapsible, { open, onOpenChange: setOpen, className: "w-full", children: [
1852
+ /* @__PURE__ */ jsx30(CollapsibleTrigger, { asChild: true, children: /* @__PURE__ */ jsxs10("button", { className: "flex w-full items-center justify-between rounded-md border border-border px-4 py-2 text-sm font-medium hover:bg-muted transition-colors", children: [
1853
+ props.title,
1854
+ /* @__PURE__ */ jsx30(
1855
+ "svg",
1856
+ {
1857
+ className: `h-4 w-4 transition-transform ${open ? "rotate-180" : ""}`,
1858
+ fill: "none",
1859
+ viewBox: "0 0 24 24",
1860
+ stroke: "currentColor",
1861
+ strokeWidth: 2,
1862
+ children: /* @__PURE__ */ jsx30(
1863
+ "path",
1864
+ {
1865
+ strokeLinecap: "round",
1866
+ strokeLinejoin: "round",
1867
+ d: "M19 9l-7 7-7-7"
1868
+ }
1869
+ )
1870
+ }
1871
+ )
1872
+ ] }) }),
1873
+ /* @__PURE__ */ jsx30(CollapsibleContent, { className: "pt-2", children })
1874
+ ] });
1875
+ },
1876
+ Dialog: ({ props, children }) => {
1877
+ const [open, setOpen] = useStateBinding(props.openPath ?? "");
1878
+ return /* @__PURE__ */ jsx30(Dialog, { open: open ?? false, onOpenChange: (v) => setOpen(v), children: /* @__PURE__ */ jsxs10(DialogContent, { children: [
1879
+ /* @__PURE__ */ jsxs10(DialogHeader, { children: [
1880
+ /* @__PURE__ */ jsx30(DialogTitle, { children: props.title }),
1881
+ props.description && /* @__PURE__ */ jsx30(DialogDescription, { children: props.description })
1882
+ ] }),
1883
+ children
1884
+ ] }) });
1885
+ },
1886
+ Drawer: ({ props, children }) => {
1887
+ const [open, setOpen] = useStateBinding(props.openPath ?? "");
1888
+ return /* @__PURE__ */ jsx30(Drawer, { open: open ?? false, onOpenChange: (v) => setOpen(v), children: /* @__PURE__ */ jsxs10(DrawerContent, { children: [
1889
+ /* @__PURE__ */ jsxs10(DrawerHeader, { children: [
1890
+ /* @__PURE__ */ jsx30(DrawerTitle, { children: props.title }),
1891
+ props.description && /* @__PURE__ */ jsx30(DrawerDescription, { children: props.description })
1892
+ ] }),
1893
+ /* @__PURE__ */ jsx30("div", { className: "p-4", children })
1894
+ ] }) });
1895
+ },
1896
+ Carousel: ({ props }) => {
1897
+ const items = props.items ?? [];
1898
+ return /* @__PURE__ */ jsxs10(Carousel, { className: "w-full", children: [
1899
+ /* @__PURE__ */ jsx30(CarouselContent, { children: items.map((item, i) => /* @__PURE__ */ jsx30(
1900
+ CarouselItem,
1901
+ {
1902
+ className: "basis-3/4 md:basis-1/2 lg:basis-1/3",
1903
+ children: /* @__PURE__ */ jsxs10("div", { className: "border border-border rounded-lg p-4 bg-card h-full", children: [
1904
+ item.title && /* @__PURE__ */ jsx30("h4", { className: "font-semibold text-sm mb-1", children: item.title }),
1905
+ item.description && /* @__PURE__ */ jsx30("p", { className: "text-sm text-muted-foreground", children: item.description })
1906
+ ] })
1907
+ },
1908
+ i
1909
+ )) }),
1910
+ /* @__PURE__ */ jsx30(CarouselPrevious, {}),
1911
+ /* @__PURE__ */ jsx30(CarouselNext, {})
1912
+ ] });
1913
+ },
1914
+ // ── Data Display ──────────────────────────────────────────────────────
1915
+ Table: ({ props }) => {
1916
+ const columns = props.columns ?? [];
1917
+ const rows = (props.rows ?? []).map((row) => row.map(String));
1918
+ return /* @__PURE__ */ jsx30("div", { className: "rounded-md border border-border overflow-hidden", children: /* @__PURE__ */ jsxs10(Table, { children: [
1919
+ props.caption && /* @__PURE__ */ jsx30(TableCaption, { children: props.caption }),
1920
+ /* @__PURE__ */ jsx30(TableHeader, { children: /* @__PURE__ */ jsx30(TableRow, { children: columns.map((col) => /* @__PURE__ */ jsx30(TableHead, { children: col }, col)) }) }),
1921
+ /* @__PURE__ */ jsx30(TableBody, { children: rows.map((row, i) => /* @__PURE__ */ jsx30(TableRow, { children: row.map((cell, j) => /* @__PURE__ */ jsx30(TableCell, { children: cell }, j)) }, i)) })
1922
+ ] }) });
1923
+ },
1924
+ Heading: ({ props }) => {
1925
+ const level = props.level ?? "h2";
1926
+ const headingClass = level === "h1" ? "text-2xl font-bold" : level === "h3" ? "text-base font-semibold" : level === "h4" ? "text-sm font-semibold" : "text-lg font-semibold";
1927
+ if (level === "h1")
1928
+ return /* @__PURE__ */ jsx30("h1", { className: `${headingClass} text-left`, children: props.text });
1929
+ if (level === "h3")
1930
+ return /* @__PURE__ */ jsx30("h3", { className: `${headingClass} text-left`, children: props.text });
1931
+ if (level === "h4")
1932
+ return /* @__PURE__ */ jsx30("h4", { className: `${headingClass} text-left`, children: props.text });
1933
+ return /* @__PURE__ */ jsx30("h2", { className: `${headingClass} text-left`, children: props.text });
1934
+ },
1935
+ Text: ({ props }) => {
1936
+ const textClass = props.variant === "caption" ? "text-xs" : props.variant === "muted" ? "text-sm text-muted-foreground" : props.variant === "lead" ? "text-xl text-muted-foreground" : props.variant === "code" ? "font-mono text-sm bg-muted px-1.5 py-0.5 rounded" : "text-sm";
1937
+ if (props.variant === "code") {
1938
+ return /* @__PURE__ */ jsx30("code", { className: `${textClass} text-left`, children: props.text });
1939
+ }
1940
+ return /* @__PURE__ */ jsx30("p", { className: `${textClass} text-left`, children: props.text });
1941
+ },
1942
+ Image: ({ props }) => {
1943
+ if (props.src) {
1944
+ return /* @__PURE__ */ jsx30(
1945
+ "img",
1946
+ {
1947
+ src: props.src,
1948
+ alt: props.alt ?? "",
1949
+ width: props.width ?? void 0,
1950
+ height: props.height ?? void 0,
1951
+ className: "rounded max-w-full"
1952
+ }
1953
+ );
1954
+ }
1955
+ return /* @__PURE__ */ jsx30(
1956
+ "div",
1957
+ {
1958
+ className: "bg-muted border border-border rounded flex items-center justify-center text-xs text-muted-foreground",
1959
+ style: { width: props.width ?? 80, height: props.height ?? 60 },
1960
+ children: props.alt || "img"
1961
+ }
1962
+ );
1963
+ },
1964
+ Avatar: ({ props }) => {
1965
+ const name = props.name || "?";
1966
+ const initials = name.split(" ").map((n) => n[0]).join("").slice(0, 2).toUpperCase();
1967
+ const sizeClass = props.size === "lg" ? "h-12 w-12" : props.size === "sm" ? "h-8 w-8" : "h-10 w-10";
1968
+ return /* @__PURE__ */ jsxs10(Avatar, { className: sizeClass, children: [
1969
+ props.src && /* @__PURE__ */ jsx30(AvatarImage, { src: props.src, alt: name }),
1970
+ /* @__PURE__ */ jsx30(AvatarFallback, { children: initials })
1971
+ ] });
1972
+ },
1973
+ Badge: ({ props }) => {
1974
+ return /* @__PURE__ */ jsx30(Badge, { variant: props.variant ?? "default", children: props.text });
1975
+ },
1976
+ Alert: ({ props }) => {
1977
+ const variant = props.type === "error" ? "destructive" : "default";
1978
+ const customClass = props.type === "success" ? "border-green-200 bg-green-50 text-green-900 dark:border-green-800 dark:bg-green-950 dark:text-green-100" : props.type === "warning" ? "border-yellow-200 bg-yellow-50 text-yellow-900 dark:border-yellow-800 dark:bg-yellow-950 dark:text-yellow-100" : props.type === "info" ? "border-blue-200 bg-blue-50 text-blue-900 dark:border-blue-800 dark:bg-blue-950 dark:text-blue-100" : "";
1979
+ return /* @__PURE__ */ jsxs10(Alert, { variant, className: customClass, children: [
1980
+ /* @__PURE__ */ jsx30(AlertTitle, { children: props.title }),
1981
+ props.message && /* @__PURE__ */ jsx30(AlertDescription, { children: props.message })
1982
+ ] });
1983
+ },
1984
+ Progress: ({ props }) => {
1985
+ const value = Math.min(100, Math.max(0, props.value || 0));
1986
+ return /* @__PURE__ */ jsxs10("div", { className: "space-y-2", children: [
1987
+ props.label && /* @__PURE__ */ jsx30(Label, { className: "text-sm text-muted-foreground", children: props.label }),
1988
+ /* @__PURE__ */ jsx30(Progress, { value })
1989
+ ] });
1990
+ },
1991
+ Skeleton: ({ props }) => {
1992
+ return /* @__PURE__ */ jsx30(
1993
+ Skeleton,
1994
+ {
1995
+ className: props.rounded ? "rounded-full" : "rounded-md",
1996
+ style: {
1997
+ width: props.width ?? "100%",
1998
+ height: props.height ?? "1.25rem"
1999
+ }
2000
+ }
2001
+ );
2002
+ },
2003
+ Spinner: ({ props }) => {
2004
+ const sizeClass = props.size === "lg" ? "h-8 w-8" : props.size === "sm" ? "h-4 w-4" : "h-6 w-6";
2005
+ return /* @__PURE__ */ jsxs10("div", { className: "flex items-center gap-2", children: [
2006
+ /* @__PURE__ */ jsxs10(
2007
+ "svg",
2008
+ {
2009
+ className: `${sizeClass} animate-spin text-muted-foreground`,
2010
+ viewBox: "0 0 24 24",
2011
+ fill: "none",
2012
+ children: [
2013
+ /* @__PURE__ */ jsx30(
2014
+ "circle",
2015
+ {
2016
+ className: "opacity-25",
2017
+ cx: "12",
2018
+ cy: "12",
2019
+ r: "10",
2020
+ stroke: "currentColor",
2021
+ strokeWidth: "4"
2022
+ }
2023
+ ),
2024
+ /* @__PURE__ */ jsx30(
2025
+ "path",
2026
+ {
2027
+ className: "opacity-75",
2028
+ fill: "currentColor",
2029
+ d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"
2030
+ }
2031
+ )
2032
+ ]
2033
+ }
2034
+ ),
2035
+ props.label && /* @__PURE__ */ jsx30("span", { className: "text-sm text-muted-foreground", children: props.label })
2036
+ ] });
2037
+ },
2038
+ Tooltip: ({ props }) => {
2039
+ return /* @__PURE__ */ jsx30(TooltipProvider, { children: /* @__PURE__ */ jsxs10(Tooltip, { children: [
2040
+ /* @__PURE__ */ jsx30(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx30("span", { className: "text-sm underline decoration-dotted cursor-help", children: props.text }) }),
2041
+ /* @__PURE__ */ jsx30(TooltipContent, { children: /* @__PURE__ */ jsx30("p", { children: props.content }) })
2042
+ ] }) });
2043
+ },
2044
+ Popover: ({ props }) => {
2045
+ return /* @__PURE__ */ jsxs10(Popover, { children: [
2046
+ /* @__PURE__ */ jsx30(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx30(Button, { variant: "outline", className: "text-sm", children: props.trigger }) }),
2047
+ /* @__PURE__ */ jsx30(PopoverContent, { className: "w-64", children: /* @__PURE__ */ jsx30("p", { className: "text-sm", children: props.content }) })
2048
+ ] });
2049
+ },
2050
+ // ── Form Inputs ───────────────────────────────────────────────────────
2051
+ Input: ({
2052
+ props,
2053
+ bindings,
2054
+ emit
2055
+ }) => {
2056
+ const [boundValue, setBoundValue] = useBoundProp(
2057
+ props.value,
2058
+ bindings?.value
2059
+ );
2060
+ const [localValue, setLocalValue] = useState2("");
2061
+ const isBound = !!bindings?.value;
2062
+ const value = isBound ? boundValue ?? "" : localValue;
2063
+ const setValue = isBound ? setBoundValue : setLocalValue;
2064
+ const hasValidation = !!(bindings?.value && props.checks?.length);
2065
+ const { errors, validate } = useFieldValidation(
2066
+ bindings?.value ?? "",
2067
+ hasValidation ? { checks: props.checks ?? [] } : void 0
2068
+ );
2069
+ return /* @__PURE__ */ jsxs10("div", { className: "space-y-2", children: [
2070
+ props.label && /* @__PURE__ */ jsx30(Label, { htmlFor: props.name ?? void 0, children: props.label }),
2071
+ /* @__PURE__ */ jsx30(
2072
+ Input,
2073
+ {
2074
+ id: props.name ?? void 0,
2075
+ name: props.name ?? void 0,
2076
+ type: props.type ?? "text",
2077
+ placeholder: props.placeholder ?? "",
2078
+ value,
2079
+ onChange: (e) => setValue(e.target.value),
2080
+ onKeyDown: (e) => {
2081
+ if (e.key === "Enter") emit("submit");
2082
+ },
2083
+ onFocus: () => emit("focus"),
2084
+ onBlur: () => {
2085
+ if (hasValidation) validate();
2086
+ emit("blur");
2087
+ }
2088
+ }
2089
+ ),
2090
+ errors.length > 0 && /* @__PURE__ */ jsx30("p", { className: "text-sm text-destructive", children: errors[0] })
2091
+ ] });
2092
+ },
2093
+ Textarea: ({
2094
+ props,
2095
+ bindings
2096
+ }) => {
2097
+ const [boundValue, setBoundValue] = useBoundProp(
2098
+ props.value,
2099
+ bindings?.value
2100
+ );
2101
+ const [localValue, setLocalValue] = useState2("");
2102
+ const isBound = !!bindings?.value;
2103
+ const value = isBound ? boundValue ?? "" : localValue;
2104
+ const setValue = isBound ? setBoundValue : setLocalValue;
2105
+ const hasValidation = !!(bindings?.value && props.checks?.length);
2106
+ const { errors, validate } = useFieldValidation(
2107
+ bindings?.value ?? "",
2108
+ hasValidation ? { checks: props.checks ?? [] } : void 0
2109
+ );
2110
+ return /* @__PURE__ */ jsxs10("div", { className: "space-y-2", children: [
2111
+ props.label && /* @__PURE__ */ jsx30(Label, { htmlFor: props.name ?? void 0, children: props.label }),
2112
+ /* @__PURE__ */ jsx30(
2113
+ Textarea,
2114
+ {
2115
+ id: props.name ?? void 0,
2116
+ name: props.name ?? void 0,
2117
+ placeholder: props.placeholder ?? "",
2118
+ rows: props.rows ?? 3,
2119
+ value,
2120
+ onChange: (e) => setValue(e.target.value),
2121
+ onBlur: () => {
2122
+ if (hasValidation) validate();
2123
+ }
2124
+ }
2125
+ ),
2126
+ errors.length > 0 && /* @__PURE__ */ jsx30("p", { className: "text-sm text-destructive", children: errors[0] })
2127
+ ] });
2128
+ },
2129
+ Select: ({
2130
+ props,
2131
+ bindings,
2132
+ emit
2133
+ }) => {
2134
+ const [boundValue, setBoundValue] = useBoundProp(
2135
+ props.value,
2136
+ bindings?.value
2137
+ );
2138
+ const [localValue, setLocalValue] = useState2("");
2139
+ const isBound = !!bindings?.value;
2140
+ const value = isBound ? boundValue ?? "" : localValue;
2141
+ const setValue = isBound ? setBoundValue : setLocalValue;
2142
+ const rawOptions = props.options ?? [];
2143
+ const options = rawOptions.map(
2144
+ (opt) => typeof opt === "string" ? opt : String(opt ?? "")
2145
+ );
2146
+ const hasValidation = !!(bindings?.value && props.checks?.length);
2147
+ const { errors, validate } = useFieldValidation(
2148
+ bindings?.value ?? "",
2149
+ hasValidation ? { checks: props.checks ?? [] } : void 0
2150
+ );
2151
+ return /* @__PURE__ */ jsxs10("div", { className: "space-y-2", children: [
2152
+ /* @__PURE__ */ jsx30(Label, { children: props.label }),
2153
+ /* @__PURE__ */ jsxs10(
2154
+ Select,
2155
+ {
2156
+ value,
2157
+ onValueChange: (v) => {
2158
+ setValue(v);
2159
+ if (hasValidation) validate();
2160
+ emit("change");
2161
+ },
2162
+ children: [
2163
+ /* @__PURE__ */ jsx30(SelectTrigger, { className: "w-full", children: /* @__PURE__ */ jsx30(SelectValue, { placeholder: props.placeholder ?? "Select..." }) }),
2164
+ /* @__PURE__ */ jsx30(SelectContent, { children: options.map((opt, idx) => /* @__PURE__ */ jsx30(SelectItem, { value: opt || `option-${idx}`, children: opt }, `${idx}-${opt}`)) })
2165
+ ]
2166
+ }
2167
+ ),
2168
+ errors.length > 0 && /* @__PURE__ */ jsx30("p", { className: "text-sm text-destructive", children: errors[0] })
2169
+ ] });
2170
+ },
2171
+ Checkbox: ({
2172
+ props,
2173
+ bindings,
2174
+ emit
2175
+ }) => {
2176
+ const [boundChecked, setBoundChecked] = useBoundProp(
2177
+ props.checked,
2178
+ bindings?.checked
2179
+ );
2180
+ const [localChecked, setLocalChecked] = useState2(!!props.checked);
2181
+ const isBound = !!bindings?.checked;
2182
+ const checked = isBound ? boundChecked ?? false : localChecked;
2183
+ const setChecked = isBound ? setBoundChecked : setLocalChecked;
2184
+ return /* @__PURE__ */ jsxs10("div", { className: "flex items-center space-x-2", children: [
2185
+ /* @__PURE__ */ jsx30(
2186
+ Checkbox,
2187
+ {
2188
+ id: props.name ?? void 0,
2189
+ checked,
2190
+ onCheckedChange: (c) => {
2191
+ setChecked(c === true);
2192
+ emit("change");
2193
+ }
2194
+ }
2195
+ ),
2196
+ /* @__PURE__ */ jsx30(Label, { htmlFor: props.name ?? void 0, className: "cursor-pointer", children: props.label })
2197
+ ] });
2198
+ },
2199
+ Radio: ({
2200
+ props,
2201
+ bindings,
2202
+ emit
2203
+ }) => {
2204
+ const rawOptions = props.options ?? [];
2205
+ const options = rawOptions.map(
2206
+ (opt) => typeof opt === "string" ? opt : String(opt ?? "")
2207
+ );
2208
+ const [boundValue, setBoundValue] = useBoundProp(
2209
+ props.value,
2210
+ bindings?.value
2211
+ );
2212
+ const [localValue, setLocalValue] = useState2(options[0] ?? "");
2213
+ const isBound = !!bindings?.value;
2214
+ const value = isBound ? boundValue ?? "" : localValue;
2215
+ const setValue = isBound ? setBoundValue : setLocalValue;
2216
+ return /* @__PURE__ */ jsxs10("div", { className: "space-y-2", children: [
2217
+ props.label && /* @__PURE__ */ jsx30(Label, { children: props.label }),
2218
+ /* @__PURE__ */ jsx30(
2219
+ RadioGroup,
2220
+ {
2221
+ value,
2222
+ onValueChange: (v) => {
2223
+ setValue(v);
2224
+ emit("change");
2225
+ },
2226
+ children: options.map((opt, idx) => /* @__PURE__ */ jsxs10("div", { className: "flex items-center space-x-2", children: [
2227
+ /* @__PURE__ */ jsx30(
2228
+ RadioGroupItem,
2229
+ {
2230
+ value: opt || `option-${idx}`,
2231
+ id: `${props.name}-${idx}-${opt}`
2232
+ }
2233
+ ),
2234
+ /* @__PURE__ */ jsx30(
2235
+ Label,
2236
+ {
2237
+ htmlFor: `${props.name}-${idx}-${opt}`,
2238
+ className: "cursor-pointer",
2239
+ children: opt
2240
+ }
2241
+ )
2242
+ ] }, `${idx}-${opt}`))
2243
+ }
2244
+ )
2245
+ ] });
2246
+ },
2247
+ Switch: ({
2248
+ props,
2249
+ bindings,
2250
+ emit
2251
+ }) => {
2252
+ const [boundChecked, setBoundChecked] = useBoundProp(
2253
+ props.checked,
2254
+ bindings?.checked
2255
+ );
2256
+ const [localChecked, setLocalChecked] = useState2(!!props.checked);
2257
+ const isBound = !!bindings?.checked;
2258
+ const checked = isBound ? boundChecked ?? false : localChecked;
2259
+ const setChecked = isBound ? setBoundChecked : setLocalChecked;
2260
+ return /* @__PURE__ */ jsxs10("div", { className: "flex items-center justify-between space-x-2", children: [
2261
+ /* @__PURE__ */ jsx30(Label, { htmlFor: props.name ?? void 0, className: "cursor-pointer", children: props.label }),
2262
+ /* @__PURE__ */ jsx30(
2263
+ Switch,
2264
+ {
2265
+ id: props.name ?? void 0,
2266
+ checked,
2267
+ onCheckedChange: (c) => {
2268
+ setChecked(c);
2269
+ emit("change");
2270
+ }
2271
+ }
2272
+ )
2273
+ ] });
2274
+ },
2275
+ Slider: ({
2276
+ props,
2277
+ bindings,
2278
+ emit
2279
+ }) => {
2280
+ const [boundValue, setBoundValue] = useBoundProp(
2281
+ props.value,
2282
+ bindings?.value
2283
+ );
2284
+ const [localValue, setLocalValue] = useState2(props.min ?? 0);
2285
+ const isBound = !!bindings?.value;
2286
+ const value = isBound ? boundValue ?? props.min ?? 0 : localValue;
2287
+ const setValue = isBound ? setBoundValue : setLocalValue;
2288
+ return /* @__PURE__ */ jsxs10("div", { className: "space-y-2", children: [
2289
+ props.label && /* @__PURE__ */ jsxs10("div", { className: "flex justify-between", children: [
2290
+ /* @__PURE__ */ jsx30(Label, { className: "text-sm", children: props.label }),
2291
+ /* @__PURE__ */ jsx30("span", { className: "text-sm text-muted-foreground", children: value })
2292
+ ] }),
2293
+ /* @__PURE__ */ jsx30(
2294
+ Slider,
2295
+ {
2296
+ value: [value],
2297
+ min: props.min ?? 0,
2298
+ max: props.max ?? 100,
2299
+ step: props.step ?? 1,
2300
+ onValueChange: (v) => {
2301
+ setValue(v[0] ?? 0);
2302
+ emit("change");
2303
+ }
2304
+ }
2305
+ )
2306
+ ] });
2307
+ },
2308
+ // ── Actions ───────────────────────────────────────────────────────────
2309
+ Button: ({ props, emit }) => {
2310
+ const variant = props.variant === "danger" ? "destructive" : props.variant === "secondary" ? "secondary" : "default";
2311
+ return /* @__PURE__ */ jsx30(
2312
+ Button,
2313
+ {
2314
+ variant,
2315
+ disabled: props.disabled ?? false,
2316
+ onClick: () => emit("press"),
2317
+ children: props.label
2318
+ }
2319
+ );
2320
+ },
2321
+ Link: ({ props, on }) => {
2322
+ return /* @__PURE__ */ jsx30(
2323
+ "a",
2324
+ {
2325
+ href: props.href ?? "#",
2326
+ className: "text-primary underline-offset-4 hover:underline text-sm font-medium",
2327
+ onClick: (e) => {
2328
+ const press = on("press");
2329
+ if (press.shouldPreventDefault) e.preventDefault();
2330
+ press.emit();
2331
+ },
2332
+ children: props.label
2333
+ }
2334
+ );
2335
+ },
2336
+ DropdownMenu: ({
2337
+ props,
2338
+ bindings,
2339
+ emit
2340
+ }) => {
2341
+ const items = props.items ?? [];
2342
+ const [, setBoundValue] = useBoundProp(
2343
+ props.value,
2344
+ bindings?.value
2345
+ );
2346
+ return /* @__PURE__ */ jsxs10(DropdownMenu, { children: [
2347
+ /* @__PURE__ */ jsx30(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx30(Button, { variant: "outline", children: props.label }) }),
2348
+ /* @__PURE__ */ jsx30(DropdownMenuContent, { children: items.map((item) => /* @__PURE__ */ jsx30(
2349
+ DropdownMenuItem,
2350
+ {
2351
+ onClick: () => {
2352
+ setBoundValue(item.value);
2353
+ emit("select");
2354
+ },
2355
+ children: item.label
2356
+ },
2357
+ item.value
2358
+ )) })
2359
+ ] });
2360
+ },
2361
+ Toggle: ({
2362
+ props,
2363
+ bindings,
2364
+ emit
2365
+ }) => {
2366
+ const [boundPressed, setBoundPressed] = useBoundProp(
2367
+ props.pressed,
2368
+ bindings?.pressed
2369
+ );
2370
+ const [localPressed, setLocalPressed] = useState2(props.pressed ?? false);
2371
+ const isBound = !!bindings?.pressed;
2372
+ const pressed = isBound ? boundPressed ?? false : localPressed;
2373
+ const setPressed = isBound ? setBoundPressed : setLocalPressed;
2374
+ return /* @__PURE__ */ jsx30(
2375
+ Toggle,
2376
+ {
2377
+ variant: props.variant ?? "default",
2378
+ pressed,
2379
+ onPressedChange: (v) => {
2380
+ setPressed(v);
2381
+ emit("change");
2382
+ },
2383
+ children: props.label
2384
+ }
2385
+ );
2386
+ },
2387
+ ToggleGroup: ({
2388
+ props,
2389
+ bindings,
2390
+ emit
2391
+ }) => {
2392
+ const type = props.type ?? "single";
2393
+ const items = props.items ?? [];
2394
+ const [boundValue, setBoundValue] = useBoundProp(
2395
+ props.value,
2396
+ bindings?.value
2397
+ );
2398
+ const [localValue, setLocalValue] = useState2(items[0]?.value ?? "");
2399
+ const isBound = !!bindings?.value;
2400
+ const value = isBound ? boundValue ?? "" : localValue;
2401
+ const setValue = isBound ? setBoundValue : setLocalValue;
2402
+ if (type === "multiple") {
2403
+ const selected = value ? value.split(",").filter(Boolean) : [];
2404
+ return /* @__PURE__ */ jsx30(
2405
+ ToggleGroup,
2406
+ {
2407
+ type: "multiple",
2408
+ value: selected,
2409
+ onValueChange: (v) => {
2410
+ setValue(v.join(","));
2411
+ emit("change");
2412
+ },
2413
+ children: items.map((item) => /* @__PURE__ */ jsx30(ToggleGroupItem, { value: item.value, children: item.label }, item.value))
2414
+ }
2415
+ );
2416
+ }
2417
+ return /* @__PURE__ */ jsx30(
2418
+ ToggleGroup,
2419
+ {
2420
+ type: "single",
2421
+ value,
2422
+ onValueChange: (v) => {
2423
+ if (v) {
2424
+ setValue(v);
2425
+ emit("change");
2426
+ }
2427
+ },
2428
+ children: items.map((item) => /* @__PURE__ */ jsx30(ToggleGroupItem, { value: item.value, children: item.label }, item.value))
2429
+ }
2430
+ );
2431
+ },
2432
+ ButtonGroup: ({
2433
+ props,
2434
+ bindings,
2435
+ emit
2436
+ }) => {
2437
+ const buttons = props.buttons ?? [];
2438
+ const [boundSelected, setBoundSelected] = useBoundProp(
2439
+ props.selected,
2440
+ bindings?.selected
2441
+ );
2442
+ const [localValue, setLocalValue] = useState2(buttons[0]?.value ?? "");
2443
+ const isBound = !!bindings?.selected;
2444
+ const value = isBound ? boundSelected ?? "" : localValue;
2445
+ const setValue = isBound ? setBoundSelected : setLocalValue;
2446
+ return /* @__PURE__ */ jsx30("div", { className: "inline-flex rounded-md border border-border", children: buttons.map((btn, i) => /* @__PURE__ */ jsx30(
2447
+ "button",
2448
+ {
2449
+ className: `px-3 py-1.5 text-sm transition-colors ${value === btn.value ? "bg-primary text-primary-foreground" : "bg-background hover:bg-muted"} ${i > 0 ? "border-l border-border" : ""} ${i === 0 ? "rounded-l-md" : ""} ${i === buttons.length - 1 ? "rounded-r-md" : ""}`,
2450
+ onClick: () => {
2451
+ setValue(btn.value);
2452
+ emit("change");
2453
+ },
2454
+ children: btn.label
2455
+ },
2456
+ btn.value
2457
+ )) });
2458
+ },
2459
+ Pagination: ({
2460
+ props,
2461
+ bindings,
2462
+ emit
2463
+ }) => {
2464
+ const [boundPage, setBoundPage] = useBoundProp(
2465
+ props.page,
2466
+ bindings?.page
2467
+ );
2468
+ const currentPage = boundPage ?? 1;
2469
+ const totalPages = props.totalPages ?? 1;
2470
+ const pages = getPaginationRange(currentPage, totalPages);
2471
+ return /* @__PURE__ */ jsx30(Pagination, { children: /* @__PURE__ */ jsxs10(PaginationContent, { children: [
2472
+ /* @__PURE__ */ jsx30(PaginationItem, { children: /* @__PURE__ */ jsx30(
2473
+ PaginationPrevious,
2474
+ {
2475
+ href: "#",
2476
+ onClick: (e) => {
2477
+ e.preventDefault();
2478
+ if (currentPage > 1) {
2479
+ setBoundPage(currentPage - 1);
2480
+ emit("change");
2481
+ }
2482
+ }
2483
+ }
2484
+ ) }),
2485
+ pages.map(
2486
+ (page, idx) => page === "ellipsis" ? /* @__PURE__ */ jsx30(PaginationItem, { children: /* @__PURE__ */ jsx30(PaginationEllipsis, {}) }, `ellipsis-${idx}`) : /* @__PURE__ */ jsx30(PaginationItem, { children: /* @__PURE__ */ jsx30(
2487
+ PaginationLink,
2488
+ {
2489
+ href: "#",
2490
+ isActive: page === currentPage,
2491
+ onClick: (e) => {
2492
+ e.preventDefault();
2493
+ setBoundPage(page);
2494
+ emit("change");
2495
+ },
2496
+ children: page
2497
+ }
2498
+ ) }, page)
2499
+ ),
2500
+ /* @__PURE__ */ jsx30(PaginationItem, { children: /* @__PURE__ */ jsx30(
2501
+ PaginationNext,
2502
+ {
2503
+ href: "#",
2504
+ onClick: (e) => {
2505
+ e.preventDefault();
2506
+ if (currentPage < totalPages) {
2507
+ setBoundPage(currentPage + 1);
2508
+ emit("change");
2509
+ }
2510
+ }
2511
+ }
2512
+ ) })
2513
+ ] }) });
2514
+ }
2515
+ };
2516
+ export {
2517
+ shadcnComponentDefinitions,
2518
+ shadcnComponents
2519
+ };
2520
+ //# sourceMappingURL=index.mjs.map