@optilogic/core 1.0.0-beta.1 → 1.0.0-beta.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -7
- package/dist/index.cjs +1244 -284
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +412 -6
- package/dist/index.d.ts +412 -6
- package/dist/index.js +1179 -234
- package/dist/index.js.map +1 -1
- package/dist/styles.css +61 -0
- package/package.json +20 -56
- package/src/components/board.tsx +251 -0
- package/src/components/card.tsx +656 -12
- package/src/components/context-menu.tsx +1 -1
- package/src/components/data-grid/hooks/useKeyboardNavigation.ts +1 -1
- package/src/components/data-table.tsx +735 -0
- package/src/index.ts +40 -0
- package/src/styles.css +61 -0
package/dist/index.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { clsx } from 'clsx';
|
|
2
2
|
import { twMerge } from 'tailwind-merge';
|
|
3
|
-
import * as
|
|
3
|
+
import * as React20 from 'react';
|
|
4
4
|
import { useMemo, useState, useRef, useEffect, useCallback } from 'react';
|
|
5
5
|
import { Slot } from '@radix-ui/react-slot';
|
|
6
6
|
import { cva } from 'class-variance-authority';
|
|
7
7
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
8
8
|
import * as LabelPrimitive from '@radix-ui/react-label';
|
|
9
9
|
import * as CheckboxPrimitive from '@radix-ui/react-checkbox';
|
|
10
|
-
import { Check, ChevronDown, ChevronUp, ChevronRight, Circle,
|
|
10
|
+
import { Check, ChevronDown, ChevronUp, ChevronRight, Circle, Search, ArrowUp, ArrowDown, ArrowUpDown, ChevronsLeft, ChevronLeft, ChevronsRight, X, Calendar as Calendar$1, Filter, GripVertical, Copy, Palette } from 'lucide-react';
|
|
11
11
|
import * as SwitchPrimitive from '@radix-ui/react-switch';
|
|
12
12
|
import * as ProgressPrimitive from '@radix-ui/react-progress';
|
|
13
13
|
import * as SeparatorPrimitive from '@radix-ui/react-separator';
|
|
@@ -53,7 +53,7 @@ var buttonVariants = cva(
|
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
55
|
);
|
|
56
|
-
var Button =
|
|
56
|
+
var Button = React20.forwardRef(
|
|
57
57
|
({ className, variant, size, asChild = false, ...props }, ref) => {
|
|
58
58
|
const Comp = asChild ? Slot : "button";
|
|
59
59
|
return /* @__PURE__ */ jsx(
|
|
@@ -67,7 +67,7 @@ var Button = React33.forwardRef(
|
|
|
67
67
|
}
|
|
68
68
|
);
|
|
69
69
|
Button.displayName = "Button";
|
|
70
|
-
var Input =
|
|
70
|
+
var Input = React20.forwardRef(
|
|
71
71
|
({ className, type, ...props }, ref) => {
|
|
72
72
|
return /* @__PURE__ */ jsx(
|
|
73
73
|
"input",
|
|
@@ -87,7 +87,7 @@ Input.displayName = "Input";
|
|
|
87
87
|
var labelVariants = cva(
|
|
88
88
|
"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
|
|
89
89
|
);
|
|
90
|
-
var Label =
|
|
90
|
+
var Label = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
91
91
|
LabelPrimitive.Root,
|
|
92
92
|
{
|
|
93
93
|
ref,
|
|
@@ -96,7 +96,7 @@ var Label = React33.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */
|
|
|
96
96
|
}
|
|
97
97
|
));
|
|
98
98
|
Label.displayName = LabelPrimitive.Root.displayName;
|
|
99
|
-
var Textarea =
|
|
99
|
+
var Textarea = React20.forwardRef(
|
|
100
100
|
({ className, ...props }, ref) => {
|
|
101
101
|
return /* @__PURE__ */ jsx(
|
|
102
102
|
"textarea",
|
|
@@ -135,7 +135,7 @@ var badgeVariants = cva(
|
|
|
135
135
|
function Badge({ className, variant, ...props }) {
|
|
136
136
|
return /* @__PURE__ */ jsx("div", { className: cn(badgeVariants({ variant }), className), ...props });
|
|
137
137
|
}
|
|
138
|
-
var Checkbox =
|
|
138
|
+
var Checkbox = React20.forwardRef(({ className, showBorder = true, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
139
139
|
CheckboxPrimitive.Root,
|
|
140
140
|
{
|
|
141
141
|
ref,
|
|
@@ -179,7 +179,7 @@ var Checkbox = React33.forwardRef(({ className, showBorder = true, ...props }, r
|
|
|
179
179
|
}
|
|
180
180
|
));
|
|
181
181
|
Checkbox.displayName = CheckboxPrimitive.Root.displayName;
|
|
182
|
-
var Switch =
|
|
182
|
+
var Switch = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
183
183
|
SwitchPrimitive.Root,
|
|
184
184
|
{
|
|
185
185
|
className: cn(
|
|
@@ -215,7 +215,7 @@ var Switch = React33.forwardRef(({ className, ...props }, ref) => /* @__PURE__ *
|
|
|
215
215
|
}
|
|
216
216
|
));
|
|
217
217
|
Switch.displayName = SwitchPrimitive.Root.displayName;
|
|
218
|
-
var Progress =
|
|
218
|
+
var Progress = React20.forwardRef(({ className, value, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
219
219
|
ProgressPrimitive.Root,
|
|
220
220
|
{
|
|
221
221
|
ref,
|
|
@@ -234,7 +234,7 @@ var Progress = React33.forwardRef(({ className, value, ...props }, ref) => /* @_
|
|
|
234
234
|
}
|
|
235
235
|
));
|
|
236
236
|
Progress.displayName = ProgressPrimitive.Root.displayName;
|
|
237
|
-
var Separator =
|
|
237
|
+
var Separator = React20.forwardRef(
|
|
238
238
|
({ className, orientation = "horizontal", decorative = true, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
239
239
|
SeparatorPrimitive.Root,
|
|
240
240
|
{
|
|
@@ -263,7 +263,7 @@ function Skeleton({ className, ...props }) {
|
|
|
263
263
|
var Select = SelectPrimitive.Root;
|
|
264
264
|
var SelectGroup = SelectPrimitive.Group;
|
|
265
265
|
var SelectValue = SelectPrimitive.Value;
|
|
266
|
-
var SelectTrigger =
|
|
266
|
+
var SelectTrigger = React20.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
|
|
267
267
|
SelectPrimitive.Trigger,
|
|
268
268
|
{
|
|
269
269
|
ref,
|
|
@@ -279,7 +279,7 @@ var SelectTrigger = React33.forwardRef(({ className, children, ...props }, ref)
|
|
|
279
279
|
}
|
|
280
280
|
));
|
|
281
281
|
SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
|
|
282
|
-
var SelectScrollUpButton =
|
|
282
|
+
var SelectScrollUpButton = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
283
283
|
SelectPrimitive.ScrollUpButton,
|
|
284
284
|
{
|
|
285
285
|
ref,
|
|
@@ -292,7 +292,7 @@ var SelectScrollUpButton = React33.forwardRef(({ className, ...props }, ref) =>
|
|
|
292
292
|
}
|
|
293
293
|
));
|
|
294
294
|
SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;
|
|
295
|
-
var SelectScrollDownButton =
|
|
295
|
+
var SelectScrollDownButton = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
296
296
|
SelectPrimitive.ScrollDownButton,
|
|
297
297
|
{
|
|
298
298
|
ref,
|
|
@@ -305,7 +305,7 @@ var SelectScrollDownButton = React33.forwardRef(({ className, ...props }, ref) =
|
|
|
305
305
|
}
|
|
306
306
|
));
|
|
307
307
|
SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName;
|
|
308
|
-
var SelectContent =
|
|
308
|
+
var SelectContent = React20.forwardRef(({ className, children, position = "popper", ...props }, ref) => /* @__PURE__ */ jsx(SelectPrimitive.Portal, { children: /* @__PURE__ */ jsxs(
|
|
309
309
|
SelectPrimitive.Content,
|
|
310
310
|
{
|
|
311
311
|
ref,
|
|
@@ -333,7 +333,7 @@ var SelectContent = React33.forwardRef(({ className, children, position = "poppe
|
|
|
333
333
|
}
|
|
334
334
|
) }));
|
|
335
335
|
SelectContent.displayName = SelectPrimitive.Content.displayName;
|
|
336
|
-
var SelectLabel =
|
|
336
|
+
var SelectLabel = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
337
337
|
SelectPrimitive.Label,
|
|
338
338
|
{
|
|
339
339
|
ref,
|
|
@@ -342,7 +342,7 @@ var SelectLabel = React33.forwardRef(({ className, ...props }, ref) => /* @__PUR
|
|
|
342
342
|
}
|
|
343
343
|
));
|
|
344
344
|
SelectLabel.displayName = SelectPrimitive.Label.displayName;
|
|
345
|
-
var SelectItem =
|
|
345
|
+
var SelectItem = React20.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
|
|
346
346
|
SelectPrimitive.Item,
|
|
347
347
|
{
|
|
348
348
|
ref,
|
|
@@ -358,7 +358,7 @@ var SelectItem = React33.forwardRef(({ className, children, ...props }, ref) =>
|
|
|
358
358
|
}
|
|
359
359
|
));
|
|
360
360
|
SelectItem.displayName = SelectPrimitive.Item.displayName;
|
|
361
|
-
var SelectSeparator =
|
|
361
|
+
var SelectSeparator = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
362
362
|
SelectPrimitive.Separator,
|
|
363
363
|
{
|
|
364
364
|
ref,
|
|
@@ -368,7 +368,7 @@ var SelectSeparator = React33.forwardRef(({ className, ...props }, ref) => /* @_
|
|
|
368
368
|
));
|
|
369
369
|
SelectSeparator.displayName = SelectPrimitive.Separator.displayName;
|
|
370
370
|
var Tabs = TabsPrimitive.Root;
|
|
371
|
-
var TabsList =
|
|
371
|
+
var TabsList = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
372
372
|
TabsPrimitive.List,
|
|
373
373
|
{
|
|
374
374
|
ref,
|
|
@@ -382,7 +382,7 @@ var TabsList = React33.forwardRef(({ className, ...props }, ref) => /* @__PURE__
|
|
|
382
382
|
}
|
|
383
383
|
));
|
|
384
384
|
TabsList.displayName = TabsPrimitive.List.displayName;
|
|
385
|
-
var TabsTrigger =
|
|
385
|
+
var TabsTrigger = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
386
386
|
TabsPrimitive.Trigger,
|
|
387
387
|
{
|
|
388
388
|
ref,
|
|
@@ -409,7 +409,7 @@ var TabsTrigger = React33.forwardRef(({ className, ...props }, ref) => /* @__PUR
|
|
|
409
409
|
}
|
|
410
410
|
));
|
|
411
411
|
TabsTrigger.displayName = TabsPrimitive.Trigger.displayName;
|
|
412
|
-
var TabsContent =
|
|
412
|
+
var TabsContent = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
413
413
|
TabsPrimitive.Content,
|
|
414
414
|
{
|
|
415
415
|
ref,
|
|
@@ -492,7 +492,7 @@ var accordionContentInnerVariants = cva("pb-4 pt-0", {
|
|
|
492
492
|
}
|
|
493
493
|
});
|
|
494
494
|
var Accordion = AccordionPrimitive.Root;
|
|
495
|
-
var AccordionItem =
|
|
495
|
+
var AccordionItem = React20.forwardRef(({ className, variant, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
496
496
|
AccordionPrimitive.Item,
|
|
497
497
|
{
|
|
498
498
|
ref,
|
|
@@ -502,7 +502,7 @@ var AccordionItem = React33.forwardRef(({ className, variant, ...props }, ref) =
|
|
|
502
502
|
}
|
|
503
503
|
));
|
|
504
504
|
AccordionItem.displayName = "AccordionItem";
|
|
505
|
-
var AccordionTrigger =
|
|
505
|
+
var AccordionTrigger = React20.forwardRef(({ className, children, variant, ...props }, ref) => /* @__PURE__ */ jsx(AccordionPrimitive.Header, { className: "flex", children: /* @__PURE__ */ jsxs(
|
|
506
506
|
AccordionPrimitive.Trigger,
|
|
507
507
|
{
|
|
508
508
|
ref,
|
|
@@ -515,7 +515,7 @@ var AccordionTrigger = React33.forwardRef(({ className, children, variant, ...pr
|
|
|
515
515
|
}
|
|
516
516
|
) }));
|
|
517
517
|
AccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName;
|
|
518
|
-
var AccordionContent =
|
|
518
|
+
var AccordionContent = React20.forwardRef(({ className, children, variant, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
519
519
|
AccordionPrimitive.Content,
|
|
520
520
|
{
|
|
521
521
|
ref,
|
|
@@ -529,7 +529,7 @@ var TooltipProvider = TooltipPrimitive.Provider;
|
|
|
529
529
|
var TooltipRoot = TooltipPrimitive.Root;
|
|
530
530
|
var TooltipTrigger = TooltipPrimitive.Trigger;
|
|
531
531
|
var TooltipPortal = TooltipPrimitive.Portal;
|
|
532
|
-
var TooltipContent =
|
|
532
|
+
var TooltipContent = React20.forwardRef(({ className, sideOffset = 6, ...props }, ref) => /* @__PURE__ */ jsx(TooltipPrimitive.Portal, { children: /* @__PURE__ */ jsx(
|
|
533
533
|
TooltipPrimitive.Content,
|
|
534
534
|
{
|
|
535
535
|
ref,
|
|
@@ -558,7 +558,7 @@ var TooltipContent = React33.forwardRef(({ className, sideOffset = 6, ...props }
|
|
|
558
558
|
}
|
|
559
559
|
) }));
|
|
560
560
|
TooltipContent.displayName = TooltipPrimitive.Content.displayName;
|
|
561
|
-
var TooltipArrow =
|
|
561
|
+
var TooltipArrow = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
562
562
|
TooltipPrimitive.Arrow,
|
|
563
563
|
{
|
|
564
564
|
ref,
|
|
@@ -597,7 +597,7 @@ function Tooltip({
|
|
|
597
597
|
var Popover = PopoverPrimitive.Root;
|
|
598
598
|
var PopoverTrigger = PopoverPrimitive.Trigger;
|
|
599
599
|
var PopoverAnchor = PopoverPrimitive.Anchor;
|
|
600
|
-
var PopoverContent =
|
|
600
|
+
var PopoverContent = React20.forwardRef(({ className, align = "center", sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx(PopoverPrimitive.Portal, { children: /* @__PURE__ */ jsx(
|
|
601
601
|
PopoverPrimitive.Content,
|
|
602
602
|
{
|
|
603
603
|
ref,
|
|
@@ -623,7 +623,7 @@ var DropdownMenuGroup = DropdownMenuPrimitive.Group;
|
|
|
623
623
|
var DropdownMenuPortal = DropdownMenuPrimitive.Portal;
|
|
624
624
|
var DropdownMenuSub = DropdownMenuPrimitive.Sub;
|
|
625
625
|
var DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup;
|
|
626
|
-
var DropdownMenuSubTrigger =
|
|
626
|
+
var DropdownMenuSubTrigger = React20.forwardRef(({ className, inset, children, ...props }, ref) => /* @__PURE__ */ jsxs(
|
|
627
627
|
DropdownMenuPrimitive.SubTrigger,
|
|
628
628
|
{
|
|
629
629
|
ref,
|
|
@@ -642,7 +642,7 @@ var DropdownMenuSubTrigger = React33.forwardRef(({ className, inset, children, .
|
|
|
642
642
|
}
|
|
643
643
|
));
|
|
644
644
|
DropdownMenuSubTrigger.displayName = DropdownMenuPrimitive.SubTrigger.displayName;
|
|
645
|
-
var DropdownMenuSubContent =
|
|
645
|
+
var DropdownMenuSubContent = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
646
646
|
DropdownMenuPrimitive.SubContent,
|
|
647
647
|
{
|
|
648
648
|
ref,
|
|
@@ -659,7 +659,7 @@ var DropdownMenuSubContent = React33.forwardRef(({ className, ...props }, ref) =
|
|
|
659
659
|
}
|
|
660
660
|
));
|
|
661
661
|
DropdownMenuSubContent.displayName = DropdownMenuPrimitive.SubContent.displayName;
|
|
662
|
-
var DropdownMenuContent =
|
|
662
|
+
var DropdownMenuContent = React20.forwardRef(({ className, sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx(DropdownMenuPrimitive.Portal, { children: /* @__PURE__ */ jsx(
|
|
663
663
|
DropdownMenuPrimitive.Content,
|
|
664
664
|
{
|
|
665
665
|
ref,
|
|
@@ -677,7 +677,7 @@ var DropdownMenuContent = React33.forwardRef(({ className, sideOffset = 4, ...pr
|
|
|
677
677
|
}
|
|
678
678
|
) }));
|
|
679
679
|
DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName;
|
|
680
|
-
var DropdownMenuItem =
|
|
680
|
+
var DropdownMenuItem = React20.forwardRef(({ className, inset, destructive, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
681
681
|
DropdownMenuPrimitive.Item,
|
|
682
682
|
{
|
|
683
683
|
ref,
|
|
@@ -693,7 +693,7 @@ var DropdownMenuItem = React33.forwardRef(({ className, inset, destructive, ...p
|
|
|
693
693
|
}
|
|
694
694
|
));
|
|
695
695
|
DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName;
|
|
696
|
-
var DropdownMenuCheckboxItem =
|
|
696
|
+
var DropdownMenuCheckboxItem = React20.forwardRef(({ className, children, checked, ...props }, ref) => /* @__PURE__ */ jsxs(
|
|
697
697
|
DropdownMenuPrimitive.CheckboxItem,
|
|
698
698
|
{
|
|
699
699
|
ref,
|
|
@@ -712,7 +712,7 @@ var DropdownMenuCheckboxItem = React33.forwardRef(({ className, children, checke
|
|
|
712
712
|
}
|
|
713
713
|
));
|
|
714
714
|
DropdownMenuCheckboxItem.displayName = DropdownMenuPrimitive.CheckboxItem.displayName;
|
|
715
|
-
var DropdownMenuRadioItem =
|
|
715
|
+
var DropdownMenuRadioItem = React20.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
|
|
716
716
|
DropdownMenuPrimitive.RadioItem,
|
|
717
717
|
{
|
|
718
718
|
ref,
|
|
@@ -730,7 +730,7 @@ var DropdownMenuRadioItem = React33.forwardRef(({ className, children, ...props
|
|
|
730
730
|
}
|
|
731
731
|
));
|
|
732
732
|
DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName;
|
|
733
|
-
var DropdownMenuLabel =
|
|
733
|
+
var DropdownMenuLabel = React20.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
734
734
|
DropdownMenuPrimitive.Label,
|
|
735
735
|
{
|
|
736
736
|
ref,
|
|
@@ -743,7 +743,7 @@ var DropdownMenuLabel = React33.forwardRef(({ className, inset, ...props }, ref)
|
|
|
743
743
|
}
|
|
744
744
|
));
|
|
745
745
|
DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName;
|
|
746
|
-
var DropdownMenuSeparator =
|
|
746
|
+
var DropdownMenuSeparator = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
747
747
|
DropdownMenuPrimitive.Separator,
|
|
748
748
|
{
|
|
749
749
|
ref,
|
|
@@ -768,7 +768,7 @@ DropdownMenuShortcut.displayName = "DropdownMenuShortcut";
|
|
|
768
768
|
var AlertDialog = AlertDialogPrimitive.Root;
|
|
769
769
|
var AlertDialogTrigger = AlertDialogPrimitive.Trigger;
|
|
770
770
|
var AlertDialogPortal = AlertDialogPrimitive.Portal;
|
|
771
|
-
var AlertDialogOverlay =
|
|
771
|
+
var AlertDialogOverlay = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
772
772
|
AlertDialogPrimitive.Overlay,
|
|
773
773
|
{
|
|
774
774
|
className: cn(
|
|
@@ -782,7 +782,7 @@ var AlertDialogOverlay = React33.forwardRef(({ className, ...props }, ref) => /*
|
|
|
782
782
|
}
|
|
783
783
|
));
|
|
784
784
|
AlertDialogOverlay.displayName = AlertDialogPrimitive.Overlay.displayName;
|
|
785
|
-
var AlertDialogContent =
|
|
785
|
+
var AlertDialogContent = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxs(AlertDialogPortal, { children: [
|
|
786
786
|
/* @__PURE__ */ jsx(AlertDialogOverlay, {}),
|
|
787
787
|
/* @__PURE__ */ jsx(
|
|
788
788
|
AlertDialogPrimitive.Content,
|
|
@@ -825,7 +825,7 @@ var AlertDialogFooter = ({ className, ...props }) => /* @__PURE__ */ jsx(
|
|
|
825
825
|
}
|
|
826
826
|
);
|
|
827
827
|
AlertDialogFooter.displayName = "AlertDialogFooter";
|
|
828
|
-
var AlertDialogTitle =
|
|
828
|
+
var AlertDialogTitle = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
829
829
|
AlertDialogPrimitive.Title,
|
|
830
830
|
{
|
|
831
831
|
ref,
|
|
@@ -834,7 +834,7 @@ var AlertDialogTitle = React33.forwardRef(({ className, ...props }, ref) => /* @
|
|
|
834
834
|
}
|
|
835
835
|
));
|
|
836
836
|
AlertDialogTitle.displayName = AlertDialogPrimitive.Title.displayName;
|
|
837
|
-
var AlertDialogDescription =
|
|
837
|
+
var AlertDialogDescription = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
838
838
|
AlertDialogPrimitive.Description,
|
|
839
839
|
{
|
|
840
840
|
ref,
|
|
@@ -843,7 +843,7 @@ var AlertDialogDescription = React33.forwardRef(({ className, ...props }, ref) =
|
|
|
843
843
|
}
|
|
844
844
|
));
|
|
845
845
|
AlertDialogDescription.displayName = AlertDialogPrimitive.Description.displayName;
|
|
846
|
-
var AlertDialogAction =
|
|
846
|
+
var AlertDialogAction = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
847
847
|
AlertDialogPrimitive.Action,
|
|
848
848
|
{
|
|
849
849
|
ref,
|
|
@@ -852,7 +852,7 @@ var AlertDialogAction = React33.forwardRef(({ className, ...props }, ref) => /*
|
|
|
852
852
|
}
|
|
853
853
|
));
|
|
854
854
|
AlertDialogAction.displayName = AlertDialogPrimitive.Action.displayName;
|
|
855
|
-
var AlertDialogCancel =
|
|
855
|
+
var AlertDialogCancel = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
856
856
|
AlertDialogPrimitive.Cancel,
|
|
857
857
|
{
|
|
858
858
|
ref,
|
|
@@ -861,21 +861,107 @@ var AlertDialogCancel = React33.forwardRef(({ className, ...props }, ref) => /*
|
|
|
861
861
|
}
|
|
862
862
|
));
|
|
863
863
|
AlertDialogCancel.displayName = AlertDialogPrimitive.Cancel.displayName;
|
|
864
|
-
var
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
{
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
864
|
+
var cardVariants = cva(
|
|
865
|
+
"rounded-xl border bg-card text-card-foreground shadow",
|
|
866
|
+
{
|
|
867
|
+
variants: {
|
|
868
|
+
/**
|
|
869
|
+
* Card width size presets
|
|
870
|
+
*/
|
|
871
|
+
size: {
|
|
872
|
+
auto: "",
|
|
873
|
+
sm: "w-64",
|
|
874
|
+
md: "w-80",
|
|
875
|
+
lg: "w-96",
|
|
876
|
+
xl: "w-[28rem]",
|
|
877
|
+
full: "w-full"
|
|
878
|
+
},
|
|
879
|
+
/**
|
|
880
|
+
* Hover effect styles
|
|
881
|
+
*/
|
|
882
|
+
hover: {
|
|
883
|
+
none: "",
|
|
884
|
+
lift: "transition-all duration-200 hover:-translate-y-1 hover:shadow-lg",
|
|
885
|
+
glow: "transition-shadow duration-200 hover:shadow-lg hover:shadow-accent/20",
|
|
886
|
+
border: "transition-colors duration-200 hover:border-accent",
|
|
887
|
+
"border-success": "transition-colors duration-200 hover:border-success",
|
|
888
|
+
"border-warning": "transition-colors duration-200 hover:border-warning",
|
|
889
|
+
"border-destructive": "transition-colors duration-200 hover:border-destructive",
|
|
890
|
+
"border-muted": "transition-colors duration-200 hover:border-muted-foreground",
|
|
891
|
+
scale: "transition-transform duration-200 hover:scale-[1.02]"
|
|
892
|
+
},
|
|
893
|
+
/**
|
|
894
|
+
* Whether the card is interactive (clickable)
|
|
895
|
+
*/
|
|
896
|
+
interactive: {
|
|
897
|
+
true: "cursor-pointer focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
|
898
|
+
false: ""
|
|
899
|
+
},
|
|
900
|
+
/**
|
|
901
|
+
* Card padding density
|
|
902
|
+
*/
|
|
903
|
+
padding: {
|
|
904
|
+
none: "",
|
|
905
|
+
sm: "[&>*:not(img)]:p-3 [&>*:not(img)]:pt-3",
|
|
906
|
+
md: "",
|
|
907
|
+
lg: "[&>*:not(img)]:p-8 [&>*:not(img)]:pt-8"
|
|
908
|
+
}
|
|
909
|
+
},
|
|
910
|
+
defaultVariants: {
|
|
911
|
+
size: "auto",
|
|
912
|
+
hover: "none",
|
|
913
|
+
interactive: false,
|
|
914
|
+
padding: "md"
|
|
874
915
|
}
|
|
875
|
-
|
|
916
|
+
}
|
|
917
|
+
);
|
|
918
|
+
var Card = React20.forwardRef(
|
|
919
|
+
({
|
|
920
|
+
className,
|
|
921
|
+
size,
|
|
922
|
+
hover,
|
|
923
|
+
interactive,
|
|
924
|
+
padding,
|
|
925
|
+
asButton,
|
|
926
|
+
hoverBorderClass,
|
|
927
|
+
onClick,
|
|
928
|
+
onKeyDown,
|
|
929
|
+
...props
|
|
930
|
+
}, ref) => {
|
|
931
|
+
const isInteractive = interactive || asButton || !!onClick;
|
|
932
|
+
const handleKeyDown = React20.useCallback(
|
|
933
|
+
(e) => {
|
|
934
|
+
if (isInteractive && (e.key === "Enter" || e.key === " ")) {
|
|
935
|
+
e.preventDefault();
|
|
936
|
+
onClick?.(e);
|
|
937
|
+
}
|
|
938
|
+
onKeyDown?.(e);
|
|
939
|
+
},
|
|
940
|
+
[isInteractive, onClick, onKeyDown]
|
|
941
|
+
);
|
|
942
|
+
return /* @__PURE__ */ jsx(
|
|
943
|
+
"div",
|
|
944
|
+
{
|
|
945
|
+
ref,
|
|
946
|
+
role: isInteractive ? "button" : void 0,
|
|
947
|
+
tabIndex: isInteractive ? 0 : void 0,
|
|
948
|
+
className: cn(
|
|
949
|
+
cardVariants({ size, hover, interactive: isInteractive, padding }),
|
|
950
|
+
"group relative",
|
|
951
|
+
// Custom hover border color overrides variant if provided
|
|
952
|
+
hoverBorderClass && "transition-colors duration-200",
|
|
953
|
+
hoverBorderClass,
|
|
954
|
+
className
|
|
955
|
+
),
|
|
956
|
+
onClick,
|
|
957
|
+
onKeyDown: handleKeyDown,
|
|
958
|
+
...props
|
|
959
|
+
}
|
|
960
|
+
);
|
|
961
|
+
}
|
|
876
962
|
);
|
|
877
963
|
Card.displayName = "Card";
|
|
878
|
-
var CardHeader =
|
|
964
|
+
var CardHeader = React20.forwardRef(
|
|
879
965
|
({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
880
966
|
"div",
|
|
881
967
|
{
|
|
@@ -886,7 +972,7 @@ var CardHeader = React33.forwardRef(
|
|
|
886
972
|
)
|
|
887
973
|
);
|
|
888
974
|
CardHeader.displayName = "CardHeader";
|
|
889
|
-
var CardTitle =
|
|
975
|
+
var CardTitle = React20.forwardRef(
|
|
890
976
|
({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
891
977
|
"div",
|
|
892
978
|
{
|
|
@@ -897,7 +983,7 @@ var CardTitle = React33.forwardRef(
|
|
|
897
983
|
)
|
|
898
984
|
);
|
|
899
985
|
CardTitle.displayName = "CardTitle";
|
|
900
|
-
var CardDescription =
|
|
986
|
+
var CardDescription = React20.forwardRef(
|
|
901
987
|
({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
902
988
|
"div",
|
|
903
989
|
{
|
|
@@ -908,11 +994,11 @@ var CardDescription = React33.forwardRef(
|
|
|
908
994
|
)
|
|
909
995
|
);
|
|
910
996
|
CardDescription.displayName = "CardDescription";
|
|
911
|
-
var CardContent =
|
|
997
|
+
var CardContent = React20.forwardRef(
|
|
912
998
|
({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("p-6 pt-0", className), ...props })
|
|
913
999
|
);
|
|
914
1000
|
CardContent.displayName = "CardContent";
|
|
915
|
-
var CardFooter =
|
|
1001
|
+
var CardFooter = React20.forwardRef(
|
|
916
1002
|
({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
917
1003
|
"div",
|
|
918
1004
|
{
|
|
@@ -923,7 +1009,422 @@ var CardFooter = React33.forwardRef(
|
|
|
923
1009
|
)
|
|
924
1010
|
);
|
|
925
1011
|
CardFooter.displayName = "CardFooter";
|
|
926
|
-
var
|
|
1012
|
+
var cardImageVariants = cva("w-full object-cover", {
|
|
1013
|
+
variants: {
|
|
1014
|
+
/**
|
|
1015
|
+
* Image aspect ratio
|
|
1016
|
+
*/
|
|
1017
|
+
aspectRatio: {
|
|
1018
|
+
auto: "",
|
|
1019
|
+
square: "aspect-square",
|
|
1020
|
+
video: "aspect-video",
|
|
1021
|
+
wide: "aspect-[2/1]",
|
|
1022
|
+
portrait: "aspect-[3/4]"
|
|
1023
|
+
},
|
|
1024
|
+
/**
|
|
1025
|
+
* Image position in the card
|
|
1026
|
+
*/
|
|
1027
|
+
position: {
|
|
1028
|
+
top: "rounded-t-xl",
|
|
1029
|
+
bottom: "rounded-b-xl",
|
|
1030
|
+
fill: "rounded-xl"
|
|
1031
|
+
}
|
|
1032
|
+
},
|
|
1033
|
+
defaultVariants: {
|
|
1034
|
+
aspectRatio: "video",
|
|
1035
|
+
position: "top"
|
|
1036
|
+
}
|
|
1037
|
+
});
|
|
1038
|
+
var CardImage = React20.forwardRef(
|
|
1039
|
+
({ className, aspectRatio, position, fallback, alt, src, onError, ...props }, ref) => {
|
|
1040
|
+
const [hasError, setHasError] = React20.useState(false);
|
|
1041
|
+
const handleError = React20.useCallback(
|
|
1042
|
+
(e) => {
|
|
1043
|
+
setHasError(true);
|
|
1044
|
+
onError?.(e);
|
|
1045
|
+
},
|
|
1046
|
+
[onError]
|
|
1047
|
+
);
|
|
1048
|
+
React20.useEffect(() => {
|
|
1049
|
+
setHasError(false);
|
|
1050
|
+
}, [src]);
|
|
1051
|
+
if (hasError && fallback) {
|
|
1052
|
+
return /* @__PURE__ */ jsx(
|
|
1053
|
+
"div",
|
|
1054
|
+
{
|
|
1055
|
+
className: cn(
|
|
1056
|
+
"flex items-center justify-center bg-muted",
|
|
1057
|
+
cardImageVariants({ aspectRatio, position }),
|
|
1058
|
+
className
|
|
1059
|
+
),
|
|
1060
|
+
children: fallback
|
|
1061
|
+
}
|
|
1062
|
+
);
|
|
1063
|
+
}
|
|
1064
|
+
return /* @__PURE__ */ jsx(
|
|
1065
|
+
"img",
|
|
1066
|
+
{
|
|
1067
|
+
ref,
|
|
1068
|
+
src,
|
|
1069
|
+
alt,
|
|
1070
|
+
className: cn(cardImageVariants({ aspectRatio, position }), className),
|
|
1071
|
+
onError: handleError,
|
|
1072
|
+
...props
|
|
1073
|
+
}
|
|
1074
|
+
);
|
|
1075
|
+
}
|
|
1076
|
+
);
|
|
1077
|
+
CardImage.displayName = "CardImage";
|
|
1078
|
+
var cardActionsVariants = cva(
|
|
1079
|
+
"absolute flex items-center gap-1 transition-opacity duration-200 z-10",
|
|
1080
|
+
{
|
|
1081
|
+
variants: {
|
|
1082
|
+
/**
|
|
1083
|
+
* When to show the actions
|
|
1084
|
+
*/
|
|
1085
|
+
showOn: {
|
|
1086
|
+
hover: "opacity-0 group-hover:opacity-100",
|
|
1087
|
+
always: "opacity-100"
|
|
1088
|
+
},
|
|
1089
|
+
/**
|
|
1090
|
+
* Position of the actions overlay
|
|
1091
|
+
*/
|
|
1092
|
+
position: {
|
|
1093
|
+
"top-right": "top-2 right-2",
|
|
1094
|
+
"top-left": "top-2 left-2",
|
|
1095
|
+
"bottom-right": "bottom-2 right-2",
|
|
1096
|
+
"bottom-left": "bottom-2 left-2"
|
|
1097
|
+
},
|
|
1098
|
+
/**
|
|
1099
|
+
* Visual style of the actions container
|
|
1100
|
+
*/
|
|
1101
|
+
variant: {
|
|
1102
|
+
/** Solid background with backdrop blur */
|
|
1103
|
+
floating: "bg-background/90 backdrop-blur-sm rounded-md shadow-sm p-1",
|
|
1104
|
+
/** No background, just spacing */
|
|
1105
|
+
ghost: "p-1",
|
|
1106
|
+
/** Muted bar background */
|
|
1107
|
+
bar: "bg-muted/80 backdrop-blur-sm rounded-md p-1.5",
|
|
1108
|
+
/** No background on container, icons get background on hover */
|
|
1109
|
+
"icon-hover": "p-0 [&>button]:bg-transparent [&>button]:hover:bg-background/90 [&>button]:hover:shadow-sm [&>button]:transition-all"
|
|
1110
|
+
}
|
|
1111
|
+
},
|
|
1112
|
+
defaultVariants: {
|
|
1113
|
+
showOn: "hover",
|
|
1114
|
+
position: "top-right",
|
|
1115
|
+
variant: "floating"
|
|
1116
|
+
}
|
|
1117
|
+
}
|
|
1118
|
+
);
|
|
1119
|
+
var CardActions = React20.forwardRef(
|
|
1120
|
+
({ className, showOn, position, variant, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
1121
|
+
"div",
|
|
1122
|
+
{
|
|
1123
|
+
ref,
|
|
1124
|
+
className: cn(cardActionsVariants({ showOn, position, variant }), className),
|
|
1125
|
+
onClick: (e) => e.stopPropagation(),
|
|
1126
|
+
...props
|
|
1127
|
+
}
|
|
1128
|
+
)
|
|
1129
|
+
);
|
|
1130
|
+
CardActions.displayName = "CardActions";
|
|
1131
|
+
var SelectableCard = React20.forwardRef(
|
|
1132
|
+
({
|
|
1133
|
+
className,
|
|
1134
|
+
selected: controlledSelected,
|
|
1135
|
+
defaultSelected = false,
|
|
1136
|
+
onSelectedChange,
|
|
1137
|
+
showCheckbox = false,
|
|
1138
|
+
checkboxPosition = "top-right",
|
|
1139
|
+
disabled = false,
|
|
1140
|
+
children,
|
|
1141
|
+
onClick,
|
|
1142
|
+
hover = "border",
|
|
1143
|
+
...props
|
|
1144
|
+
}, ref) => {
|
|
1145
|
+
const [uncontrolledSelected, setUncontrolledSelected] = React20.useState(defaultSelected);
|
|
1146
|
+
const isControlled = controlledSelected !== void 0;
|
|
1147
|
+
const isSelected = isControlled ? controlledSelected : uncontrolledSelected;
|
|
1148
|
+
const handleClick = React20.useCallback(
|
|
1149
|
+
(e) => {
|
|
1150
|
+
if (disabled) return;
|
|
1151
|
+
const newSelected = !isSelected;
|
|
1152
|
+
if (!isControlled) {
|
|
1153
|
+
setUncontrolledSelected(newSelected);
|
|
1154
|
+
}
|
|
1155
|
+
onSelectedChange?.(newSelected);
|
|
1156
|
+
onClick?.(e);
|
|
1157
|
+
},
|
|
1158
|
+
[disabled, isSelected, isControlled, onSelectedChange, onClick]
|
|
1159
|
+
);
|
|
1160
|
+
const handleCheckboxChange = React20.useCallback(
|
|
1161
|
+
(checked) => {
|
|
1162
|
+
if (disabled) return;
|
|
1163
|
+
const newSelected = checked === true;
|
|
1164
|
+
if (!isControlled) {
|
|
1165
|
+
setUncontrolledSelected(newSelected);
|
|
1166
|
+
}
|
|
1167
|
+
onSelectedChange?.(newSelected);
|
|
1168
|
+
},
|
|
1169
|
+
[disabled, isControlled, onSelectedChange]
|
|
1170
|
+
);
|
|
1171
|
+
const isInline = checkboxPosition === "inline-left";
|
|
1172
|
+
return /* @__PURE__ */ jsxs(
|
|
1173
|
+
Card,
|
|
1174
|
+
{
|
|
1175
|
+
ref,
|
|
1176
|
+
className: cn(
|
|
1177
|
+
// Selection styling
|
|
1178
|
+
isSelected && "ring-2 ring-accent border-accent",
|
|
1179
|
+
disabled && "opacity-50 cursor-not-allowed",
|
|
1180
|
+
className
|
|
1181
|
+
),
|
|
1182
|
+
interactive: !disabled,
|
|
1183
|
+
hover: disabled ? "none" : hover,
|
|
1184
|
+
onClick: handleClick,
|
|
1185
|
+
"aria-selected": isSelected,
|
|
1186
|
+
"aria-disabled": disabled,
|
|
1187
|
+
...props,
|
|
1188
|
+
children: [
|
|
1189
|
+
showCheckbox && isInline && /* @__PURE__ */ jsxs(
|
|
1190
|
+
"div",
|
|
1191
|
+
{
|
|
1192
|
+
className: "flex items-center gap-3 px-4 py-3 border-b border-border/50",
|
|
1193
|
+
onClick: (e) => e.stopPropagation(),
|
|
1194
|
+
children: [
|
|
1195
|
+
/* @__PURE__ */ jsx(
|
|
1196
|
+
Checkbox,
|
|
1197
|
+
{
|
|
1198
|
+
checked: isSelected,
|
|
1199
|
+
onCheckedChange: handleCheckboxChange,
|
|
1200
|
+
disabled
|
|
1201
|
+
}
|
|
1202
|
+
),
|
|
1203
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: isSelected ? "Selected" : "Click to select" })
|
|
1204
|
+
]
|
|
1205
|
+
}
|
|
1206
|
+
),
|
|
1207
|
+
showCheckbox && !isInline && /* @__PURE__ */ jsx(
|
|
1208
|
+
"div",
|
|
1209
|
+
{
|
|
1210
|
+
className: cn(
|
|
1211
|
+
"absolute z-10 p-1 bg-background/90 backdrop-blur-sm rounded-md",
|
|
1212
|
+
checkboxPosition === "top-left" ? "top-2 left-2" : "top-2 right-2"
|
|
1213
|
+
),
|
|
1214
|
+
onClick: (e) => e.stopPropagation(),
|
|
1215
|
+
children: /* @__PURE__ */ jsx(
|
|
1216
|
+
Checkbox,
|
|
1217
|
+
{
|
|
1218
|
+
checked: isSelected,
|
|
1219
|
+
onCheckedChange: handleCheckboxChange,
|
|
1220
|
+
disabled
|
|
1221
|
+
}
|
|
1222
|
+
)
|
|
1223
|
+
}
|
|
1224
|
+
),
|
|
1225
|
+
children
|
|
1226
|
+
]
|
|
1227
|
+
}
|
|
1228
|
+
);
|
|
1229
|
+
}
|
|
1230
|
+
);
|
|
1231
|
+
SelectableCard.displayName = "SelectableCard";
|
|
1232
|
+
var cardGridVariants = cva("grid", {
|
|
1233
|
+
variants: {
|
|
1234
|
+
/**
|
|
1235
|
+
* Number of columns
|
|
1236
|
+
*/
|
|
1237
|
+
columns: {
|
|
1238
|
+
1: "grid-cols-1",
|
|
1239
|
+
2: "grid-cols-1 sm:grid-cols-2",
|
|
1240
|
+
3: "grid-cols-1 sm:grid-cols-2 lg:grid-cols-3",
|
|
1241
|
+
4: "grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4",
|
|
1242
|
+
auto: "grid-cols-[repeat(auto-fill,minmax(280px,1fr))]"
|
|
1243
|
+
},
|
|
1244
|
+
/**
|
|
1245
|
+
* Gap between cards
|
|
1246
|
+
*/
|
|
1247
|
+
gap: {
|
|
1248
|
+
none: "gap-0",
|
|
1249
|
+
sm: "gap-3",
|
|
1250
|
+
md: "gap-4",
|
|
1251
|
+
lg: "gap-6",
|
|
1252
|
+
xl: "gap-8"
|
|
1253
|
+
}
|
|
1254
|
+
},
|
|
1255
|
+
defaultVariants: {
|
|
1256
|
+
columns: "auto",
|
|
1257
|
+
gap: "md"
|
|
1258
|
+
}
|
|
1259
|
+
});
|
|
1260
|
+
var CardGrid = React20.forwardRef(
|
|
1261
|
+
({ className, columns, gap, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
1262
|
+
"div",
|
|
1263
|
+
{
|
|
1264
|
+
ref,
|
|
1265
|
+
className: cn(cardGridVariants({ columns, gap }), className),
|
|
1266
|
+
...props
|
|
1267
|
+
}
|
|
1268
|
+
)
|
|
1269
|
+
);
|
|
1270
|
+
CardGrid.displayName = "CardGrid";
|
|
1271
|
+
var cardListVariants = cva("flex flex-col", {
|
|
1272
|
+
variants: {
|
|
1273
|
+
/**
|
|
1274
|
+
* Gap between cards
|
|
1275
|
+
*/
|
|
1276
|
+
gap: {
|
|
1277
|
+
none: "gap-0",
|
|
1278
|
+
sm: "gap-2",
|
|
1279
|
+
md: "gap-4",
|
|
1280
|
+
lg: "gap-6"
|
|
1281
|
+
},
|
|
1282
|
+
/**
|
|
1283
|
+
* Whether to show dividers between cards
|
|
1284
|
+
*/
|
|
1285
|
+
divided: {
|
|
1286
|
+
true: "[&>*:not(:last-child)]:border-b [&>*:not(:last-child)]:pb-4 [&>*:not(:last-child)]:rounded-b-none",
|
|
1287
|
+
false: ""
|
|
1288
|
+
}
|
|
1289
|
+
},
|
|
1290
|
+
defaultVariants: {
|
|
1291
|
+
gap: "md",
|
|
1292
|
+
divided: false
|
|
1293
|
+
}
|
|
1294
|
+
});
|
|
1295
|
+
var CardList = React20.forwardRef(
|
|
1296
|
+
({ className, gap, divided, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
1297
|
+
"div",
|
|
1298
|
+
{
|
|
1299
|
+
ref,
|
|
1300
|
+
className: cn(cardListVariants({ gap, divided }), className),
|
|
1301
|
+
...props
|
|
1302
|
+
}
|
|
1303
|
+
)
|
|
1304
|
+
);
|
|
1305
|
+
CardList.displayName = "CardList";
|
|
1306
|
+
var boardVariants = cva("text-card-foreground", {
|
|
1307
|
+
variants: {
|
|
1308
|
+
/**
|
|
1309
|
+
* Elevation (shadow depth) - similar to MUI Paper
|
|
1310
|
+
*/
|
|
1311
|
+
elevation: {
|
|
1312
|
+
none: "",
|
|
1313
|
+
sm: "shadow-sm",
|
|
1314
|
+
md: "shadow",
|
|
1315
|
+
lg: "shadow-lg",
|
|
1316
|
+
xl: "shadow-xl"
|
|
1317
|
+
},
|
|
1318
|
+
/**
|
|
1319
|
+
* Border style
|
|
1320
|
+
*/
|
|
1321
|
+
border: {
|
|
1322
|
+
none: "",
|
|
1323
|
+
default: "border",
|
|
1324
|
+
muted: "border border-muted"
|
|
1325
|
+
},
|
|
1326
|
+
/**
|
|
1327
|
+
* Padding size
|
|
1328
|
+
*/
|
|
1329
|
+
padding: {
|
|
1330
|
+
none: "",
|
|
1331
|
+
sm: "p-2",
|
|
1332
|
+
md: "p-4",
|
|
1333
|
+
lg: "p-6",
|
|
1334
|
+
xl: "p-8"
|
|
1335
|
+
},
|
|
1336
|
+
/**
|
|
1337
|
+
* Border radius
|
|
1338
|
+
*/
|
|
1339
|
+
radius: {
|
|
1340
|
+
none: "rounded-none",
|
|
1341
|
+
sm: "rounded-sm",
|
|
1342
|
+
md: "rounded-md",
|
|
1343
|
+
lg: "rounded-lg",
|
|
1344
|
+
xl: "rounded-xl",
|
|
1345
|
+
full: "rounded-full"
|
|
1346
|
+
},
|
|
1347
|
+
/**
|
|
1348
|
+
* Background color
|
|
1349
|
+
*/
|
|
1350
|
+
background: {
|
|
1351
|
+
default: "bg-card",
|
|
1352
|
+
muted: "bg-muted",
|
|
1353
|
+
transparent: "bg-transparent"
|
|
1354
|
+
},
|
|
1355
|
+
/**
|
|
1356
|
+
* Hover effect styles
|
|
1357
|
+
*/
|
|
1358
|
+
hover: {
|
|
1359
|
+
none: "",
|
|
1360
|
+
border: "transition-colors duration-200 hover:border-accent",
|
|
1361
|
+
elevate: "transition-shadow duration-200 hover:shadow-lg",
|
|
1362
|
+
"border-success": "transition-colors duration-200 hover:border-success",
|
|
1363
|
+
"border-warning": "transition-colors duration-200 hover:border-warning",
|
|
1364
|
+
"border-destructive": "transition-colors duration-200 hover:border-destructive"
|
|
1365
|
+
}
|
|
1366
|
+
},
|
|
1367
|
+
defaultVariants: {
|
|
1368
|
+
elevation: "none",
|
|
1369
|
+
border: "default",
|
|
1370
|
+
padding: "none",
|
|
1371
|
+
radius: "lg",
|
|
1372
|
+
background: "default",
|
|
1373
|
+
hover: "none"
|
|
1374
|
+
}
|
|
1375
|
+
});
|
|
1376
|
+
var Board = React20.forwardRef(
|
|
1377
|
+
({
|
|
1378
|
+
className,
|
|
1379
|
+
elevation,
|
|
1380
|
+
border,
|
|
1381
|
+
padding,
|
|
1382
|
+
radius,
|
|
1383
|
+
background,
|
|
1384
|
+
hover,
|
|
1385
|
+
hoverBorderClass,
|
|
1386
|
+
...props
|
|
1387
|
+
}, ref) => {
|
|
1388
|
+
return /* @__PURE__ */ jsx(
|
|
1389
|
+
"div",
|
|
1390
|
+
{
|
|
1391
|
+
ref,
|
|
1392
|
+
className: cn(
|
|
1393
|
+
boardVariants({
|
|
1394
|
+
elevation,
|
|
1395
|
+
border,
|
|
1396
|
+
padding,
|
|
1397
|
+
radius,
|
|
1398
|
+
background,
|
|
1399
|
+
hover
|
|
1400
|
+
}),
|
|
1401
|
+
// Custom hover border color overrides variant if provided
|
|
1402
|
+
hoverBorderClass && "transition-colors duration-200",
|
|
1403
|
+
hoverBorderClass,
|
|
1404
|
+
className
|
|
1405
|
+
),
|
|
1406
|
+
...props
|
|
1407
|
+
}
|
|
1408
|
+
);
|
|
1409
|
+
}
|
|
1410
|
+
);
|
|
1411
|
+
Board.displayName = "Board";
|
|
1412
|
+
var BoardHeader = React20.forwardRef(
|
|
1413
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
1414
|
+
"div",
|
|
1415
|
+
{
|
|
1416
|
+
ref,
|
|
1417
|
+
className: cn("flex items-center p-4 border-b", className),
|
|
1418
|
+
...props
|
|
1419
|
+
}
|
|
1420
|
+
)
|
|
1421
|
+
);
|
|
1422
|
+
BoardHeader.displayName = "BoardHeader";
|
|
1423
|
+
var BoardContent = React20.forwardRef(
|
|
1424
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("p-4", className), ...props })
|
|
1425
|
+
);
|
|
1426
|
+
BoardContent.displayName = "BoardContent";
|
|
1427
|
+
var Table = React20.forwardRef(
|
|
927
1428
|
({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { className: "relative w-full overflow-auto", children: /* @__PURE__ */ jsx(
|
|
928
1429
|
"table",
|
|
929
1430
|
{
|
|
@@ -934,11 +1435,11 @@ var Table = React33.forwardRef(
|
|
|
934
1435
|
) })
|
|
935
1436
|
);
|
|
936
1437
|
Table.displayName = "Table";
|
|
937
|
-
var TableHeader =
|
|
1438
|
+
var TableHeader = React20.forwardRef(
|
|
938
1439
|
({ className, ...props }, ref) => /* @__PURE__ */ jsx("thead", { ref, className: cn("[&_tr]:border-b", className), ...props })
|
|
939
1440
|
);
|
|
940
1441
|
TableHeader.displayName = "TableHeader";
|
|
941
|
-
var TableBody =
|
|
1442
|
+
var TableBody = React20.forwardRef(
|
|
942
1443
|
({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
943
1444
|
"tbody",
|
|
944
1445
|
{
|
|
@@ -949,7 +1450,7 @@ var TableBody = React33.forwardRef(
|
|
|
949
1450
|
)
|
|
950
1451
|
);
|
|
951
1452
|
TableBody.displayName = "TableBody";
|
|
952
|
-
var TableFooter =
|
|
1453
|
+
var TableFooter = React20.forwardRef(
|
|
953
1454
|
({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
954
1455
|
"tfoot",
|
|
955
1456
|
{
|
|
@@ -963,7 +1464,7 @@ var TableFooter = React33.forwardRef(
|
|
|
963
1464
|
)
|
|
964
1465
|
);
|
|
965
1466
|
TableFooter.displayName = "TableFooter";
|
|
966
|
-
var TableRow =
|
|
1467
|
+
var TableRow = React20.forwardRef(
|
|
967
1468
|
({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
968
1469
|
"tr",
|
|
969
1470
|
{
|
|
@@ -977,7 +1478,7 @@ var TableRow = React33.forwardRef(
|
|
|
977
1478
|
)
|
|
978
1479
|
);
|
|
979
1480
|
TableRow.displayName = "TableRow";
|
|
980
|
-
var TableHead =
|
|
1481
|
+
var TableHead = React20.forwardRef(
|
|
981
1482
|
({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
982
1483
|
"th",
|
|
983
1484
|
{
|
|
@@ -991,7 +1492,7 @@ var TableHead = React33.forwardRef(
|
|
|
991
1492
|
)
|
|
992
1493
|
);
|
|
993
1494
|
TableHead.displayName = "TableHead";
|
|
994
|
-
var TableCell =
|
|
1495
|
+
var TableCell = React20.forwardRef(
|
|
995
1496
|
({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
996
1497
|
"td",
|
|
997
1498
|
{
|
|
@@ -1005,7 +1506,7 @@ var TableCell = React33.forwardRef(
|
|
|
1005
1506
|
)
|
|
1006
1507
|
);
|
|
1007
1508
|
TableCell.displayName = "TableCell";
|
|
1008
|
-
var TableCaption =
|
|
1509
|
+
var TableCaption = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
1009
1510
|
"caption",
|
|
1010
1511
|
{
|
|
1011
1512
|
ref,
|
|
@@ -1014,6 +1515,518 @@ var TableCaption = React33.forwardRef(({ className, ...props }, ref) => /* @__PU
|
|
|
1014
1515
|
}
|
|
1015
1516
|
));
|
|
1016
1517
|
TableCaption.displayName = "TableCaption";
|
|
1518
|
+
var loadingSpinnerVariants = cva("rounded-full animate-spin border-current", {
|
|
1519
|
+
variants: {
|
|
1520
|
+
/**
|
|
1521
|
+
* Size of the spinner
|
|
1522
|
+
*/
|
|
1523
|
+
size: {
|
|
1524
|
+
sm: "w-4 h-4 border-2",
|
|
1525
|
+
default: "w-8 h-8 border-2",
|
|
1526
|
+
lg: "w-12 h-12 border-[3px]",
|
|
1527
|
+
xl: "w-16 h-16 border-4"
|
|
1528
|
+
},
|
|
1529
|
+
/**
|
|
1530
|
+
* Visual variant
|
|
1531
|
+
*/
|
|
1532
|
+
variant: {
|
|
1533
|
+
/** Primary color spinner (default) */
|
|
1534
|
+
default: "border-primary/20 border-t-primary",
|
|
1535
|
+
/** Accent color spinner */
|
|
1536
|
+
accent: "border-accent/20 border-t-accent",
|
|
1537
|
+
/** Muted/subtle spinner */
|
|
1538
|
+
muted: "border-muted-foreground/20 border-t-muted-foreground",
|
|
1539
|
+
/** Inherits current text color */
|
|
1540
|
+
inherit: "border-current/20 border-t-current"
|
|
1541
|
+
}
|
|
1542
|
+
},
|
|
1543
|
+
defaultVariants: {
|
|
1544
|
+
size: "default",
|
|
1545
|
+
variant: "default"
|
|
1546
|
+
}
|
|
1547
|
+
});
|
|
1548
|
+
var LoadingSpinner = React20.forwardRef(
|
|
1549
|
+
({ className, size, variant, label, showDots = false, ...props }, ref) => {
|
|
1550
|
+
const [dots, setDots] = React20.useState("");
|
|
1551
|
+
React20.useEffect(() => {
|
|
1552
|
+
if (!showDots || !label) return;
|
|
1553
|
+
const interval = setInterval(() => {
|
|
1554
|
+
setDots((prev) => prev.length >= 3 ? "" : prev + ".");
|
|
1555
|
+
}, 500);
|
|
1556
|
+
return () => clearInterval(interval);
|
|
1557
|
+
}, [showDots, label]);
|
|
1558
|
+
if (label) {
|
|
1559
|
+
return /* @__PURE__ */ jsxs(
|
|
1560
|
+
"div",
|
|
1561
|
+
{
|
|
1562
|
+
ref,
|
|
1563
|
+
className: cn("flex flex-col items-center gap-3", className),
|
|
1564
|
+
...props,
|
|
1565
|
+
children: [
|
|
1566
|
+
/* @__PURE__ */ jsx("div", { className: loadingSpinnerVariants({ size, variant }) }),
|
|
1567
|
+
/* @__PURE__ */ jsxs("p", { className: "text-sm text-muted-foreground", children: [
|
|
1568
|
+
label,
|
|
1569
|
+
showDots && /* @__PURE__ */ jsx("span", { className: "inline-block w-4", children: dots })
|
|
1570
|
+
] })
|
|
1571
|
+
]
|
|
1572
|
+
}
|
|
1573
|
+
);
|
|
1574
|
+
}
|
|
1575
|
+
return /* @__PURE__ */ jsx(
|
|
1576
|
+
"div",
|
|
1577
|
+
{
|
|
1578
|
+
ref,
|
|
1579
|
+
className: cn(loadingSpinnerVariants({ size, variant }), className),
|
|
1580
|
+
...props
|
|
1581
|
+
}
|
|
1582
|
+
);
|
|
1583
|
+
}
|
|
1584
|
+
);
|
|
1585
|
+
LoadingSpinner.displayName = "LoadingSpinner";
|
|
1586
|
+
function getCellRawValue(row, col) {
|
|
1587
|
+
if (col.accessor) return col.accessor(row);
|
|
1588
|
+
return row[col.key];
|
|
1589
|
+
}
|
|
1590
|
+
function defaultSearch(row, query, columns) {
|
|
1591
|
+
const lowerQuery = query.toLowerCase();
|
|
1592
|
+
return columns.some((col) => {
|
|
1593
|
+
const val = getCellRawValue(row, col);
|
|
1594
|
+
if (val == null) return false;
|
|
1595
|
+
return String(val).toLowerCase().includes(lowerQuery);
|
|
1596
|
+
});
|
|
1597
|
+
}
|
|
1598
|
+
function defaultSortComparator(a, b, col, direction) {
|
|
1599
|
+
if (col.sortFn) {
|
|
1600
|
+
const result = col.sortFn(a, b);
|
|
1601
|
+
return direction === "asc" ? result : -result;
|
|
1602
|
+
}
|
|
1603
|
+
const aVal = getCellRawValue(a, col);
|
|
1604
|
+
const bVal = getCellRawValue(b, col);
|
|
1605
|
+
const aStr = aVal == null ? "" : String(aVal);
|
|
1606
|
+
const bStr = bVal == null ? "" : String(bVal);
|
|
1607
|
+
const aNum = Number(aStr);
|
|
1608
|
+
const bNum = Number(bStr);
|
|
1609
|
+
if (!isNaN(aNum) && !isNaN(bNum) && aStr !== "" && bStr !== "") {
|
|
1610
|
+
return direction === "asc" ? aNum - bNum : bNum - aNum;
|
|
1611
|
+
}
|
|
1612
|
+
const cmp = aStr.localeCompare(bStr);
|
|
1613
|
+
return direction === "asc" ? cmp : -cmp;
|
|
1614
|
+
}
|
|
1615
|
+
function DataTable({
|
|
1616
|
+
data,
|
|
1617
|
+
columns,
|
|
1618
|
+
getRowKey,
|
|
1619
|
+
// Sorting
|
|
1620
|
+
defaultSort,
|
|
1621
|
+
sort: controlledSort,
|
|
1622
|
+
onSortChange,
|
|
1623
|
+
// Search
|
|
1624
|
+
searchable = false,
|
|
1625
|
+
searchPlaceholder = "Search...",
|
|
1626
|
+
searchValue: controlledSearchValue,
|
|
1627
|
+
onSearchChange,
|
|
1628
|
+
searchFn,
|
|
1629
|
+
// Pagination
|
|
1630
|
+
pageSize: defaultPageSize,
|
|
1631
|
+
pageSizeOptions = [10, 15, 25, 50, 100],
|
|
1632
|
+
currentPage: controlledPage,
|
|
1633
|
+
onPageChange,
|
|
1634
|
+
onPageSizeChange,
|
|
1635
|
+
// Selection
|
|
1636
|
+
selectable,
|
|
1637
|
+
selectedRows: controlledSelectedRows,
|
|
1638
|
+
onSelectedRowsChange,
|
|
1639
|
+
// Row interaction
|
|
1640
|
+
onRowClick,
|
|
1641
|
+
rowClassName,
|
|
1642
|
+
// Pinned rows
|
|
1643
|
+
pinnedRows = [],
|
|
1644
|
+
// Slots
|
|
1645
|
+
toolbar,
|
|
1646
|
+
emptyState,
|
|
1647
|
+
caption,
|
|
1648
|
+
// Loading
|
|
1649
|
+
loading = false,
|
|
1650
|
+
// Styling
|
|
1651
|
+
className
|
|
1652
|
+
}) {
|
|
1653
|
+
const [internalSort, setInternalSort] = React20.useState(
|
|
1654
|
+
defaultSort ?? null
|
|
1655
|
+
);
|
|
1656
|
+
const [internalSearchValue, setInternalSearchValue] = React20.useState("");
|
|
1657
|
+
const [internalPage, setInternalPage] = React20.useState(0);
|
|
1658
|
+
const [internalPageSize, setInternalPageSize] = React20.useState(
|
|
1659
|
+
defaultPageSize ?? 10
|
|
1660
|
+
);
|
|
1661
|
+
const [internalSelectedRows, setInternalSelectedRows] = React20.useState([]);
|
|
1662
|
+
const sort = controlledSort !== void 0 ? controlledSort : internalSort;
|
|
1663
|
+
const searchQuery = controlledSearchValue !== void 0 ? controlledSearchValue : internalSearchValue;
|
|
1664
|
+
const page = controlledPage !== void 0 ? controlledPage : internalPage;
|
|
1665
|
+
const pageSize = defaultPageSize != null ? internalPageSize ?? defaultPageSize : void 0;
|
|
1666
|
+
const selectedRowKeys = controlledSelectedRows !== void 0 ? controlledSelectedRows : internalSelectedRows;
|
|
1667
|
+
const handleSortChange = React20.useCallback(
|
|
1668
|
+
(next) => {
|
|
1669
|
+
if (onSortChange) onSortChange(next);
|
|
1670
|
+
else setInternalSort(next);
|
|
1671
|
+
},
|
|
1672
|
+
[onSortChange]
|
|
1673
|
+
);
|
|
1674
|
+
const handleSearchChange = React20.useCallback(
|
|
1675
|
+
(value) => {
|
|
1676
|
+
if (onSearchChange) onSearchChange(value);
|
|
1677
|
+
else setInternalSearchValue(value);
|
|
1678
|
+
if (onPageChange) onPageChange(0);
|
|
1679
|
+
else setInternalPage(0);
|
|
1680
|
+
},
|
|
1681
|
+
[onSearchChange, onPageChange]
|
|
1682
|
+
);
|
|
1683
|
+
const handlePageChange = React20.useCallback(
|
|
1684
|
+
(p) => {
|
|
1685
|
+
if (onPageChange) onPageChange(p);
|
|
1686
|
+
else setInternalPage(p);
|
|
1687
|
+
},
|
|
1688
|
+
[onPageChange]
|
|
1689
|
+
);
|
|
1690
|
+
const handlePageSizeChange = React20.useCallback(
|
|
1691
|
+
(size) => {
|
|
1692
|
+
if (onPageSizeChange) onPageSizeChange(size);
|
|
1693
|
+
else setInternalPageSize(size);
|
|
1694
|
+
if (onPageChange) onPageChange(0);
|
|
1695
|
+
else setInternalPage(0);
|
|
1696
|
+
},
|
|
1697
|
+
[onPageSizeChange, onPageChange]
|
|
1698
|
+
);
|
|
1699
|
+
const handleSelectionChange = React20.useCallback(
|
|
1700
|
+
(keys) => {
|
|
1701
|
+
if (onSelectedRowsChange) onSelectedRowsChange(keys);
|
|
1702
|
+
else setInternalSelectedRows(keys);
|
|
1703
|
+
},
|
|
1704
|
+
[onSelectedRowsChange]
|
|
1705
|
+
);
|
|
1706
|
+
const handleHeaderClick = React20.useCallback(
|
|
1707
|
+
(colKey) => {
|
|
1708
|
+
if (sort?.key === colKey) {
|
|
1709
|
+
if (sort.direction === "asc") {
|
|
1710
|
+
handleSortChange({ key: colKey, direction: "desc" });
|
|
1711
|
+
} else {
|
|
1712
|
+
handleSortChange(null);
|
|
1713
|
+
}
|
|
1714
|
+
} else {
|
|
1715
|
+
handleSortChange({ key: colKey, direction: "asc" });
|
|
1716
|
+
}
|
|
1717
|
+
},
|
|
1718
|
+
[sort, handleSortChange]
|
|
1719
|
+
);
|
|
1720
|
+
const searchedData = React20.useMemo(() => {
|
|
1721
|
+
if (!searchable || !searchQuery) return data;
|
|
1722
|
+
if (searchFn) return data.filter((row) => searchFn(row, searchQuery));
|
|
1723
|
+
return data.filter((row) => defaultSearch(row, searchQuery, columns));
|
|
1724
|
+
}, [data, searchable, searchQuery, searchFn, columns]);
|
|
1725
|
+
const sortedData = React20.useMemo(() => {
|
|
1726
|
+
if (!sort) return searchedData;
|
|
1727
|
+
const col = columns.find((c) => c.key === sort.key);
|
|
1728
|
+
if (!col) return searchedData;
|
|
1729
|
+
return [...searchedData].sort(
|
|
1730
|
+
(a, b) => defaultSortComparator(a, b, col, sort.direction)
|
|
1731
|
+
);
|
|
1732
|
+
}, [searchedData, sort, columns]);
|
|
1733
|
+
const pinnedSet = React20.useMemo(() => new Set(pinnedRows), [pinnedRows]);
|
|
1734
|
+
const { pinnedData, unpinnedData } = React20.useMemo(() => {
|
|
1735
|
+
if (pinnedSet.size === 0) return { pinnedData: [], unpinnedData: sortedData };
|
|
1736
|
+
const pinned = [];
|
|
1737
|
+
const unpinned = [];
|
|
1738
|
+
const dataByKey = /* @__PURE__ */ new Map();
|
|
1739
|
+
data.forEach((row, i) => {
|
|
1740
|
+
dataByKey.set(getRowKey(row, i), row);
|
|
1741
|
+
});
|
|
1742
|
+
pinnedRows.forEach((key) => {
|
|
1743
|
+
const row = dataByKey.get(key);
|
|
1744
|
+
if (row) pinned.push(row);
|
|
1745
|
+
});
|
|
1746
|
+
sortedData.forEach((row, i) => {
|
|
1747
|
+
const key = getRowKey(row, i);
|
|
1748
|
+
if (!pinnedSet.has(key)) unpinned.push(row);
|
|
1749
|
+
});
|
|
1750
|
+
return { pinnedData: pinned, unpinnedData: unpinned };
|
|
1751
|
+
}, [sortedData, pinnedSet, pinnedRows, data, getRowKey]);
|
|
1752
|
+
const totalUnpinned = unpinnedData.length;
|
|
1753
|
+
const totalPages = pageSize ? Math.max(1, Math.ceil(totalUnpinned / pageSize)) : 1;
|
|
1754
|
+
const paginatedData = React20.useMemo(() => {
|
|
1755
|
+
if (!pageSize) return unpinnedData;
|
|
1756
|
+
const start = page * pageSize;
|
|
1757
|
+
return unpinnedData.slice(start, start + pageSize);
|
|
1758
|
+
}, [unpinnedData, pageSize, page]);
|
|
1759
|
+
const visibleRows = React20.useMemo(
|
|
1760
|
+
() => [...pinnedData, ...paginatedData],
|
|
1761
|
+
[pinnedData, paginatedData]
|
|
1762
|
+
);
|
|
1763
|
+
const totalItems = searchedData.length;
|
|
1764
|
+
const visibleKeys = React20.useMemo(
|
|
1765
|
+
() => visibleRows.map((row, i) => getRowKey(row, i)),
|
|
1766
|
+
[visibleRows, getRowKey]
|
|
1767
|
+
);
|
|
1768
|
+
const allVisibleSelected = visibleKeys.length > 0 && visibleKeys.every((k) => selectedRowKeys.includes(k));
|
|
1769
|
+
const someVisibleSelected = !allVisibleSelected && visibleKeys.some((k) => selectedRowKeys.includes(k));
|
|
1770
|
+
const toggleRowSelection = React20.useCallback(
|
|
1771
|
+
(key) => {
|
|
1772
|
+
const isSelected = selectedRowKeys.includes(key);
|
|
1773
|
+
const next = isSelected ? selectedRowKeys.filter((k) => k !== key) : [...selectedRowKeys, key];
|
|
1774
|
+
handleSelectionChange(next);
|
|
1775
|
+
},
|
|
1776
|
+
[selectedRowKeys, handleSelectionChange]
|
|
1777
|
+
);
|
|
1778
|
+
const toggleAllVisible = React20.useCallback(() => {
|
|
1779
|
+
if (allVisibleSelected) {
|
|
1780
|
+
const visibleSet = new Set(visibleKeys);
|
|
1781
|
+
handleSelectionChange(selectedRowKeys.filter((k) => !visibleSet.has(k)));
|
|
1782
|
+
} else {
|
|
1783
|
+
const merged = /* @__PURE__ */ new Set([...selectedRowKeys, ...visibleKeys]);
|
|
1784
|
+
handleSelectionChange(Array.from(merged));
|
|
1785
|
+
}
|
|
1786
|
+
}, [allVisibleSelected, visibleKeys, selectedRowKeys, handleSelectionChange]);
|
|
1787
|
+
const handleRowClick = React20.useCallback(
|
|
1788
|
+
(row, index, key) => {
|
|
1789
|
+
if (selectable === "highlight") {
|
|
1790
|
+
toggleRowSelection(key);
|
|
1791
|
+
}
|
|
1792
|
+
onRowClick?.(row, index);
|
|
1793
|
+
},
|
|
1794
|
+
[selectable, toggleRowSelection, onRowClick]
|
|
1795
|
+
);
|
|
1796
|
+
const renderCellContent = (row, col, rowIndex) => {
|
|
1797
|
+
if (col.cell) return col.cell(row, rowIndex);
|
|
1798
|
+
const val = getCellRawValue(row, col);
|
|
1799
|
+
if (val == null) return /* @__PURE__ */ jsx("span", { className: "text-muted-foreground italic", children: "--" });
|
|
1800
|
+
return String(val);
|
|
1801
|
+
};
|
|
1802
|
+
const alignClass = (align) => {
|
|
1803
|
+
if (align === "center") return "text-center";
|
|
1804
|
+
if (align === "right") return "text-right";
|
|
1805
|
+
return "text-left";
|
|
1806
|
+
};
|
|
1807
|
+
if (loading) {
|
|
1808
|
+
return /* @__PURE__ */ jsx("div", { className: cn("flex items-center justify-center py-16", className), children: /* @__PURE__ */ jsx(LoadingSpinner, { label: "Loading", showDots: true }) });
|
|
1809
|
+
}
|
|
1810
|
+
const showSearch = searchable;
|
|
1811
|
+
const showPagination = pageSize != null;
|
|
1812
|
+
const showCheckboxColumn = selectable === "checkbox";
|
|
1813
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col w-full", className), children: [
|
|
1814
|
+
(showSearch || toolbar) && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 pb-4", children: [
|
|
1815
|
+
showSearch && /* @__PURE__ */ jsxs("div", { className: "relative flex-1 max-w-sm", children: [
|
|
1816
|
+
/* @__PURE__ */ jsx(Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" }),
|
|
1817
|
+
/* @__PURE__ */ jsx(
|
|
1818
|
+
Input,
|
|
1819
|
+
{
|
|
1820
|
+
type: "text",
|
|
1821
|
+
placeholder: searchPlaceholder,
|
|
1822
|
+
value: searchQuery,
|
|
1823
|
+
onChange: (e) => handleSearchChange(e.target.value),
|
|
1824
|
+
className: "pl-9"
|
|
1825
|
+
}
|
|
1826
|
+
)
|
|
1827
|
+
] }),
|
|
1828
|
+
toolbar && /* @__PURE__ */ jsx("div", { className: "flex items-center gap-2", children: toolbar })
|
|
1829
|
+
] }),
|
|
1830
|
+
/* @__PURE__ */ jsxs(Table, { children: [
|
|
1831
|
+
caption && /* @__PURE__ */ jsx(TableCaption, { children: caption }),
|
|
1832
|
+
/* @__PURE__ */ jsx(TableHeader, { children: /* @__PURE__ */ jsxs(TableRow, { children: [
|
|
1833
|
+
showCheckboxColumn && /* @__PURE__ */ jsx(TableHead, { className: "w-[40px]", children: /* @__PURE__ */ jsx(
|
|
1834
|
+
Checkbox,
|
|
1835
|
+
{
|
|
1836
|
+
checked: allVisibleSelected ? true : someVisibleSelected ? "indeterminate" : false,
|
|
1837
|
+
onCheckedChange: () => toggleAllVisible(),
|
|
1838
|
+
"aria-label": "Select all"
|
|
1839
|
+
}
|
|
1840
|
+
) }),
|
|
1841
|
+
columns.map((col) => {
|
|
1842
|
+
const isSorted = sort?.key === col.key;
|
|
1843
|
+
const sortDir = isSorted ? sort.direction : null;
|
|
1844
|
+
return /* @__PURE__ */ jsx(
|
|
1845
|
+
TableHead,
|
|
1846
|
+
{
|
|
1847
|
+
className: cn(
|
|
1848
|
+
col.width,
|
|
1849
|
+
col.headerClassName,
|
|
1850
|
+
alignClass(col.align),
|
|
1851
|
+
col.sortable && "cursor-pointer select-none"
|
|
1852
|
+
),
|
|
1853
|
+
onClick: col.sortable ? () => handleHeaderClick(col.key) : void 0,
|
|
1854
|
+
children: /* @__PURE__ */ jsxs(
|
|
1855
|
+
"div",
|
|
1856
|
+
{
|
|
1857
|
+
className: cn(
|
|
1858
|
+
"flex items-center gap-1",
|
|
1859
|
+
col.align === "center" && "justify-center",
|
|
1860
|
+
col.align === "right" && "justify-end"
|
|
1861
|
+
),
|
|
1862
|
+
children: [
|
|
1863
|
+
/* @__PURE__ */ jsx("span", { children: col.header }),
|
|
1864
|
+
col.sortable && /* @__PURE__ */ jsx("span", { className: "inline-flex ml-1", children: sortDir === "asc" ? /* @__PURE__ */ jsx(ArrowUp, { className: "h-3.5 w-3.5" }) : sortDir === "desc" ? /* @__PURE__ */ jsx(ArrowDown, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ jsx(ArrowUpDown, { className: "h-3.5 w-3.5 opacity-40" }) })
|
|
1865
|
+
]
|
|
1866
|
+
}
|
|
1867
|
+
)
|
|
1868
|
+
},
|
|
1869
|
+
col.key
|
|
1870
|
+
);
|
|
1871
|
+
})
|
|
1872
|
+
] }) }),
|
|
1873
|
+
pinnedData.length > 0 && /* @__PURE__ */ jsx(TableBody, { className: "bg-muted/30 border-b-2 border-border", children: pinnedData.map((row, i) => {
|
|
1874
|
+
const key = getRowKey(row, i);
|
|
1875
|
+
const isSelected = selectedRowKeys.includes(key);
|
|
1876
|
+
return /* @__PURE__ */ jsxs(
|
|
1877
|
+
TableRow,
|
|
1878
|
+
{
|
|
1879
|
+
"data-state": isSelected ? "selected" : void 0,
|
|
1880
|
+
className: cn(
|
|
1881
|
+
(onRowClick || selectable === "highlight") && "cursor-pointer",
|
|
1882
|
+
rowClassName?.(row, i)
|
|
1883
|
+
),
|
|
1884
|
+
onClick: () => handleRowClick(row, i, key),
|
|
1885
|
+
children: [
|
|
1886
|
+
showCheckboxColumn && /* @__PURE__ */ jsx(TableCell, { className: "w-[40px]", children: /* @__PURE__ */ jsx(
|
|
1887
|
+
Checkbox,
|
|
1888
|
+
{
|
|
1889
|
+
checked: isSelected,
|
|
1890
|
+
onCheckedChange: () => toggleRowSelection(key),
|
|
1891
|
+
onClick: (e) => e.stopPropagation(),
|
|
1892
|
+
"aria-label": "Select row"
|
|
1893
|
+
}
|
|
1894
|
+
) }),
|
|
1895
|
+
columns.map((col) => /* @__PURE__ */ jsx(
|
|
1896
|
+
TableCell,
|
|
1897
|
+
{
|
|
1898
|
+
className: cn(alignClass(col.align), col.className),
|
|
1899
|
+
children: renderCellContent(row, col, i)
|
|
1900
|
+
},
|
|
1901
|
+
col.key
|
|
1902
|
+
))
|
|
1903
|
+
]
|
|
1904
|
+
},
|
|
1905
|
+
key
|
|
1906
|
+
);
|
|
1907
|
+
}) }),
|
|
1908
|
+
/* @__PURE__ */ jsx(TableBody, { children: paginatedData.length === 0 && pinnedData.length === 0 ? /* @__PURE__ */ jsx(TableRow, { children: /* @__PURE__ */ jsx(
|
|
1909
|
+
TableCell,
|
|
1910
|
+
{
|
|
1911
|
+
colSpan: columns.length + (showCheckboxColumn ? 1 : 0),
|
|
1912
|
+
className: "h-24 text-center",
|
|
1913
|
+
children: emptyState ?? /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "No results." })
|
|
1914
|
+
}
|
|
1915
|
+
) }) : paginatedData.map((row, i) => {
|
|
1916
|
+
const globalIndex = pageSize ? page * pageSize + i : i;
|
|
1917
|
+
const key = getRowKey(row, globalIndex);
|
|
1918
|
+
const isSelected = selectedRowKeys.includes(key);
|
|
1919
|
+
return /* @__PURE__ */ jsxs(
|
|
1920
|
+
TableRow,
|
|
1921
|
+
{
|
|
1922
|
+
"data-state": isSelected ? "selected" : void 0,
|
|
1923
|
+
className: cn(
|
|
1924
|
+
(onRowClick || selectable === "highlight") && "cursor-pointer",
|
|
1925
|
+
rowClassName?.(row, globalIndex)
|
|
1926
|
+
),
|
|
1927
|
+
onClick: () => handleRowClick(row, globalIndex, key),
|
|
1928
|
+
children: [
|
|
1929
|
+
showCheckboxColumn && /* @__PURE__ */ jsx(TableCell, { className: "w-[40px]", children: /* @__PURE__ */ jsx(
|
|
1930
|
+
Checkbox,
|
|
1931
|
+
{
|
|
1932
|
+
checked: isSelected,
|
|
1933
|
+
onCheckedChange: () => toggleRowSelection(key),
|
|
1934
|
+
onClick: (e) => e.stopPropagation(),
|
|
1935
|
+
"aria-label": "Select row"
|
|
1936
|
+
}
|
|
1937
|
+
) }),
|
|
1938
|
+
columns.map((col) => /* @__PURE__ */ jsx(
|
|
1939
|
+
TableCell,
|
|
1940
|
+
{
|
|
1941
|
+
className: cn(alignClass(col.align), col.className),
|
|
1942
|
+
children: renderCellContent(row, col, globalIndex)
|
|
1943
|
+
},
|
|
1944
|
+
col.key
|
|
1945
|
+
))
|
|
1946
|
+
]
|
|
1947
|
+
},
|
|
1948
|
+
key
|
|
1949
|
+
);
|
|
1950
|
+
}) })
|
|
1951
|
+
] }),
|
|
1952
|
+
showPagination && /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between pt-4", children: [
|
|
1953
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
1954
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm text-muted-foreground", children: "Rows per page" }),
|
|
1955
|
+
/* @__PURE__ */ jsxs(
|
|
1956
|
+
Select,
|
|
1957
|
+
{
|
|
1958
|
+
value: String(pageSize),
|
|
1959
|
+
onValueChange: (val) => handlePageSizeChange(Number(val)),
|
|
1960
|
+
children: [
|
|
1961
|
+
/* @__PURE__ */ jsx(SelectTrigger, { className: "h-8 w-[70px]", children: /* @__PURE__ */ jsx(SelectValue, { placeholder: String(pageSize) }) }),
|
|
1962
|
+
/* @__PURE__ */ jsx(SelectContent, { children: pageSizeOptions.map((opt) => /* @__PURE__ */ jsx(SelectItem, { value: String(opt), children: opt }, opt)) })
|
|
1963
|
+
]
|
|
1964
|
+
}
|
|
1965
|
+
)
|
|
1966
|
+
] }),
|
|
1967
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-4", children: [
|
|
1968
|
+
/* @__PURE__ */ jsxs("span", { className: "text-sm text-muted-foreground", children: [
|
|
1969
|
+
"Page ",
|
|
1970
|
+
page + 1,
|
|
1971
|
+
" of ",
|
|
1972
|
+
totalPages,
|
|
1973
|
+
` (${totalItems} total)`
|
|
1974
|
+
] }),
|
|
1975
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
|
|
1976
|
+
/* @__PURE__ */ jsx(
|
|
1977
|
+
Button,
|
|
1978
|
+
{
|
|
1979
|
+
variant: "ghost",
|
|
1980
|
+
size: "icon",
|
|
1981
|
+
className: "h-8 w-8",
|
|
1982
|
+
onClick: () => handlePageChange(0),
|
|
1983
|
+
disabled: page === 0,
|
|
1984
|
+
"aria-label": "First page",
|
|
1985
|
+
children: /* @__PURE__ */ jsx(ChevronsLeft, { className: "h-4 w-4" })
|
|
1986
|
+
}
|
|
1987
|
+
),
|
|
1988
|
+
/* @__PURE__ */ jsx(
|
|
1989
|
+
Button,
|
|
1990
|
+
{
|
|
1991
|
+
variant: "ghost",
|
|
1992
|
+
size: "icon",
|
|
1993
|
+
className: "h-8 w-8",
|
|
1994
|
+
onClick: () => handlePageChange(page - 1),
|
|
1995
|
+
disabled: page === 0,
|
|
1996
|
+
"aria-label": "Previous page",
|
|
1997
|
+
children: /* @__PURE__ */ jsx(ChevronLeft, { className: "h-4 w-4" })
|
|
1998
|
+
}
|
|
1999
|
+
),
|
|
2000
|
+
/* @__PURE__ */ jsx(
|
|
2001
|
+
Button,
|
|
2002
|
+
{
|
|
2003
|
+
variant: "ghost",
|
|
2004
|
+
size: "icon",
|
|
2005
|
+
className: "h-8 w-8",
|
|
2006
|
+
onClick: () => handlePageChange(page + 1),
|
|
2007
|
+
disabled: page >= totalPages - 1,
|
|
2008
|
+
"aria-label": "Next page",
|
|
2009
|
+
children: /* @__PURE__ */ jsx(ChevronRight, { className: "h-4 w-4" })
|
|
2010
|
+
}
|
|
2011
|
+
),
|
|
2012
|
+
/* @__PURE__ */ jsx(
|
|
2013
|
+
Button,
|
|
2014
|
+
{
|
|
2015
|
+
variant: "ghost",
|
|
2016
|
+
size: "icon",
|
|
2017
|
+
className: "h-8 w-8",
|
|
2018
|
+
onClick: () => handlePageChange(totalPages - 1),
|
|
2019
|
+
disabled: page >= totalPages - 1,
|
|
2020
|
+
"aria-label": "Last page",
|
|
2021
|
+
children: /* @__PURE__ */ jsx(ChevronsRight, { className: "h-4 w-4" })
|
|
2022
|
+
}
|
|
2023
|
+
)
|
|
2024
|
+
] })
|
|
2025
|
+
] })
|
|
2026
|
+
] })
|
|
2027
|
+
] });
|
|
2028
|
+
}
|
|
2029
|
+
DataTable.displayName = "DataTable";
|
|
1017
2030
|
function Modal({
|
|
1018
2031
|
isOpen,
|
|
1019
2032
|
onClose,
|
|
@@ -1024,7 +2037,7 @@ function Modal({
|
|
|
1024
2037
|
zIndex = 50,
|
|
1025
2038
|
className
|
|
1026
2039
|
}) {
|
|
1027
|
-
|
|
2040
|
+
React20.useEffect(() => {
|
|
1028
2041
|
if (!isOpen) return;
|
|
1029
2042
|
const handleEscape = (e) => {
|
|
1030
2043
|
if (e.key === "Escape") {
|
|
@@ -1034,7 +2047,7 @@ function Modal({
|
|
|
1034
2047
|
window.addEventListener("keydown", handleEscape);
|
|
1035
2048
|
return () => window.removeEventListener("keydown", handleEscape);
|
|
1036
2049
|
}, [isOpen, onClose]);
|
|
1037
|
-
|
|
2050
|
+
React20.useEffect(() => {
|
|
1038
2051
|
if (isOpen) {
|
|
1039
2052
|
document.body.style.overflow = "hidden";
|
|
1040
2053
|
} else {
|
|
@@ -1149,12 +2162,12 @@ function ConfirmationModal({
|
|
|
1149
2162
|
] }) });
|
|
1150
2163
|
}
|
|
1151
2164
|
function useConfirmation() {
|
|
1152
|
-
const [state, setState] =
|
|
2165
|
+
const [state, setState] = React20.useState({
|
|
1153
2166
|
open: false,
|
|
1154
2167
|
title: "",
|
|
1155
2168
|
description: ""
|
|
1156
2169
|
});
|
|
1157
|
-
const confirm =
|
|
2170
|
+
const confirm = React20.useCallback(
|
|
1158
2171
|
(options) => {
|
|
1159
2172
|
return new Promise((resolve) => {
|
|
1160
2173
|
setState({
|
|
@@ -1166,15 +2179,15 @@ function useConfirmation() {
|
|
|
1166
2179
|
},
|
|
1167
2180
|
[]
|
|
1168
2181
|
);
|
|
1169
|
-
const handleConfirm =
|
|
2182
|
+
const handleConfirm = React20.useCallback(() => {
|
|
1170
2183
|
state.resolve?.(true);
|
|
1171
2184
|
setState((prev) => ({ ...prev, open: false }));
|
|
1172
2185
|
}, [state.resolve]);
|
|
1173
|
-
const handleCancel =
|
|
2186
|
+
const handleCancel = React20.useCallback(() => {
|
|
1174
2187
|
state.resolve?.(false);
|
|
1175
2188
|
setState((prev) => ({ ...prev, open: false }));
|
|
1176
2189
|
}, [state.resolve]);
|
|
1177
|
-
const handleOpenChange =
|
|
2190
|
+
const handleOpenChange = React20.useCallback(
|
|
1178
2191
|
(open) => {
|
|
1179
2192
|
if (!open) {
|
|
1180
2193
|
state.resolve?.(false);
|
|
@@ -1210,11 +2223,11 @@ function ResizeHandle({
|
|
|
1210
2223
|
ariaLabel,
|
|
1211
2224
|
className
|
|
1212
2225
|
}) {
|
|
1213
|
-
const [isDragging, setIsDragging] =
|
|
1214
|
-
const [isFocused, setIsFocused] =
|
|
1215
|
-
const startXRef =
|
|
1216
|
-
const handleRef =
|
|
1217
|
-
const handleMouseDown =
|
|
2226
|
+
const [isDragging, setIsDragging] = React20.useState(false);
|
|
2227
|
+
const [isFocused, setIsFocused] = React20.useState(false);
|
|
2228
|
+
const startXRef = React20.useRef(0);
|
|
2229
|
+
const handleRef = React20.useRef(null);
|
|
2230
|
+
const handleMouseDown = React20.useCallback(
|
|
1218
2231
|
(e) => {
|
|
1219
2232
|
if (!resizable) return;
|
|
1220
2233
|
e.preventDefault();
|
|
@@ -1225,7 +2238,7 @@ function ResizeHandle({
|
|
|
1225
2238
|
},
|
|
1226
2239
|
[resizable, onDragStart]
|
|
1227
2240
|
);
|
|
1228
|
-
const handleMouseMove =
|
|
2241
|
+
const handleMouseMove = React20.useCallback(
|
|
1229
2242
|
(e) => {
|
|
1230
2243
|
if (!isDragging) return;
|
|
1231
2244
|
const deltaX = e.clientX - startXRef.current;
|
|
@@ -1234,13 +2247,13 @@ function ResizeHandle({
|
|
|
1234
2247
|
},
|
|
1235
2248
|
[isDragging, onDrag]
|
|
1236
2249
|
);
|
|
1237
|
-
const handleMouseUp =
|
|
2250
|
+
const handleMouseUp = React20.useCallback(() => {
|
|
1238
2251
|
if (!isDragging) return;
|
|
1239
2252
|
setIsDragging(false);
|
|
1240
2253
|
document.body.style.userSelect = "";
|
|
1241
2254
|
onDragEnd?.();
|
|
1242
2255
|
}, [isDragging, onDragEnd]);
|
|
1243
|
-
const handleKeyDown =
|
|
2256
|
+
const handleKeyDown = React20.useCallback(
|
|
1244
2257
|
(e) => {
|
|
1245
2258
|
if (!resizable || !onKeyboardResize) return;
|
|
1246
2259
|
let direction = null;
|
|
@@ -1259,7 +2272,7 @@ function ResizeHandle({
|
|
|
1259
2272
|
},
|
|
1260
2273
|
[resizable, onKeyboardResize, orientation]
|
|
1261
2274
|
);
|
|
1262
|
-
|
|
2275
|
+
React20.useEffect(() => {
|
|
1263
2276
|
if (isDragging) {
|
|
1264
2277
|
window.addEventListener("mousemove", handleMouseMove);
|
|
1265
2278
|
window.addEventListener("mouseup", handleMouseUp);
|
|
@@ -1329,12 +2342,12 @@ function ResizablePanel({
|
|
|
1329
2342
|
className,
|
|
1330
2343
|
dataAttributes = {}
|
|
1331
2344
|
}) {
|
|
1332
|
-
const panelRef =
|
|
1333
|
-
const [isDragging, setIsDragging] =
|
|
1334
|
-
const [localWidth, setLocalWidth] =
|
|
1335
|
-
const [localOuterWidth, setLocalOuterWidth] =
|
|
2345
|
+
const panelRef = React20.useRef(null);
|
|
2346
|
+
const [isDragging, setIsDragging] = React20.useState(false);
|
|
2347
|
+
const [localWidth, setLocalWidth] = React20.useState(null);
|
|
2348
|
+
const [localOuterWidth, setLocalOuterWidth] = React20.useState(null);
|
|
1336
2349
|
const currentWidthVW = isExpanded ? (isDragging && localWidth !== null ? localWidth : expandedWidthVW) || collapsedSizeVW : collapsedSizeVW;
|
|
1337
|
-
const clampWidth =
|
|
2350
|
+
const clampWidth = React20.useCallback(
|
|
1338
2351
|
(width) => {
|
|
1339
2352
|
let effectiveMinWidth = minWidthVW;
|
|
1340
2353
|
let effectiveMaxWidth = maxWidthVW;
|
|
@@ -1347,11 +2360,11 @@ function ResizablePanel({
|
|
|
1347
2360
|
},
|
|
1348
2361
|
[minWidthVW, maxWidthVW, orientation, leftWidthVW, isOverlay]
|
|
1349
2362
|
);
|
|
1350
|
-
const handleDragStart =
|
|
2363
|
+
const handleDragStart = React20.useCallback(() => {
|
|
1351
2364
|
setIsDragging(true);
|
|
1352
2365
|
setLocalWidth(currentWidthVW);
|
|
1353
2366
|
}, [currentWidthVW]);
|
|
1354
|
-
const handleDrag =
|
|
2367
|
+
const handleDrag = React20.useCallback(
|
|
1355
2368
|
(deltaX) => {
|
|
1356
2369
|
if (!isExpanded || isOverlay) return;
|
|
1357
2370
|
const viewportWidth = window.innerWidth;
|
|
@@ -1370,14 +2383,14 @@ function ResizablePanel({
|
|
|
1370
2383
|
clampWidth
|
|
1371
2384
|
]
|
|
1372
2385
|
);
|
|
1373
|
-
const handleDragEnd =
|
|
2386
|
+
const handleDragEnd = React20.useCallback(() => {
|
|
1374
2387
|
if (localWidth !== null && onResize) {
|
|
1375
2388
|
onResize(localWidth);
|
|
1376
2389
|
}
|
|
1377
2390
|
setIsDragging(false);
|
|
1378
2391
|
setLocalWidth(null);
|
|
1379
2392
|
}, [localWidth, onResize]);
|
|
1380
|
-
const handleKeyboardResize =
|
|
2393
|
+
const handleKeyboardResize = React20.useCallback(
|
|
1381
2394
|
(direction) => {
|
|
1382
2395
|
if (!isExpanded || isOverlay || !onResize) return;
|
|
1383
2396
|
const step = 1;
|
|
@@ -1386,13 +2399,13 @@ function ResizablePanel({
|
|
|
1386
2399
|
},
|
|
1387
2400
|
[isExpanded, isOverlay, onResize, currentWidthVW, clampWidth]
|
|
1388
2401
|
);
|
|
1389
|
-
const handleOverlayDragStart =
|
|
2402
|
+
const handleOverlayDragStart = React20.useCallback(() => {
|
|
1390
2403
|
if (outerWidthVW) {
|
|
1391
2404
|
setIsDragging(true);
|
|
1392
2405
|
setLocalOuterWidth(outerWidthVW);
|
|
1393
2406
|
}
|
|
1394
2407
|
}, [outerWidthVW]);
|
|
1395
|
-
const handleOverlayDrag =
|
|
2408
|
+
const handleOverlayDrag = React20.useCallback(
|
|
1396
2409
|
(deltaX) => {
|
|
1397
2410
|
if (!isOverlay) return;
|
|
1398
2411
|
const viewportWidth = window.innerWidth;
|
|
@@ -1403,14 +2416,14 @@ function ResizablePanel({
|
|
|
1403
2416
|
},
|
|
1404
2417
|
[isOverlay, localOuterWidth, outerWidthVW]
|
|
1405
2418
|
);
|
|
1406
|
-
const handleOverlayDragEnd =
|
|
2419
|
+
const handleOverlayDragEnd = React20.useCallback(() => {
|
|
1407
2420
|
if (localOuterWidth !== null && onResizeOverlay) {
|
|
1408
2421
|
onResizeOverlay(localOuterWidth);
|
|
1409
2422
|
}
|
|
1410
2423
|
setIsDragging(false);
|
|
1411
2424
|
setLocalOuterWidth(null);
|
|
1412
2425
|
}, [localOuterWidth, onResizeOverlay]);
|
|
1413
|
-
|
|
2426
|
+
React20.useEffect(() => {
|
|
1414
2427
|
if (isOverlay && panelRef.current) {
|
|
1415
2428
|
const focusableElement = panelRef.current.querySelector(
|
|
1416
2429
|
'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
|
|
@@ -1418,7 +2431,7 @@ function ResizablePanel({
|
|
|
1418
2431
|
focusableElement?.focus();
|
|
1419
2432
|
}
|
|
1420
2433
|
}, [isOverlay]);
|
|
1421
|
-
|
|
2434
|
+
React20.useEffect(() => {
|
|
1422
2435
|
if (!isOverlay) return;
|
|
1423
2436
|
const handleEscape = (e) => {
|
|
1424
2437
|
if (e.key === "Escape") {
|
|
@@ -1604,74 +2617,6 @@ function Chip({
|
|
|
1604
2617
|
}
|
|
1605
2618
|
);
|
|
1606
2619
|
}
|
|
1607
|
-
var loadingSpinnerVariants = cva("rounded-full animate-spin border-current", {
|
|
1608
|
-
variants: {
|
|
1609
|
-
/**
|
|
1610
|
-
* Size of the spinner
|
|
1611
|
-
*/
|
|
1612
|
-
size: {
|
|
1613
|
-
sm: "w-4 h-4 border-2",
|
|
1614
|
-
default: "w-8 h-8 border-2",
|
|
1615
|
-
lg: "w-12 h-12 border-[3px]",
|
|
1616
|
-
xl: "w-16 h-16 border-4"
|
|
1617
|
-
},
|
|
1618
|
-
/**
|
|
1619
|
-
* Visual variant
|
|
1620
|
-
*/
|
|
1621
|
-
variant: {
|
|
1622
|
-
/** Primary color spinner (default) */
|
|
1623
|
-
default: "border-primary/20 border-t-primary",
|
|
1624
|
-
/** Accent color spinner */
|
|
1625
|
-
accent: "border-accent/20 border-t-accent",
|
|
1626
|
-
/** Muted/subtle spinner */
|
|
1627
|
-
muted: "border-muted-foreground/20 border-t-muted-foreground",
|
|
1628
|
-
/** Inherits current text color */
|
|
1629
|
-
inherit: "border-current/20 border-t-current"
|
|
1630
|
-
}
|
|
1631
|
-
},
|
|
1632
|
-
defaultVariants: {
|
|
1633
|
-
size: "default",
|
|
1634
|
-
variant: "default"
|
|
1635
|
-
}
|
|
1636
|
-
});
|
|
1637
|
-
var LoadingSpinner = React33.forwardRef(
|
|
1638
|
-
({ className, size, variant, label, showDots = false, ...props }, ref) => {
|
|
1639
|
-
const [dots, setDots] = React33.useState("");
|
|
1640
|
-
React33.useEffect(() => {
|
|
1641
|
-
if (!showDots || !label) return;
|
|
1642
|
-
const interval = setInterval(() => {
|
|
1643
|
-
setDots((prev) => prev.length >= 3 ? "" : prev + ".");
|
|
1644
|
-
}, 500);
|
|
1645
|
-
return () => clearInterval(interval);
|
|
1646
|
-
}, [showDots, label]);
|
|
1647
|
-
if (label) {
|
|
1648
|
-
return /* @__PURE__ */ jsxs(
|
|
1649
|
-
"div",
|
|
1650
|
-
{
|
|
1651
|
-
ref,
|
|
1652
|
-
className: cn("flex flex-col items-center gap-3", className),
|
|
1653
|
-
...props,
|
|
1654
|
-
children: [
|
|
1655
|
-
/* @__PURE__ */ jsx("div", { className: loadingSpinnerVariants({ size, variant }) }),
|
|
1656
|
-
/* @__PURE__ */ jsxs("p", { className: "text-sm text-muted-foreground", children: [
|
|
1657
|
-
label,
|
|
1658
|
-
showDots && /* @__PURE__ */ jsx("span", { className: "inline-block w-4", children: dots })
|
|
1659
|
-
] })
|
|
1660
|
-
]
|
|
1661
|
-
}
|
|
1662
|
-
);
|
|
1663
|
-
}
|
|
1664
|
-
return /* @__PURE__ */ jsx(
|
|
1665
|
-
"div",
|
|
1666
|
-
{
|
|
1667
|
-
ref,
|
|
1668
|
-
className: cn(loadingSpinnerVariants({ size, variant }), className),
|
|
1669
|
-
...props
|
|
1670
|
-
}
|
|
1671
|
-
);
|
|
1672
|
-
}
|
|
1673
|
-
);
|
|
1674
|
-
LoadingSpinner.displayName = "LoadingSpinner";
|
|
1675
2620
|
function Toaster({
|
|
1676
2621
|
position = "top-right",
|
|
1677
2622
|
expand = false,
|
|
@@ -1734,12 +2679,12 @@ function Calendar({
|
|
|
1734
2679
|
const endMonth = props.endMonth ?? props.toDate;
|
|
1735
2680
|
const fromYear = startMonth?.getFullYear();
|
|
1736
2681
|
const toYear = endMonth?.getFullYear();
|
|
1737
|
-
const years =
|
|
1738
|
-
const [internalMonth, setInternalMonth] =
|
|
2682
|
+
const years = React20.useMemo(() => getYearRange(fromYear, toYear), [fromYear, toYear]);
|
|
2683
|
+
const [internalMonth, setInternalMonth] = React20.useState(
|
|
1739
2684
|
defaultMonth ?? /* @__PURE__ */ new Date()
|
|
1740
2685
|
);
|
|
1741
2686
|
const displayedMonth = controlledMonth ?? internalMonth;
|
|
1742
|
-
const handleMonthChange =
|
|
2687
|
+
const handleMonthChange = React20.useCallback(
|
|
1743
2688
|
(newMonth) => {
|
|
1744
2689
|
if (controlledMonth === void 0) {
|
|
1745
2690
|
setInternalMonth(newMonth);
|
|
@@ -1870,8 +2815,8 @@ function DatePicker({
|
|
|
1870
2815
|
matchTriggerWidth = false,
|
|
1871
2816
|
onOpenChange
|
|
1872
2817
|
}) {
|
|
1873
|
-
const [open, setOpen] =
|
|
1874
|
-
const [internalValue, setInternalValue] =
|
|
2818
|
+
const [open, setOpen] = React20.useState(false);
|
|
2819
|
+
const [internalValue, setInternalValue] = React20.useState(
|
|
1875
2820
|
defaultValue
|
|
1876
2821
|
);
|
|
1877
2822
|
const isControlled = value !== void 0;
|
|
@@ -1973,15 +2918,15 @@ function DatePickerInput({
|
|
|
1973
2918
|
onOpenChange,
|
|
1974
2919
|
size = "default"
|
|
1975
2920
|
}) {
|
|
1976
|
-
const [open, setOpen] =
|
|
1977
|
-
const [internalValue, setInternalValue] =
|
|
2921
|
+
const [open, setOpen] = React20.useState(false);
|
|
2922
|
+
const [internalValue, setInternalValue] = React20.useState(
|
|
1978
2923
|
defaultValue
|
|
1979
2924
|
);
|
|
1980
|
-
const [inputValue, setInputValue] =
|
|
1981
|
-
const inputRef =
|
|
2925
|
+
const [inputValue, setInputValue] = React20.useState("");
|
|
2926
|
+
const inputRef = React20.useRef(null);
|
|
1982
2927
|
const isControlled = value !== void 0;
|
|
1983
2928
|
const selectedDate = isControlled ? value : internalValue;
|
|
1984
|
-
|
|
2929
|
+
React20.useEffect(() => {
|
|
1985
2930
|
if (selectedDate) {
|
|
1986
2931
|
setInputValue(format(selectedDate, dateFormat));
|
|
1987
2932
|
} else {
|
|
@@ -2142,11 +3087,11 @@ function FilterPopover({
|
|
|
2142
3087
|
onFilterChange
|
|
2143
3088
|
}) {
|
|
2144
3089
|
const filterType = column.filterType || "text";
|
|
2145
|
-
const [operator, setOperator] =
|
|
3090
|
+
const [operator, setOperator] = React20.useState(
|
|
2146
3091
|
filter?.operator || getDefaultOperator(filterType)
|
|
2147
3092
|
);
|
|
2148
|
-
const [value, setValue] =
|
|
2149
|
-
const [valueTo, setValueTo] =
|
|
3093
|
+
const [value, setValue] = React20.useState(filter?.value ?? "");
|
|
3094
|
+
const [valueTo, setValueTo] = React20.useState(filter?.valueTo ?? "");
|
|
2150
3095
|
function getDefaultOperator(type) {
|
|
2151
3096
|
switch (type) {
|
|
2152
3097
|
case "text":
|
|
@@ -2289,7 +3234,7 @@ function FilterPopover({
|
|
|
2289
3234
|
] })
|
|
2290
3235
|
] });
|
|
2291
3236
|
const renderDateFilter = () => {
|
|
2292
|
-
const dateValue =
|
|
3237
|
+
const dateValue = React20.useMemo(() => {
|
|
2293
3238
|
if (!value) return void 0;
|
|
2294
3239
|
if (value instanceof Date) return value;
|
|
2295
3240
|
if (typeof value === "string") {
|
|
@@ -2298,7 +3243,7 @@ function FilterPopover({
|
|
|
2298
3243
|
}
|
|
2299
3244
|
return void 0;
|
|
2300
3245
|
}, [value]);
|
|
2301
|
-
const dateToValue =
|
|
3246
|
+
const dateToValue = React20.useMemo(() => {
|
|
2302
3247
|
if (!valueTo) return void 0;
|
|
2303
3248
|
if (valueTo instanceof Date) return valueTo;
|
|
2304
3249
|
if (typeof valueTo === "string") {
|
|
@@ -2433,7 +3378,7 @@ function HeaderCell({
|
|
|
2433
3378
|
onResizeDoubleClick,
|
|
2434
3379
|
isResizing
|
|
2435
3380
|
}) {
|
|
2436
|
-
const [filterOpen, setFilterOpen] =
|
|
3381
|
+
const [filterOpen, setFilterOpen] = React20.useState(false);
|
|
2437
3382
|
const isSorted = sorting?.field === column.key;
|
|
2438
3383
|
const isFiltered = !!filter;
|
|
2439
3384
|
const isSortable = column.sortable && onSort;
|
|
@@ -2591,15 +3536,15 @@ function CellEditor({
|
|
|
2591
3536
|
className
|
|
2592
3537
|
}) {
|
|
2593
3538
|
const editorType = column.editorType || "text";
|
|
2594
|
-
const [internalValue, setInternalValue] =
|
|
2595
|
-
const [validationError, setValidationError] =
|
|
3539
|
+
const [internalValue, setInternalValue] = React20.useState(value);
|
|
3540
|
+
const [validationError, setValidationError] = React20.useState(
|
|
2596
3541
|
null
|
|
2597
3542
|
);
|
|
2598
|
-
const inputRef =
|
|
2599
|
-
const selectRef =
|
|
3543
|
+
const inputRef = React20.useRef(null);
|
|
3544
|
+
const selectRef = React20.useRef(null);
|
|
2600
3545
|
const currentValue = onChange ? value : internalValue;
|
|
2601
3546
|
const setValue = onChange || setInternalValue;
|
|
2602
|
-
const validate =
|
|
3547
|
+
const validate = React20.useCallback(
|
|
2603
3548
|
(val) => {
|
|
2604
3549
|
if (!column.validator) return true;
|
|
2605
3550
|
const result = column.validator(val, row);
|
|
@@ -2647,7 +3592,7 @@ function CellEditor({
|
|
|
2647
3592
|
}
|
|
2648
3593
|
handleCommit();
|
|
2649
3594
|
};
|
|
2650
|
-
|
|
3595
|
+
React20.useEffect(() => {
|
|
2651
3596
|
const timer = setTimeout(() => {
|
|
2652
3597
|
if (editorType === "select") {
|
|
2653
3598
|
selectRef.current?.focus();
|
|
@@ -2694,7 +3639,7 @@ function CellEditor({
|
|
|
2694
3639
|
}
|
|
2695
3640
|
);
|
|
2696
3641
|
const renderDateEditor = () => {
|
|
2697
|
-
const dateValue =
|
|
3642
|
+
const dateValue = React20.useMemo(() => {
|
|
2698
3643
|
if (!currentValue) return void 0;
|
|
2699
3644
|
if (currentValue instanceof Date) return currentValue;
|
|
2700
3645
|
if (typeof currentValue === "string") {
|
|
@@ -3742,15 +4687,15 @@ function DataGrid({
|
|
|
3742
4687
|
hasMore = false,
|
|
3743
4688
|
loadingMore = false
|
|
3744
4689
|
}) {
|
|
3745
|
-
const parentRef =
|
|
3746
|
-
const headerRef =
|
|
3747
|
-
const [headerHeight, setHeaderHeight] =
|
|
3748
|
-
const [hoveredCell, setHoveredCell] =
|
|
3749
|
-
const visibleColumns =
|
|
4690
|
+
const parentRef = React20.useRef(null);
|
|
4691
|
+
const headerRef = React20.useRef(null);
|
|
4692
|
+
const [headerHeight, setHeaderHeight] = React20.useState(40);
|
|
4693
|
+
const [hoveredCell, setHoveredCell] = React20.useState(null);
|
|
4694
|
+
const visibleColumns = React20.useMemo(
|
|
3750
4695
|
() => columns.filter((col) => !col.hidden),
|
|
3751
4696
|
[columns]
|
|
3752
4697
|
);
|
|
3753
|
-
const getCellValue2 =
|
|
4698
|
+
const getCellValue2 = React20.useCallback(
|
|
3754
4699
|
(row, column) => {
|
|
3755
4700
|
if (column.accessor) {
|
|
3756
4701
|
return column.accessor(row);
|
|
@@ -3779,7 +4724,7 @@ function DataGrid({
|
|
|
3779
4724
|
data,
|
|
3780
4725
|
getCellValue: getCellValue2
|
|
3781
4726
|
});
|
|
3782
|
-
const processedData =
|
|
4727
|
+
const processedData = React20.useMemo(() => {
|
|
3783
4728
|
let result = data;
|
|
3784
4729
|
if (enableInternalFiltering && !isControlled.filters && state.filters.length > 0) {
|
|
3785
4730
|
result = applyFilters(result, state.filters, visibleColumns);
|
|
@@ -3807,7 +4752,7 @@ function DataGrid({
|
|
|
3807
4752
|
onColumnResizeEnd
|
|
3808
4753
|
});
|
|
3809
4754
|
const shouldVirtualize = virtualized ?? processedData.length > 100;
|
|
3810
|
-
|
|
4755
|
+
React20.useLayoutEffect(() => {
|
|
3811
4756
|
if (headerRef.current && shouldVirtualize) {
|
|
3812
4757
|
setHeaderHeight(headerRef.current.offsetHeight);
|
|
3813
4758
|
}
|
|
@@ -3819,13 +4764,13 @@ function DataGrid({
|
|
|
3819
4764
|
overscan: DEFAULT_OVERSCAN,
|
|
3820
4765
|
enabled: shouldVirtualize
|
|
3821
4766
|
});
|
|
3822
|
-
const tableWidth =
|
|
4767
|
+
const tableWidth = React20.useMemo(() => {
|
|
3823
4768
|
return visibleColumns.reduce((acc, col) => {
|
|
3824
4769
|
const width = state.columnWidths[col.key] || col.width || estimateColumnWidth(col);
|
|
3825
4770
|
return acc + width;
|
|
3826
4771
|
}, 0);
|
|
3827
4772
|
}, [visibleColumns, state.columnWidths]);
|
|
3828
|
-
const visibleRowCount =
|
|
4773
|
+
const visibleRowCount = React20.useMemo(() => {
|
|
3829
4774
|
if (!parentRef.current) return 10;
|
|
3830
4775
|
return Math.floor(parentRef.current.clientHeight / DEFAULT_ROW_HEIGHT);
|
|
3831
4776
|
}, []);
|
|
@@ -3844,7 +4789,7 @@ function DataGrid({
|
|
|
3844
4789
|
rowVirtualizer.scrollToIndex(rowIndex, { align: "auto" });
|
|
3845
4790
|
}
|
|
3846
4791
|
});
|
|
3847
|
-
const handleBlur =
|
|
4792
|
+
const handleBlur = React20.useCallback(
|
|
3848
4793
|
(event) => {
|
|
3849
4794
|
const target = event.target;
|
|
3850
4795
|
const relatedTarget = event.relatedTarget;
|
|
@@ -3902,7 +4847,7 @@ function DataGrid({
|
|
|
3902
4847
|
},
|
|
3903
4848
|
[state.editingCell, actions]
|
|
3904
4849
|
);
|
|
3905
|
-
|
|
4850
|
+
React20.useEffect(() => {
|
|
3906
4851
|
if (!infiniteScroll || !hasMore || loadingMore || !parentRef.current) return;
|
|
3907
4852
|
const observer = new IntersectionObserver(
|
|
3908
4853
|
(entries) => {
|
|
@@ -4346,7 +5291,7 @@ function DataGrid({
|
|
|
4346
5291
|
);
|
|
4347
5292
|
}
|
|
4348
5293
|
function PaginationFooter({ pagination }) {
|
|
4349
|
-
const [goToPage, setGoToPage] =
|
|
5294
|
+
const [goToPage, setGoToPage] = React20.useState("");
|
|
4350
5295
|
const handleGoToPage = () => {
|
|
4351
5296
|
const page = parseInt(goToPage, 10);
|
|
4352
5297
|
if (!isNaN(page) && page >= 1 && page <= pagination.totalPages) {
|
|
@@ -4464,21 +5409,21 @@ function Autocomplete({
|
|
|
4464
5409
|
className,
|
|
4465
5410
|
clearable = false
|
|
4466
5411
|
}) {
|
|
4467
|
-
const [open, setOpen] =
|
|
4468
|
-
const [search, setSearch] =
|
|
4469
|
-
const inputRef =
|
|
4470
|
-
const selectedOption =
|
|
5412
|
+
const [open, setOpen] = React20.useState(false);
|
|
5413
|
+
const [search, setSearch] = React20.useState("");
|
|
5414
|
+
const inputRef = React20.useRef(null);
|
|
5415
|
+
const selectedOption = React20.useMemo(
|
|
4471
5416
|
() => options.find((opt) => opt.value === value),
|
|
4472
5417
|
[options, value]
|
|
4473
5418
|
);
|
|
4474
|
-
const filteredOptions =
|
|
5419
|
+
const filteredOptions = React20.useMemo(() => {
|
|
4475
5420
|
if (!search.trim()) return options;
|
|
4476
5421
|
const searchLower = search.toLowerCase();
|
|
4477
5422
|
return options.filter(
|
|
4478
5423
|
(opt) => opt.label.toLowerCase().includes(searchLower) || opt.description?.toLowerCase().includes(searchLower)
|
|
4479
5424
|
);
|
|
4480
5425
|
}, [options, search]);
|
|
4481
|
-
const groupedOptions =
|
|
5426
|
+
const groupedOptions = React20.useMemo(() => {
|
|
4482
5427
|
const groups = {};
|
|
4483
5428
|
const ungrouped = [];
|
|
4484
5429
|
filteredOptions.forEach((opt) => {
|
|
@@ -4492,7 +5437,7 @@ function Autocomplete({
|
|
|
4492
5437
|
return { groups, ungrouped };
|
|
4493
5438
|
}, [filteredOptions]);
|
|
4494
5439
|
const hasGroups = Object.keys(groupedOptions.groups).length > 0;
|
|
4495
|
-
const handleSelect =
|
|
5440
|
+
const handleSelect = React20.useCallback(
|
|
4496
5441
|
(optionValue) => {
|
|
4497
5442
|
onChange?.(optionValue);
|
|
4498
5443
|
setOpen(false);
|
|
@@ -4500,7 +5445,7 @@ function Autocomplete({
|
|
|
4500
5445
|
},
|
|
4501
5446
|
[onChange]
|
|
4502
5447
|
);
|
|
4503
|
-
const handleClear =
|
|
5448
|
+
const handleClear = React20.useCallback(
|
|
4504
5449
|
(e) => {
|
|
4505
5450
|
e.stopPropagation();
|
|
4506
5451
|
onChange?.(void 0);
|
|
@@ -4508,7 +5453,7 @@ function Autocomplete({
|
|
|
4508
5453
|
},
|
|
4509
5454
|
[onChange]
|
|
4510
5455
|
);
|
|
4511
|
-
|
|
5456
|
+
React20.useEffect(() => {
|
|
4512
5457
|
if (open) {
|
|
4513
5458
|
const timeout = setTimeout(() => {
|
|
4514
5459
|
inputRef.current?.focus();
|
|
@@ -4518,7 +5463,7 @@ function Autocomplete({
|
|
|
4518
5463
|
setSearch("");
|
|
4519
5464
|
}
|
|
4520
5465
|
}, [open]);
|
|
4521
|
-
const handleKeyDown =
|
|
5466
|
+
const handleKeyDown = React20.useCallback((e) => {
|
|
4522
5467
|
if (e.key === "Escape") {
|
|
4523
5468
|
setOpen(false);
|
|
4524
5469
|
}
|
|
@@ -4694,7 +5639,7 @@ var iconButtonVariants = cva(
|
|
|
4694
5639
|
}
|
|
4695
5640
|
}
|
|
4696
5641
|
);
|
|
4697
|
-
var IconButton =
|
|
5642
|
+
var IconButton = React20.forwardRef(
|
|
4698
5643
|
({ className, variant, size, isActive = false, icon, children, ...props }, ref) => {
|
|
4699
5644
|
return /* @__PURE__ */ jsx(
|
|
4700
5645
|
"button",
|
|
@@ -4718,7 +5663,7 @@ var IconButton = React33.forwardRef(
|
|
|
4718
5663
|
);
|
|
4719
5664
|
IconButton.displayName = "IconButton";
|
|
4720
5665
|
function CopyButton({ content, className, size = "md" }) {
|
|
4721
|
-
const [copied, setCopied] =
|
|
5666
|
+
const [copied, setCopied] = React20.useState(false);
|
|
4722
5667
|
const handleCopy = async () => {
|
|
4723
5668
|
try {
|
|
4724
5669
|
await navigator.clipboard.writeText(content);
|
|
@@ -5491,11 +6436,11 @@ function ThemePicker({
|
|
|
5491
6436
|
align = "end",
|
|
5492
6437
|
side = "bottom"
|
|
5493
6438
|
}) {
|
|
5494
|
-
const [open, setOpen] =
|
|
5495
|
-
const [selectedTheme, setSelectedTheme] =
|
|
6439
|
+
const [open, setOpen] = React20.useState(false);
|
|
6440
|
+
const [selectedTheme, setSelectedTheme] = React20.useState(
|
|
5496
6441
|
value || themes[0]
|
|
5497
6442
|
);
|
|
5498
|
-
|
|
6443
|
+
React20.useEffect(() => {
|
|
5499
6444
|
if (value) {
|
|
5500
6445
|
setSelectedTheme(value);
|
|
5501
6446
|
}
|
|
@@ -5605,19 +6550,19 @@ function getSafePosition(x, y, menuWidth, menuHeight) {
|
|
|
5605
6550
|
return { x: safeX, y: safeY };
|
|
5606
6551
|
}
|
|
5607
6552
|
function MenuItem({ item, onClose, depth = 0 }) {
|
|
5608
|
-
const [isSubmenuOpen, setIsSubmenuOpen] =
|
|
5609
|
-
const [submenuPosition, setSubmenuPosition] =
|
|
5610
|
-
const itemRef =
|
|
5611
|
-
const hoverTimeoutRef =
|
|
6553
|
+
const [isSubmenuOpen, setIsSubmenuOpen] = React20.useState(false);
|
|
6554
|
+
const [submenuPosition, setSubmenuPosition] = React20.useState(null);
|
|
6555
|
+
const itemRef = React20.useRef(null);
|
|
6556
|
+
const hoverTimeoutRef = React20.useRef(null);
|
|
5612
6557
|
const hasSubmenu = item.submenu && item.submenu.length > 0;
|
|
5613
|
-
|
|
6558
|
+
React20.useEffect(() => {
|
|
5614
6559
|
return () => {
|
|
5615
6560
|
if (hoverTimeoutRef.current) {
|
|
5616
6561
|
clearTimeout(hoverTimeoutRef.current);
|
|
5617
6562
|
}
|
|
5618
6563
|
};
|
|
5619
6564
|
}, []);
|
|
5620
|
-
const handleMouseEnter =
|
|
6565
|
+
const handleMouseEnter = React20.useCallback(() => {
|
|
5621
6566
|
if (hoverTimeoutRef.current) {
|
|
5622
6567
|
clearTimeout(hoverTimeoutRef.current);
|
|
5623
6568
|
}
|
|
@@ -5637,22 +6582,22 @@ function MenuItem({ item, onClose, depth = 0 }) {
|
|
|
5637
6582
|
setIsSubmenuOpen(true);
|
|
5638
6583
|
}
|
|
5639
6584
|
}, [hasSubmenu, item.submenu?.length]);
|
|
5640
|
-
const handleMouseLeave =
|
|
6585
|
+
const handleMouseLeave = React20.useCallback(() => {
|
|
5641
6586
|
hoverTimeoutRef.current = setTimeout(() => {
|
|
5642
6587
|
setIsSubmenuOpen(false);
|
|
5643
6588
|
}, 100);
|
|
5644
6589
|
}, []);
|
|
5645
|
-
const handleSubmenuMouseEnter =
|
|
6590
|
+
const handleSubmenuMouseEnter = React20.useCallback(() => {
|
|
5646
6591
|
if (hoverTimeoutRef.current) {
|
|
5647
6592
|
clearTimeout(hoverTimeoutRef.current);
|
|
5648
6593
|
}
|
|
5649
6594
|
}, []);
|
|
5650
|
-
const handleSubmenuMouseLeave =
|
|
6595
|
+
const handleSubmenuMouseLeave = React20.useCallback(() => {
|
|
5651
6596
|
hoverTimeoutRef.current = setTimeout(() => {
|
|
5652
6597
|
setIsSubmenuOpen(false);
|
|
5653
6598
|
}, 100);
|
|
5654
6599
|
}, []);
|
|
5655
|
-
const handleClick =
|
|
6600
|
+
const handleClick = React20.useCallback(() => {
|
|
5656
6601
|
if (item.disabled) return;
|
|
5657
6602
|
if (!hasSubmenu && item.action) {
|
|
5658
6603
|
item.action();
|
|
@@ -5732,12 +6677,12 @@ function ContextMenu({
|
|
|
5732
6677
|
anchorEl,
|
|
5733
6678
|
className
|
|
5734
6679
|
}) {
|
|
5735
|
-
const menuRef =
|
|
5736
|
-
const [menuPosition, setMenuPosition] =
|
|
6680
|
+
const menuRef = React20.useRef(null);
|
|
6681
|
+
const [menuPosition, setMenuPosition] = React20.useState({
|
|
5737
6682
|
x: 0,
|
|
5738
6683
|
y: 0
|
|
5739
6684
|
});
|
|
5740
|
-
|
|
6685
|
+
React20.useEffect(() => {
|
|
5741
6686
|
if (!isOpen) return;
|
|
5742
6687
|
let x = position.x;
|
|
5743
6688
|
let y = position.y;
|
|
@@ -5756,7 +6701,7 @@ function ContextMenu({
|
|
|
5756
6701
|
}
|
|
5757
6702
|
});
|
|
5758
6703
|
}, [isOpen, position, anchorEl]);
|
|
5759
|
-
|
|
6704
|
+
React20.useEffect(() => {
|
|
5760
6705
|
if (!isOpen) return;
|
|
5761
6706
|
const handleClickOutside = (e) => {
|
|
5762
6707
|
if (menuRef.current && !menuRef.current.contains(e.target)) {
|
|
@@ -5800,16 +6745,16 @@ function ContextMenu({
|
|
|
5800
6745
|
);
|
|
5801
6746
|
}
|
|
5802
6747
|
function useContextMenu() {
|
|
5803
|
-
const [isOpen, setIsOpen] =
|
|
5804
|
-
const [position, setPosition] =
|
|
5805
|
-
const [targetItem, setTargetItem] =
|
|
5806
|
-
const menuRef =
|
|
5807
|
-
const openMenu =
|
|
6748
|
+
const [isOpen, setIsOpen] = React20.useState(false);
|
|
6749
|
+
const [position, setPosition] = React20.useState({ x: 0, y: 0 });
|
|
6750
|
+
const [targetItem, setTargetItem] = React20.useState(null);
|
|
6751
|
+
const menuRef = React20.useRef(null);
|
|
6752
|
+
const openMenu = React20.useCallback((x, y, item) => {
|
|
5808
6753
|
setPosition({ x, y });
|
|
5809
6754
|
setTargetItem(item);
|
|
5810
6755
|
setIsOpen(true);
|
|
5811
6756
|
}, []);
|
|
5812
|
-
const closeMenu =
|
|
6757
|
+
const closeMenu = React20.useCallback(() => {
|
|
5813
6758
|
setIsOpen(false);
|
|
5814
6759
|
setTargetItem(null);
|
|
5815
6760
|
}, []);
|
|
@@ -5823,6 +6768,6 @@ function useContextMenu() {
|
|
|
5823
6768
|
};
|
|
5824
6769
|
}
|
|
5825
6770
|
|
|
5826
|
-
export { ALL_THEMES, Accordion, AccordionContent, AccordionItem, AccordionTrigger, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, Autocomplete, Badge, Button, CYBERPUNK_THEME, Calendar, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, CellEditor, Checkbox, Chip, ConfirmationModal, ContextMenu, CopyButton, DARK_ELEGANT_THEME, DataGrid, DatePicker, DatePickerInput, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, FOREST_THEME, FUTURISTIC_THEME, FilterPopover, GREEN_THEME, HeaderCell, IconButton, Input, Label, LoadingSpinner, MINIMALIST_LIGHT_THEME, Modal, ModalButton, NATURE_THEME, OCEAN_THEME, OPTILOGIC_LEGACY_THEME, PRESET_THEMES, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, Progress, ResizablePanel, ResizeHandle, SCIFI_THEME, SUNSET_THEME, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator, Skeleton, Switch, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, ThemePicker, Toaster, Tooltip, TooltipArrow, TooltipContent, TooltipPortal, TooltipProvider, TooltipRoot, TooltipTrigger, accordionContentVariants, accordionItemVariants, accordionTriggerVariants, applyFilterOperator, applyFilters, applySorting, applyTheme, areThemesEqual, badgeVariants, buttonVariants, cloneTheme, cn, exportTheme, getCellValue, getCurrentTheme, getDefaultTheme, getPresetTheme, hexToHsl, iconButtonVariants, importTheme, isPresetTheme, labelVariants, loadingSpinnerVariants, themeToHsl, useColumnResize, useColumnResizeManager, useConfirmation, useContextMenu, useDataGridState, useKeyboardNavigation, validateTheme };
|
|
6771
|
+
export { ALL_THEMES, Accordion, AccordionContent, AccordionItem, AccordionTrigger, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, Autocomplete, Badge, Board, BoardContent, BoardHeader, Button, CYBERPUNK_THEME, Calendar, Card, CardActions, CardContent, CardDescription, CardFooter, CardGrid, CardHeader, CardImage, CardList, CardTitle, CellEditor, Checkbox, Chip, ConfirmationModal, ContextMenu, CopyButton, DARK_ELEGANT_THEME, DataGrid, DataTable, DatePicker, DatePickerInput, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, FOREST_THEME, FUTURISTIC_THEME, FilterPopover, GREEN_THEME, HeaderCell, IconButton, Input, Label, LoadingSpinner, MINIMALIST_LIGHT_THEME, Modal, ModalButton, NATURE_THEME, OCEAN_THEME, OPTILOGIC_LEGACY_THEME, PRESET_THEMES, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, Progress, ResizablePanel, ResizeHandle, SCIFI_THEME, SUNSET_THEME, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, SelectableCard, Separator, Skeleton, Switch, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, ThemePicker, Toaster, Tooltip, TooltipArrow, TooltipContent, TooltipPortal, TooltipProvider, TooltipRoot, TooltipTrigger, accordionContentVariants, accordionItemVariants, accordionTriggerVariants, applyFilterOperator, applyFilters, applySorting, applyTheme, areThemesEqual, badgeVariants, boardVariants, buttonVariants, cardActionsVariants, cardGridVariants, cardImageVariants, cardListVariants, cardVariants, cloneTheme, cn, exportTheme, getCellValue, getCurrentTheme, getDefaultTheme, getPresetTheme, hexToHsl, iconButtonVariants, importTheme, isPresetTheme, labelVariants, loadingSpinnerVariants, themeToHsl, useColumnResize, useColumnResizeManager, useConfirmation, useContextMenu, useDataGridState, useKeyboardNavigation, validateTheme };
|
|
5827
6772
|
//# sourceMappingURL=index.js.map
|
|
5828
6773
|
//# sourceMappingURL=index.js.map
|