@akira-io/ui 1.0.0 → 1.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 (70) hide show
  1. package/README.md +15 -10
  2. package/dist/blocks.d.ts +159 -6
  3. package/dist/blocks.js +1388 -29
  4. package/dist/blocks.js.map +1 -1
  5. package/dist/button-B6wQRe7p.d.ts +16 -0
  6. package/dist/chunk-5AJFQ6C4.js +35 -0
  7. package/dist/chunk-5AJFQ6C4.js.map +1 -0
  8. package/dist/chunk-6QM5BA7B.js +148 -0
  9. package/dist/chunk-6QM5BA7B.js.map +1 -0
  10. package/dist/chunk-6X4TKSF6.js +21 -0
  11. package/dist/chunk-6X4TKSF6.js.map +1 -0
  12. package/dist/chunk-DSD7MVLL.js +287 -0
  13. package/dist/chunk-DSD7MVLL.js.map +1 -0
  14. package/dist/chunk-IQMRJXEO.js +59 -0
  15. package/dist/chunk-IQMRJXEO.js.map +1 -0
  16. package/dist/chunk-JAHTUAQL.js +82 -0
  17. package/dist/chunk-JAHTUAQL.js.map +1 -0
  18. package/dist/{chunk-A2SIZOEA.js → chunk-KYWA5UYN.js} +125 -45
  19. package/dist/chunk-KYWA5UYN.js.map +1 -0
  20. package/dist/chunk-L2H5GIF7.js +22 -0
  21. package/dist/chunk-L2H5GIF7.js.map +1 -0
  22. package/dist/chunk-LKSM3WLK.js +44 -0
  23. package/dist/chunk-LKSM3WLK.js.map +1 -0
  24. package/dist/{chunk-5MQWJVM2.js → chunk-MNGNBEYN.js} +168 -200
  25. package/dist/chunk-MNGNBEYN.js.map +1 -0
  26. package/dist/chunk-SA5LM2GD.js +102 -0
  27. package/dist/chunk-SA5LM2GD.js.map +1 -0
  28. package/dist/chunk-UUEWFCKT.js +28 -0
  29. package/dist/chunk-UUEWFCKT.js.map +1 -0
  30. package/dist/{chunk-42BJBH56.js → chunk-UUTXPPRN.js} +521 -107
  31. package/dist/chunk-UUTXPPRN.js.map +1 -0
  32. package/dist/{chunk-UXL33CZ4.js → chunk-YOVY3KT6.js} +13 -11
  33. package/dist/chunk-YOVY3KT6.js.map +1 -0
  34. package/dist/code.d.ts +6 -0
  35. package/dist/code.js +651 -0
  36. package/dist/code.js.map +1 -0
  37. package/dist/context-VgHq4U98.d.ts +384 -0
  38. package/dist/editor.d.ts +126 -0
  39. package/dist/editor.js +436 -0
  40. package/dist/editor.js.map +1 -0
  41. package/dist/index.d.ts +93 -17
  42. package/dist/index.js +996 -472
  43. package/dist/index.js.map +1 -1
  44. package/dist/inertia.d.ts +47 -2
  45. package/dist/inertia.js +138 -7
  46. package/dist/inertia.js.map +1 -1
  47. package/dist/input-4uxAHW6y.d.ts +5 -0
  48. package/dist/json-viewer-BTHBACj9.d.ts +50 -0
  49. package/dist/{language-Bft6rBBt.d.ts → language-Dgjr9bm3.d.ts} +1 -1
  50. package/dist/locales/pt.d.ts +26 -4
  51. package/dist/locales/pt.js +127 -1
  52. package/dist/locales/pt.js.map +1 -1
  53. package/dist/password-input-r39y2pCT.d.ts +50 -0
  54. package/dist/shells.d.ts +45 -7
  55. package/dist/shells.js +95 -60
  56. package/dist/shells.js.map +1 -1
  57. package/dist/{sidebar-BDhG9SUU.d.ts → sidebar-BhOIlSjt.d.ts} +4 -12
  58. package/dist/{types-Cno1_Ijx.d.ts → types-B4QS3h5p.d.ts} +9 -1
  59. package/dist/types-CT0rBsFc.d.ts +110 -0
  60. package/package.json +170 -130
  61. package/theme.css +20 -0
  62. package/themes/nosferry.css +4 -0
  63. package/dist/chunk-42BJBH56.js.map +0 -1
  64. package/dist/chunk-5MQWJVM2.js.map +0 -1
  65. package/dist/chunk-A2SIZOEA.js.map +0 -1
  66. package/dist/chunk-POE7OYET.js +0 -96
  67. package/dist/chunk-POE7OYET.js.map +0 -1
  68. package/dist/chunk-UXL33CZ4.js.map +0 -1
  69. package/dist/date-range-filter-QEa8fhUM.d.ts +0 -149
  70. package/dist/types-cOieac8G.d.ts +0 -77
package/dist/index.js CHANGED
@@ -1,17 +1,30 @@
1
- import { Label, Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter, Popover, PopoverTrigger, PopoverContent, Command, CommandInput, CommandList, CommandEmpty, CommandGroup, CommandItem, Select, SelectTrigger, SelectContent, SelectItem, Calendar } from './chunk-42BJBH56.js';
2
- export { Calendar, CalendarDayButton, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, Label, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Switch, Tabs, TabsContent, TabsList, TabsTrigger, Textarea } from './chunk-42BJBH56.js';
3
- import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem } from './chunk-5MQWJVM2.js';
4
- export { Avatar, AvatarFallback, AvatarImage, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, Collapsible, CollapsibleContent, CollapsibleTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, Icon, Separator, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, SheetTrigger, Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInput, SidebarInset, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSkeleton, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarRail, SidebarSeparator, SidebarTrigger, Skeleton, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, useSidebar } from './chunk-5MQWJVM2.js';
5
- import { cn, focusRing, elevatedSurface, nestedRadius, nestedSurfaceReset, nestedEdgeToEdge, glassControl, controlFill, Button, modalSurface, recessedSurface, menuSurface, Input, floatingSurface, panelSurface, buttonVariants } from './chunk-POE7OYET.js';
6
- export { Button, Input, buttonVariants, cn, controlFill, elevatedSurface, focusRing, menuHighlight, nestedEdgeToEdge, nestedRadius, nestedSurfaceReset, recessedSurface, surface } from './chunk-POE7OYET.js';
7
- import { ChevronDown, Minus, AlertCircle, ChevronRight, ArrowLeft, ArrowRight, CheckIcon, ChevronsUpDown, Check, ChevronRightIcon, CircleIcon, MoreVertical, Search, X, Plus, ArrowUpDown, ChevronLeft, CalendarRange, ChevronDownIcon, ChevronLeftIcon, MoreHorizontalIcon, Loader2Icon, OctagonXIcon, TriangleAlertIcon, InfoIcon, CircleCheckIcon, PlusCircle } from 'lucide-react';
1
+ import { Popover, PopoverTrigger, PopoverContent, Command, CommandInput, CommandList, CommandEmpty, CommandGroup, CommandItem, Select, SelectTrigger, SelectContent, SelectItem, Calendar, FieldContext, FieldError, useField, ConfirmDialog } from './chunk-UUTXPPRN.js';
2
+ export { Alert, AlertDescription, AlertTitle, Calendar, CalendarDayButton, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut, ConfirmDialog, FieldError, FloatingSheet, FloatingSheetBody, FloatingSheetFooter, FloatingSheetStack, InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Switch, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, confirmDialogDefaultLabels, floatingSheetDefaultLabels, useField } from './chunk-UUTXPPRN.js';
3
+ export { CopyButton, copyButtonLabels } from './chunk-JAHTUAQL.js';
4
+ import { toggleVariants } from './chunk-LKSM3WLK.js';
5
+ export { Toggle, toggleVariants } from './chunk-LKSM3WLK.js';
6
+ import { Label } from './chunk-6QM5BA7B.js';
7
+ export { Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, Label } from './chunk-6QM5BA7B.js';
8
+ import { useAppearance } from './chunk-IQMRJXEO.js';
9
+ export { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, cardVariants } from './chunk-SA5LM2GD.js';
10
+ import { useUiLabels } from './chunk-5AJFQ6C4.js';
11
+ export { UiLocaleProvider, useUiLabels, useUiLocale } from './chunk-5AJFQ6C4.js';
12
+ import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuItem } from './chunk-MNGNBEYN.js';
13
+ export { Avatar, AvatarFallback, AvatarImage, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, Collapsible, CollapsibleContent, CollapsibleTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, Icon, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, SheetTrigger, Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInput, SidebarInset, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSkeleton, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarRail, SidebarSeparator, SidebarTrigger, Skeleton, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, useSidebar } from './chunk-MNGNBEYN.js';
14
+ export { Separator } from './chunk-UUEWFCKT.js';
15
+ import { Input } from './chunk-6X4TKSF6.js';
16
+ export { Input } from './chunk-6X4TKSF6.js';
17
+ import { cn, focusRing, nestedRadius, nestedSurfaceReset, nestedEdgeToEdge, elevatedSurface, modalSurface, Button, menuSurface, fieldSurface, floatingSurface, panelSurface, buttonVariants, Spinner } from './chunk-DSD7MVLL.js';
18
+ export { Button, Spinner, buttonVariants, cn, controlFill, elevatedSurface, focusRing, menuHighlight, nestedEdgeToEdge, nestedRadius, nestedSurfaceReset, recessedSurface, spinnerVariants, surface } from './chunk-DSD7MVLL.js';
19
+ import * as React3 from 'react';
20
+ import { useState, useRef, useCallback, useEffect, useMemo, useId } from 'react';
8
21
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
9
- import * as React2 from 'react';
10
- import { useState, useMemo, useId, useEffect } from 'react';
11
22
  import * as AccordionPrimitive from '@radix-ui/react-accordion';
12
- import { cva } from 'class-variance-authority';
23
+ import { ChevronDown, SunIcon, MoonIcon, MonitorIcon, ArrowLeft, ArrowRight, CheckIcon, ChevronsUpDown, Check, ChevronRightIcon, CircleIcon, MoreVertical, SearchX, Search, X, Plus, ArrowUpDown, ChevronLeft, ChevronRight, CalendarIcon, CalendarRange, ChevronDownIcon, ChevronLeftIcon, MoreHorizontalIcon, EyeOff, Eye, TriangleAlert, Loader2Icon, OctagonXIcon, TriangleAlertIcon, InfoIcon, CircleCheckIcon, PlusCircle } from 'lucide-react';
13
24
  import { AlertDialog as AlertDialog$1, AspectRatio as AspectRatio$1, ContextMenu as ContextMenu$1, HoverCard as HoverCard$1, Menubar as Menubar$1, Progress as Progress$1, RadioGroup as RadioGroup$1, Slider as Slider$1 } from 'radix-ui';
25
+ import * as ToggleGroupPrimitive from '@radix-ui/react-toggle-group';
14
26
  import { Slot } from '@radix-ui/react-slot';
27
+ import { cva } from 'class-variance-authority';
15
28
  import useEmblaCarousel from 'embla-carousel-react';
16
29
  import * as RechartsPrimitive from 'recharts';
17
30
  import * as CheckboxPrimitive from '@radix-ui/react-checkbox';
