@quinkit/ui 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/dist/index.d.cts +1445 -0
  2. package/dist/index.d.ts +1445 -0
  3. package/dist/index.js +2567 -0
  4. package/dist/index.js.map +1 -0
  5. package/dist/index.mjs +2366 -0
  6. package/dist/index.mjs.map +1 -0
  7. package/package.json +97 -0
  8. package/src/styles/globals.css +150 -0
  9. package/src/styles/theme-switcher.tsx +95 -0
  10. package/src/styles/themes/.gitkeep +0 -0
  11. package/src/styles/themes/dashboard-data.css +64 -0
  12. package/src/styles/themes/dashboard-executive.css +64 -0
  13. package/src/styles/themes/dashboard-glass.css +64 -0
  14. package/src/styles/themes/dashboard.css +46 -0
  15. package/src/styles/themes/ecommerce-luxury.css +64 -0
  16. package/src/styles/themes/ecommerce-minimal.css +64 -0
  17. package/src/styles/themes/ecommerce-playful.css +64 -0
  18. package/src/styles/themes/ecommerce.css +36 -0
  19. package/src/styles/themes/edtech-campus.css +64 -0
  20. package/src/styles/themes/edtech-kids.css +64 -0
  21. package/src/styles/themes/edtech-professional.css +64 -0
  22. package/src/styles/themes/edtech.css +36 -0
  23. package/src/styles/themes/fintech-crypto.css +64 -0
  24. package/src/styles/themes/fintech-modern.css +64 -0
  25. package/src/styles/themes/fintech-wealth.css +64 -0
  26. package/src/styles/themes/fintech.css +46 -0
  27. package/src/styles/themes/healthcare-clinical.css +64 -0
  28. package/src/styles/themes/healthcare-urgent.css +64 -0
  29. package/src/styles/themes/healthcare-wellness.css +64 -0
  30. package/src/styles/themes/healthcare.css +46 -0
  31. package/src/styles/tokens/.gitkeep +0 -0
  32. package/src/styles/tokens/charts.css +26 -0
  33. package/src/styles/tokens/dark.css +36 -0
  34. package/src/styles/tokens/palettes.css +2663 -0
  35. package/src/styles/tokens/primitives.css +34 -0
  36. package/src/styles/tokens/semantic.css +35 -0
  37. package/src/styles/tokens/typography.css +82 -0
package/dist/index.mjs ADDED
@@ -0,0 +1,2366 @@
1
+ import { forwardRef, createContext, useState, useEffect, useCallback, useMemo, useContext } from 'react';
2
+ import * as AvatarPrimitive from '@radix-ui/react-avatar';
3
+ import { clsx } from 'clsx';
4
+ import { twMerge } from 'tailwind-merge';
5
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
6
+ import * as CheckboxPrimitive from '@radix-ui/react-checkbox';
7
+ import * as LabelPrimitive from '@radix-ui/react-label';
8
+ import * as RadioGroupPrimitive from '@radix-ui/react-radio-group';
9
+ import * as SelectPrimitive from '@radix-ui/react-select';
10
+ import * as SeparatorPrimitive from '@radix-ui/react-separator';
11
+ import * as SwitchPrimitive from '@radix-ui/react-switch';
12
+ import * as AspectRatioPrimitive from '@radix-ui/react-aspect-ratio';
13
+ import { DayPicker } from 'react-day-picker';
14
+ import { useReactTable, getPaginationRowModel, getFilteredRowModel, getSortedRowModel, getCoreRowModel, flexRender } from '@tanstack/react-table';
15
+ import { format } from 'date-fns';
16
+ import * as PopoverPrimitive from '@radix-ui/react-popover';
17
+ import * as ProgressPrimitive from '@radix-ui/react-progress';
18
+ import * as ScrollAreaPrimitive from '@radix-ui/react-scroll-area';
19
+ import * as AccordionPrimitive from '@radix-ui/react-accordion';
20
+ import * as AlertDialogPrimitive from '@radix-ui/react-alert-dialog';
21
+ import { Command as Command$1 } from 'cmdk';
22
+ import * as DialogPrimitive from '@radix-ui/react-dialog';
23
+ import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';
24
+ import * as NavigationMenuPrimitive from '@radix-ui/react-navigation-menu';
25
+ import * as TabsPrimitive from '@radix-ui/react-tabs';
26
+ import * as TooltipPrimitive from '@radix-ui/react-tooltip';
27
+ import { Toaster as Toaster$1 } from 'sonner';
28
+ export { toast } from 'sonner';
29
+ import { FormProvider, Controller, useFormContext } from 'react-hook-form';
30
+
31
+ // src/hooks/useDebounce.ts
32
+ function useDebounce(value, delayMs = 300) {
33
+ const [debouncedValue, setDebouncedValue] = useState(value);
34
+ useEffect(() => {
35
+ const timeout = window.setTimeout(() => setDebouncedValue(value), delayMs);
36
+ return () => window.clearTimeout(timeout);
37
+ }, [value, delayMs]);
38
+ return debouncedValue;
39
+ }
40
+ function useMediaQuery(query, initialValue = false) {
41
+ const [matches, setMatches] = useState(initialValue);
42
+ useEffect(() => {
43
+ const mediaQuery = window.matchMedia(query);
44
+ const updateMatches = () => setMatches(mediaQuery.matches);
45
+ updateMatches();
46
+ mediaQuery.addEventListener("change", updateMatches);
47
+ return () => mediaQuery.removeEventListener("change", updateMatches);
48
+ }, [query]);
49
+ return matches;
50
+ }
51
+
52
+ // src/lib/palettes.ts
53
+ var uiPalettes = [
54
+ {
55
+ name: "Neutral Slate",
56
+ value: "neutral-slate",
57
+ category: "Neutral",
58
+ description: "Neutral Slate palette for neutral interfaces.",
59
+ inspiredBy: ["Neutral Slate"],
60
+ bestFor: ["Neutral UI", "dashboards", "product screens"]
61
+ },
62
+ {
63
+ name: "Executive Slate",
64
+ value: "executive-slate",
65
+ category: "Neutral",
66
+ description: "Executive Slate palette for neutral interfaces.",
67
+ inspiredBy: ["Executive Slate"],
68
+ bestFor: ["Neutral UI", "dashboards", "product screens"]
69
+ },
70
+ {
71
+ name: "Vercel Mono",
72
+ value: "vercel-mono",
73
+ category: "Neutral",
74
+ description: "Vercel Mono palette for neutral interfaces.",
75
+ inspiredBy: ["Vercel Mono"],
76
+ bestFor: ["Neutral UI", "dashboards", "product screens"]
77
+ },
78
+ {
79
+ name: "Warm Sand",
80
+ value: "warm-sand",
81
+ category: "Neutral",
82
+ description: "Warm Sand palette for neutral interfaces.",
83
+ inspiredBy: ["Warm Sand"],
84
+ bestFor: ["Neutral UI", "dashboards", "product screens"]
85
+ },
86
+ {
87
+ name: "Zinc Cool",
88
+ value: "zinc-cool",
89
+ category: "Neutral",
90
+ description: "Zinc Cool palette for neutral interfaces.",
91
+ inspiredBy: ["Zinc Cool"],
92
+ bestFor: ["Neutral UI", "dashboards", "product screens"]
93
+ },
94
+ {
95
+ name: "Stone Warm",
96
+ value: "stone-warm",
97
+ category: "Neutral",
98
+ description: "Stone Warm palette for neutral interfaces.",
99
+ inspiredBy: ["Stone Warm"],
100
+ bestFor: ["Neutral UI", "dashboards", "product screens"]
101
+ },
102
+ {
103
+ name: "Ink Black",
104
+ value: "ink-black",
105
+ category: "Neutral",
106
+ description: "Ink Black palette for neutral interfaces.",
107
+ inspiredBy: ["Ink Black"],
108
+ bestFor: ["Neutral UI", "dashboards", "product screens"]
109
+ },
110
+ {
111
+ name: "Parchment",
112
+ value: "parchment",
113
+ category: "Neutral",
114
+ description: "Parchment palette for neutral interfaces.",
115
+ inspiredBy: ["Parchment"],
116
+ bestFor: ["Neutral UI", "dashboards", "product screens"]
117
+ },
118
+ {
119
+ name: "Default Blue",
120
+ value: "default-blue",
121
+ category: "SaaS",
122
+ description: "Default Blue palette for saas interfaces.",
123
+ inspiredBy: ["Default Blue"],
124
+ bestFor: ["SaaS UI", "dashboards", "product screens"]
125
+ },
126
+ {
127
+ name: "Linear Minimal",
128
+ value: "linear-minimal",
129
+ category: "SaaS",
130
+ description: "Linear Minimal palette for saas interfaces.",
131
+ inspiredBy: ["Linear Minimal"],
132
+ bestFor: ["SaaS UI", "dashboards", "product screens"]
133
+ },
134
+ {
135
+ name: "Github Neutral",
136
+ value: "github-neutral",
137
+ category: "SaaS",
138
+ description: "Github Neutral palette for saas interfaces.",
139
+ inspiredBy: ["Github Neutral"],
140
+ bestFor: ["SaaS UI", "dashboards", "product screens"]
141
+ },
142
+ {
143
+ name: "Atlassian Blue",
144
+ value: "atlassian-blue",
145
+ category: "SaaS",
146
+ description: "Atlassian Blue palette for saas interfaces.",
147
+ inspiredBy: ["Atlassian Blue"],
148
+ bestFor: ["SaaS UI", "dashboards", "product screens"]
149
+ },
150
+ {
151
+ name: "Analytics Cyan",
152
+ value: "analytics-cyan",
153
+ category: "SaaS",
154
+ description: "Analytics Cyan palette for saas interfaces.",
155
+ inspiredBy: ["Analytics Cyan"],
156
+ bestFor: ["SaaS UI", "dashboards", "product screens"]
157
+ },
158
+ {
159
+ name: "Notion Blue",
160
+ value: "notion-blue",
161
+ category: "SaaS",
162
+ description: "Notion Blue palette for saas interfaces.",
163
+ inspiredBy: ["Notion Blue"],
164
+ bestFor: ["SaaS UI", "dashboards", "product screens"]
165
+ },
166
+ {
167
+ name: "Intercom Blue",
168
+ value: "intercom-blue",
169
+ category: "SaaS",
170
+ description: "Intercom Blue palette for saas interfaces.",
171
+ inspiredBy: ["Intercom Blue"],
172
+ bestFor: ["SaaS UI", "dashboards", "product screens"]
173
+ },
174
+ {
175
+ name: "Salesforce Sky",
176
+ value: "salesforce-sky",
177
+ category: "SaaS",
178
+ description: "Salesforce Sky palette for saas interfaces.",
179
+ inspiredBy: ["Salesforce Sky"],
180
+ bestFor: ["SaaS UI", "dashboards", "product screens"]
181
+ },
182
+ {
183
+ name: "Medical Teal",
184
+ value: "medical-teal",
185
+ category: "Healthcare",
186
+ description: "Medical Teal palette for healthcare interfaces.",
187
+ inspiredBy: ["Medical Teal"],
188
+ bestFor: ["Healthcare UI", "dashboards", "product screens"]
189
+ },
190
+ {
191
+ name: "Clinical Blue",
192
+ value: "clinical-blue",
193
+ category: "Healthcare",
194
+ description: "Clinical Blue palette for healthcare interfaces.",
195
+ inspiredBy: ["Clinical Blue"],
196
+ bestFor: ["Healthcare UI", "dashboards", "product screens"]
197
+ },
198
+ {
199
+ name: "Calm Cyan",
200
+ value: "calm-cyan",
201
+ category: "Healthcare",
202
+ description: "Calm Cyan palette for healthcare interfaces.",
203
+ inspiredBy: ["Calm Cyan"],
204
+ bestFor: ["Healthcare UI", "dashboards", "product screens"]
205
+ },
206
+ {
207
+ name: "Teladoc Teal",
208
+ value: "teladoc-teal",
209
+ category: "Healthcare",
210
+ description: "Teladoc Teal palette for healthcare interfaces.",
211
+ inspiredBy: ["Teladoc Teal"],
212
+ bestFor: ["Healthcare UI", "dashboards", "product screens"]
213
+ },
214
+ {
215
+ name: "Noom Green",
216
+ value: "noom-green",
217
+ category: "Healthcare",
218
+ description: "Noom Green palette for healthcare interfaces.",
219
+ inspiredBy: ["Noom Green"],
220
+ bestFor: ["Healthcare UI", "dashboards", "product screens"]
221
+ },
222
+ {
223
+ name: "Headspace Orange",
224
+ value: "headspace-orange",
225
+ category: "Healthcare",
226
+ description: "Headspace Orange palette for healthcare interfaces.",
227
+ inspiredBy: ["Headspace Orange"],
228
+ bestFor: ["Healthcare UI", "dashboards", "product screens"]
229
+ },
230
+ {
231
+ name: "Epic Blue",
232
+ value: "epic-blue",
233
+ category: "Healthcare",
234
+ description: "Epic Blue palette for healthcare interfaces.",
235
+ inspiredBy: ["Epic Blue"],
236
+ bestFor: ["Healthcare UI", "dashboards", "product screens"]
237
+ },
238
+ {
239
+ name: "Fintech Navy",
240
+ value: "fintech-navy",
241
+ category: "Fintech",
242
+ description: "Fintech Navy palette for fintech interfaces.",
243
+ inspiredBy: ["Fintech Navy"],
244
+ bestFor: ["Fintech UI", "dashboards", "product screens"]
245
+ },
246
+ {
247
+ name: "Finance Gold",
248
+ value: "finance-gold",
249
+ category: "Fintech",
250
+ description: "Finance Gold palette for fintech interfaces.",
251
+ inspiredBy: ["Finance Gold"],
252
+ bestFor: ["Fintech UI", "dashboards", "product screens"]
253
+ },
254
+ {
255
+ name: "Emerald Wealth",
256
+ value: "emerald-wealth",
257
+ category: "Fintech",
258
+ description: "Emerald Wealth palette for fintech interfaces.",
259
+ inspiredBy: ["Emerald Wealth"],
260
+ bestFor: ["Fintech UI", "dashboards", "product screens"]
261
+ },
262
+ {
263
+ name: "Risk Amber",
264
+ value: "risk-amber",
265
+ category: "Fintech",
266
+ description: "Risk Amber palette for fintech interfaces.",
267
+ inspiredBy: ["Risk Amber"],
268
+ bestFor: ["Fintech UI", "dashboards", "product screens"]
269
+ },
270
+ {
271
+ name: "Stripe Indigo",
272
+ value: "stripe-indigo",
273
+ category: "Fintech",
274
+ description: "Stripe Indigo palette for fintech interfaces.",
275
+ inspiredBy: ["Stripe Indigo"],
276
+ bestFor: ["Fintech UI", "dashboards", "product screens"]
277
+ },
278
+ {
279
+ name: "Coinbase Blue",
280
+ value: "coinbase-blue",
281
+ category: "Fintech",
282
+ description: "Coinbase Blue palette for fintech interfaces.",
283
+ inspiredBy: ["Coinbase Blue"],
284
+ bestFor: ["Fintech UI", "dashboards", "product screens"]
285
+ },
286
+ {
287
+ name: "Robinhood Green",
288
+ value: "robinhood-green",
289
+ category: "Fintech",
290
+ description: "Robinhood Green palette for fintech interfaces.",
291
+ inspiredBy: ["Robinhood Green"],
292
+ bestFor: ["Fintech UI", "dashboards", "product screens"]
293
+ },
294
+ {
295
+ name: "Plaid Navy",
296
+ value: "plaid-navy",
297
+ category: "Fintech",
298
+ description: "Plaid Navy palette for fintech interfaces.",
299
+ inspiredBy: ["Plaid Navy"],
300
+ bestFor: ["Fintech UI", "dashboards", "product screens"]
301
+ },
302
+ {
303
+ name: "E-commerce Rose",
304
+ value: "ecommerce-rose",
305
+ category: "E-commerce",
306
+ description: "E-commerce Rose palette for e-commerce interfaces.",
307
+ inspiredBy: ["E-commerce Rose"],
308
+ bestFor: ["E-commerce UI", "dashboards", "product screens"]
309
+ },
310
+ {
311
+ name: "Luxury Black Gold",
312
+ value: "luxury-black-gold",
313
+ category: "E-commerce",
314
+ description: "Luxury Black Gold palette for e-commerce interfaces.",
315
+ inspiredBy: ["Luxury Black Gold"],
316
+ bestFor: ["E-commerce UI", "dashboards", "product screens"]
317
+ },
318
+ {
319
+ name: "Commerce Green",
320
+ value: "commerce-green",
321
+ category: "E-commerce",
322
+ description: "Commerce Green palette for e-commerce interfaces.",
323
+ inspiredBy: ["Commerce Green"],
324
+ bestFor: ["E-commerce UI", "dashboards", "product screens"]
325
+ },
326
+ {
327
+ name: "Lifestyle Coral",
328
+ value: "lifestyle-coral",
329
+ category: "E-commerce",
330
+ description: "Lifestyle Coral palette for e-commerce interfaces.",
331
+ inspiredBy: ["Lifestyle Coral"],
332
+ bestFor: ["E-commerce UI", "dashboards", "product screens"]
333
+ },
334
+ {
335
+ name: "Shopify Green",
336
+ value: "shopify-green",
337
+ category: "E-commerce",
338
+ description: "Shopify Green palette for e-commerce interfaces.",
339
+ inspiredBy: ["Shopify Green"],
340
+ bestFor: ["E-commerce UI", "dashboards", "product screens"]
341
+ },
342
+ {
343
+ name: "Amazon Orange",
344
+ value: "amazon-orange",
345
+ category: "E-commerce",
346
+ description: "Amazon Orange palette for e-commerce interfaces.",
347
+ inspiredBy: ["Amazon Orange"],
348
+ bestFor: ["E-commerce UI", "dashboards", "product screens"]
349
+ },
350
+ {
351
+ name: "Etsy Orange",
352
+ value: "etsy-orange",
353
+ category: "E-commerce",
354
+ description: "Etsy Orange palette for e-commerce interfaces.",
355
+ inspiredBy: ["Etsy Orange"],
356
+ bestFor: ["E-commerce UI", "dashboards", "product screens"]
357
+ },
358
+ {
359
+ name: "Netflix Red",
360
+ value: "netflix-red",
361
+ category: "E-commerce",
362
+ description: "Netflix Red palette for e-commerce interfaces.",
363
+ inspiredBy: ["Netflix Red"],
364
+ bestFor: ["E-commerce UI", "dashboards", "product screens"]
365
+ },
366
+ {
367
+ name: "Edtech Playful",
368
+ value: "edtech-playful",
369
+ category: "EdTech",
370
+ description: "Edtech Playful palette for edtech interfaces.",
371
+ inspiredBy: ["Edtech Playful"],
372
+ bestFor: ["EdTech UI", "dashboards", "product screens"]
373
+ },
374
+ {
375
+ name: "Learning Purple",
376
+ value: "learning-purple",
377
+ category: "EdTech",
378
+ description: "Learning Purple palette for edtech interfaces.",
379
+ inspiredBy: ["Learning Purple"],
380
+ bestFor: ["EdTech UI", "dashboards", "product screens"]
381
+ },
382
+ {
383
+ name: "Gamified Green",
384
+ value: "gamified-green",
385
+ category: "EdTech",
386
+ description: "Gamified Green palette for edtech interfaces.",
387
+ inspiredBy: ["Gamified Green"],
388
+ bestFor: ["EdTech UI", "dashboards", "product screens"]
389
+ },
390
+ {
391
+ name: "Achievement Amber",
392
+ value: "achievement-amber",
393
+ category: "EdTech",
394
+ description: "Achievement Amber palette for edtech interfaces.",
395
+ inspiredBy: ["Achievement Amber"],
396
+ bestFor: ["EdTech UI", "dashboards", "product screens"]
397
+ },
398
+ {
399
+ name: "Duolingo Green",
400
+ value: "duolingo-green",
401
+ category: "EdTech",
402
+ description: "Duolingo Green palette for edtech interfaces.",
403
+ inspiredBy: ["Duolingo Green"],
404
+ bestFor: ["EdTech UI", "dashboards", "product screens"]
405
+ },
406
+ {
407
+ name: "Coursera Blue",
408
+ value: "coursera-blue",
409
+ category: "EdTech",
410
+ description: "Coursera Blue palette for edtech interfaces.",
411
+ inspiredBy: ["Coursera Blue"],
412
+ bestFor: ["EdTech UI", "dashboards", "product screens"]
413
+ },
414
+ {
415
+ name: "Khan Blue",
416
+ value: "khan-blue",
417
+ category: "EdTech",
418
+ description: "Khan Blue palette for edtech interfaces.",
419
+ inspiredBy: ["Khan Blue"],
420
+ bestFor: ["EdTech UI", "dashboards", "product screens"]
421
+ },
422
+ {
423
+ name: "Udemy Purple",
424
+ value: "udemy-purple",
425
+ category: "EdTech",
426
+ description: "Udemy Purple palette for edtech interfaces.",
427
+ inspiredBy: ["Udemy Purple"],
428
+ bestFor: ["EdTech UI", "dashboards", "product screens"]
429
+ },
430
+ {
431
+ name: "AI Cyber",
432
+ value: "ai-cyber",
433
+ category: "AI/Dev",
434
+ description: "AI Cyber palette for ai/dev interfaces.",
435
+ inspiredBy: ["AI Cyber"],
436
+ bestFor: ["AI/Dev UI", "dashboards", "product screens"]
437
+ },
438
+ {
439
+ name: "Raycast Dark",
440
+ value: "raycast-dark",
441
+ category: "AI/Dev",
442
+ description: "Raycast Dark palette for ai/dev interfaces.",
443
+ inspiredBy: ["Raycast Dark"],
444
+ bestFor: ["AI/Dev UI", "dashboards", "product screens"]
445
+ },
446
+ {
447
+ name: "Railway Violet",
448
+ value: "railway-violet",
449
+ category: "AI/Dev",
450
+ description: "Railway Violet palette for ai/dev interfaces.",
451
+ inspiredBy: ["Railway Violet"],
452
+ bestFor: ["AI/Dev UI", "dashboards", "product screens"]
453
+ },
454
+ {
455
+ name: "Terminal Green",
456
+ value: "terminal-green",
457
+ category: "AI/Dev",
458
+ description: "Terminal Green palette for ai/dev interfaces.",
459
+ inspiredBy: ["Terminal Green"],
460
+ bestFor: ["AI/Dev UI", "dashboards", "product screens"]
461
+ },
462
+ {
463
+ name: "VS Code Dark",
464
+ value: "vscode-dark",
465
+ category: "Developer Tools",
466
+ description: "VS Code Dark palette for developer tools interfaces.",
467
+ inspiredBy: ["VS Code Dark"],
468
+ bestFor: ["Developer Tools UI", "dashboards", "product screens"]
469
+ },
470
+ {
471
+ name: "iTerm Green",
472
+ value: "iterm-green",
473
+ category: "Developer Tools",
474
+ description: "iTerm Green palette for developer tools interfaces.",
475
+ inspiredBy: ["iTerm Green"],
476
+ bestFor: ["Developer Tools UI", "dashboards", "product screens"]
477
+ },
478
+ {
479
+ name: "Supabase Emerald",
480
+ value: "supabase-emerald",
481
+ category: "Developer Tools",
482
+ description: "Supabase Emerald palette for developer tools interfaces.",
483
+ inspiredBy: ["Supabase Emerald"],
484
+ bestFor: ["Developer Tools UI", "dashboards", "product screens"]
485
+ },
486
+ {
487
+ name: "Neon Cyber",
488
+ value: "neon-cyber",
489
+ category: "Developer Tools",
490
+ description: "Neon Cyber palette for developer tools interfaces.",
491
+ inspiredBy: ["Neon Cyber"],
492
+ bestFor: ["Developer Tools UI", "dashboards", "product screens"]
493
+ },
494
+ {
495
+ name: "IBM Carbon",
496
+ value: "ibm-carbon",
497
+ category: "Enterprise",
498
+ description: "IBM Carbon palette for enterprise interfaces.",
499
+ inspiredBy: ["IBM Carbon"],
500
+ bestFor: ["Enterprise UI", "dashboards", "product screens"]
501
+ },
502
+ {
503
+ name: "Microsoft Fluent",
504
+ value: "microsoft-fluent",
505
+ category: "Enterprise",
506
+ description: "Microsoft Fluent palette for enterprise interfaces.",
507
+ inspiredBy: ["Microsoft Fluent"],
508
+ bestFor: ["Enterprise UI", "dashboards", "product screens"]
509
+ },
510
+ {
511
+ name: "Gov Blue",
512
+ value: "gov-blue",
513
+ category: "Enterprise",
514
+ description: "Gov Blue palette for enterprise interfaces.",
515
+ inspiredBy: ["Gov Blue"],
516
+ bestFor: ["Enterprise UI", "dashboards", "product screens"]
517
+ },
518
+ {
519
+ name: "Stripe Gradient",
520
+ value: "stripe-gradient",
521
+ category: "Enterprise",
522
+ description: "Stripe Gradient palette for enterprise interfaces.",
523
+ inspiredBy: ["Stripe Gradient"],
524
+ bestFor: ["Enterprise UI", "dashboards", "product screens"]
525
+ },
526
+ {
527
+ name: "Solana Gradient",
528
+ value: "solana-gradient",
529
+ category: "Creative",
530
+ description: "Solana Gradient palette for creative interfaces.",
531
+ inspiredBy: ["Solana Gradient"],
532
+ bestFor: ["Creative UI", "dashboards", "product screens"]
533
+ },
534
+ {
535
+ name: "Figma Purple",
536
+ value: "figma-purple",
537
+ category: "Creative",
538
+ description: "Figma Purple palette for creative interfaces.",
539
+ inspiredBy: ["Figma Purple"],
540
+ bestFor: ["Creative UI", "dashboards", "product screens"]
541
+ },
542
+ {
543
+ name: "Dribbble Pink",
544
+ value: "dribbble-pink",
545
+ category: "Creative",
546
+ description: "Dribbble Pink palette for creative interfaces.",
547
+ inspiredBy: ["Dribbble Pink"],
548
+ bestFor: ["Creative UI", "dashboards", "product screens"]
549
+ },
550
+ {
551
+ name: "Behance Blue",
552
+ value: "behance-blue",
553
+ category: "Creative",
554
+ description: "Behance Blue palette for creative interfaces.",
555
+ inspiredBy: ["Behance Blue"],
556
+ bestFor: ["Creative UI", "dashboards", "product screens"]
557
+ },
558
+ {
559
+ name: "Awwwards Dark",
560
+ value: "awwwards-dark",
561
+ category: "Creative",
562
+ description: "Awwwards Dark palette for creative interfaces.",
563
+ inspiredBy: ["Awwwards Dark"],
564
+ bestFor: ["Creative UI", "dashboards", "product screens"]
565
+ }
566
+ ];
567
+ var uiPaletteValues = uiPalettes.map((palette) => palette.value);
568
+ var DEFAULT_PALETTE = "neutral-slate";
569
+ function palettesByCategory() {
570
+ const out = {};
571
+ for (const palette of uiPalettes) {
572
+ out[palette.category] = out[palette.category] ?? [];
573
+ out[palette.category].push(palette);
574
+ }
575
+ return out;
576
+ }
577
+ function isUiPalette(value) {
578
+ return uiPaletteValues.includes(value);
579
+ }
580
+ var STORAGE_PALETTE = "ui-palette";
581
+ var STORAGE_APPEARANCE = "ui-appearance";
582
+ function applyPalette(palette) {
583
+ if (typeof document === "undefined") return;
584
+ document.documentElement.dataset.palette = palette;
585
+ try {
586
+ localStorage.setItem(STORAGE_PALETTE, palette);
587
+ } catch {
588
+ }
589
+ }
590
+ function applyAppearance(appearance) {
591
+ if (typeof document === "undefined") return;
592
+ const prefersDark = typeof window !== "undefined" && window.matchMedia("(prefers-color-scheme: dark)").matches;
593
+ const isDark = appearance === "dark" || appearance === "system" && prefersDark;
594
+ document.documentElement.classList.toggle("dark", isDark);
595
+ try {
596
+ localStorage.setItem(STORAGE_APPEARANCE, appearance);
597
+ } catch {
598
+ }
599
+ }
600
+ var appliers = {
601
+ appearance: applyAppearance,
602
+ palette: applyPalette
603
+ };
604
+ function getStoredPalette() {
605
+ if (typeof localStorage === "undefined") return DEFAULT_PALETTE;
606
+ const raw = localStorage.getItem(STORAGE_PALETTE);
607
+ return raw && isUiPalette(raw) ? raw : DEFAULT_PALETTE;
608
+ }
609
+ function getStoredAppearance() {
610
+ if (typeof localStorage === "undefined") return "system";
611
+ const raw = localStorage.getItem(STORAGE_APPEARANCE);
612
+ return raw === "light" || raw === "dark" || raw === "system" ? raw : "system";
613
+ }
614
+
615
+ // src/hooks/useTheme.ts
616
+ var uiThemes = [
617
+ // base kits
618
+ "dashboard",
619
+ "ecommerce",
620
+ "healthcare",
621
+ "fintech",
622
+ "edtech",
623
+ // SaaS sub-themes
624
+ "dashboard-executive",
625
+ "dashboard-glass",
626
+ "dashboard-data",
627
+ // E-commerce sub-themes
628
+ "ecommerce-luxury",
629
+ "ecommerce-playful",
630
+ "ecommerce-minimal",
631
+ // Healthcare sub-themes
632
+ "healthcare-clinical",
633
+ "healthcare-wellness",
634
+ "healthcare-urgent",
635
+ // Fintech sub-themes
636
+ "fintech-wealth",
637
+ "fintech-crypto",
638
+ "fintech-modern",
639
+ // EdTech sub-themes
640
+ "edtech-campus",
641
+ "edtech-kids",
642
+ "edtech-professional"
643
+ ];
644
+ var uiThemeLabels = {
645
+ dashboard: "Dashboard",
646
+ ecommerce: "E-Commerce",
647
+ healthcare: "Healthcare",
648
+ fintech: "Fintech",
649
+ edtech: "EdTech",
650
+ "dashboard-executive": "Dashboard \xB7 Executive",
651
+ "dashboard-glass": "Dashboard \xB7 Glass",
652
+ "dashboard-data": "Dashboard \xB7 Data",
653
+ "ecommerce-luxury": "E-Commerce \xB7 Luxury",
654
+ "ecommerce-playful": "E-Commerce \xB7 Playful",
655
+ "ecommerce-minimal": "E-Commerce \xB7 Minimal",
656
+ "healthcare-clinical": "Healthcare \xB7 Clinical",
657
+ "healthcare-wellness": "Healthcare \xB7 Wellness",
658
+ "healthcare-urgent": "Healthcare \xB7 Urgent",
659
+ "fintech-wealth": "Fintech \xB7 Wealth",
660
+ "fintech-crypto": "Fintech \xB7 Crypto",
661
+ "fintech-modern": "Fintech \xB7 Modern",
662
+ "edtech-campus": "EdTech \xB7 Campus",
663
+ "edtech-kids": "EdTech \xB7 Kids",
664
+ "edtech-professional": "EdTech \xB7 Professional"
665
+ };
666
+ var DEFAULT_THEME = "dashboard";
667
+ var STORAGE_THEME = "ui-theme";
668
+ function isUiTheme(value) {
669
+ return uiThemes.includes(value);
670
+ }
671
+ function applyTheme(theme) {
672
+ if (typeof document === "undefined") return;
673
+ document.documentElement.dataset.theme = theme;
674
+ try {
675
+ localStorage.setItem(STORAGE_THEME, theme);
676
+ } catch {
677
+ }
678
+ }
679
+ function getStoredTheme() {
680
+ if (typeof localStorage === "undefined") return DEFAULT_THEME;
681
+ const raw = localStorage.getItem(STORAGE_THEME);
682
+ return raw && isUiTheme(raw) ? raw : DEFAULT_THEME;
683
+ }
684
+ function useTheme() {
685
+ const [mounted, setMounted] = useState(false);
686
+ const [theme, setThemeState] = useState(DEFAULT_THEME);
687
+ const [palette, setPaletteState] = useState("neutral-slate");
688
+ const [appearance, setAppearanceState] = useState("system");
689
+ useEffect(() => {
690
+ setThemeState(getStoredTheme());
691
+ setPaletteState(getStoredPalette());
692
+ setAppearanceState(getStoredAppearance());
693
+ setMounted(true);
694
+ }, []);
695
+ const setTheme = useCallback((nextTheme) => {
696
+ setThemeState(nextTheme);
697
+ applyTheme(nextTheme);
698
+ }, []);
699
+ const setPalette = useCallback((nextPalette) => {
700
+ setPaletteState(nextPalette);
701
+ applyPalette(nextPalette);
702
+ }, []);
703
+ const setAppearance = useCallback((nextAppearance) => {
704
+ setAppearanceState(nextAppearance);
705
+ applyAppearance(nextAppearance);
706
+ }, []);
707
+ useEffect(() => {
708
+ if (!mounted) return;
709
+ applyTheme(theme);
710
+ }, [mounted, theme]);
711
+ useEffect(() => {
712
+ if (!mounted) return;
713
+ applyPalette(palette);
714
+ }, [mounted, palette]);
715
+ useEffect(() => {
716
+ if (!mounted) return;
717
+ applyAppearance(appearance);
718
+ if (appearance !== "system") return;
719
+ const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
720
+ const updateAppearance = () => applyAppearance("system");
721
+ mediaQuery.addEventListener("change", updateAppearance);
722
+ return () => mediaQuery.removeEventListener("change", updateAppearance);
723
+ }, [mounted, appearance]);
724
+ return {
725
+ appearance,
726
+ mounted,
727
+ palette,
728
+ setAppearance,
729
+ setPalette,
730
+ setTheme,
731
+ theme
732
+ };
733
+ }
734
+
735
+ // src/lib/fonts.ts
736
+ var uiFonts = {
737
+ inter: {
738
+ name: "Inter",
739
+ googleUrl: "https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap",
740
+ cssValue: '"Inter", ui-sans-serif, system-ui, -apple-system, sans-serif',
741
+ recommendedFor: [
742
+ "dashboard-executive",
743
+ "fintech-modern",
744
+ "ecommerce-minimal",
745
+ "edtech-professional"
746
+ ]
747
+ },
748
+ geist: {
749
+ name: "Geist",
750
+ googleUrl: "https://fonts.googleapis.com/css2?family=Geist:wght@100..900&display=swap",
751
+ cssValue: '"Geist", ui-sans-serif, system-ui, sans-serif',
752
+ recommendedFor: ["dashboard-executive", "fintech-crypto"]
753
+ },
754
+ "geist-mono": {
755
+ name: "Geist Mono",
756
+ googleUrl: "https://fonts.googleapis.com/css2?family=Geist+Mono:wght@100..900&display=swap",
757
+ cssValue: '"Geist Mono", ui-monospace, "JetBrains Mono", monospace',
758
+ recommendedFor: ["code", "price data", "dashboard-data"]
759
+ },
760
+ "jetbrains-mono": {
761
+ name: "JetBrains Mono",
762
+ googleUrl: "https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;700&display=swap",
763
+ cssValue: '"JetBrains Mono", ui-monospace, monospace',
764
+ recommendedFor: ["code fallback", "logs"]
765
+ },
766
+ manrope: {
767
+ name: "Manrope",
768
+ googleUrl: "https://fonts.googleapis.com/css2?family=Manrope:wght@400;500;600;700;800&display=swap",
769
+ cssValue: '"Manrope", ui-sans-serif, system-ui, sans-serif',
770
+ recommendedFor: ["healthcare base", "calm headings"]
771
+ },
772
+ outfit: {
773
+ name: "Outfit",
774
+ googleUrl: "https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;500;600;700&display=swap",
775
+ cssValue: '"Outfit", ui-sans-serif, system-ui, sans-serif',
776
+ recommendedFor: ["fintech base", "geometric headings"]
777
+ },
778
+ lato: {
779
+ name: "Lato",
780
+ googleUrl: "https://fonts.googleapis.com/css2?family=Lato:wght@400;700;900&display=swap",
781
+ cssValue: '"Lato", ui-sans-serif, system-ui, sans-serif',
782
+ recommendedFor: ["ecommerce-luxury body", "editorial body"]
783
+ },
784
+ "playfair-display": {
785
+ name: "Playfair Display",
786
+ googleUrl: "https://fonts.googleapis.com/css2?family=Playfair+Display:ital,wght@0,400;0,600;0,700;0,800;1,500&display=swap",
787
+ cssValue: '"Playfair Display", ui-serif, Georgia, serif',
788
+ recommendedFor: ["ecommerce-luxury", "fintech-wealth"]
789
+ },
790
+ "plus-jakarta-sans": {
791
+ name: "Plus Jakarta Sans",
792
+ googleUrl: "https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700;800&display=swap",
793
+ cssValue: '"Plus Jakarta Sans", ui-sans-serif, system-ui, sans-serif',
794
+ recommendedFor: ["dashboard-glass", "edtech base"]
795
+ },
796
+ "cormorant-garamond": {
797
+ name: "Cormorant Garamond",
798
+ googleUrl: "https://fonts.googleapis.com/css2?family=Cormorant+Garamond:ital,wght@0,400;0,500;0,600;0,700;1,400&display=swap",
799
+ cssValue: '"Cormorant Garamond", ui-serif, Georgia, serif',
800
+ recommendedFor: ["luxury display", "editorial"]
801
+ },
802
+ "dm-sans": {
803
+ name: "DM Sans",
804
+ googleUrl: "https://fonts.googleapis.com/css2?family=DM+Sans:wght@400;500;600;700&display=swap",
805
+ cssValue: '"DM Sans", ui-sans-serif, system-ui, sans-serif',
806
+ recommendedFor: ["ecommerce-playful"]
807
+ },
808
+ "ibm-plex-sans": {
809
+ name: "IBM Plex Sans",
810
+ googleUrl: "https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@400;500;600;700&display=swap",
811
+ cssValue: '"IBM Plex Sans", ui-sans-serif, system-ui, sans-serif',
812
+ recommendedFor: ["healthcare-clinical"]
813
+ },
814
+ "ibm-plex-mono": {
815
+ name: "IBM Plex Mono",
816
+ googleUrl: "https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600;700&display=swap",
817
+ cssValue: '"IBM Plex Mono", ui-monospace, monospace',
818
+ recommendedFor: ["healthcare-urgent data", "clinical tables"]
819
+ },
820
+ nunito: {
821
+ name: "Nunito",
822
+ googleUrl: "https://fonts.googleapis.com/css2?family=Nunito:wght@400;600;700;800;900&display=swap",
823
+ cssValue: '"Nunito", ui-sans-serif, system-ui, sans-serif',
824
+ recommendedFor: ["healthcare-wellness", "edtech-kids"]
825
+ },
826
+ "source-serif-4": {
827
+ name: "Source Serif 4",
828
+ googleUrl: "https://fonts.googleapis.com/css2?family=Source+Serif+4:wght@400;600;700&display=swap",
829
+ cssValue: '"Source Serif 4", ui-serif, Georgia, serif',
830
+ recommendedFor: ["edtech-campus"]
831
+ }
832
+ };
833
+ var uiFontValues = Object.keys(uiFonts);
834
+ var allFontsHref = "https://fonts.googleapis.com/css2?" + uiFontValues.map((f) => new URL(uiFonts[f].googleUrl).searchParams.get("family") ?? "").filter((family) => family.length > 0).map((fam) => `family=${fam}`).join("&") + "&display=swap";
835
+ function cn(...inputs) {
836
+ return twMerge(clsx(inputs));
837
+ }
838
+ var avatarSizes = {
839
+ sm: "size-8 text-xs",
840
+ md: "size-10 text-sm",
841
+ lg: "size-12 text-base"
842
+ };
843
+ var Avatar = forwardRef(
844
+ ({ className, size = "md", ...props }, ref) => /* @__PURE__ */ jsx(
845
+ AvatarPrimitive.Root,
846
+ {
847
+ ref,
848
+ className: cn(
849
+ "relative flex shrink-0 overflow-hidden rounded-full",
850
+ avatarSizes[size],
851
+ className
852
+ ),
853
+ ...props
854
+ }
855
+ )
856
+ );
857
+ Avatar.displayName = "Avatar";
858
+ var AvatarImage = forwardRef(
859
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
860
+ AvatarPrimitive.Image,
861
+ {
862
+ ref,
863
+ className: cn("aspect-square size-full object-cover", className),
864
+ ...props
865
+ }
866
+ )
867
+ );
868
+ AvatarImage.displayName = "AvatarImage";
869
+ var AvatarFallback = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
870
+ AvatarPrimitive.Fallback,
871
+ {
872
+ ref,
873
+ className: cn(
874
+ "flex size-full items-center justify-center rounded-full bg-muted font-medium text-muted-foreground",
875
+ className
876
+ ),
877
+ ...props
878
+ }
879
+ ));
880
+ AvatarFallback.displayName = "AvatarFallback";
881
+ var badgeVariants = {
882
+ default: "border-transparent bg-primary text-primary-foreground",
883
+ secondary: "border-transparent bg-secondary text-secondary-foreground",
884
+ outline: "border-border text-foreground",
885
+ destructive: "border-transparent bg-destructive text-destructive-foreground"
886
+ };
887
+ function Badge({ className, variant = "default", ...props }) {
888
+ return /* @__PURE__ */ jsx(
889
+ "span",
890
+ {
891
+ className: cn(
892
+ "inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors motion-reduce:transition-none focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
893
+ badgeVariants[variant],
894
+ className
895
+ ),
896
+ ...props
897
+ }
898
+ );
899
+ }
900
+ var variantClasses = {
901
+ default: "bg-primary text-primary-foreground shadow-sm hover:bg-primary/90",
902
+ secondary: "bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80",
903
+ outline: "border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground",
904
+ ghost: "hover:bg-accent hover:text-accent-foreground",
905
+ link: "h-auto p-0 text-primary underline-offset-4 hover:underline",
906
+ destructive: "bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90"
907
+ };
908
+ var sizeClasses = {
909
+ sm: "h-8 rounded-md px-3 text-xs",
910
+ md: "h-10 rounded-md px-4 py-2 text-sm",
911
+ lg: "h-11 rounded-lg px-8 text-base",
912
+ icon: "size-10 rounded-md p-0"
913
+ };
914
+ var Button = forwardRef(
915
+ ({
916
+ className,
917
+ variant = "default",
918
+ size = "md",
919
+ isLoading = false,
920
+ disabled,
921
+ children,
922
+ ...props
923
+ }, ref) => {
924
+ return /* @__PURE__ */ jsxs(
925
+ "button",
926
+ {
927
+ ref,
928
+ "aria-busy": isLoading || void 0,
929
+ className: cn(
930
+ "inline-flex items-center justify-center gap-2 whitespace-nowrap font-medium transition-colors motion-reduce:transition-none focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
931
+ variantClasses[variant],
932
+ sizeClasses[size],
933
+ className
934
+ ),
935
+ disabled: disabled || isLoading,
936
+ type: "button",
937
+ ...props,
938
+ children: [
939
+ isLoading ? /* @__PURE__ */ jsx(
940
+ "span",
941
+ {
942
+ "aria-hidden": "true",
943
+ className: "size-4 animate-spin rounded-full border-2 border-current border-t-transparent motion-reduce:animate-none"
944
+ }
945
+ ) : null,
946
+ children
947
+ ]
948
+ }
949
+ );
950
+ }
951
+ );
952
+ Button.displayName = "Button";
953
+ var Checkbox = forwardRef(
954
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
955
+ CheckboxPrimitive.Root,
956
+ {
957
+ ref,
958
+ className: cn(
959
+ "peer size-4 shrink-0 rounded-sm border border-primary bg-background shadow-sm transition-colors motion-reduce:transition-none focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground data-[state=indeterminate]:bg-primary data-[state=indeterminate]:text-primary-foreground",
960
+ className
961
+ ),
962
+ ...props,
963
+ children: /* @__PURE__ */ jsx(CheckboxPrimitive.Indicator, { className: "flex items-center justify-center text-current", children: /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "text-xs leading-none", children: "\u2713" }) })
964
+ }
965
+ )
966
+ );
967
+ Checkbox.displayName = "Checkbox";
968
+ var Input = forwardRef(
969
+ ({ className, type = "text", error = false, "aria-invalid": ariaInvalid, ...props }, ref) => /* @__PURE__ */ jsx(
970
+ "input",
971
+ {
972
+ ref,
973
+ "aria-invalid": ariaInvalid ?? (error || void 0),
974
+ className: cn(
975
+ "flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm text-foreground shadow-sm transition-colors motion-reduce:transition-none file:border-0 file:bg-transparent file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50",
976
+ error && "border-destructive focus-visible:ring-destructive",
977
+ className
978
+ ),
979
+ type,
980
+ ...props
981
+ }
982
+ )
983
+ );
984
+ Input.displayName = "Input";
985
+ var Label = forwardRef(
986
+ ({ className, required = false, optional = false, error = false, children, ...props }, ref) => /* @__PURE__ */ jsxs(
987
+ LabelPrimitive.Root,
988
+ {
989
+ ref,
990
+ className: cn(
991
+ "text-sm font-medium leading-none text-foreground peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
992
+ error && "text-destructive",
993
+ className
994
+ ),
995
+ ...props,
996
+ children: [
997
+ children,
998
+ required ? /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "ml-1 text-destructive", children: "*" }) : null,
999
+ optional && !required ? /* @__PURE__ */ jsx("span", { className: "ml-1 text-xs font-normal text-muted-foreground", children: "Optional" }) : null
1000
+ ]
1001
+ }
1002
+ )
1003
+ );
1004
+ Label.displayName = "Label";
1005
+ var RadioGroup = forwardRef(
1006
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx(RadioGroupPrimitive.Root, { ref, className: cn("grid gap-2", className), ...props })
1007
+ );
1008
+ RadioGroup.displayName = "RadioGroup";
1009
+ var RadioGroupItem = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
1010
+ RadioGroupPrimitive.Item,
1011
+ {
1012
+ ref,
1013
+ className: cn(
1014
+ "aspect-square size-4 rounded-full border border-primary bg-background text-primary shadow-sm transition-colors motion-reduce:transition-none focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
1015
+ className
1016
+ ),
1017
+ ...props,
1018
+ children: /* @__PURE__ */ jsx(RadioGroupPrimitive.Indicator, { className: "flex items-center justify-center", children: /* @__PURE__ */ jsx("span", { className: "size-2 rounded-full bg-current" }) })
1019
+ }
1020
+ ));
1021
+ RadioGroupItem.displayName = "RadioGroupItem";
1022
+ var Select = SelectPrimitive.Root;
1023
+ var SelectTrigger = forwardRef(({ className, children, placeholder = "Select an option", ...props }, ref) => /* @__PURE__ */ jsxs(
1024
+ SelectPrimitive.Trigger,
1025
+ {
1026
+ ref,
1027
+ className: cn(
1028
+ "flex h-10 w-full items-center justify-between rounded-md border border-input bg-background px-3 py-2 text-sm text-foreground shadow-sm transition-colors motion-reduce:transition-none placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring disabled:cursor-not-allowed disabled:opacity-50 data-[placeholder]:text-muted-foreground",
1029
+ className
1030
+ ),
1031
+ ...props,
1032
+ children: [
1033
+ children ?? /* @__PURE__ */ jsx(SelectPrimitive.Value, { placeholder }),
1034
+ /* @__PURE__ */ jsx(SelectPrimitive.Icon, { "aria-hidden": "true", className: "ml-2 text-muted-foreground", children: "\u2304" })
1035
+ ]
1036
+ }
1037
+ ));
1038
+ SelectTrigger.displayName = "SelectTrigger";
1039
+ var SelectContent = forwardRef(({ className, children, position = "popper", ...props }, ref) => /* @__PURE__ */ jsx(SelectPrimitive.Portal, { children: /* @__PURE__ */ jsx(
1040
+ SelectPrimitive.Content,
1041
+ {
1042
+ ref,
1043
+ className: cn(
1044
+ "relative z-50 max-h-96 min-w-32 overflow-hidden rounded-md border border-border bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in motion-reduce:animate-none",
1045
+ position === "popper" && "data-[side=bottom]:translate-y-1 data-[side=top]:-translate-y-1",
1046
+ className
1047
+ ),
1048
+ position,
1049
+ ...props,
1050
+ children: /* @__PURE__ */ jsx(
1051
+ SelectPrimitive.Viewport,
1052
+ {
1053
+ className: cn("p-1", position === "popper" && "min-w-[var(--radix-select-trigger-width)]"),
1054
+ children
1055
+ }
1056
+ )
1057
+ }
1058
+ ) }));
1059
+ SelectContent.displayName = "SelectContent";
1060
+ var SelectItem = forwardRef(
1061
+ ({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
1062
+ SelectPrimitive.Item,
1063
+ {
1064
+ ref,
1065
+ className: cn(
1066
+ "relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pr-8 pl-2 text-sm outline-none transition-colors motion-reduce:transition-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
1067
+ className
1068
+ ),
1069
+ ...props,
1070
+ children: [
1071
+ /* @__PURE__ */ jsx(SelectPrimitive.ItemText, { children }),
1072
+ /* @__PURE__ */ jsx(SelectPrimitive.ItemIndicator, { className: "absolute right-2 inline-flex items-center", children: "\u2713" })
1073
+ ]
1074
+ }
1075
+ )
1076
+ );
1077
+ SelectItem.displayName = "SelectItem";
1078
+ var Separator = forwardRef(
1079
+ ({ className, orientation = "horizontal", decorative = true, ...props }, ref) => /* @__PURE__ */ jsx(
1080
+ SeparatorPrimitive.Root,
1081
+ {
1082
+ ref,
1083
+ className: cn(
1084
+ "shrink-0 bg-border",
1085
+ orientation === "horizontal" ? "h-px w-full" : "h-full w-px",
1086
+ className
1087
+ ),
1088
+ decorative,
1089
+ orientation,
1090
+ ...props
1091
+ }
1092
+ )
1093
+ );
1094
+ Separator.displayName = "Separator";
1095
+ var spinnerSizes = {
1096
+ sm: "size-4 border-2",
1097
+ md: "size-6 border-2",
1098
+ lg: "size-8 border-4"
1099
+ };
1100
+ function Spinner({ className, label = "Loading", size = "md", ...props }) {
1101
+ return /* @__PURE__ */ jsx("span", { "aria-label": label, role: "status", className: "inline-flex items-center", ...props, children: /* @__PURE__ */ jsx(
1102
+ "span",
1103
+ {
1104
+ "aria-hidden": "true",
1105
+ className: cn(
1106
+ "inline-block animate-spin rounded-full border-current border-t-transparent text-primary motion-reduce:animate-none",
1107
+ spinnerSizes[size],
1108
+ className
1109
+ )
1110
+ }
1111
+ ) });
1112
+ }
1113
+ var Switch = forwardRef(
1114
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
1115
+ SwitchPrimitive.Root,
1116
+ {
1117
+ ref,
1118
+ className: cn(
1119
+ "peer inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent bg-input shadow-sm transition-colors motion-reduce:transition-none focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input",
1120
+ className
1121
+ ),
1122
+ ...props,
1123
+ children: /* @__PURE__ */ jsx(SwitchPrimitive.Thumb, { className: "pointer-events-none block size-5 rounded-full bg-background shadow-lg ring-0 transition-transform motion-reduce:transition-none data-[state=checked]:translate-x-5 data-[state=unchecked]:translate-x-0" })
1124
+ }
1125
+ )
1126
+ );
1127
+ Switch.displayName = "Switch";
1128
+ var resizeClasses = {
1129
+ none: "resize-none",
1130
+ vertical: "resize-y",
1131
+ horizontal: "resize-x",
1132
+ both: "resize"
1133
+ };
1134
+ var Textarea = forwardRef(
1135
+ ({ className, error = false, resize = "vertical", "aria-invalid": ariaInvalid, ...props }, ref) => /* @__PURE__ */ jsx(
1136
+ "textarea",
1137
+ {
1138
+ ref,
1139
+ "aria-invalid": ariaInvalid ?? (error || void 0),
1140
+ className: cn(
1141
+ "flex min-h-24 w-full rounded-md border border-input bg-background px-3 py-2 text-sm text-foreground shadow-sm transition-colors motion-reduce:transition-none placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50",
1142
+ resizeClasses[resize],
1143
+ error && "border-destructive focus-visible:ring-destructive",
1144
+ className
1145
+ ),
1146
+ ...props
1147
+ }
1148
+ )
1149
+ );
1150
+ Textarea.displayName = "Textarea";
1151
+ var variants = {
1152
+ info: "border-primary/40 bg-primary/10 text-foreground",
1153
+ success: "border-green-500/40 bg-green-500/10 text-foreground",
1154
+ warning: "border-yellow-500/40 bg-yellow-500/10 text-foreground",
1155
+ error: "border-destructive/40 bg-destructive/10 text-foreground",
1156
+ destructive: "border-destructive bg-destructive/10 text-destructive"
1157
+ };
1158
+ var Alert = forwardRef(
1159
+ ({ className, variant = "info", ...props }, ref) => /* @__PURE__ */ jsx(
1160
+ "div",
1161
+ {
1162
+ ref,
1163
+ role: "alert",
1164
+ className: cn("relative w-full rounded-lg border p-4", variants[variant], className),
1165
+ ...props
1166
+ }
1167
+ )
1168
+ );
1169
+ Alert.displayName = "Alert";
1170
+ var AlertTitle = forwardRef(
1171
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx("h5", { ref, className: cn("mb-1 font-medium leading-none", className), ...props })
1172
+ );
1173
+ AlertTitle.displayName = "AlertTitle";
1174
+ var AlertDescription = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("p", { ref, className: cn("text-sm [&_p]:leading-relaxed", className), ...props }));
1175
+ AlertDescription.displayName = "AlertDescription";
1176
+ var AspectRatio = AspectRatioPrimitive.Root;
1177
+ var Breadcrumb = forwardRef(
1178
+ ({ label = "breadcrumb", ...props }, ref) => /* @__PURE__ */ jsx("nav", { ref, "aria-label": label, ...props })
1179
+ );
1180
+ Breadcrumb.displayName = "Breadcrumb";
1181
+ var BreadcrumbList = forwardRef(
1182
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
1183
+ "ol",
1184
+ {
1185
+ ref,
1186
+ className: cn(
1187
+ "flex flex-wrap items-center gap-1.5 break-words text-muted-foreground text-sm",
1188
+ className
1189
+ ),
1190
+ ...props
1191
+ }
1192
+ )
1193
+ );
1194
+ BreadcrumbList.displayName = "BreadcrumbList";
1195
+ var BreadcrumbItem = forwardRef(
1196
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx("li", { ref, className: cn("inline-flex items-center gap-1.5", className), ...props })
1197
+ );
1198
+ BreadcrumbItem.displayName = "BreadcrumbItem";
1199
+ var BreadcrumbLink = forwardRef(
1200
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
1201
+ "a",
1202
+ {
1203
+ ref,
1204
+ className: cn(
1205
+ "transition-colors motion-reduce:transition-none hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
1206
+ className
1207
+ ),
1208
+ ...props
1209
+ }
1210
+ )
1211
+ );
1212
+ BreadcrumbLink.displayName = "BreadcrumbLink";
1213
+ var BreadcrumbPage = forwardRef(
1214
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
1215
+ "span",
1216
+ {
1217
+ ref,
1218
+ "aria-current": "page",
1219
+ className: cn("font-normal text-foreground", className),
1220
+ ...props
1221
+ }
1222
+ )
1223
+ );
1224
+ BreadcrumbPage.displayName = "BreadcrumbPage";
1225
+ var BreadcrumbSeparator = forwardRef(
1226
+ ({ children = "/", className, ...props }, ref) => /* @__PURE__ */ jsx("li", { ref, "aria-hidden": "true", className: cn("select-none", className), ...props, children })
1227
+ );
1228
+ BreadcrumbSeparator.displayName = "BreadcrumbSeparator";
1229
+ var BreadcrumbEllipsis = forwardRef(
1230
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
1231
+ "span",
1232
+ {
1233
+ ref,
1234
+ role: "img",
1235
+ "aria-label": "More pages",
1236
+ className: cn("flex size-9 items-center justify-center", className),
1237
+ ...props,
1238
+ children: "\u2026"
1239
+ }
1240
+ )
1241
+ );
1242
+ BreadcrumbEllipsis.displayName = "BreadcrumbEllipsis";
1243
+ function Calendar({ className, showOutsideDays = true, ...props }) {
1244
+ return /* @__PURE__ */ jsx(
1245
+ DayPicker,
1246
+ {
1247
+ showOutsideDays,
1248
+ className: cn(
1249
+ "rounded-md border border-border bg-popover p-3 text-popover-foreground",
1250
+ className
1251
+ ),
1252
+ ...props
1253
+ }
1254
+ );
1255
+ }
1256
+ var Table = forwardRef(
1257
+ ({ className, label, ...props }, ref) => /* @__PURE__ */ jsx("div", { className: "w-full overflow-auto", children: /* @__PURE__ */ jsx(
1258
+ "table",
1259
+ {
1260
+ ref,
1261
+ "aria-label": label,
1262
+ className: cn("w-full caption-bottom text-sm", className),
1263
+ ...props
1264
+ }
1265
+ ) })
1266
+ );
1267
+ Table.displayName = "Table";
1268
+ var TableHeader = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("thead", { ref, className: cn("border-b", className), ...props }));
1269
+ TableHeader.displayName = "TableHeader";
1270
+ var TableBody = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("tbody", { ref, className: cn("[&_tr:last-child]:border-0", className), ...props }));
1271
+ TableBody.displayName = "TableBody";
1272
+ var TableFooter = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("tfoot", { ref, className: cn("border-t bg-muted/50 font-medium", className), ...props }));
1273
+ TableFooter.displayName = "TableFooter";
1274
+ var TableRow = forwardRef(
1275
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
1276
+ "tr",
1277
+ {
1278
+ ref,
1279
+ className: cn(
1280
+ "border-b transition-colors motion-reduce:transition-none hover:bg-muted/50 data-[state=selected]:bg-muted",
1281
+ className
1282
+ ),
1283
+ ...props
1284
+ }
1285
+ )
1286
+ );
1287
+ TableRow.displayName = "TableRow";
1288
+ var TableHead = forwardRef(
1289
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
1290
+ "th",
1291
+ {
1292
+ ref,
1293
+ className: cn(
1294
+ "h-10 px-2 text-left align-middle font-medium text-muted-foreground",
1295
+ className
1296
+ ),
1297
+ ...props
1298
+ }
1299
+ )
1300
+ );
1301
+ TableHead.displayName = "TableHead";
1302
+ var TableCell = forwardRef(
1303
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx("td", { ref, className: cn("p-2 align-middle", className), ...props })
1304
+ );
1305
+ TableCell.displayName = "TableCell";
1306
+ var TableCaption = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("caption", { ref, className: cn("mt-4 text-muted-foreground text-sm", className), ...props }));
1307
+ TableCaption.displayName = "TableCaption";
1308
+ function DataTable({
1309
+ columns,
1310
+ data,
1311
+ filterPlaceholder = "Filter rows...",
1312
+ loading = false,
1313
+ emptyMessage = "No results."
1314
+ }) {
1315
+ const table = useReactTable({
1316
+ data,
1317
+ columns,
1318
+ getCoreRowModel: getCoreRowModel(),
1319
+ getSortedRowModel: getSortedRowModel(),
1320
+ getFilteredRowModel: getFilteredRowModel(),
1321
+ getPaginationRowModel: getPaginationRowModel()
1322
+ });
1323
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
1324
+ /* @__PURE__ */ jsx(
1325
+ Input,
1326
+ {
1327
+ type: "search",
1328
+ placeholder: filterPlaceholder,
1329
+ value: table.getState().globalFilter ?? "",
1330
+ onChange: (event) => table.setGlobalFilter(event.target.value)
1331
+ }
1332
+ ),
1333
+ /* @__PURE__ */ jsxs(Table, { children: [
1334
+ /* @__PURE__ */ jsx(TableHeader, { children: table.getHeaderGroups().map((group) => /* @__PURE__ */ jsx(TableRow, { children: group.headers.map((header) => /* @__PURE__ */ jsx(TableHead, { children: header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext()) }, header.id)) }, group.id)) }),
1335
+ /* @__PURE__ */ jsx(TableBody, { children: loading ? /* @__PURE__ */ jsx(TableRow, { children: /* @__PURE__ */ jsx(TableCell, { colSpan: columns.length, children: "Loading..." }) }) : table.getRowModel().rows.length ? table.getRowModel().rows.map((row) => /* @__PURE__ */ jsx(TableRow, { children: row.getVisibleCells().map((cell) => /* @__PURE__ */ jsx(TableCell, { children: flexRender(cell.column.columnDef.cell, cell.getContext()) }, cell.id)) }, row.id)) : /* @__PURE__ */ jsx(TableRow, { children: /* @__PURE__ */ jsx(TableCell, { colSpan: columns.length, children: emptyMessage }) }) })
1336
+ ] }),
1337
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-2", children: [
1338
+ /* @__PURE__ */ jsx(
1339
+ Button,
1340
+ {
1341
+ variant: "outline",
1342
+ size: "sm",
1343
+ disabled: !table.getCanPreviousPage(),
1344
+ onClick: () => table.previousPage(),
1345
+ children: "Previous"
1346
+ }
1347
+ ),
1348
+ /* @__PURE__ */ jsx(
1349
+ Button,
1350
+ {
1351
+ variant: "outline",
1352
+ size: "sm",
1353
+ disabled: !table.getCanNextPage(),
1354
+ onClick: () => table.nextPage(),
1355
+ children: "Next"
1356
+ }
1357
+ )
1358
+ ] })
1359
+ ] });
1360
+ }
1361
+ var Popover = PopoverPrimitive.Root;
1362
+ var PopoverTrigger = PopoverPrimitive.Trigger;
1363
+ var PopoverAnchor = PopoverPrimitive.Anchor;
1364
+ var PopoverContent = forwardRef(({ className, sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx(PopoverPrimitive.Portal, { children: /* @__PURE__ */ jsx(
1365
+ PopoverPrimitive.Content,
1366
+ {
1367
+ ref,
1368
+ sideOffset,
1369
+ className: cn(
1370
+ "z-50 w-72 rounded-md border border-border bg-popover p-4 text-popover-foreground shadow-md outline-none data-[state=closed]:animate-out data-[state=open]:animate-in motion-reduce:animate-none",
1371
+ className
1372
+ ),
1373
+ ...props
1374
+ }
1375
+ ) }));
1376
+ PopoverContent.displayName = "PopoverContent";
1377
+ function DateRangePicker({
1378
+ value,
1379
+ onChange,
1380
+ placeholder = "Pick a date range"
1381
+ }) {
1382
+ const label = value?.from ? value.to ? `${format(value.from, "LLL dd, y")} - ${format(value.to, "LLL dd, y")}` : format(value.from, "LLL dd, y") : placeholder;
1383
+ return /* @__PURE__ */ jsxs(Popover, { children: [
1384
+ /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx(Button, { variant: "outline", children: label }) }),
1385
+ /* @__PURE__ */ jsx(PopoverContent, { className: "w-auto p-0", align: "start", children: /* @__PURE__ */ jsx(Calendar, { mode: "range", selected: value, onSelect: onChange, numberOfMonths: 2 }) })
1386
+ ] });
1387
+ }
1388
+ var Pagination = forwardRef(({ label = "pagination", ...props }, ref) => /* @__PURE__ */ jsx("nav", { ref, "aria-label": label, ...props }));
1389
+ Pagination.displayName = "Pagination";
1390
+ var PaginationContent = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("ul", { ref, className: cn("flex flex-row items-center gap-1", className), ...props }));
1391
+ PaginationContent.displayName = "PaginationContent";
1392
+ var PaginationItem = forwardRef((props, ref) => /* @__PURE__ */ jsx("li", { ref, ...props }));
1393
+ PaginationItem.displayName = "PaginationItem";
1394
+ var PaginationLink = forwardRef(({ className, isActive = false, ...props }, ref) => /* @__PURE__ */ jsx(
1395
+ "a",
1396
+ {
1397
+ ref,
1398
+ "aria-current": isActive ? "page" : void 0,
1399
+ className: cn(
1400
+ "inline-flex size-10 items-center justify-center rounded-md text-sm transition-colors motion-reduce:transition-none hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
1401
+ isActive && "border border-input bg-background",
1402
+ className
1403
+ ),
1404
+ ...props
1405
+ }
1406
+ ));
1407
+ PaginationLink.displayName = "PaginationLink";
1408
+ var PaginationPrevious = forwardRef(({ children = "Previous", ...props }, ref) => /* @__PURE__ */ jsx(PaginationLink, { ref, "aria-label": "Go to previous page", ...props, children }));
1409
+ PaginationPrevious.displayName = "PaginationPrevious";
1410
+ var PaginationNext = forwardRef(({ children = "Next", ...props }, ref) => /* @__PURE__ */ jsx(PaginationLink, { ref, "aria-label": "Go to next page", ...props, children }));
1411
+ PaginationNext.displayName = "PaginationNext";
1412
+ function PaginationEllipsis(props) {
1413
+ return /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "flex size-10 items-center justify-center", ...props, children: "\u2026" });
1414
+ }
1415
+ var Progress = forwardRef(({ className, value = 0, ...props }, ref) => /* @__PURE__ */ jsx(
1416
+ ProgressPrimitive.Root,
1417
+ {
1418
+ ref,
1419
+ value,
1420
+ className: cn("relative h-2 w-full overflow-hidden rounded-full bg-muted", className),
1421
+ ...props,
1422
+ children: /* @__PURE__ */ jsx(
1423
+ ProgressPrimitive.Indicator,
1424
+ {
1425
+ className: "h-full w-full flex-1 bg-primary transition-all motion-reduce:transition-none",
1426
+ style: { transform: `translateX(-${100 - value}%)` }
1427
+ }
1428
+ )
1429
+ }
1430
+ ));
1431
+ Progress.displayName = "Progress";
1432
+ var ScrollArea = forwardRef(
1433
+ ({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
1434
+ ScrollAreaPrimitive.Root,
1435
+ {
1436
+ ref,
1437
+ className: cn("relative overflow-hidden", className),
1438
+ ...props,
1439
+ children: [
1440
+ /* @__PURE__ */ jsx(ScrollAreaPrimitive.Viewport, { className: "h-full w-full rounded-[inherit]", children }),
1441
+ /* @__PURE__ */ jsx(
1442
+ ScrollAreaPrimitive.Scrollbar,
1443
+ {
1444
+ orientation: "vertical",
1445
+ className: "flex touch-none select-none p-0.5",
1446
+ children: /* @__PURE__ */ jsx(ScrollAreaPrimitive.Thumb, { className: "relative flex-1 rounded-full bg-border" })
1447
+ }
1448
+ ),
1449
+ /* @__PURE__ */ jsx(ScrollAreaPrimitive.Corner, {})
1450
+ ]
1451
+ }
1452
+ )
1453
+ );
1454
+ ScrollArea.displayName = "ScrollArea";
1455
+ var Skeleton = forwardRef(({ className, animated = true, ...props }, ref) => /* @__PURE__ */ jsx(
1456
+ "div",
1457
+ {
1458
+ ref,
1459
+ "aria-hidden": "true",
1460
+ className: cn(
1461
+ "rounded-md bg-muted",
1462
+ animated && "animate-pulse motion-reduce:animate-none",
1463
+ className
1464
+ ),
1465
+ ...props
1466
+ }
1467
+ ));
1468
+ Skeleton.displayName = "Skeleton";
1469
+ var Accordion = AccordionPrimitive.Root;
1470
+ var AccordionItem = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
1471
+ AccordionPrimitive.Item,
1472
+ {
1473
+ ref,
1474
+ className: cn("border-b border-border", className),
1475
+ ...props
1476
+ }
1477
+ ));
1478
+ AccordionItem.displayName = "AccordionItem";
1479
+ var AccordionTrigger = forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsx(AccordionPrimitive.Header, { className: "flex", children: /* @__PURE__ */ jsxs(
1480
+ AccordionPrimitive.Trigger,
1481
+ {
1482
+ ref,
1483
+ className: cn(
1484
+ "flex flex-1 items-center justify-between py-4 font-medium text-sm transition-all motion-reduce:transition-none hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring data-[state=open]:[&>span]:rotate-180",
1485
+ className
1486
+ ),
1487
+ ...props,
1488
+ children: [
1489
+ children,
1490
+ /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "transition-transform motion-reduce:transition-none", children: "\u2304" })
1491
+ ]
1492
+ }
1493
+ ) }));
1494
+ AccordionTrigger.displayName = "AccordionTrigger";
1495
+ var AccordionContent = forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsx(
1496
+ AccordionPrimitive.Content,
1497
+ {
1498
+ ref,
1499
+ className: "overflow-hidden text-sm data-[state=closed]:animate-out data-[state=open]:animate-in motion-reduce:animate-none",
1500
+ ...props,
1501
+ children: /* @__PURE__ */ jsx("div", { className: cn("pb-4 pt-0", className), children })
1502
+ }
1503
+ ));
1504
+ AccordionContent.displayName = "AccordionContent";
1505
+ var AlertDialog = AlertDialogPrimitive.Root;
1506
+ var AlertDialogTrigger = AlertDialogPrimitive.Trigger;
1507
+ var AlertDialogPortal = AlertDialogPrimitive.Portal;
1508
+ var AlertDialogOverlay = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
1509
+ AlertDialogPrimitive.Overlay,
1510
+ {
1511
+ ref,
1512
+ className: cn(
1513
+ "fixed inset-0 z-50 bg-background/80 backdrop-blur-sm data-[state=closed]:animate-out data-[state=open]:animate-in motion-reduce:animate-none",
1514
+ className
1515
+ ),
1516
+ ...props
1517
+ }
1518
+ ));
1519
+ AlertDialogOverlay.displayName = "AlertDialogOverlay";
1520
+ var AlertDialogContent = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxs(AlertDialogPortal, { children: [
1521
+ /* @__PURE__ */ jsx(AlertDialogOverlay, {}),
1522
+ /* @__PURE__ */ jsx(
1523
+ AlertDialogPrimitive.Content,
1524
+ {
1525
+ ref,
1526
+ className: cn(
1527
+ "fixed top-1/2 left-1/2 z-50 grid w-[calc(100%-2rem)] max-w-lg -translate-x-1/2 -translate-y-1/2 gap-4 rounded-xl border border-border bg-popover p-6 text-popover-foreground shadow-lg duration-200 data-[state=closed]:animate-out data-[state=open]:animate-in motion-reduce:animate-none sm:w-full",
1528
+ className
1529
+ ),
1530
+ ...props
1531
+ }
1532
+ )
1533
+ ] }));
1534
+ AlertDialogContent.displayName = "AlertDialogContent";
1535
+ function AlertDialogHeader({ className, ...props }) {
1536
+ return /* @__PURE__ */ jsx(
1537
+ "div",
1538
+ {
1539
+ className: cn("flex flex-col space-y-1.5 text-center sm:text-left", className),
1540
+ ...props
1541
+ }
1542
+ );
1543
+ }
1544
+ function AlertDialogFooter({ className, ...props }) {
1545
+ return /* @__PURE__ */ jsx(
1546
+ "div",
1547
+ {
1548
+ className: cn("flex flex-col-reverse gap-2 sm:flex-row sm:justify-end", className),
1549
+ ...props
1550
+ }
1551
+ );
1552
+ }
1553
+ var AlertDialogTitle = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
1554
+ AlertDialogPrimitive.Title,
1555
+ {
1556
+ ref,
1557
+ className: cn("font-semibold text-lg leading-none tracking-tight", className),
1558
+ ...props
1559
+ }
1560
+ ));
1561
+ AlertDialogTitle.displayName = "AlertDialogTitle";
1562
+ var AlertDialogDescription = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
1563
+ AlertDialogPrimitive.Description,
1564
+ {
1565
+ ref,
1566
+ className: cn("text-muted-foreground text-sm", className),
1567
+ ...props
1568
+ }
1569
+ ));
1570
+ AlertDialogDescription.displayName = "AlertDialogDescription";
1571
+ var AlertDialogCancel = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
1572
+ AlertDialogPrimitive.Cancel,
1573
+ {
1574
+ ref,
1575
+ className: cn(
1576
+ "inline-flex h-10 items-center justify-center rounded-md border border-input bg-background px-4 py-2 font-medium text-sm shadow-sm transition-colors motion-reduce:transition-none hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
1577
+ className
1578
+ ),
1579
+ ...props
1580
+ }
1581
+ ));
1582
+ AlertDialogCancel.displayName = "AlertDialogCancel";
1583
+ var AlertDialogAction = forwardRef(({ className, intent = "default", ...props }, ref) => /* @__PURE__ */ jsx(
1584
+ AlertDialogPrimitive.Action,
1585
+ {
1586
+ ref,
1587
+ className: cn(
1588
+ "inline-flex h-10 items-center justify-center rounded-md px-4 py-2 font-medium text-sm shadow-sm transition-colors motion-reduce:transition-none focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
1589
+ intent === "destructive" ? "bg-destructive text-destructive-foreground hover:bg-destructive/90" : "bg-primary text-primary-foreground hover:bg-primary/90",
1590
+ className
1591
+ ),
1592
+ ...props
1593
+ }
1594
+ ));
1595
+ AlertDialogAction.displayName = "AlertDialogAction";
1596
+ var Card = forwardRef(
1597
+ ({ className, density = "default", ...props }, ref) => /* @__PURE__ */ jsx(
1598
+ "div",
1599
+ {
1600
+ ref,
1601
+ className: cn(
1602
+ "rounded-xl border border-border bg-card text-card-foreground shadow-sm transition-colors motion-reduce:transition-none",
1603
+ density === "compact" && "text-sm",
1604
+ className
1605
+ ),
1606
+ ...props
1607
+ }
1608
+ )
1609
+ );
1610
+ Card.displayName = "Card";
1611
+ var CardHeader = forwardRef(
1612
+ ({ className, density = "default", ...props }, ref) => /* @__PURE__ */ jsx(
1613
+ "div",
1614
+ {
1615
+ ref,
1616
+ className: cn("flex flex-col space-y-1.5", density === "compact" ? "p-4" : "p-6", className),
1617
+ ...props
1618
+ }
1619
+ )
1620
+ );
1621
+ CardHeader.displayName = "CardHeader";
1622
+ var CardTitle = forwardRef(
1623
+ ({ className, as: Heading = "h3", ...props }, ref) => /* @__PURE__ */ jsx(
1624
+ Heading,
1625
+ {
1626
+ ref,
1627
+ className: cn("font-semibold leading-none tracking-tight text-card-foreground", className),
1628
+ ...props
1629
+ }
1630
+ )
1631
+ );
1632
+ CardTitle.displayName = "CardTitle";
1633
+ var CardDescription = forwardRef(
1634
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx("p", { ref, className: cn("text-sm text-muted-foreground", className), ...props })
1635
+ );
1636
+ CardDescription.displayName = "CardDescription";
1637
+ var CardContent = forwardRef(
1638
+ ({ className, density = "default", ...props }, ref) => /* @__PURE__ */ jsx(
1639
+ "div",
1640
+ {
1641
+ ref,
1642
+ className: cn(density === "compact" ? "p-4 pt-0" : "p-6 pt-0", className),
1643
+ ...props
1644
+ }
1645
+ )
1646
+ );
1647
+ CardContent.displayName = "CardContent";
1648
+ var CardFooter = forwardRef(
1649
+ ({ className, density = "default", ...props }, ref) => /* @__PURE__ */ jsx(
1650
+ "div",
1651
+ {
1652
+ ref,
1653
+ className: cn(
1654
+ "flex items-center gap-2",
1655
+ density === "compact" ? "p-4 pt-0" : "p-6 pt-0",
1656
+ className
1657
+ ),
1658
+ ...props
1659
+ }
1660
+ )
1661
+ );
1662
+ CardFooter.displayName = "CardFooter";
1663
+ var Dialog = DialogPrimitive.Root;
1664
+ var DialogTrigger = DialogPrimitive.Trigger;
1665
+ var DialogClose = DialogPrimitive.Close;
1666
+ var DialogPortal = DialogPrimitive.Portal;
1667
+ var DialogOverlay = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
1668
+ DialogPrimitive.Overlay,
1669
+ {
1670
+ ref,
1671
+ className: cn(
1672
+ "fixed inset-0 z-50 bg-background/80 backdrop-blur-sm data-[state=closed]:animate-out data-[state=open]:animate-in motion-reduce:animate-none",
1673
+ className
1674
+ ),
1675
+ ...props
1676
+ }
1677
+ ));
1678
+ DialogOverlay.displayName = "DialogOverlay";
1679
+ var DialogContent = forwardRef(({ className, children, showClose = true, ...props }, ref) => /* @__PURE__ */ jsxs(DialogPortal, { children: [
1680
+ /* @__PURE__ */ jsx(DialogOverlay, {}),
1681
+ /* @__PURE__ */ jsxs(
1682
+ DialogPrimitive.Content,
1683
+ {
1684
+ ref,
1685
+ className: cn(
1686
+ "fixed top-1/2 left-1/2 z-50 grid w-[calc(100%-2rem)] max-w-lg -translate-x-1/2 -translate-y-1/2 gap-4 rounded-xl border border-border bg-popover p-6 text-popover-foreground shadow-lg duration-200 data-[state=closed]:animate-out data-[state=open]:animate-in motion-reduce:animate-none sm:w-full",
1687
+ className
1688
+ ),
1689
+ ...props,
1690
+ children: [
1691
+ children,
1692
+ showClose ? /* @__PURE__ */ jsxs(DialogPrimitive.Close, { className: "absolute top-4 right-4 rounded-sm opacity-70 transition-opacity motion-reduce:transition-none hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none", children: [
1693
+ /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "\xD7" }),
1694
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Close" })
1695
+ ] }) : null
1696
+ ]
1697
+ }
1698
+ )
1699
+ ] }));
1700
+ DialogContent.displayName = "DialogContent";
1701
+ function DialogHeader({ className, ...props }) {
1702
+ return /* @__PURE__ */ jsx(
1703
+ "div",
1704
+ {
1705
+ className: cn("flex flex-col space-y-1.5 text-center sm:text-left", className),
1706
+ ...props
1707
+ }
1708
+ );
1709
+ }
1710
+ function DialogFooter({ className, ...props }) {
1711
+ return /* @__PURE__ */ jsx(
1712
+ "div",
1713
+ {
1714
+ className: cn("flex flex-col-reverse gap-2 sm:flex-row sm:justify-end", className),
1715
+ ...props
1716
+ }
1717
+ );
1718
+ }
1719
+ var DialogTitle = forwardRef(
1720
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
1721
+ DialogPrimitive.Title,
1722
+ {
1723
+ ref,
1724
+ className: cn("font-semibold text-lg leading-none tracking-tight", className),
1725
+ ...props
1726
+ }
1727
+ )
1728
+ );
1729
+ DialogTitle.displayName = "DialogTitle";
1730
+ var DialogDescription = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
1731
+ DialogPrimitive.Description,
1732
+ {
1733
+ ref,
1734
+ className: cn("text-muted-foreground text-sm", className),
1735
+ ...props
1736
+ }
1737
+ ));
1738
+ DialogDescription.displayName = "DialogDescription";
1739
+ var Command = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
1740
+ Command$1,
1741
+ {
1742
+ ref,
1743
+ className: cn(
1744
+ "flex h-full w-full flex-col overflow-hidden rounded-md bg-popover text-popover-foreground",
1745
+ className
1746
+ ),
1747
+ ...props
1748
+ }
1749
+ ));
1750
+ Command.displayName = "Command";
1751
+ function CommandDialog({ children, ...props }) {
1752
+ return /* @__PURE__ */ jsx(Dialog, { ...props, children: /* @__PURE__ */ jsx(DialogContent, { className: "overflow-hidden p-0", children: /* @__PURE__ */ jsx(Command, { children }) }) });
1753
+ }
1754
+ var CommandInput = forwardRef(
1755
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { className: "flex items-center border-b px-3", children: /* @__PURE__ */ jsx(
1756
+ Command$1.Input,
1757
+ {
1758
+ ref,
1759
+ className: cn(
1760
+ "flex h-11 w-full rounded-md bg-transparent py-3 text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50",
1761
+ className
1762
+ ),
1763
+ ...props
1764
+ }
1765
+ ) })
1766
+ );
1767
+ CommandInput.displayName = "CommandInput";
1768
+ var CommandList = forwardRef(
1769
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
1770
+ Command$1.List,
1771
+ {
1772
+ ref,
1773
+ className: cn("max-h-72 overflow-y-auto overflow-x-hidden", className),
1774
+ ...props
1775
+ }
1776
+ )
1777
+ );
1778
+ CommandList.displayName = "CommandList";
1779
+ var CommandEmpty = forwardRef(
1780
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
1781
+ Command$1.Empty,
1782
+ {
1783
+ ref,
1784
+ className: cn("py-6 text-center text-muted-foreground text-sm", className),
1785
+ ...props
1786
+ }
1787
+ )
1788
+ );
1789
+ CommandEmpty.displayName = "CommandEmpty";
1790
+ var CommandGroup = forwardRef(
1791
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
1792
+ Command$1.Group,
1793
+ {
1794
+ ref,
1795
+ className: cn("overflow-hidden p-1 text-foreground", className),
1796
+ ...props
1797
+ }
1798
+ )
1799
+ );
1800
+ CommandGroup.displayName = "CommandGroup";
1801
+ var CommandItem = forwardRef(
1802
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
1803
+ Command$1.Item,
1804
+ {
1805
+ ref,
1806
+ className: cn(
1807
+ "relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[disabled=true]:pointer-events-none data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-[disabled=true]:opacity-50",
1808
+ className
1809
+ ),
1810
+ ...props
1811
+ }
1812
+ )
1813
+ );
1814
+ CommandItem.displayName = "CommandItem";
1815
+ var CommandSeparator = forwardRef(
1816
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
1817
+ Command$1.Separator,
1818
+ {
1819
+ ref,
1820
+ className: cn("-mx-1 h-px bg-border", className),
1821
+ ...props
1822
+ }
1823
+ )
1824
+ );
1825
+ CommandSeparator.displayName = "CommandSeparator";
1826
+ function CommandShortcut({ className, ...props }) {
1827
+ return /* @__PURE__ */ jsx(
1828
+ "span",
1829
+ {
1830
+ className: cn("ml-auto text-muted-foreground text-xs tracking-widest", className),
1831
+ ...props
1832
+ }
1833
+ );
1834
+ }
1835
+ var DropdownMenu = DropdownMenuPrimitive.Root;
1836
+ var DropdownMenuTrigger = DropdownMenuPrimitive.Trigger;
1837
+ var DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup;
1838
+ var DropdownMenuContent = forwardRef(({ className, sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx(DropdownMenuPrimitive.Portal, { children: /* @__PURE__ */ jsx(
1839
+ DropdownMenuPrimitive.Content,
1840
+ {
1841
+ ref,
1842
+ sideOffset,
1843
+ className: cn(
1844
+ "z-50 min-w-40 overflow-hidden rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-md data-[state=closed]:animate-out data-[state=open]:animate-in motion-reduce:animate-none",
1845
+ className
1846
+ ),
1847
+ ...props
1848
+ }
1849
+ ) }));
1850
+ DropdownMenuContent.displayName = "DropdownMenuContent";
1851
+ var DropdownMenuItem = forwardRef(({ className, inset = false, ...props }, ref) => /* @__PURE__ */ jsx(
1852
+ DropdownMenuPrimitive.Item,
1853
+ {
1854
+ ref,
1855
+ className: cn(
1856
+ "relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors motion-reduce:transition-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
1857
+ inset && "pl-8",
1858
+ className
1859
+ ),
1860
+ ...props
1861
+ }
1862
+ ));
1863
+ DropdownMenuItem.displayName = "DropdownMenuItem";
1864
+ var DropdownMenuCheckboxItem = forwardRef(({ className, children, checked, ...props }, ref) => /* @__PURE__ */ jsxs(
1865
+ DropdownMenuPrimitive.CheckboxItem,
1866
+ {
1867
+ ref,
1868
+ checked,
1869
+ className: cn(
1870
+ "relative flex cursor-default select-none items-center rounded-sm py-1.5 pr-2 pl-8 text-sm outline-none transition-colors motion-reduce:transition-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
1871
+ className
1872
+ ),
1873
+ ...props,
1874
+ children: [
1875
+ /* @__PURE__ */ jsx("span", { className: "absolute left-2 flex size-3.5 items-center justify-center", children: /* @__PURE__ */ jsx(DropdownMenuPrimitive.ItemIndicator, { children: "\u2713" }) }),
1876
+ children
1877
+ ]
1878
+ }
1879
+ ));
1880
+ DropdownMenuCheckboxItem.displayName = "DropdownMenuCheckboxItem";
1881
+ var DropdownMenuRadioItem = forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
1882
+ DropdownMenuPrimitive.RadioItem,
1883
+ {
1884
+ ref,
1885
+ className: cn(
1886
+ "relative flex cursor-default select-none items-center rounded-sm py-1.5 pr-2 pl-8 text-sm outline-none transition-colors motion-reduce:transition-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
1887
+ className
1888
+ ),
1889
+ ...props,
1890
+ children: [
1891
+ /* @__PURE__ */ jsx("span", { className: "absolute left-2 flex size-3.5 items-center justify-center", children: /* @__PURE__ */ jsx(DropdownMenuPrimitive.ItemIndicator, { children: "\u25CF" }) }),
1892
+ children
1893
+ ]
1894
+ }
1895
+ ));
1896
+ DropdownMenuRadioItem.displayName = "DropdownMenuRadioItem";
1897
+ function DropdownMenuLabel({ className, inset = false, ...props }) {
1898
+ return /* @__PURE__ */ jsx(
1899
+ DropdownMenuPrimitive.Label,
1900
+ {
1901
+ className: cn("px-2 py-1.5 font-semibold text-sm", inset && "pl-8", className),
1902
+ ...props
1903
+ }
1904
+ );
1905
+ }
1906
+ var DropdownMenuSeparator = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
1907
+ DropdownMenuPrimitive.Separator,
1908
+ {
1909
+ ref,
1910
+ className: cn("-mx-1 my-1 h-px bg-border", className),
1911
+ ...props
1912
+ }
1913
+ ));
1914
+ DropdownMenuSeparator.displayName = "DropdownMenuSeparator";
1915
+ function DropdownMenuShortcut({ className, ...props }) {
1916
+ return /* @__PURE__ */ jsx(
1917
+ "span",
1918
+ {
1919
+ className: cn("ml-auto text-muted-foreground text-xs tracking-widest", className),
1920
+ ...props
1921
+ }
1922
+ );
1923
+ }
1924
+ var NavigationMenu = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
1925
+ NavigationMenuPrimitive.Root,
1926
+ {
1927
+ ref,
1928
+ className: cn("relative z-10 flex max-w-max flex-1 items-center justify-center", className),
1929
+ ...props
1930
+ }
1931
+ ));
1932
+ NavigationMenu.displayName = "NavigationMenu";
1933
+ var NavigationMenuList = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
1934
+ NavigationMenuPrimitive.List,
1935
+ {
1936
+ ref,
1937
+ className: cn("group flex flex-1 list-none items-center justify-center gap-1", className),
1938
+ ...props
1939
+ }
1940
+ ));
1941
+ NavigationMenuList.displayName = "NavigationMenuList";
1942
+ var NavigationMenuItem = NavigationMenuPrimitive.Item;
1943
+ var NavigationMenuTrigger = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
1944
+ NavigationMenuPrimitive.Trigger,
1945
+ {
1946
+ ref,
1947
+ className: cn(
1948
+ "inline-flex h-10 items-center justify-center rounded-md bg-background px-4 py-2 font-medium text-sm transition-colors motion-reduce:transition-none hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
1949
+ className
1950
+ ),
1951
+ ...props
1952
+ }
1953
+ ));
1954
+ NavigationMenuTrigger.displayName = "NavigationMenuTrigger";
1955
+ var NavigationMenuContent = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
1956
+ NavigationMenuPrimitive.Content,
1957
+ {
1958
+ ref,
1959
+ className: cn(
1960
+ "left-0 top-0 w-full rounded-md border border-border bg-popover p-4 text-popover-foreground shadow-md md:absolute md:w-auto",
1961
+ className
1962
+ ),
1963
+ ...props
1964
+ }
1965
+ ));
1966
+ NavigationMenuContent.displayName = "NavigationMenuContent";
1967
+ var NavigationMenuLink = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
1968
+ NavigationMenuPrimitive.Link,
1969
+ {
1970
+ ref,
1971
+ className: cn(
1972
+ "block rounded-md p-2 text-sm transition-colors motion-reduce:transition-none hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
1973
+ className
1974
+ ),
1975
+ ...props
1976
+ }
1977
+ ));
1978
+ NavigationMenuLink.displayName = "NavigationMenuLink";
1979
+ var NavigationMenuViewport = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
1980
+ NavigationMenuPrimitive.Viewport,
1981
+ {
1982
+ ref,
1983
+ className: cn(
1984
+ "origin-top-center relative mt-1.5 h-[var(--radix-navigation-menu-viewport-height)] w-full overflow-hidden rounded-md border border-border bg-popover shadow-lg motion-reduce:transition-none md:w-[var(--radix-navigation-menu-viewport-width)]",
1985
+ className
1986
+ ),
1987
+ ...props
1988
+ }
1989
+ ));
1990
+ NavigationMenuViewport.displayName = "NavigationMenuViewport";
1991
+ var NavigationMenuIndicator = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
1992
+ NavigationMenuPrimitive.Indicator,
1993
+ {
1994
+ ref,
1995
+ className: cn("top-full z-10 flex h-1.5 items-end justify-center overflow-hidden", className),
1996
+ ...props
1997
+ }
1998
+ ));
1999
+ NavigationMenuIndicator.displayName = "NavigationMenuIndicator";
2000
+ var sideClasses = {
2001
+ top: "inset-x-0 top-0 border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top",
2002
+ right: "inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm",
2003
+ bottom: "inset-x-0 bottom-0 border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom",
2004
+ left: "inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm"
2005
+ };
2006
+ var Sheet = DialogPrimitive.Root;
2007
+ var SheetTrigger = DialogPrimitive.Trigger;
2008
+ var SheetClose = DialogPrimitive.Close;
2009
+ var SheetPortal = DialogPrimitive.Portal;
2010
+ var SheetOverlay = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
2011
+ DialogPrimitive.Overlay,
2012
+ {
2013
+ ref,
2014
+ className: cn(
2015
+ "fixed inset-0 z-50 bg-background/80 backdrop-blur-sm data-[state=closed]:animate-out data-[state=open]:animate-in motion-reduce:animate-none",
2016
+ className
2017
+ ),
2018
+ ...props
2019
+ }
2020
+ ));
2021
+ SheetOverlay.displayName = "SheetOverlay";
2022
+ var SheetContent = forwardRef(({ className, children, side = "right", showClose = true, ...props }, ref) => /* @__PURE__ */ jsxs(SheetPortal, { children: [
2023
+ /* @__PURE__ */ jsx(SheetOverlay, {}),
2024
+ /* @__PURE__ */ jsxs(
2025
+ DialogPrimitive.Content,
2026
+ {
2027
+ ref,
2028
+ className: cn(
2029
+ "fixed z-50 gap-4 bg-popover p-6 text-popover-foreground shadow-lg transition ease-in-out data-[state=closed]:animate-out data-[state=open]:animate-in motion-reduce:animate-none motion-reduce:transition-none",
2030
+ sideClasses[side],
2031
+ className
2032
+ ),
2033
+ ...props,
2034
+ children: [
2035
+ children,
2036
+ showClose ? /* @__PURE__ */ jsxs(DialogPrimitive.Close, { className: "absolute top-4 right-4 rounded-sm opacity-70 transition-opacity motion-reduce:transition-none hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none", children: [
2037
+ /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "\xD7" }),
2038
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Close" })
2039
+ ] }) : null
2040
+ ]
2041
+ }
2042
+ )
2043
+ ] }));
2044
+ SheetContent.displayName = "SheetContent";
2045
+ function SheetHeader({ className, ...props }) {
2046
+ return /* @__PURE__ */ jsx("div", { className: cn("flex flex-col space-y-2 text-left", className), ...props });
2047
+ }
2048
+ function SheetFooter({ className, ...props }) {
2049
+ return /* @__PURE__ */ jsx(
2050
+ "div",
2051
+ {
2052
+ className: cn("mt-6 flex flex-col-reverse gap-2 sm:flex-row sm:justify-end", className),
2053
+ ...props
2054
+ }
2055
+ );
2056
+ }
2057
+ var SheetTitle = forwardRef(
2058
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
2059
+ DialogPrimitive.Title,
2060
+ {
2061
+ ref,
2062
+ className: cn("font-semibold text-lg text-popover-foreground", className),
2063
+ ...props
2064
+ }
2065
+ )
2066
+ );
2067
+ SheetTitle.displayName = "SheetTitle";
2068
+ var SheetDescription = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
2069
+ DialogPrimitive.Description,
2070
+ {
2071
+ ref,
2072
+ className: cn("text-muted-foreground text-sm", className),
2073
+ ...props
2074
+ }
2075
+ ));
2076
+ SheetDescription.displayName = "SheetDescription";
2077
+ var Tabs = TabsPrimitive.Root;
2078
+ var TabsList = forwardRef(
2079
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
2080
+ TabsPrimitive.List,
2081
+ {
2082
+ ref,
2083
+ className: cn(
2084
+ "inline-flex h-10 items-center justify-center rounded-md bg-muted p-1 text-muted-foreground",
2085
+ className
2086
+ ),
2087
+ ...props
2088
+ }
2089
+ )
2090
+ );
2091
+ TabsList.displayName = "TabsList";
2092
+ var TabsTrigger = forwardRef(
2093
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
2094
+ TabsPrimitive.Trigger,
2095
+ {
2096
+ ref,
2097
+ className: cn(
2098
+ "inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 font-medium text-sm transition-all motion-reduce:transition-none focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-sm",
2099
+ className
2100
+ ),
2101
+ ...props
2102
+ }
2103
+ )
2104
+ );
2105
+ TabsTrigger.displayName = "TabsTrigger";
2106
+ var TabsContent = forwardRef(
2107
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
2108
+ TabsPrimitive.Content,
2109
+ {
2110
+ ref,
2111
+ className: cn(
2112
+ "mt-2 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
2113
+ className
2114
+ ),
2115
+ ...props
2116
+ }
2117
+ )
2118
+ );
2119
+ TabsContent.displayName = "TabsContent";
2120
+ var TooltipProvider = TooltipPrimitive.Provider;
2121
+ var Tooltip = TooltipPrimitive.Root;
2122
+ var TooltipTrigger = TooltipPrimitive.Trigger;
2123
+ var TooltipContent = forwardRef(({ className, sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx(TooltipPrimitive.Portal, { children: /* @__PURE__ */ jsx(
2124
+ TooltipPrimitive.Content,
2125
+ {
2126
+ ref,
2127
+ sideOffset,
2128
+ className: cn(
2129
+ "z-50 overflow-hidden rounded-md bg-primary px-3 py-1.5 text-primary-foreground text-xs shadow-md data-[state=closed]:animate-out data-[state=delayed-open]:animate-in motion-reduce:animate-none",
2130
+ className
2131
+ ),
2132
+ ...props
2133
+ }
2134
+ ) }));
2135
+ TooltipContent.displayName = "TooltipContent";
2136
+ function Toaster({
2137
+ richColors = true,
2138
+ closeButton = true,
2139
+ position = "bottom-right",
2140
+ ...props
2141
+ }) {
2142
+ return /* @__PURE__ */ jsx(
2143
+ Toaster$1,
2144
+ {
2145
+ richColors,
2146
+ closeButton,
2147
+ position,
2148
+ ...props
2149
+ }
2150
+ );
2151
+ }
2152
+ function Combobox({
2153
+ options,
2154
+ value,
2155
+ onValueChange,
2156
+ placeholder = "Select option...",
2157
+ emptyText = "No option found.",
2158
+ disabled = false
2159
+ }) {
2160
+ const [open, setOpen] = useState(false);
2161
+ const selected = useMemo(() => options.find((o) => o.value === value), [options, value]);
2162
+ return /* @__PURE__ */ jsxs(Popover, { open, onOpenChange: setOpen, children: [
2163
+ /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx(Button, { variant: "outline", disabled, "aria-expanded": open, children: selected?.label ?? placeholder }) }),
2164
+ /* @__PURE__ */ jsx(PopoverContent, { className: "w-64 p-0", children: /* @__PURE__ */ jsxs(Command, { children: [
2165
+ /* @__PURE__ */ jsx(CommandInput, { placeholder: "Search..." }),
2166
+ /* @__PURE__ */ jsxs(CommandList, { children: [
2167
+ /* @__PURE__ */ jsx(CommandEmpty, { children: emptyText }),
2168
+ /* @__PURE__ */ jsx(CommandGroup, { children: options.map((option) => /* @__PURE__ */ jsxs(
2169
+ CommandItem,
2170
+ {
2171
+ value: option.label,
2172
+ onSelect: () => {
2173
+ onValueChange?.(option.value);
2174
+ setOpen(false);
2175
+ },
2176
+ children: [
2177
+ option.label,
2178
+ option.value === value ? /* @__PURE__ */ jsx("span", { className: "ml-auto", children: "\u2713" }) : null
2179
+ ]
2180
+ },
2181
+ option.value
2182
+ )) })
2183
+ ] })
2184
+ ] }) })
2185
+ ] });
2186
+ }
2187
+ var Form = FormProvider;
2188
+ var FormFieldContext = createContext(null);
2189
+ function FormField(props) {
2190
+ return /* @__PURE__ */ jsx(FormFieldContext.Provider, { value: { name: props.name }, children: /* @__PURE__ */ jsx(Controller, { ...props }) });
2191
+ }
2192
+ function useFormField() {
2193
+ const ctx = useContext(FormFieldContext);
2194
+ const form = useFormContext();
2195
+ const state = ctx ? form.getFieldState(ctx.name, form.formState) : void 0;
2196
+ return { name: ctx?.name, error: state?.error };
2197
+ }
2198
+ function FormItem({
2199
+ className,
2200
+ ...props
2201
+ }) {
2202
+ return /* @__PURE__ */ jsx("div", { className: cn("space-y-2", className), ...props });
2203
+ }
2204
+ function FormLabel(props) {
2205
+ const { error } = useFormField();
2206
+ return /* @__PURE__ */ jsx(Label, { error: !!error, ...props });
2207
+ }
2208
+ function FormControl({ children }) {
2209
+ return /* @__PURE__ */ jsx(Fragment, { children });
2210
+ }
2211
+ function FormDescription({
2212
+ className,
2213
+ ...props
2214
+ }) {
2215
+ return /* @__PURE__ */ jsx("p", { className: cn("text-muted-foreground text-sm", className), ...props });
2216
+ }
2217
+ function FormMessage({
2218
+ className,
2219
+ children,
2220
+ ...props
2221
+ }) {
2222
+ const { error } = useFormField();
2223
+ const body = children ?? error?.message;
2224
+ if (!body) return null;
2225
+ return /* @__PURE__ */ jsx("p", { className: cn("text-destructive text-sm", className), ...props, children: body });
2226
+ }
2227
+ function Sidebar({
2228
+ sections,
2229
+ defaultCollapsed = false,
2230
+ className,
2231
+ ...props
2232
+ }) {
2233
+ const [collapsed, setCollapsed] = useState(defaultCollapsed);
2234
+ return /* @__PURE__ */ jsxs(
2235
+ "aside",
2236
+ {
2237
+ className: cn(
2238
+ "flex h-full flex-col border-r border-border bg-background",
2239
+ collapsed ? "w-16" : "w-64",
2240
+ className
2241
+ ),
2242
+ ...props,
2243
+ children: [
2244
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between p-2", children: [
2245
+ /* @__PURE__ */ jsx("span", { className: cn("font-semibold", collapsed && "sr-only"), children: "Navigation" }),
2246
+ /* @__PURE__ */ jsx(
2247
+ Button,
2248
+ {
2249
+ size: "icon",
2250
+ variant: "ghost",
2251
+ "aria-label": "Toggle sidebar",
2252
+ onClick: () => setCollapsed((v) => !v),
2253
+ children: "\u2630"
2254
+ }
2255
+ )
2256
+ ] }),
2257
+ /* @__PURE__ */ jsx("nav", { className: "space-y-4 p-2", children: sections.map((section, i) => /* @__PURE__ */ jsxs("div", { children: [
2258
+ section.label && !collapsed ? /* @__PURE__ */ jsx("p", { className: "px-2 py-1 text-muted-foreground text-xs", children: section.label }) : null,
2259
+ /* @__PURE__ */ jsx("ul", { className: "space-y-1", children: section.items.map((item) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(
2260
+ "a",
2261
+ {
2262
+ href: item.href,
2263
+ "aria-current": item.active ? "page" : void 0,
2264
+ className: cn(
2265
+ "flex rounded-md px-2 py-2 text-sm transition-colors motion-reduce:transition-none hover:bg-accent hover:text-accent-foreground",
2266
+ item.active && "bg-accent text-accent-foreground"
2267
+ ),
2268
+ children: collapsed ? item.label.slice(0, 1) : item.label
2269
+ }
2270
+ ) }, item.label)) })
2271
+ ] }, section.label ?? i)) })
2272
+ ]
2273
+ }
2274
+ );
2275
+ }
2276
+ function ThemeSwitcher() {
2277
+ const [mounted, setMounted] = useState(false);
2278
+ const [palette, setPalette] = useState("neutral-slate");
2279
+ const [appearance, setAppearance] = useState("system");
2280
+ useEffect(() => {
2281
+ setPalette(getStoredPalette());
2282
+ setAppearance(getStoredAppearance());
2283
+ setMounted(true);
2284
+ }, []);
2285
+ useEffect(() => {
2286
+ if (mounted) applyPalette(palette);
2287
+ }, [mounted, palette]);
2288
+ useEffect(() => {
2289
+ if (!mounted) return;
2290
+ applyAppearance(appearance);
2291
+ if (appearance !== "system") return;
2292
+ const mq = window.matchMedia("(prefers-color-scheme: dark)");
2293
+ const onChange = () => applyAppearance("system");
2294
+ mq.addEventListener("change", onChange);
2295
+ return () => mq.removeEventListener("change", onChange);
2296
+ }, [mounted, appearance]);
2297
+ if (!mounted) {
2298
+ return /* @__PURE__ */ jsx("div", { "aria-hidden": true, className: "h-9" });
2299
+ }
2300
+ const appearances = ["light", "dark", "system"];
2301
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-3", children: [
2302
+ /* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2 text-sm text-muted-foreground", children: [
2303
+ "Palette",
2304
+ /* @__PURE__ */ jsx(
2305
+ "select",
2306
+ {
2307
+ value: palette,
2308
+ onChange: (e) => setPalette(e.target.value),
2309
+ className: "rounded-md border border-input bg-background px-2 py-1 text-sm text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
2310
+ children: uiPalettes.map((p) => /* @__PURE__ */ jsxs("option", { value: p.value, children: [
2311
+ p.name,
2312
+ " (",
2313
+ p.category,
2314
+ ")"
2315
+ ] }, p.value))
2316
+ }
2317
+ )
2318
+ ] }),
2319
+ /* @__PURE__ */ jsxs("fieldset", { className: "inline-flex rounded-md border border-input p-0.5", children: [
2320
+ /* @__PURE__ */ jsx("legend", { className: "sr-only", children: "Appearance" }),
2321
+ appearances.map((a) => /* @__PURE__ */ jsx(
2322
+ "button",
2323
+ {
2324
+ type: "button",
2325
+ "aria-pressed": appearance === a,
2326
+ onClick: () => setAppearance(a),
2327
+ className: "rounded px-2.5 py-1 text-sm capitalize transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring " + (appearance === a ? "bg-primary text-primary-foreground" : "text-muted-foreground hover:text-foreground"),
2328
+ children: a
2329
+ },
2330
+ a
2331
+ ))
2332
+ ] })
2333
+ ] });
2334
+ }
2335
+
2336
+ // src/utils/formatters.ts
2337
+ function formatCurrency(value, options = {}) {
2338
+ const {
2339
+ currency = "USD",
2340
+ locale = "en-US",
2341
+ minimumFractionDigits,
2342
+ maximumFractionDigits
2343
+ } = options;
2344
+ return new Intl.NumberFormat(locale, {
2345
+ style: "currency",
2346
+ currency,
2347
+ minimumFractionDigits,
2348
+ maximumFractionDigits
2349
+ }).format(value);
2350
+ }
2351
+ function formatDate(value, options = {}) {
2352
+ const { locale = "en-US", ...dateOptions } = options;
2353
+ const date = value instanceof Date ? value : new Date(value);
2354
+ return new Intl.DateTimeFormat(locale, {
2355
+ dateStyle: "medium",
2356
+ ...dateOptions
2357
+ }).format(date);
2358
+ }
2359
+ function formatNumber(value, options = {}) {
2360
+ const { locale = "en-US", ...numberOptions } = options;
2361
+ return new Intl.NumberFormat(locale, numberOptions).format(value);
2362
+ }
2363
+
2364
+ export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, Alert, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger, AlertTitle, AspectRatio, Avatar, AvatarFallback, AvatarImage, Badge, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, Button, Calendar, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Checkbox, Combobox, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut, DEFAULT_PALETTE, DataTable, DateRangePicker, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuTrigger, Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, Input, Label, NavigationMenu, NavigationMenuContent, NavigationMenuIndicator, NavigationMenuItem, NavigationMenuLink, NavigationMenuList, NavigationMenuTrigger, NavigationMenuViewport, Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, Progress, RadioGroup, RadioGroupItem, ScrollArea, Select, SelectContent, SelectItem, SelectTrigger, Separator, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, SheetTrigger, Sidebar, Skeleton, Spinner, Switch, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, ThemeSwitcher, Toaster, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, allFontsHref, appliers, applyAppearance, applyPalette, applyTheme, cn, formatCurrency, formatDate, formatNumber, getStoredAppearance, getStoredPalette, getStoredTheme, isUiPalette, isUiTheme, palettesByCategory, uiFontValues, uiFonts, uiPaletteValues, uiPalettes, uiThemeLabels, uiThemes, useDebounce, useMediaQuery, useTheme };
2365
+ //# sourceMappingURL=index.mjs.map
2366
+ //# sourceMappingURL=index.mjs.map