@@ -19,82 +32,100 @@ import { useReactTable, getPaginationRowModel, getFilteredRowModel, getSortedRow
19
32
  import { format } from 'date-fns';
20
33
  import { Drawer as Drawer$1 } from 'vaul';
21
34
  import { useFormContext, FormProvider, Controller } from 'react-hook-form';
22
- import { OTPInput, OTPInputContext } from 'input-otp';
23
35
  import * as NavigationMenuPrimitive from '@radix-ui/react-navigation-menu';
24
36
  import * as ResizablePrimitive from 'react-resizable-panels';
25
37
  import * as ScrollAreaPrimitive from '@radix-ui/react-scroll-area';
26
38
  import { Toaster as Toaster$1 } from 'sonner';
27
39
  export { toast } from 'sonner';
28
- import * as TogglePrimitive from '@radix-ui/react-toggle';
29
- import * as ToggleGroupPrimitive from '@radix-ui/react-toggle-group';
30
40
 
31
- function ConfirmDialog({
32
- open,
33
- onOpenChange,
34
- title = "Confirm Action",
35
- description = "Are you sure you want to continue? This action cannot be undone.",
36
- confirmText = "Confirm",
37
- cancelText = "Cancel",
38
- variant = "destructive",
39
- processing = false,
40
- onConfirm,
41
- onCancel
42
- }) {
43
- const handleConfirm = () => {
44
- if (processing) {
45
- return;
41
+ var AUTOSAVE_DELAY = 700;
42
+ function shallowEqual(a, b) {
43
+ if (Object.is(a, b)) {
44
+ return true;
45
+ }
46
+ if (typeof a !== "object" || typeof b !== "object" || a === null || b === null) {
47
+ return false;
48
+ }
49
+ const keys = Object.keys(a);
50
+ if (keys.length !== Object.keys(b).length) {
51
+ return false;
52
+ }
53
+ return keys.every(
54
+ (key) => Object.is(
55
+ a[key],
56
+ b[key]
57
+ )
58
+ );
59
+ }
60
+ function messageOf(reason) {
61
+ if (reason instanceof Error) {
62
+ return reason.message;
63
+ }
64
+ return typeof reason === "string" ? reason : void 0;
65
+ }
66
+ function useAutosave(values, onSave, options = {}) {
67
+ const { delay = AUTOSAVE_DELAY, enabled = true, isEqual } = options;
68
+ const [status, setStatus] = useState("idle");
69
+ const [error, setError] = useState(void 0);
70
+ const latest = useRef(values);
71
+ const dispatched = useRef(values);
72
+ const timer = useRef(void 0);
73
+ const issued = useRef(0);
74
+ const settled = useRef(0);
75
+ const mounted = useRef(true);
76
+ const save = useRef(onSave);
77
+ const equal = useRef(isEqual ?? shallowEqual);
78
+ latest.current = values;
79
+ save.current = onSave;
80
+ equal.current = isEqual ?? shallowEqual;
81
+ const run = useCallback(async () => {
82
+ const payload = latest.current;
83
+ const ticket = issued.current += 1;
84
+ setStatus("saving");
85
+ setError(void 0);
86
+ try {
87
+ await save.current(payload);
88
+ if (ticket < settled.current || !mounted.current) {
89
+ return;
90
+ }
91
+ settled.current = ticket;
92
+ setStatus("saved");
93
+ } catch (reason) {
94
+ if (ticket < settled.current || !mounted.current) {
95
+ return;
96
+ }
97
+ settled.current = ticket;
98
+ setError(messageOf(reason));
99
+ setStatus("error");
46
100
  }
47
- onConfirm();
48
- onOpenChange(false);
49
- };
50
- const handleCancel = () => {
51
- if (processing) {
101
+ }, []);
102
+ const flush = useCallback(() => {
103
+ clearTimeout(timer.current);
104
+ dispatched.current = latest.current;
105
+ void run();
106
+ }, [run]);
107
+ const reset = useCallback(() => {
108
+ clearTimeout(timer.current);
109
+ dispatched.current = latest.current;
110
+ setError(void 0);
111
+ setStatus("idle");
112
+ }, []);
113
+ useEffect(() => {
114
+ mounted.current = true;
115
+ return () => {
116
+ mounted.current = false;
117
+ clearTimeout(timer.current);
118
+ };
119
+ }, []);
120
+ useEffect(() => {
121
+ if (!enabled || equal.current(values, dispatched.current)) {
52
122
  return;
53
123
  }
54
- onCancel?.();
55
- onOpenChange(false);
56
- };
57
- return /* @__PURE__ */ jsx(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs(DialogContent, { className: "max-w-md p-0", "data-slot": "confirm-dialog", children: [
58
- /* @__PURE__ */ jsxs(DialogHeader, { className: "p-6 md:p-8", children: [
59
- /* @__PURE__ */ jsx("div", { className: "mb-6 flex justify-center", children: /* @__PURE__ */ jsx(
60
- "div",
61
- {
62
- className: cn(
63
- "size-16 rounded-3xl shadow-xl flex items-center justify-center",
64
- variant === "destructive" ? "bg-destructive text-destructive-foreground shadow-destructive/20" : "bg-primary text-primary-foreground shadow-primary/20"
65
- ),
66
- children: /* @__PURE__ */ jsx(AlertCircle, { className: "h-8 w-8" })
67
- }
68
- ) }),
69
- /* @__PURE__ */ jsx(DialogTitle, { children: title }),
70
- /* @__PURE__ */ jsx(DialogDescription, { children: description })
71
- ] }),
72
- /* @__PURE__ */ jsx(DialogFooter, { className: "p-6 md:p-8", children: /* @__PURE__ */ jsxs("div", { className: "gap-4 sm:grid-cols-2 grid w-full", children: [
73
- /* @__PURE__ */ jsx(
74
- Button,
75
- {
76
- type: "button",
77
- variant: "ghost",
78
- disabled: processing,
79
- onClick: handleCancel,
80
- className: "text-muted-foreground",
81
- children: cancelText
82
- }
83
- ),
84
- /* @__PURE__ */ jsxs(
85
- Button,
86
- {
87
- variant,
88
- disabled: processing,
89
- onClick: handleConfirm,
90
- children: [
91
- confirmText,
92
- /* @__PURE__ */ jsx(ChevronRight, { className: "ml-2 h-5 w-5" })
93
- ]
94
- }
95
- )
96
- ] }) })
97
- ] }) });
124
+ dispatched.current = values;
125
+ clearTimeout(timer.current);
126
+ timer.current = setTimeout(() => void run(), delay);
127
+ }, [values, delay, enabled, run]);
128
+ return { status, error, flush, reset };
98
129
  }
99
130
  function useConfirmDialog() {
100
131
  const [isOpen, setIsOpen] = useState(false);
@@ -140,7 +171,7 @@ function Accordion({
140
171
  }
141
172
  );
142
173
  }
143
- var AccordionItem = React2.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
174
+ var AccordionItem = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
144
175
  AccordionPrimitive.Item,
145
176
  {
146
177
  "data-slot": "accordion-item",
@@ -150,7 +181,7 @@ var AccordionItem = React2.forwardRef(({ className, ...props }, ref) => /* @__PU
150
181
  }
151
182
  ));
152
183
  AccordionItem.displayName = "AccordionItem";
153
- var AccordionTrigger = React2.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsx(AccordionPrimitive.Header, { className: "flex", children: /* @__PURE__ */ jsxs(
184
+ var AccordionTrigger = React3.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsx(AccordionPrimitive.Header, { className: "flex", children: /* @__PURE__ */ jsxs(
154
185
  AccordionPrimitive.Trigger,
155
186
  {
156
187
  "data-slot": "accordion-trigger",
@@ -167,7 +198,7 @@ var AccordionTrigger = React2.forwardRef(({ className, children, ...props }, ref
167
198
  }
168
199
  ) }));
169
200
  AccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName;
170
- var AccordionContent = React2.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsx(
201
+ var AccordionContent = React3.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsx(
171
202
  AccordionPrimitive.Content,
172
203
  {
173
204
  "data-slot": "accordion-content",
@@ -178,64 +209,6 @@ var AccordionContent = React2.forwardRef(({ className, children, ...props }, ref
178
209
  }
179
210
  ));
180
211
  AccordionContent.displayName = AccordionPrimitive.Content.displayName;
181
- var alertVariants = cva(
182
- `${elevatedSurface} relative w-full px-5 py-4 text-sm grid has-[>svg]:grid-cols-[calc(var(--spacing)*4)_1fr] grid-cols-[0_1fr] has-[>svg]:gap-x-3 gap-y-0.5 items-start [&>svg]:size-4 [&>svg]:translate-y-0.5 [&>svg]:text-current`,
183
- {
184
- variants: {
185
- variant: {
186
- default: "bg-card/60 text-card-foreground",
187
- destructive: "border-destructive/30 bg-destructive/10 text-destructive [&>svg]:text-current *:data-[slot=alert-description]:text-destructive/80"
188
- }
189
- },
190
- defaultVariants: {
191
- variant: "default"
192
- }
193
- }
194
- );
195
- function Alert({
196
- className,
197
- variant,
198
- ...props
199
- }) {
200
- return /* @__PURE__ */ jsx(
201
- "div",
202
- {
203
- "data-slot": "alert",
204
- role: "alert",
205
- className: cn(alertVariants({ variant }), className),
206
- ...props
207
- }
208
- );
209
- }
210
- function AlertTitle({ className, ...props }) {
211
- return /* @__PURE__ */ jsx(
212
- "div",
213
- {
214
- "data-slot": "alert-title",
215
- className: cn(
216
- "min-h-4 font-medium tracking-tight col-start-2 line-clamp-1",
217
- className
218
- ),
219
- ...props
220
- }
221
- );
222
- }
223
- function AlertDescription({
224
- className,
225
- ...props
226
- }) {
227
- return /* @__PURE__ */ jsx(
228
- "div",
229
- {
230
- "data-slot": "alert-description",
231
- className: cn(
232
- "gap-1 text-sm [&_p]:leading-relaxed col-start-2 grid justify-items-start text-muted-foreground",
233
- className
234
- ),
235
- ...props
236
- }
237
- );
238
- }
239
212
  function AlertDialog({
240
213
  ...props
241
214
  }) {
@@ -407,6 +380,167 @@ function AlertDialogCancel({
407
380
  }
408
381
  ) });
409
382
  }
383
+ var ToggleGroupContext = React3.createContext({
384
+ size: "default",
385
+ variant: "default"
386
+ });
387
+ function ToggleGroup({
388
+ className,
389
+ variant,
390
+ size,
391
+ children,
392
+ ...props
393
+ }) {
394
+ return /* @__PURE__ */ jsx(
395
+ ToggleGroupPrimitive.Root,
396
+ {
397
+ "data-slot": "toggle-group",
398
+ "data-variant": variant,
399
+ "data-size": size,
400
+ className: cn(
401
+ "group/toggle-group data-[variant=outline]:shadow-xs rounded-2xl flex items-center",
402
+ className
403
+ ),
404
+ ...props,
405
+ children: /* @__PURE__ */ jsx(ToggleGroupContext.Provider, { value: { variant, size }, children })
406
+ }
407
+ );
408
+ }
409
+ function ToggleGroupItem({
410
+ className,
411
+ children,
412
+ variant,
413
+ size,
414
+ ...props
415
+ }) {
416
+ const context = React3.useContext(ToggleGroupContext);
417
+ return /* @__PURE__ */ jsx(
418
+ ToggleGroupPrimitive.Item,
419
+ {
420
+ "data-slot": "toggle-group-item",
421
+ "data-variant": context.variant || variant,
422
+ "data-size": context.size || size,
423
+ className: cn(
424
+ toggleVariants({
425
+ variant: context.variant || variant,
426
+ size: context.size || size
427
+ }),
428
+ "min-w-0 first:rounded-l-2xl last:rounded-r-2xl shrink-0 rounded-none shadow-none focus:z-10 focus-visible:z-10 data-[variant=outline]:border-l-0 data-[variant=outline]:first:border-l",
429
+ className
430
+ ),
431
+ ...props,
432
+ children
433
+ }
434
+ );
435
+ }
436
+ var appearanceToggleDefaultLabels = {
437
+ groupLabel: "Appearance",
438
+ lightLabel: "Light",
439
+ darkLabel: "Dark",
440
+ systemLabel: "System"
441
+ };
442
+ var OPTIONS = [
443
+ { value: "light", icon: SunIcon, label: (labels) => labels.lightLabel },
444
+ { value: "dark", icon: MoonIcon, label: (labels) => labels.darkLabel },
445
+ {
446
+ value: "system",
447
+ icon: MonitorIcon,
448
+ label: (labels) => labels.systemLabel
449
+ }
450
+ ];
451
+ function AppearanceToggle({
452
+ className,
453
+ variant = "segmented",
454
+ labels: labelOverrides,
455
+ ...props
456
+ }) {
457
+ const labels = useUiLabels(
458
+ "appearanceToggle",
459
+ appearanceToggleDefaultLabels,
460
+ labelOverrides
461
+ );
462
+ const { appearance, updateAppearance } = useAppearance();
463
+ const current = OPTIONS.find((option) => option.value === appearance);
464
+ const CurrentIcon = current?.icon ?? MonitorIcon;
465
+ if (variant === "menu") {
466
+ return /* @__PURE__ */ jsx(
467
+ "div",
468
+ {
469
+ "data-slot": "appearance-toggle",
470
+ "data-variant": "menu",
471
+ className: cn("inline-flex", className),
472
+ ...props,
473
+ children: /* @__PURE__ */ jsxs(DropdownMenu, { children: [
474
+ /* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
475
+ Button,
476
+ {
477
+ "data-slot": "appearance-toggle-trigger",
478
+ variant: "ghost",
479
+ size: "icon-sm",
480
+ "aria-label": labels.groupLabel,
481
+ children: /* @__PURE__ */ jsx(CurrentIcon, { "aria-hidden": "true" })
482
+ }
483
+ ) }),
484
+ /* @__PURE__ */ jsx(DropdownMenuContent, { align: "end", children: /* @__PURE__ */ jsx(
485
+ DropdownMenuRadioGroup,
486
+ {
487
+ value: appearance,
488
+ onValueChange: (value) => updateAppearance(value),
489
+ children: OPTIONS.map((option) => /* @__PURE__ */ jsxs(
490
+ DropdownMenuRadioItem,
491
+ {
492
+ "data-slot": "appearance-toggle-item",
493
+ value: option.value,
494
+ children: [
495
+ /* @__PURE__ */ jsx(option.icon, { "aria-hidden": "true" }),
496
+ option.label(labels)
497
+ ]
498
+ },
499
+ option.value
500
+ ))
501
+ }
502
+ ) })
503
+ ] })
504
+ }
505
+ );
506
+ }
507
+ return /* @__PURE__ */ jsx(
508
+ "div",
509
+ {
510
+ "data-slot": "appearance-toggle",
511
+ "data-variant": "segmented",
512
+ className: cn("inline-flex", className),
513
+ ...props,
514
+ children: /* @__PURE__ */ jsx(
515
+ ToggleGroup,
516
+ {
517
+ type: "single",
518
+ size: "sm",
519
+ value: appearance,
520
+ "aria-label": labels.groupLabel,
521
+ onValueChange: (value) => {
522
+ if (value) {
523
+ updateAppearance(value);
524
+ }
525
+ },
526
+ children: OPTIONS.map((option) => /* @__PURE__ */ jsxs(
527
+ ToggleGroupItem,
528
+ {
529
+ "data-slot": "appearance-toggle-item",
530
+ value: option.value,
531
+ "aria-label": option.label(labels),
532
+ children: [
533
+ /* @__PURE__ */ jsx(option.icon, { "aria-hidden": "true" }),
534
+ /* @__PURE__ */ jsx("span", { children: option.label(labels) })
535
+ ]
536
+ },
537
+ option.value
538
+ ))
539
+ }
540
+ )
541
+ }
542
+ );
543
+ }
410
544
  function AspectRatio({
411
545
  ...props
412
546
  }) {
@@ -444,103 +578,9 @@ function Badge({
444
578
  }
445
579
  );
446
580
  }
447
- var cardVariants = cva(
448
- `relative flex flex-col gap-6 overflow-hidden text-card-foreground ${elevatedSurface}`,
449
- {
450
- variants: {
451
- variant: {
452
- default: "bg-card/60",
453
- subtle: "border-border/60 bg-card/40",
454
- solid: "bg-card"
455
- },
456
- interactive: {
457
- true: "transition-colors duration-200 hover:border-foreground/20",
458
- false: ""
459
- },
460
- padding: { none: "py-0", sm: "py-4", md: "py-6", lg: "py-8" }
461
- },
462
- defaultVariants: {
463
- variant: "default",
464
- interactive: false,
465
- padding: "md"
466
- }
467
- }
468
- );
469
- function Card({
470
- className,
471
- variant,
472
- interactive,
473
- padding,
474
- inset = false,
475
- ...props
476
- }) {
477
- return /* @__PURE__ */ jsx(
478
- "div",
479
- {
480
- "data-slot": "card",
481
- "data-inset": inset || void 0,
482
- className: cn(
483
- cardVariants({ variant, interactive, padding }),
484
- inset && recessedSurface,
485
- className
486
- ),
487
- ...props
488
- }
489
- );
490
- }
491
- function CardHeader({ className, ...props }) {
492
- return /* @__PURE__ */ jsx(
493
- "div",
494
- {
495
- "data-slot": "card-header",
496
- className: cn("gap-1.5 px-6 flex flex-col", className),
497
- ...props
498
- }
499
- );
500
- }
501
- function CardTitle({ className, ...props }) {
502
- return /* @__PURE__ */ jsx(
503
- "div",
504
- {
505
- "data-slot": "card-title",
506
- className: cn("font-semibold leading-none", className),
507
- ...props
508
- }
509
- );
510
- }
511
- function CardDescription({ className, ...props }) {
512
- return /* @__PURE__ */ jsx(
513
- "div",
514
- {
515
- "data-slot": "card-description",
516
- className: cn("text-sm text-muted-foreground", className),
517
- ...props
518
- }
519
- );
520
- }
521
- function CardContent({ className, ...props }) {
522
- return /* @__PURE__ */ jsx(
523
- "div",
524
- {
525
- "data-slot": "card-content",
526
- className: cn("px-6", className),
527
- ...props
528
- }
529
- );
530
- }
531
- function CardFooter({ className, ...props }) {
532
- return /* @__PURE__ */ jsx(
533
- "div",
534
- {
535
- "data-slot": "card-footer",
536
- className: cn("px-6 flex items-center", className),
537
- ...props
538
- }
539
- );
540
- }
541
- var CarouselContext = React2.createContext(null);
581
+ var CarouselContext = React3.createContext(null);
542
582
  function useCarousel() {
543
- const context = React2.useContext(CarouselContext);
583
+ const context = React3.useContext(CarouselContext);
544
584
  if (!context) {
545
585
  throw new Error("useCarousel must be used within a <Carousel />");
546
586
  }
@@ -562,20 +602,20 @@ function Carousel({
562
602
  },
563
603
  plugins
564
604
  );
565
- const [canScrollPrev, setCanScrollPrev] = React2.useState(false);
566
- const [canScrollNext, setCanScrollNext] = React2.useState(false);
567
- const onSelect = React2.useCallback((api2) => {
605
+ const [canScrollPrev, setCanScrollPrev] = React3.useState(false);
606
+ const [canScrollNext, setCanScrollNext] = React3.useState(false);
607
+ const onSelect = React3.useCallback((api2) => {
568
608
  if (!api2) return;
569
609
  setCanScrollPrev(api2.canScrollPrev());
570
610
  setCanScrollNext(api2.canScrollNext());
571
611
  }, []);
572
- const scrollPrev = React2.useCallback(() => {
612
+ const scrollPrev = React3.useCallback(() => {
573
613
  api?.scrollPrev();
574
614
  }, [api]);
575
- const scrollNext = React2.useCallback(() => {
615
+ const scrollNext = React3.useCallback(() => {
576
616
  api?.scrollNext();
577
617
  }, [api]);
578
- const handleKeyDown = React2.useCallback(
618
+ const handleKeyDown = React3.useCallback(
579
619
  (event) => {
580
620
  if (event.key !== "ArrowLeft" && event.key !== "ArrowRight") {
581
621
  return;
@@ -589,11 +629,11 @@ function Carousel({
589
629
  },
590
630
  [scrollPrev, scrollNext]
591
631
  );
592
- React2.useEffect(() => {
632
+ React3.useEffect(() => {
593
633
  if (!api || !setApi) return;
594
634
  setApi(api);
595
635
  }, [api, setApi]);
596
- React2.useEffect(() => {
636
+ React3.useEffect(() => {
597
637
  if (!api) return;
598
638
  onSelect(api);
599
639
  api.on("reInit", onSelect);
@@ -732,9 +772,9 @@ function CarouselNext({
732
772
  }
733
773
  var THEMES = { light: "", dark: ".dark" };
734
774
  var INITIAL_DIMENSION = { width: 320, height: 200 };
735
- var ChartContext = React2.createContext(null);
775
+ var ChartContext = React3.createContext(null);
736
776
  function useChart() {
737
- const context = React2.useContext(ChartContext);
777
+ const context = React3.useContext(ChartContext);
738
778
  if (!context) {
739
779
  throw new Error("useChart must be used within a <ChartContainer />");
740
780
  }
@@ -748,7 +788,7 @@ function ChartContainer({
748
788
  initialDimension = INITIAL_DIMENSION,
749
789
  ...props
750
790
  }) {
751
- const uniqueId = React2.useId();
791
+ const uniqueId = React3.useId();
752
792
  const chartId = `chart-${id ?? uniqueId.replace(/:/g, "")}`;
753
793
  return /* @__PURE__ */ jsx(ChartContext.Provider, { value: { config }, children: /* @__PURE__ */ jsxs(
754
794
  "div",
@@ -818,7 +858,7 @@ function ChartTooltipContent({
818
858
  labelKey
819
859
  }) {
820
860
  const { config } = useChart();
821
- const tooltipLabel = React2.useMemo(() => {
861
+ const tooltipLabel = React3.useMemo(() => {
822
862
  if (hideLabel || !payload?.length) {
823
863
  return null;
824
864
  }
@@ -1011,17 +1051,27 @@ function Checkbox({
1011
1051
  }
1012
1052
  );
1013
1053
  }
1054
+ var comboboxDefaultLabels = {
1055
+ placeholder: "Select an option",
1056
+ searchPlaceholder: "Search...",
1057
+ emptyText: "No results."
1058
+ };
1014
1059
  function Combobox({
1015
1060
  id,
1016
1061
  value,
1017
1062
  options,
1018
1063
  onChange,
1019
- placeholder = "Select an option",
1020
- searchPlaceholder = "Search...",
1021
- emptyText = "No results.",
1064
+ placeholder,
1065
+ searchPlaceholder,
1066
+ emptyText,
1022
1067
  disabled = false,
1023
1068
  invalid = false
1024
1069
  }) {
1070
+ const labels = useUiLabels("combobox", comboboxDefaultLabels, {
1071
+ placeholder,
1072
+ searchPlaceholder,
1073
+ emptyText
1074
+ });
1025
1075
  const [open, setOpen] = useState(false);
1026
1076
  const selected = options.find((option) => option.value === value);
1027
1077
  return /* @__PURE__ */ jsxs(Popover, { open, onOpenChange: setOpen, children: [
@@ -1040,7 +1090,7 @@ function Combobox({
1040
1090
  invalid && "border-destructive ring-destructive"
1041
1091
  ),
1042
1092
  children: [
1043
- selected ? selected.label : placeholder,
1093
+ selected ? selected.label : labels.placeholder,
1044
1094
  /* @__PURE__ */ jsx(ChevronsUpDown, { className: "ml-2 h-4 w-4 shrink-0 opacity-50" })
1045
1095
  ]
1046
1096
  }
@@ -1054,12 +1104,12 @@ function Combobox({
1054
1104
  /* @__PURE__ */ jsx(
1055
1105
  CommandInput,
1056
1106
  {
1057
- placeholder: searchPlaceholder,
1107
+ placeholder: labels.searchPlaceholder,
1058
1108
  className: "h-11"
1059
1109
  }
1060
1110
  ),
1061
1111
  /* @__PURE__ */ jsxs(CommandList, { children: [
1062
- /* @__PURE__ */ jsx(CommandEmpty, { children: emptyText }),
1112
+ /* @__PURE__ */ jsx(CommandEmpty, { children: labels.emptyText }),
1063
1113
  /* @__PURE__ */ jsx(CommandGroup, { children: options.map((option) => /* @__PURE__ */ jsxs(
1064
1114
  CommandItem,
1065
1115
  {
@@ -1304,13 +1354,16 @@ function ContextMenuShortcut({
1304
1354
  }
1305
1355
  );
1306
1356
  }
1357
+ var dataTableFacetedFilterDefaultLabels = {
1358
+ noOptionsLabel: "No options."
1359
+ };
1307
1360
  function FilterPopover({
1308
1361
  label,
1309
1362
  options,
1310
1363
  selected,
1311
1364
  onToggle,
1312
1365
  width,
1313
- noOptionsLabel = "No options."
1366
+ noOptionsLabel
1314
1367
  }) {
1315
1368
  return /* @__PURE__ */ jsxs(Popover, { children: [
1316
1369
  /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
@@ -1365,6 +1418,11 @@ function FacetedFilter({
1365
1418
  filter,
1366
1419
  noOptionsLabel
1367
1420
  }) {
1421
+ const labels = useUiLabels(
1422
+ "dataTableFacetedFilter",
1423
+ dataTableFacetedFilterDefaultLabels,
1424
+ { noOptionsLabel }
1425
+ );
1368
1426
  const selected = new Set(column?.getFilterValue() ?? []);
1369
1427
  const toggle = (value) => {
1370
1428
  const next = new Set(selected);
@@ -1384,7 +1442,7 @@ function FacetedFilter({
1384
1442
  selected,
1385
1443
  onToggle: toggle,
1386
1444
  width: "w-[220px]",
1387
- noOptionsLabel
1445
+ noOptionsLabel: labels.noOptionsLabel
1388
1446
  }
1389
1447
  );
1390
1448
  }
@@ -1394,6 +1452,11 @@ function ServerFacetedFilter({
1394
1452
  onChange,
1395
1453
  noOptionsLabel
1396
1454
  }) {
1455
+ const labels = useUiLabels(
1456
+ "dataTableFacetedFilter",
1457
+ dataTableFacetedFilterDefaultLabels,
1458
+ { noOptionsLabel }
1459
+ );
1397
1460
  const selectedSet = new Set(selected);
1398
1461
  const toggle = (value) => {
1399
1462
  const next = new Set(selectedSet);
@@ -1412,7 +1475,7 @@ function ServerFacetedFilter({
1412
1475
  selected: selectedSet,
1413
1476
  onToggle: toggle,
1414
1477
  width: "w-[240px]",
1415
- noOptionsLabel
1478
+ noOptionsLabel: labels.noOptionsLabel
1416
1479
  }
1417
1480
  );
1418
1481
  }
@@ -1452,18 +1515,96 @@ function RowActionsMenu({
1452
1515
  }
1453
1516
  );
1454
1517
  }
1455
- var Table = React2.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
1456
- "div",
1457
- {
1458
- "data-slot": "table-container",
1459
- className: cn(
1460
- elevatedSurface,
1461
- nestedSurfaceReset,
1462
- nestedEdgeToEdge,
1463
- "relative w-full overflow-hidden bg-card"
1464
- ),
1465
- children: /* @__PURE__ */ jsx(
1466
- "div",
1518
+ var emptyStateLabels = {
1519
+ title: "Nothing to show"
1520
+ };
1521
+ function EmptyState({
1522
+ icon: Icon2 = SearchX,
1523
+ title = emptyStateLabels.title,
1524
+ description,
1525
+ actions,
1526
+ compact = false,
1527
+ className
1528
+ }) {
1529
+ return /* @__PURE__ */ jsxs(
1530
+ "div",
1531
+ {
1532
+ "data-slot": "empty-state",
1533
+ "data-compact": compact || void 0,
1534
+ className: cn(
1535
+ "flex h-full w-full flex-col items-center justify-center text-center",
1536
+ compact ? "gap-2 px-4 py-6" : "gap-3 px-6 py-12",
1537
+ className
1538
+ ),
1539
+ children: [
1540
+ /* @__PURE__ */ jsx(
1541
+ "span",
1542
+ {
1543
+ "data-slot": "empty-state-icon",
1544
+ className: cn(
1545
+ "flex shrink-0 items-center justify-center rounded-full bg-surface-recessed text-muted-foreground",
1546
+ compact ? "size-8" : "size-10"
1547
+ ),
1548
+ children: /* @__PURE__ */ jsx(Icon2, { className: compact ? "size-4" : "size-5" })
1549
+ }
1550
+ ),
1551
+ /* @__PURE__ */ jsxs(
1552
+ "div",
1553
+ {
1554
+ className: cn(
1555
+ "max-w-md flex flex-col",
1556
+ compact ? "gap-0.5" : "gap-1"
1557
+ ),
1558
+ children: [
1559
+ /* @__PURE__ */ jsx(
1560
+ "p",
1561
+ {
1562
+ "data-slot": "empty-state-title",
1563
+ className: cn(
1564
+ "font-semibold text-foreground",
1565
+ compact ? "text-sm" : "text-base"
1566
+ ),
1567
+ children: title
1568
+ }
1569
+ ),
1570
+ description && /* @__PURE__ */ jsx(
1571
+ "p",
1572
+ {
1573
+ "data-slot": "empty-state-description",
1574
+ className: "text-sm font-medium text-muted-foreground",
1575
+ children: description
1576
+ }
1577
+ )
1578
+ ]
1579
+ }
1580
+ ),
1581
+ actions && /* @__PURE__ */ jsx(
1582
+ "div",
1583
+ {
1584
+ "data-slot": "empty-state-actions",
1585
+ className: cn(
1586
+ "gap-2 flex flex-wrap items-center justify-center",
1587
+ compact ? "mt-1" : "mt-2"
1588
+ ),
1589
+ children: actions
1590
+ }
1591
+ )
1592
+ ]
1593
+ }
1594
+ );
1595
+ }
1596
+ var Table = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
1597
+ "div",
1598
+ {
1599
+ "data-slot": "table-container",
1600
+ className: cn(
1601
+ elevatedSurface,
1602
+ nestedSurfaceReset,
1603
+ nestedEdgeToEdge,
1604
+ "relative w-full overflow-hidden bg-card"
1605
+ ),
1606
+ children: /* @__PURE__ */ jsx(
1607
+ "div",
1467
1608
  {
1468
1609
  className: cn(
1469
1610
  nestedRadius,
@@ -1484,9 +1625,9 @@ var Table = React2.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */
1484
1625
  }
1485
1626
  ));
1486
1627
  Table.displayName = "Table";
1487
- var TableHeader = React2.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("thead", { ref, className: cn("[&_tr]:border-b", className), ...props }));
1628
+ var TableHeader = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("thead", { ref, className: cn("[&_tr]:border-b", className), ...props }));
1488
1629
  TableHeader.displayName = "TableHeader";
1489
- var TableBody = React2.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
1630
+ var TableBody = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
1490
1631
  "tbody",
1491
1632
  {
1492
1633
  ref,
@@ -1495,7 +1636,7 @@ var TableBody = React2.forwardRef(({ className, ...props }, ref) => /* @__PURE__
1495
1636
  }
1496
1637
  ));
1497
1638
  TableBody.displayName = "TableBody";
1498
- var TableFooter = React2.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
1639
+ var TableFooter = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
1499
1640
  "tfoot",
1500
1641
  {
1501
1642
  ref,
@@ -1507,7 +1648,7 @@ var TableFooter = React2.forwardRef(({ className, ...props }, ref) => /* @__PURE
1507
1648
  }
1508
1649
  ));
1509
1650
  TableFooter.displayName = "TableFooter";
1510
- var TableRow = React2.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
1651
+ var TableRow = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
1511
1652
  "tr",
1512
1653
  {
1513
1654
  ref,
@@ -1519,7 +1660,7 @@ var TableRow = React2.forwardRef(({ className, ...props }, ref) => /* @__PURE__
1519
1660
  }
1520
1661
  ));
1521
1662
  TableRow.displayName = "TableRow";
1522
- var TableHead = React2.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
1663
+ var TableHead = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
1523
1664
  "th",
1524
1665
  {
1525
1666
  ref,
@@ -1531,7 +1672,7 @@ var TableHead = React2.forwardRef(({ className, ...props }, ref) => /* @__PURE__
1531
1672
  }
1532
1673
  ));
1533
1674
  TableHead.displayName = "TableHead";
1534
- var TableCell = React2.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
1675
+ var TableCell = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
1535
1676
  "td",
1536
1677
  {
1537
1678
  ref,
@@ -1543,7 +1684,7 @@ var TableCell = React2.forwardRef(({ className, ...props }, ref) => /* @__PURE__
1543
1684
  }
1544
1685
  ));
1545
1686
  TableCell.displayName = "TableCell";
1546
- var TableCaption = React2.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
1687
+ var TableCaption = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
1547
1688
  "caption",
1548
1689
  {
1549
1690
  ref,
@@ -1568,11 +1709,20 @@ function pageRange(current, last) {
1568
1709
  pages.push(last);
1569
1710
  return pages;
1570
1711
  }
1712
+ var dataTableDefaultLabels = {
1713
+ searchPlaceholder: "Search...",
1714
+ emptyLabel: "No results.",
1715
+ createLabel: "New",
1716
+ clearFiltersLabel: "Clear filters",
1717
+ paginationLabel: (page, pages) => `Page ${page} of ${pages}`,
1718
+ noOptionsLabel: "No options.",
1719
+ totalLabel: (total) => `${total.toLocaleString("en-US")} records`
1720
+ };
1571
1721
  function DataTable({
1572
1722
  columns,
1573
1723
  data,
1574
1724
  searchKey,
1575
- searchPlaceholder = "Search...",
1725
+ searchPlaceholder,
1576
1726
  pageSize = 10,
1577
1727
  pageSizeOptions = [10, 25, 50, 100],
1578
1728
  onPageSizeChange,
@@ -1584,11 +1734,11 @@ function DataTable({
1584
1734
  onClearFilters,
1585
1735
  toolbarExtra,
1586
1736
  toolbarAction,
1587
- emptyLabel = "No results.",
1588
- clearFiltersLabel = "Clear filters",
1589
- paginationLabel = (page, pages) => `Page ${page} of ${pages}`,
1590
- noOptionsLabel = "No options.",
1591
- totalLabel = (total2) => `${total2.toLocaleString("en-US")} records`,
1737
+ emptyLabel,
1738
+ clearFiltersLabel,
1739
+ paginationLabel,
1740
+ noOptionsLabel,
1741
+ totalLabel,
1592
1742
  renderRow,
1593
1743
  onRowClick,
1594
1744
  isRowActive,
@@ -1601,8 +1751,17 @@ function DataTable({
1601
1751
  total,
1602
1752
  onPageChange,
1603
1753
  onCreate,
1604
- createLabel = "New"
1605
- }) {
1754
+ createLabel
1755
+ }) {
1756
+ const labels = useUiLabels("dataTable", dataTableDefaultLabels, {
1757
+ searchPlaceholder,
1758
+ emptyLabel,
1759
+ createLabel,
1760
+ clearFiltersLabel,
1761
+ paginationLabel,
1762
+ noOptionsLabel,
1763
+ totalLabel
1764
+ });
1606
1765
  const [sorting, setSorting] = useState([]);
1607
1766
  const [globalFilter, setGlobalFilter] = useState("");
1608
1767
  const [columnFilters, setColumnFilters] = useState([]);
@@ -1669,7 +1828,7 @@ function DataTable({
1669
1828
  {
1670
1829
  value: serverSearch ? searchValue ?? "" : globalFilter,
1671
1830
  onChange: (e) => serverSearch ? onSearchChange?.(e.target.value) : setGlobalFilter(e.target.value),
1672
- placeholder: searchPlaceholder,
1831
+ placeholder: labels.searchPlaceholder,
1673
1832
  className: "h-11 rounded-2xl pl-11 font-medium focus:shadow-lg border-none bg-muted/50 focus:bg-muted"
1674
1833
  }
1675
1834
  )
@@ -1679,7 +1838,7 @@ function DataTable({
1679
1838
  {
1680
1839
  column: table.getColumn(filter.columnId),
1681
1840
  filter,
1682
- noOptionsLabel
1841
+ noOptionsLabel: labels.noOptionsLabel
1683
1842
  },
1684
1843
  filter.columnId
1685
1844
  )),
@@ -1689,7 +1848,7 @@ function DataTable({
1689
1848
  filter,
1690
1849
  selected: filterValues?.[filter.paramKey] ?? [],
1691
1850
  onChange: (values) => onFilterChange?.(filter.paramKey, values),
1692
- noOptionsLabel
1851
+ noOptionsLabel: labels.noOptionsLabel
1693
1852
  },
1694
1853
  filter.paramKey
1695
1854
  )),
@@ -1708,7 +1867,7 @@ function DataTable({
1708
1867
  },
1709
1868
  className: "h-11 rounded-2xl",
1710
1869
  children: [
1711
- clearFiltersLabel,
1870
+ labels.clearFiltersLabel,
1712
1871
  /* @__PURE__ */ jsx(X, { className: "ml-1 size-4" })
1713
1872
  ]
1714
1873
  }
@@ -1717,7 +1876,7 @@ function DataTable({
1717
1876
  Button,
1718
1877
  {
1719
1878
  onClick: onCreate,
1720
- "aria-label": createLabel,
1879
+ "aria-label": labels.createLabel,
1721
1880
  size: "icon",
1722
1881
  className: "size-11 rounded-2xl shrink-0 cursor-pointer bg-primary text-primary-foreground hover:bg-primary/90",
1723
1882
  children: /* @__PURE__ */ jsx(Plus, { className: "size-5" })
@@ -1787,8 +1946,8 @@ function DataTable({
1787
1946
  TableCell,
1788
1947
  {
1789
1948
  colSpan: tableColumns.length,
1790
- className: "h-24 text-sm font-medium text-center text-muted-foreground italic",
1791
- children: emptyLabel
1949
+ className: "h-24 p-0",
1950
+ children: /* @__PURE__ */ jsx(EmptyState, { compact: true, title: labels.emptyLabel })
1792
1951
  }
1793
1952
  ) }) })
1794
1953
  ] }),
@@ -1814,8 +1973,8 @@ function DataTable({
1814
1973
  }
1815
1974
  ),
1816
1975
  /* @__PURE__ */ jsxs("span", { className: "text-xs font-medium text-muted-foreground", children: [
1817
- paginationLabel(currentPage, lastPage),
1818
- total !== void 0 && ` \xB7 ${totalLabel(total)}`
1976
+ labels.paginationLabel(currentPage, lastPage),
1977
+ total !== void 0 && ` \xB7 ${labels.totalLabel(total)}`
1819
1978
  ] })
1820
1979
  ] }),
1821
1980
  /* @__PURE__ */ jsxs("div", { className: "gap-1.5 flex items-center", children: [
@@ -1869,69 +2028,224 @@ function DataTable({
1869
2028
  }
1870
2029
  );
1871
2030
  }
2031
+ function CalendarPopover({
2032
+ open,
2033
+ onOpenChange,
2034
+ trigger,
2035
+ align = "start",
2036
+ className,
2037
+ children
2038
+ }) {
2039
+ return /* @__PURE__ */ jsxs(Popover, { open, onOpenChange, children: [
2040
+ /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: trigger }),
2041
+ /* @__PURE__ */ jsx(
2042
+ PopoverContent,
2043
+ {
2044
+ "data-slot": "calendar-popover",
2045
+ className: cn("p-2 w-auto", className),
2046
+ align,
2047
+ sideOffset: 4,
2048
+ collisionPadding: 16,
2049
+ children
2050
+ }
2051
+ )
2052
+ ] });
2053
+ }
2054
+ var datePickerDefaultLabels = {
2055
+ placeholder: "Pick a date",
2056
+ dateFormat: "dd MMM yy",
2057
+ clearLabel: "Clear date"
2058
+ };
2059
+ var triggerClasses = `h-11 px-4 text-sm font-medium flex w-full cursor-pointer items-center gap-2 text-left transition-all disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 ${fieldSurface} ${focusRing}`;
2060
+ function boundaries(minDate, maxDate, disabledDays) {
2061
+ const matchers = [];
2062
+ if (minDate) {
2063
+ matchers.push({ before: minDate });
2064
+ }
2065
+ if (maxDate) {
2066
+ matchers.push({ after: maxDate });
2067
+ }
2068
+ if (disabledDays) {
2069
+ matchers.push(disabledDays);
2070
+ }
2071
+ return matchers;
2072
+ }
2073
+ function DatePicker(props) {
2074
+ const {
2075
+ id,
2076
+ value,
2077
+ defaultValue,
2078
+ onChange,
2079
+ minDate,
2080
+ maxDate,
2081
+ disabledDays,
2082
+ disabled = false,
2083
+ clearable = true,
2084
+ invalid = false,
2085
+ formatDate,
2086
+ placeholder,
2087
+ dateFormat,
2088
+ clearLabel,
2089
+ className
2090
+ } = props;
2091
+ const labels = useUiLabels("datePicker", datePickerDefaultLabels, {
2092
+ placeholder,
2093
+ dateFormat,
2094
+ clearLabel
2095
+ });
2096
+ const [open, setOpen] = useState(false);
2097
+ const [ownValue, setOwnValue] = useState(defaultValue);
2098
+ const isControlled = "value" in props;
2099
+ const selected = isControlled ? value : ownValue;
2100
+ const showClear = clearable && !disabled && selected !== void 0;
2101
+ const label = selected ? formatDate?.(selected) ?? format(selected, labels.dateFormat) : labels.placeholder;
2102
+ function commit(next) {
2103
+ if (!isControlled) {
2104
+ setOwnValue(next);
2105
+ }
2106
+ onChange?.(next);
2107
+ }
2108
+ return /* @__PURE__ */ jsxs(
2109
+ "div",
2110
+ {
2111
+ "data-slot": "date-picker",
2112
+ className: cn("relative w-full", className),
2113
+ children: [
2114
+ /* @__PURE__ */ jsx(
2115
+ CalendarPopover,
2116
+ {
2117
+ open,
2118
+ onOpenChange: setOpen,
2119
+ trigger: /* @__PURE__ */ jsxs(
2120
+ "button",
2121
+ {
2122
+ type: "button",
2123
+ id,
2124
+ "data-slot": "date-picker-trigger",
2125
+ disabled,
2126
+ "aria-invalid": invalid || void 0,
2127
+ className: cn(triggerClasses, showClear && "pr-11"),
2128
+ children: [
2129
+ /* @__PURE__ */ jsx(CalendarIcon, { className: "size-4 shrink-0 opacity-60" }),
2130
+ /* @__PURE__ */ jsx(
2131
+ "span",
2132
+ {
2133
+ className: cn(
2134
+ "truncate",
2135
+ !selected && "text-muted-foreground"
2136
+ ),
2137
+ children: label
2138
+ }
2139
+ )
2140
+ ]
2141
+ }
2142
+ ),
2143
+ children: /* @__PURE__ */ jsx(
2144
+ Calendar,
2145
+ {
2146
+ mode: "single",
2147
+ autoFocus: true,
2148
+ selected,
2149
+ defaultMonth: selected ?? minDate,
2150
+ startMonth: minDate,
2151
+ endMonth: maxDate,
2152
+ disabled: boundaries(minDate, maxDate, disabledDays),
2153
+ onSelect: (date) => {
2154
+ if (!date) {
2155
+ return;
2156
+ }
2157
+ commit(date);
2158
+ setOpen(false);
2159
+ },
2160
+ className: "rounded-2xl bg-transparent"
2161
+ }
2162
+ )
2163
+ }
2164
+ ),
2165
+ showClear && /* @__PURE__ */ jsx(
2166
+ "button",
2167
+ {
2168
+ type: "button",
2169
+ "data-slot": "date-picker-clear",
2170
+ "aria-label": labels.clearLabel,
2171
+ onClick: () => commit(void 0),
2172
+ className: `size-7 rounded-xl right-2 absolute top-1/2 inline-flex -translate-y-1/2 cursor-pointer items-center justify-center text-muted-foreground hover:text-foreground ${focusRing}`,
2173
+ children: /* @__PURE__ */ jsx(X, { className: "size-3.5" })
2174
+ }
2175
+ )
2176
+ ]
2177
+ }
2178
+ );
2179
+ }
1872
2180
  function parse(value) {
1873
2181
  return value ? /* @__PURE__ */ new Date(`${value}T00:00:00`) : void 0;
1874
2182
  }
2183
+ var dateRangeFilterDefaultLabels = {
2184
+ emptyLabel: "Date range",
2185
+ dateFormat: "dd MMM yy"
2186
+ };
1875
2187
  function DateRangeFilter({
1876
2188
  from,
1877
2189
  to,
1878
2190
  onChange,
1879
- emptyLabel = "Date range",
1880
- dateFormat = "dd MMM yy"
2191
+ emptyLabel,
2192
+ dateFormat
1881
2193
  }) {
2194
+ const labels = useUiLabels(
2195
+ "dateRangeFilter",
2196
+ dateRangeFilterDefaultLabels,
2197
+ { emptyLabel, dateFormat }
2198
+ );
1882
2199
  const [open, setOpen] = useState(false);
1883
2200
  const selected = from || to ? { from: parse(from), to: parse(to) } : void 0;
1884
- const label = from ? to && to !== from ? `${format(parse(from), dateFormat)} - ${format(parse(to), dateFormat)}` : format(parse(from), dateFormat) : emptyLabel;
1885
- return /* @__PURE__ */ jsxs(Popover, { open, onOpenChange: setOpen, children: [
1886
- /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
1887
- Button,
1888
- {
1889
- variant: "outline",
1890
- "data-slot": "date-range-filter",
1891
- className: "h-11 rounded-2xl cursor-pointer border-dashed border-border",
1892
- children: [
1893
- /* @__PURE__ */ jsx(CalendarRange, { className: "mr-2 size-4" }),
1894
- label,
1895
- (from || to) && /* @__PURE__ */ jsx(
1896
- "span",
1897
- {
1898
- role: "button",
1899
- tabIndex: 0,
1900
- onClick: (event) => {
1901
- event.stopPropagation();
1902
- onChange({ from: void 0, to: void 0 });
1903
- },
1904
- className: "ml-2 inline-flex",
1905
- children: /* @__PURE__ */ jsx(X, { className: "size-3.5 opacity-60 hover:opacity-100" })
1906
- }
1907
- )
1908
- ]
1909
- }
1910
- ) }),
1911
- /* @__PURE__ */ jsx(
1912
- PopoverContent,
1913
- {
1914
- className: "p-2 w-auto",
1915
- align: "end",
1916
- sideOffset: 4,
1917
- collisionPadding: 16,
1918
- children: /* @__PURE__ */ jsx(
1919
- Calendar,
1920
- {
1921
- mode: "range",
1922
- numberOfMonths: 2,
1923
- defaultMonth: parse(from),
1924
- selected,
1925
- onSelect: (range) => onChange({
1926
- from: range?.from ? format(range.from, "yyyy-MM-dd") : void 0,
1927
- to: range?.to ? format(range.to, "yyyy-MM-dd") : void 0
1928
- }),
1929
- className: "rounded-2xl bg-transparent"
1930
- }
1931
- )
1932
- }
1933
- )
1934
- ] });
2201
+ const label = from ? to && to !== from ? `${format(parse(from), labels.dateFormat)} - ${format(parse(to), labels.dateFormat)}` : format(parse(from), labels.dateFormat) : labels.emptyLabel;
2202
+ return /* @__PURE__ */ jsx(
2203
+ CalendarPopover,
2204
+ {
2205
+ open,
2206
+ onOpenChange: setOpen,
2207
+ align: "end",
2208
+ trigger: /* @__PURE__ */ jsxs(
2209
+ Button,
2210
+ {
2211
+ variant: "outline",
2212
+ "data-slot": "date-range-filter",
2213
+ className: "h-11 rounded-2xl cursor-pointer border-dashed border-border",
2214
+ children: [
2215
+ /* @__PURE__ */ jsx(CalendarRange, { className: "mr-2 size-4" }),
2216
+ label,
2217
+ (from || to) && /* @__PURE__ */ jsx(
2218
+ "span",
2219
+ {
2220
+ role: "button",
2221
+ tabIndex: 0,
2222
+ onClick: (event) => {
2223
+ event.stopPropagation();
2224
+ onChange({ from: void 0, to: void 0 });
2225
+ },
2226
+ className: "ml-2 inline-flex",
2227
+ children: /* @__PURE__ */ jsx(X, { className: "size-3.5 opacity-60 hover:opacity-100" })
2228
+ }
2229
+ )
2230
+ ]
2231
+ }
2232
+ ),
2233
+ children: /* @__PURE__ */ jsx(
2234
+ Calendar,
2235
+ {
2236
+ mode: "range",
2237
+ numberOfMonths: 2,
2238
+ defaultMonth: parse(from),
2239
+ selected,
2240
+ onSelect: (range) => onChange({
2241
+ from: range?.from ? format(range.from, "yyyy-MM-dd") : void 0,
2242
+ to: range?.to ? format(range.to, "yyyy-MM-dd") : void 0
2243
+ }),
2244
+ className: "rounded-2xl bg-transparent"
2245
+ }
2246
+ )
2247
+ }
2248
+ );
1935
2249
  }
1936
2250
  function Drawer({
1937
2251
  ...props
@@ -2046,21 +2360,158 @@ function DrawerDescription({
2046
2360
  }
2047
2361
  );
2048
2362
  }
2049
- function FieldError({ message }) {
2050
- if (!message) {
2051
- return null;
2052
- }
2363
+ function Field({
2364
+ className,
2365
+ children,
2366
+ id,
2367
+ orientation = "vertical",
2368
+ error,
2369
+ invalid,
2370
+ required = false,
2371
+ ...props
2372
+ }) {
2373
+ const generatedId = React3.useId();
2374
+ const fieldId = id ?? generatedId;
2375
+ const [hasDescription, setHasDescription] = React3.useState(false);
2376
+ const isInvalid = invalid ?? Boolean(error);
2377
+ const field = React3.useMemo(
2378
+ () => ({
2379
+ controlId: fieldId,
2380
+ descriptionId: `${fieldId}-description`,
2381
+ errorId: `${fieldId}-error`,
2382
+ orientation,
2383
+ invalid: isInvalid,
2384
+ required,
2385
+ hasDescription,
2386
+ setHasDescription
2387
+ }),
2388
+ [fieldId, orientation, isInvalid, required, hasDescription]
2389
+ );
2390
+ return /* @__PURE__ */ jsx(FieldContext.Provider, { value: field, children: /* @__PURE__ */ jsxs(
2391
+ "div",
2392
+ {
2393
+ "data-slot": "field",
2394
+ "data-orientation": orientation,
2395
+ "data-invalid": isInvalid ? "true" : void 0,
2396
+ className: cn(
2397
+ "group/field",
2398
+ orientation === "horizontal" ? "gap-x-4 gap-y-1 grid grid-cols-[1fr_auto] items-center" : "gap-2 flex flex-col",
2399
+ className
2400
+ ),
2401
+ ...props,
2402
+ children: [
2403
+ children,
2404
+ /* @__PURE__ */ jsx(FieldError, { message: error })
2405
+ ]
2406
+ }
2407
+ ) });
2408
+ }
2409
+ function FieldGroup({
2410
+ className,
2411
+ ...props
2412
+ }) {
2413
+ return /* @__PURE__ */ jsx(
2414
+ "div",
2415
+ {
2416
+ "data-slot": "field-group",
2417
+ className: cn("gap-6 flex w-full flex-col", className),
2418
+ ...props
2419
+ }
2420
+ );
2421
+ }
2422
+ function FieldLabel({
2423
+ className,
2424
+ children,
2425
+ requiredLabel = "Required",
2426
+ ...props
2427
+ }) {
2428
+ const { controlId, invalid, required } = useField();
2429
+ return /* @__PURE__ */ jsxs(
2430
+ Label,
2431
+ {
2432
+ "data-slot": "field-label",
2433
+ htmlFor: controlId,
2434
+ className: cn(
2435
+ "gap-1 flex items-center group-data-[orientation=horizontal]/field:col-start-1 group-data-[orientation=horizontal]/field:row-start-1",
2436
+ invalid && "text-destructive",
2437
+ className
2438
+ ),
2439
+ ...props,
2440
+ children: [
2441
+ children,
2442
+ required ? /* @__PURE__ */ jsxs(Fragment, { children: [
2443
+ /* @__PURE__ */ jsx(
2444
+ "span",
2445
+ {
2446
+ "data-slot": "field-required",
2447
+ "aria-hidden": "true",
2448
+ className: "text-destructive",
2449
+ children: "*"
2450
+ }
2451
+ ),
2452
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: requiredLabel })
2453
+ ] }) : null
2454
+ ]
2455
+ }
2456
+ );
2457
+ }
2458
+ function FieldDescription({
2459
+ className,
2460
+ ...props
2461
+ }) {
2462
+ const { descriptionId, setHasDescription } = useField();
2463
+ React3.useEffect(() => {
2464
+ setHasDescription(true);
2465
+ return () => setHasDescription(false);
2466
+ }, [setHasDescription]);
2053
2467
  return /* @__PURE__ */ jsx(
2054
2468
  "p",
2055
2469
  {
2056
- className: "ml-1 text-xs font-medium text-destructive",
2057
- "data-slot": "field-error",
2058
- children: message
2470
+ id: descriptionId,
2471
+ "data-slot": "field-description",
2472
+ className: cn(
2473
+ "ml-1 text-xs font-medium text-muted-foreground group-data-[orientation=horizontal]/field:col-start-1 group-data-[orientation=horizontal]/field:row-start-2",
2474
+ className
2475
+ ),
2476
+ ...props
2477
+ }
2478
+ );
2479
+ }
2480
+ function FieldControl({
2481
+ className,
2482
+ ...props
2483
+ }) {
2484
+ const {
2485
+ controlId,
2486
+ descriptionId,
2487
+ errorId,
2488
+ invalid,
2489
+ required,
2490
+ hasDescription
2491
+ } = useField();
2492
+ const requiredProps = required ? { required: true } : {};
2493
+ const describedBy = [
2494
+ hasDescription ? descriptionId : null,
2495
+ invalid ? errorId : null
2496
+ ].filter(Boolean).join(" ");
2497
+ return /* @__PURE__ */ jsx(
2498
+ Slot,
2499
+ {
2500
+ "data-slot": "field-control",
2501
+ id: controlId,
2502
+ "aria-describedby": describedBy || void 0,
2503
+ "aria-invalid": invalid ? true : void 0,
2504
+ ...requiredProps,
2505
+ className: cn(
2506
+ "group-data-[orientation=horizontal]/field:col-start-2 group-data-[orientation=horizontal]/field:row-span-2 group-data-[orientation=horizontal]/field:row-start-1 group-data-[orientation=horizontal]/field:justify-self-end",
2507
+ className
2508
+ ),
2509
+ ...props
2059
2510
  }
2060
2511
  );
2061
2512
  }
2062
2513
  var Form = FormProvider;
2063
- var FormFieldContext = React2.createContext(
2514
+ var FormFieldContext = React3.createContext(
2064
2515
  {}
2065
2516
  );
2066
2517
  var FormField = ({
@@ -2069,8 +2520,8 @@ var FormField = ({
2069
2520
  return /* @__PURE__ */ jsx(FormFieldContext.Provider, { value: { name: props.name }, children: /* @__PURE__ */ jsx(Controller, { ...props }) });
2070
2521
  };
2071
2522
  var useFormField = () => {
2072
- const fieldContext = React2.useContext(FormFieldContext);
2073
- const itemContext = React2.useContext(FormItemContext);
2523
+ const fieldContext = React3.useContext(FormFieldContext);
2524
+ const itemContext = React3.useContext(FormItemContext);
2074
2525
  const { getFieldState, formState } = useFormContext();
2075
2526
  const fieldState = getFieldState(fieldContext.name, formState);
2076
2527
  if (!fieldContext) {
@@ -2086,11 +2537,11 @@ var useFormField = () => {
2086
2537
  ...fieldState
2087
2538
  };
2088
2539
  };
2089
- var FormItemContext = React2.createContext(
2540
+ var FormItemContext = React3.createContext(
2090
2541
  {}
2091
2542
  );
2092
- var FormItem = React2.forwardRef(({ className, ...props }, ref) => {
2093
- const id = React2.useId();
2543
+ var FormItem = React3.forwardRef(({ className, ...props }, ref) => {
2544
+ const id = React3.useId();
2094
2545
  return /* @__PURE__ */ jsx(FormItemContext.Provider, { value: { id }, children: /* @__PURE__ */ jsx(
2095
2546
  "div",
2096
2547
  {
@@ -2102,7 +2553,7 @@ var FormItem = React2.forwardRef(({ className, ...props }, ref) => {
2102
2553
  ) });
2103
2554
  });
2104
2555
  FormItem.displayName = "FormItem";
2105
- var FormLabel = React2.forwardRef(({ className, ...props }, ref) => {
2556
+ var FormLabel = React3.forwardRef(({ className, ...props }, ref) => {
2106
2557
  const { error, formItemId } = useFormField();
2107
2558
  return /* @__PURE__ */ jsx(
2108
2559
  Label,
@@ -2115,7 +2566,7 @@ var FormLabel = React2.forwardRef(({ className, ...props }, ref) => {
2115
2566
  );
2116
2567
  });
2117
2568
  FormLabel.displayName = "FormLabel";
2118
- var FormControl = React2.forwardRef(({ ...props }, ref) => {
2569
+ var FormControl = React3.forwardRef(({ ...props }, ref) => {
2119
2570
  const { error, formItemId, formDescriptionId, formMessageId } = useFormField();
2120
2571
  return /* @__PURE__ */ jsx(
2121
2572
  Slot,
@@ -2129,7 +2580,7 @@ var FormControl = React2.forwardRef(({ ...props }, ref) => {
2129
2580
  );
2130
2581
  });
2131
2582
  FormControl.displayName = "FormControl";
2132
- var FormDescription = React2.forwardRef(({ className, ...props }, ref) => {
2583
+ var FormDescription = React3.forwardRef(({ className, ...props }, ref) => {
2133
2584
  const { formDescriptionId } = useFormField();
2134
2585
  return /* @__PURE__ */ jsx(
2135
2586
  "p",
@@ -2142,7 +2593,7 @@ var FormDescription = React2.forwardRef(({ className, ...props }, ref) => {
2142
2593
  );
2143
2594
  });
2144
2595
  FormDescription.displayName = "FormDescription";
2145
- var FormMessage = React2.forwardRef(({ className, children, ...props }, ref) => {
2596
+ var FormMessage = React3.forwardRef(({ className, children, ...props }, ref) => {
2146
2597
  const { error, formMessageId } = useFormField();
2147
2598
  const body = error ? String(error?.message ?? "") : children;
2148
2599
  if (!body) {
@@ -2193,47 +2644,6 @@ function HoverCardContent({
2193
2644
  }
2194
2645
  ) });
2195
2646
  }
2196
- var InputOTP = React2.forwardRef(({ className, containerClassName, ...props }, ref) => /* @__PURE__ */ jsx(
2197
- OTPInput,
2198
- {
2199
- ref,
2200
- containerClassName: cn(
2201
- "gap-2 flex items-center has-[:disabled]:opacity-50",
2202
- containerClassName
2203
- ),
2204
- className: cn("disabled:cursor-not-allowed", className),
2205
- ...props
2206
- }
2207
- ));
2208
- InputOTP.displayName = "InputOTP";
2209
- var InputOTPGroup = React2.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("flex items-center", className), ...props }));
2210
- InputOTPGroup.displayName = "InputOTPGroup";
2211
- var InputOTPSlot = React2.forwardRef(({ index, className, ...props }, ref) => {
2212
- const inputOTPContext = React2.useContext(OTPInputContext);
2213
- const { char, hasFakeCaret, isActive } = inputOTPContext.slots[index];
2214
- return /* @__PURE__ */ jsxs(
2215
- "div",
2216
- {
2217
- ref,
2218
- "data-slot": "input-otp-slot",
2219
- className: cn(
2220
- glassControl,
2221
- controlFill,
2222
- "size-11 text-sm font-medium first:rounded-l-2xl last:rounded-r-2xl relative flex items-center justify-center rounded-none transition-all",
2223
- isActive && "z-10 ring-[3px] ring-ring/50",
2224
- className
2225
- ),
2226
- ...props,
2227
- children: [
2228
- char,
2229
- hasFakeCaret && /* @__PURE__ */ jsx("div", { className: "inset-0 pointer-events-none absolute flex items-center justify-center", children: /* @__PURE__ */ jsx("div", { className: "h-4 animate-caret-blink w-px bg-foreground duration-1000" }) })
2230
- ]
2231
- }
2232
- );
2233
- });
2234
- InputOTPSlot.displayName = "InputOTPSlot";
2235
- var InputOTPSeparator = React2.forwardRef(({ ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, role: "separator", ...props, children: /* @__PURE__ */ jsx(Minus, {}) }));
2236
- InputOTPSeparator.displayName = "InputOTPSeparator";
2237
2647
  function Menubar({
2238
2648
  className,
2239
2649
  ...props
@@ -2731,6 +3141,41 @@ function PaginationEllipsis({
2731
3141
  }
2732
3142
  );
2733
3143
  }
3144
+ function PasswordInput({
3145
+ className,
3146
+ revealable = true,
3147
+ showLabel = "Show password",
3148
+ hideLabel = "Hide password",
3149
+ ...props
3150
+ }) {
3151
+ const [visible, setVisible] = React3.useState(false);
3152
+ return /* @__PURE__ */ jsxs("div", { "data-slot": "password-input", className: "relative w-full", children: [
3153
+ /* @__PURE__ */ jsx(
3154
+ Input,
3155
+ {
3156
+ type: visible ? "text" : "password",
3157
+ className: cn(revealable && "pr-12", className),
3158
+ ...props
3159
+ }
3160
+ ),
3161
+ revealable ? /* @__PURE__ */ jsx(
3162
+ Button,
3163
+ {
3164
+ type: "button",
3165
+ variant: "ghost",
3166
+ size: "icon-sm",
3167
+ "data-slot": "password-input-toggle",
3168
+ "aria-label": visible ? hideLabel : showLabel,
3169
+ "aria-pressed": visible,
3170
+ disabled: props.disabled,
3171
+ onMouseDown: (event) => event.preventDefault(),
3172
+ onClick: () => setVisible((current) => !current),
3173
+ className: "right-1 absolute top-1/2 -translate-y-1/2",
3174
+ children: visible ? /* @__PURE__ */ jsx(EyeOff, { "aria-hidden": "true" }) : /* @__PURE__ */ jsx(Eye, { "aria-hidden": "true" })
3175
+ }
3176
+ ) : null
3177
+ ] });
3178
+ }
2734
3179
  function PlaceholderPattern({ className }) {
2735
3180
  const patternId = useId();
2736
3181
  return /* @__PURE__ */ jsxs("svg", { "data-slot": "placeholder-pattern", className, fill: "none", children: [
@@ -2864,7 +3309,96 @@ function ResizableHandle({
2864
3309
  }
2865
3310
  );
2866
3311
  }
2867
- var ScrollArea = React2.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
3312
+ var saveStatusLabels = {
3313
+ error: "Your changes could not be saved",
3314
+ idle: "Changes are saved automatically",
3315
+ saved: "Saved",
3316
+ saving: "Saving"
3317
+ };
3318
+ var SAVED_DURATION = 2e3;
3319
+ function SaveStatus({
3320
+ status,
3321
+ message,
3322
+ showIdle = false,
3323
+ savedDuration = SAVED_DURATION,
3324
+ labels,
3325
+ className,
3326
+ ...props
3327
+ }) {
3328
+ const text = useUiLabels("saveStatus", saveStatusLabels, labels);
3329
+ const [faded, setFaded] = React3.useState(false);
3330
+ React3.useEffect(() => {
3331
+ if (status !== "saved" || savedDuration <= 0) {
3332
+ setFaded(false);
3333
+ return;
3334
+ }
3335
+ setFaded(false);
3336
+ const timer = setTimeout(() => setFaded(true), savedDuration);
3337
+ return () => clearTimeout(timer);
3338
+ }, [status, savedDuration, message]);
3339
+ const hidden = status === "saved" && faded;
3340
+ return /* @__PURE__ */ jsxs(
3341
+ "div",
3342
+ {
3343
+ ...props,
3344
+ "data-slot": "save-status",
3345
+ "data-state": status,
3346
+ "data-faded": hidden || void 0,
3347
+ role: "status",
3348
+ "aria-live": "polite",
3349
+ "aria-hidden": hidden || void 0,
3350
+ className: cn(
3351
+ "gap-2 text-xs font-medium min-h-5 flex items-center transition-opacity duration-300",
3352
+ hidden ? "opacity-0" : "opacity-100",
3353
+ className
3354
+ ),
3355
+ children: [
3356
+ status === "idle" && showIdle && /* @__PURE__ */ jsx(
3357
+ "span",
3358
+ {
3359
+ "data-slot": "save-status-idle",
3360
+ className: "text-muted-foreground",
3361
+ children: text.idle
3362
+ }
3363
+ ),
3364
+ status === "saving" && /* @__PURE__ */ jsxs(
3365
+ "span",
3366
+ {
3367
+ "data-slot": "save-status-saving",
3368
+ className: "gap-2 flex items-center text-muted-foreground",
3369
+ children: [
3370
+ /* @__PURE__ */ jsx(Spinner, { size: "sm", label: "", "aria-hidden": "true" }),
3371
+ text.saving
3372
+ ]
3373
+ }
3374
+ ),
3375
+ status === "saved" && /* @__PURE__ */ jsxs(
3376
+ "span",
3377
+ {
3378
+ "data-slot": "save-status-saved",
3379
+ className: "gap-2 flex items-center text-success",
3380
+ children: [
3381
+ /* @__PURE__ */ jsx(Check, { "aria-hidden": "true", className: "size-3.5" }),
3382
+ text.saved
3383
+ ]
3384
+ }
3385
+ ),
3386
+ status === "error" && /* @__PURE__ */ jsxs(
3387
+ "span",
3388
+ {
3389
+ "data-slot": "save-status-error",
3390
+ className: "gap-2 flex items-center text-destructive",
3391
+ children: [
3392
+ /* @__PURE__ */ jsx(TriangleAlert, { "aria-hidden": "true", className: "size-3.5" }),
3393
+ message ?? text.error
3394
+ ]
3395
+ }
3396
+ )
3397
+ ]
3398
+ }
3399
+ );
3400
+ }
3401
+ var ScrollArea = React3.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
2868
3402
  ScrollAreaPrimitive.Root,
2869
3403
  {
2870
3404
  "data-slot": "scroll-area",
@@ -2885,7 +3419,7 @@ var ScrollArea = React2.forwardRef(({ className, children, ...props }, ref) => /
2885
3419
  }
2886
3420
  ));
2887
3421
  ScrollArea.displayName = ScrollAreaPrimitive.Root.displayName;
2888
- var ScrollBar = React2.forwardRef(({ className, orientation = "vertical", ...props }, ref) => /* @__PURE__ */ jsx(
3422
+ var ScrollBar = React3.forwardRef(({ className, orientation = "vertical", ...props }, ref) => /* @__PURE__ */ jsx(
2889
3423
  ScrollAreaPrimitive.ScrollAreaScrollbar,
2890
3424
  {
2891
3425
  "data-slot": "scroll-area-scrollbar",
@@ -2910,7 +3444,7 @@ function Slider({
2910
3444
  max = 100,
2911
3445
  ...props
2912
3446
  }) {
2913
- const _values = React2.useMemo(
3447
+ const _values = React3.useMemo(
2914
3448
  () => Array.isArray(value) ? value : Array.isArray(defaultValue) ? defaultValue : [min, max],
2915
3449
  [value, defaultValue, min, max]
2916
3450
  );
@@ -3000,95 +3534,85 @@ var Toaster = ({ theme, ...props }) => {
3000
3534
  }
3001
3535
  );
3002
3536
  };
3003
- var toggleVariants = cva(
3004
- `inline-flex items-center justify-center gap-2 rounded-xl text-sm font-medium hover:bg-muted hover:text-muted-foreground disabled:pointer-events-none disabled:opacity-50 data-[state=on]:bg-accent data-[state=on]:font-semibold data-[state=on]:text-accent-foreground [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 transition-[color,box-shadow] aria-invalid:ring-destructive/20 aria-invalid:border-destructive ${focusRing}`,
3005
- {
3006
- variants: {
3007
- variant: {
3008
- default: "bg-transparent",
3009
- outline: `${glassControl} ${controlFill} hover:bg-accent hover:text-accent-foreground`
3010
- },
3011
- size: {
3012
- default: "h-11 px-4 min-w-11",
3013
- sm: "h-9 px-3 min-w-9",
3014
- lg: "h-12 px-6 min-w-12"
3015
- }
3016
- },
3017
- defaultVariants: {
3018
- variant: "default",
3019
- size: "default"
3020
- }
3537
+ var statusBadgeVariants = cva("", {
3538
+ variants: {
3539
+ status: {
3540
+ neutral: "border-border bg-muted text-muted-foreground",
3541
+ info: "border-info/20 bg-info/10 text-info",
3542
+ success: "border-success/20 bg-success/10 text-success",
3543
+ warning: "border-warning/20 bg-warning/10 text-warning",
3544
+ danger: "border-destructive/20 bg-destructive/10 text-destructive"
3545
+ }
3546
+ },
3547
+ defaultVariants: {
3548
+ status: "neutral"
3021
3549
  }
3022
- );
3023
- function Toggle({
3024
- className,
3025
- variant,
3026
- size,
3027
- ...props
3028
- }) {
3029
- return /* @__PURE__ */ jsx(
3030
- TogglePrimitive.Root,
3031
- {
3032
- "data-slot": "toggle",
3033
- className: cn(toggleVariants({ variant, size, className })),
3034
- ...props
3035
- }
3036
- );
3037
- }
3038
- var ToggleGroupContext = React2.createContext({
3039
- size: "default",
3040
- variant: "default"
3041
3550
  });
3042
- function ToggleGroup({
3551
+ function StatusBadge({
3043
3552
  className,
3044
- variant,
3045
- size,
3553
+ status = "neutral",
3554
+ dot = false,
3046
3555
  children,
3047
3556
  ...props
3048
3557
  }) {
3049
- return /* @__PURE__ */ jsx(
3050
- ToggleGroupPrimitive.Root,
3558
+ const resolvedStatus = status ?? "neutral";
3559
+ return /* @__PURE__ */ jsxs(
3560
+ Badge,
3051
3561
  {
3052
- "data-slot": "toggle-group",
3053
- "data-variant": variant,
3054
- "data-size": size,
3562
+ variant: "outline",
3563
+ "data-slot": "status-badge",
3564
+ "data-status": resolvedStatus,
3055
3565
  className: cn(
3056
- "group/toggle-group data-[variant=outline]:shadow-xs rounded-2xl flex items-center",
3566
+ statusBadgeVariants({ status: resolvedStatus }),
3057
3567
  className
3058
3568
  ),
3059
3569
  ...props,
3060
- children: /* @__PURE__ */ jsx(ToggleGroupContext.Provider, { value: { variant, size }, children })
3570
+ children: [
3571
+ dot && /* @__PURE__ */ jsx(
3572
+ "span",
3573
+ {
3574
+ "aria-hidden": "true",
3575
+ "data-slot": "status-badge-dot",
3576
+ className: "size-1.5 shrink-0 rounded-full bg-current"
3577
+ }
3578
+ ),
3579
+ children
3580
+ ]
3061
3581
  }
3062
3582
  );
3063
3583
  }
3064
- function ToggleGroupItem({
3584
+ var textLinkVariants = cva(
3585
+ `cursor-pointer rounded-xl underline decoration-border underline-offset-4 transition-colors duration-300 ease-out hover:decoration-current ${focusRing}`,
3586
+ {
3587
+ variants: {
3588
+ variant: {
3589
+ default: "text-foreground",
3590
+ muted: "text-muted-foreground hover:text-foreground"
3591
+ }
3592
+ },
3593
+ defaultVariants: {
3594
+ variant: "default"
3595
+ }
3596
+ }
3597
+ );
3598
+ function TextLink({
3065
3599
  className,
3066
- children,
3067
- variant,
3068
- size,
3600
+ variant = "default",
3601
+ asChild = false,
3069
3602
  ...props
3070
3603
  }) {
3071
- const context = React2.useContext(ToggleGroupContext);
3604
+ const Comp = asChild ? Slot : "a";
3072
3605
  return /* @__PURE__ */ jsx(
3073
- ToggleGroupPrimitive.Item,
3606
+ Comp,
3074
3607
  {
3075
- "data-slot": "toggle-group-item",
3076
- "data-variant": context.variant || variant,
3077
- "data-size": context.size || size,
3078
- className: cn(
3079
- toggleVariants({
3080
- variant: context.variant || variant,
3081
- size: context.size || size
3082
- }),
3083
- "min-w-0 first:rounded-l-2xl last:rounded-r-2xl shrink-0 rounded-none shadow-none focus:z-10 focus-visible:z-10 data-[variant=outline]:border-l-0 data-[variant=outline]:first:border-l",
3084
- className
3085
- ),
3086
- ...props,
3087
- children
3608
+ "data-slot": "text-link",
3609
+ "data-variant": variant,
3610
+ className: cn(textLinkVariants({ variant }), className),
3611
+ ...props
3088
3612
  }
3089
3613
  );
3090
3614
  }
3091
3615
 
3092
- export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, Alert, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogMedia, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AlertTitle, AspectRatio, Badge, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Carousel, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious, ChartContainer, ChartLegend, ChartLegendContent, ChartStyle, ChartTooltip, ChartTooltipContent, Checkbox, Combobox, ConfirmDialog, ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuGroup, ContextMenuItem, ContextMenuLabel, ContextMenuPortal, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSeparator, ContextMenuShortcut, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger, DataTable, DateRangeFilter, Drawer, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerPortal, DrawerTitle, DrawerTrigger, FacetedFilter, FieldError, Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, HoverCard, HoverCardContent, HoverCardTrigger, InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot, Menubar, MenubarCheckboxItem, MenubarContent, MenubarGroup, MenubarItem, MenubarLabel, MenubarMenu, MenubarPortal, MenubarRadioGroup, MenubarRadioItem, MenubarSeparator, MenubarShortcut, MenubarSub, MenubarSubContent, MenubarSubTrigger, MenubarTrigger, NavigationMenu, NavigationMenuContent, NavigationMenuIndicator, NavigationMenuItem, NavigationMenuLink, NavigationMenuList, NavigationMenuTrigger, NavigationMenuViewport, Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious, PlaceholderPattern, Progress, RadioGroup, RadioGroupItem, ResizableHandle, ResizablePanel, ResizablePanelGroup, RowActionsMenu, ScrollArea, ScrollBar, ServerFacetedFilter, Slider, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Toaster, Toggle, ToggleGroup, ToggleGroupItem, badgeVariants, cardVariants, navigationMenuTriggerStyle, toggleVariants, useConfirmDialog, useFormField };
3616
+ export { AUTOSAVE_DELAY, Accordion, AccordionContent, AccordionItem, AccordionTrigger, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogMedia, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AppearanceToggle, AspectRatio, Badge, Carousel, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious, ChartContainer, ChartLegend, ChartLegendContent, ChartStyle, ChartTooltip, ChartTooltipContent, Checkbox, Combobox, ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuGroup, ContextMenuItem, ContextMenuLabel, ContextMenuPortal, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSeparator, ContextMenuShortcut, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger, DataTable, DatePicker, DateRangeFilter, Drawer, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerPortal, DrawerTitle, DrawerTrigger, EmptyState, FacetedFilter, Field, FieldControl, FieldDescription, FieldGroup, FieldLabel, Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, HoverCard, HoverCardContent, HoverCardTrigger, Menubar, MenubarCheckboxItem, MenubarContent, MenubarGroup, MenubarItem, MenubarLabel, MenubarMenu, MenubarPortal, MenubarRadioGroup, MenubarRadioItem, MenubarSeparator, MenubarShortcut, MenubarSub, MenubarSubContent, MenubarSubTrigger, MenubarTrigger, NavigationMenu, NavigationMenuContent, NavigationMenuIndicator, NavigationMenuItem, NavigationMenuLink, NavigationMenuList, NavigationMenuTrigger, NavigationMenuViewport, Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious, PasswordInput, PlaceholderPattern, Progress, RadioGroup, RadioGroupItem, ResizableHandle, ResizablePanel, ResizablePanelGroup, RowActionsMenu, SAVED_DURATION, SaveStatus, ScrollArea, ScrollBar, ServerFacetedFilter, Slider, StatusBadge, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, TextLink, Toaster, ToggleGroup, ToggleGroupItem, appearanceToggleDefaultLabels, badgeVariants, comboboxDefaultLabels, dataTableDefaultLabels, dataTableFacetedFilterDefaultLabels, datePickerDefaultLabels, dateRangeFilterDefaultLabels, emptyStateLabels, navigationMenuTriggerStyle, saveStatusLabels, statusBadgeVariants, textLinkVariants, useAutosave, useConfirmDialog, useFormField };
3093
3617
  //# sourceMappingURL=index.js.map
3094
3618
  //# sourceMappingURL=index.js.map