@krak-stack/registry 0.1.19 → 0.1.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/dist/components/ui/code-block.d.ts +1 -3
  2. package/dist/components/ui/code-block.js +32 -60
  3. package/dist/components/ui/data-table.d.ts +202 -273
  4. package/dist/components/ui/data-table.js +1810 -2115
  5. package/dist/components/ui/effect-form.js +169 -170
  6. package/dist/components/ui/form.js +112 -113
  7. package/dist/components/ui/icon-input.js +40 -43
  8. package/dist/components/ui/menubar.d.ts +29 -0
  9. package/dist/components/ui/pagination.js +2 -2
  10. package/dist/components/ui/sidebar-layout.js +67 -72
  11. package/dist/components/ui/theme-switcher.js +3 -3
  12. package/dist/components/ui/virtualized-combobox.js +31 -34
  13. package/dist/lib/{docs-core.d.ts → docs.d.ts} +135 -144
  14. package/dist/lib/{docs-core.js → docs.js} +597 -440
  15. package/dist/lib/documentation-toolkit.d.ts +19 -1
  16. package/dist/lib/documentation-toolkit.js +164 -66
  17. package/dist/lib/httpapi-cli.d.ts +5 -4
  18. package/dist/lib/httpapi-cli.js +256 -34
  19. package/dist/lib/httpapi-client.js +3 -3
  20. package/dist/lib/httpapi-helpers.d.ts +8 -6
  21. package/dist/lib/httpapi-helpers.js +12 -12
  22. package/dist/lib/httpapi-mcp.js +3 -3
  23. package/dist/lib/httpapi-toolkit.js +3 -3
  24. package/dist/lib/markdown/content.d.ts +13 -0
  25. package/dist/lib/markdown/server.d.ts +19 -0
  26. package/dist/lib/query.js +6 -6
  27. package/dist/lib/seo.js +2 -2
  28. package/dist/lib/webfetch-toolkit.js +6 -6
  29. package/dist/services/agent/client/atom.d.ts +7 -0
  30. package/dist/services/agent/client/index.js +481 -304
  31. package/dist/services/agent/index.d.ts +16 -0
  32. package/dist/services/agent/index.js +102 -1
  33. package/dist/services/agent/schema.d.ts +28 -0
  34. package/dist/services/agent/schema.js +15 -4
  35. package/dist/services/file-extraction/index.js +4 -4
  36. package/dist/services/file-extraction/schema.js +2 -2
  37. package/dist/services/health/index.js +9 -9
  38. package/dist/services/notification/channels/ses/index.js +2 -2
  39. package/dist/services/notification/channels/ses/schema.js +2 -2
  40. package/dist/services/notification/client/index.js +5 -5
  41. package/dist/services/notification/index.js +2 -2
  42. package/dist/services/notification/persistence/drizzle.js +2 -2
  43. package/dist/services/notification/persistence/index.js +15 -15
  44. package/dist/services/notification/persistence/schema.js +12 -12
  45. package/dist/services/notification/public.js +7 -7
  46. package/dist/services/notification/schema.js +2 -2
  47. package/dist/services/s3/index.js +2 -2
  48. package/dist/services/s3/schema.js +2 -2
  49. package/package.json +6 -38
@@ -1,3 +1,36 @@
1
+ // ../../src/components/ui/data-table.tsx
2
+ import { useAtom, useAtomSet } from "@effect/atom-react";
3
+ import { Schema } from "effect";
4
+ import { Atom } from "effect/unstable/reactivity";
5
+ import {
6
+ ArrowDown,
7
+ ArrowUp,
8
+ ChevronDown,
9
+ ChevronRight as ChevronRight2,
10
+ ChevronsUpDown as ChevronsUpDown2,
11
+ Download,
12
+ EyeOff,
13
+ FileJson,
14
+ FileText,
15
+ GripVertical,
16
+ LayoutGrid,
17
+ MoreHorizontal,
18
+ RefreshCw,
19
+ Rows3,
20
+ Search,
21
+ Settings2,
22
+ X as X2
23
+ } from "lucide-react";
24
+ import {
25
+ createContext,
26
+ isValidElement,
27
+ useContext,
28
+ useLayoutEffect,
29
+ useRef as useRef2,
30
+ useState
31
+ } from "react";
32
+ import { createPortal } from "react-dom";
33
+
1
34
  // ../../src/components/ui/badge.tsx
2
35
  import { mergeProps } from "@base-ui/react/merge-props";
3
36
  import { useRender } from "@base-ui/react/use-render";
@@ -88,32 +121,14 @@ function Button({
88
121
  });
89
122
  }
90
123
 
91
- // ../../src/components/ui/checkbox.tsx
92
- import { Checkbox as CheckboxPrimitive } from "@base-ui/react/checkbox";
93
- import { CheckIcon } from "lucide-react";
94
- import { jsx as jsx2 } from "react/jsx-runtime";
95
- "use client";
96
- function Checkbox({ className, ...props }) {
97
- return /* @__PURE__ */ jsx2(CheckboxPrimitive.Root, {
98
- "data-slot": "checkbox",
99
- className: cn("peer relative flex size-4 shrink-0 items-center justify-center rounded-[4px] border border-input shadow-xs transition-shadow outline-none group-has-disabled/field:opacity-50 after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 aria-invalid:aria-checked:border-primary dark:bg-input/30 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 data-checked:border-primary data-checked:bg-primary data-checked:text-primary-foreground dark:data-checked:bg-primary", className),
100
- ...props,
101
- children: /* @__PURE__ */ jsx2(CheckboxPrimitive.Indicator, {
102
- "data-slot": "checkbox-indicator",
103
- className: "grid place-content-center text-current transition-none [&>svg]:size-3.5",
104
- children: /* @__PURE__ */ jsx2(CheckIcon, {})
105
- })
106
- });
107
- }
108
-
109
124
  // ../../src/components/ui/card.tsx
110
- import { jsx as jsx3 } from "react/jsx-runtime";
125
+ import { jsx as jsx2 } from "react/jsx-runtime";
111
126
  function Card({
112
127
  className,
113
128
  size = "default",
114
129
  ...props
115
130
  }) {
116
- return /* @__PURE__ */ jsx3("div", {
131
+ return /* @__PURE__ */ jsx2("div", {
117
132
  "data-slot": "card",
118
133
  "data-size": size,
119
134
  className: cn("group/card flex flex-col gap-(--card-spacing) overflow-hidden rounded-xl bg-card py-(--card-spacing) text-sm text-card-foreground shadow-xs ring-1 ring-foreground/10 [--card-spacing:--spacing(6)] has-[>img:first-child]:pt-0 data-[size=sm]:[--card-spacing:--spacing(4)] *:[img:first-child]:rounded-t-xl *:[img:last-child]:rounded-b-xl", className),
@@ -121,38 +136,35 @@ function Card({
121
136
  });
122
137
  }
123
138
  function CardHeader({ className, ...props }) {
124
- return /* @__PURE__ */ jsx3("div", {
139
+ return /* @__PURE__ */ jsx2("div", {
125
140
  "data-slot": "card-header",
126
141
  className: cn("group/card-header @container/card-header grid auto-rows-min items-start gap-1 rounded-t-xl px-(--card-spacing) has-data-[slot=card-action]:grid-cols-[1fr_auto] has-data-[slot=card-description]:grid-rows-[auto_auto] [.border-b]:pb-(--card-spacing)", className),
127
142
  ...props
128
143
  });
129
144
  }
130
145
  function CardTitle({ className, ...props }) {
131
- return /* @__PURE__ */ jsx3("div", {
146
+ return /* @__PURE__ */ jsx2("div", {
132
147
  "data-slot": "card-title",
133
148
  className: cn("text-base leading-normal font-medium group-data-[size=sm]/card:text-sm", className),
134
149
  ...props
135
150
  });
136
151
  }
137
- function CardDescription({ className, ...props }) {
138
- return /* @__PURE__ */ jsx3("div", {
139
- "data-slot": "card-description",
140
- className: cn("text-sm text-muted-foreground", className),
141
- ...props
142
- });
143
- }
144
- function CardAction({ className, ...props }) {
145
- return /* @__PURE__ */ jsx3("div", {
146
- "data-slot": "card-action",
147
- className: cn("col-start-2 row-span-2 row-start-1 self-start justify-self-end", className),
148
- ...props
149
- });
150
- }
151
- function CardContent({ className, ...props }) {
152
- return /* @__PURE__ */ jsx3("div", {
153
- "data-slot": "card-content",
154
- className: cn("px-(--card-spacing)", className),
155
- ...props
152
+
153
+ // ../../src/components/ui/checkbox.tsx
154
+ import { Checkbox as CheckboxPrimitive } from "@base-ui/react/checkbox";
155
+ import { CheckIcon } from "lucide-react";
156
+ import { jsx as jsx3 } from "react/jsx-runtime";
157
+ "use client";
158
+ function Checkbox({ className, ...props }) {
159
+ return /* @__PURE__ */ jsx3(CheckboxPrimitive.Root, {
160
+ "data-slot": "checkbox",
161
+ className: cn("peer relative flex size-4 shrink-0 items-center justify-center rounded-[4px] border border-input shadow-xs transition-shadow outline-none group-has-disabled/field:opacity-50 after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 aria-invalid:aria-checked:border-primary dark:bg-input/30 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 data-checked:border-primary data-checked:bg-primary data-checked:text-primary-foreground dark:data-checked:bg-primary", className),
162
+ ...props,
163
+ children: /* @__PURE__ */ jsx3(CheckboxPrimitive.Indicator, {
164
+ "data-slot": "checkbox-indicator",
165
+ className: "grid place-content-center text-current transition-none [&>svg]:size-3.5",
166
+ children: /* @__PURE__ */ jsx3(CheckIcon, {})
167
+ })
156
168
  });
157
169
  }
158
170
 
@@ -270,60 +282,12 @@ function DropdownMenuSubContent({
270
282
  ...props
271
283
  });
272
284
  }
273
- function DropdownMenuCheckboxItem({
274
- className,
275
- children,
276
- checked,
277
- inset,
278
- ...props
279
- }) {
280
- return /* @__PURE__ */ jsxs(MenuPrimitive.CheckboxItem, {
281
- "data-slot": "dropdown-menu-checkbox-item",
282
- "data-inset": inset,
283
- className: cn("relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground data-inset:pl-8 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", className),
284
- checked,
285
- ...props,
286
- children: [
287
- /* @__PURE__ */ jsx4("span", {
288
- className: "pointer-events-none absolute right-2 flex items-center justify-center",
289
- "data-slot": "dropdown-menu-checkbox-item-indicator",
290
- children: /* @__PURE__ */ jsx4(MenuPrimitive.CheckboxItemIndicator, {
291
- children: /* @__PURE__ */ jsx4(CheckIcon2, {})
292
- })
293
- }),
294
- children
295
- ]
296
- });
297
- }
298
285
  function DropdownMenuRadioGroup({ ...props }) {
299
286
  return /* @__PURE__ */ jsx4(MenuPrimitive.RadioGroup, {
300
287
  "data-slot": "dropdown-menu-radio-group",
301
288
  ...props
302
289
  });
303
290
  }
304
- function DropdownMenuRadioItem({
305
- className,
306
- children,
307
- inset,
308
- ...props
309
- }) {
310
- return /* @__PURE__ */ jsxs(MenuPrimitive.RadioItem, {
311
- "data-slot": "dropdown-menu-radio-item",
312
- "data-inset": inset,
313
- className: cn("relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground data-inset:pl-8 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", className),
314
- ...props,
315
- children: [
316
- /* @__PURE__ */ jsx4("span", {
317
- className: "pointer-events-none absolute right-2 flex items-center justify-center",
318
- "data-slot": "dropdown-menu-radio-item-indicator",
319
- children: /* @__PURE__ */ jsx4(MenuPrimitive.RadioItemIndicator, {
320
- children: /* @__PURE__ */ jsx4(CheckIcon2, {})
321
- })
322
- }),
323
- children
324
- ]
325
- });
326
- }
327
291
  function DropdownMenuSeparator({
328
292
  className,
329
293
  ...props
@@ -813,6 +777,180 @@ function Loading({
813
777
  });
814
778
  }
815
779
 
780
+ // ../../src/components/ui/menubar.tsx
781
+ import { Menu as MenuPrimitive2 } from "@base-ui/react/menu";
782
+ import { Menubar as MenubarPrimitive } from "@base-ui/react/menubar";
783
+ import { CheckIcon as CheckIcon3 } from "lucide-react";
784
+ import { jsx as jsx7, jsxs as jsxs3 } from "react/jsx-runtime";
785
+ "use client";
786
+ function Menubar({ className, ...props }) {
787
+ return /* @__PURE__ */ jsx7(MenubarPrimitive, {
788
+ "data-slot": "menubar",
789
+ className: cn("flex h-9 items-center gap-1 rounded-md border p-1 shadow-xs", className),
790
+ ...props
791
+ });
792
+ }
793
+ function MenubarMenu({ ...props }) {
794
+ return /* @__PURE__ */ jsx7(DropdownMenu, {
795
+ "data-slot": "menubar-menu",
796
+ ...props
797
+ });
798
+ }
799
+ function MenubarGroup({
800
+ ...props
801
+ }) {
802
+ return /* @__PURE__ */ jsx7(DropdownMenuGroup, {
803
+ "data-slot": "menubar-group",
804
+ ...props
805
+ });
806
+ }
807
+ function MenubarTrigger({
808
+ className,
809
+ ...props
810
+ }) {
811
+ return /* @__PURE__ */ jsx7(DropdownMenuTrigger, {
812
+ "data-slot": "menubar-trigger",
813
+ className: cn("flex items-center rounded-sm px-2 py-1 text-sm font-medium outline-hidden select-none hover:bg-muted aria-expanded:bg-muted", className),
814
+ ...props
815
+ });
816
+ }
817
+ function MenubarContent({
818
+ className,
819
+ align = "start",
820
+ alignOffset = -4,
821
+ sideOffset = 8,
822
+ ...props
823
+ }) {
824
+ return /* @__PURE__ */ jsx7(DropdownMenuContent, {
825
+ "data-slot": "menubar-content",
826
+ align,
827
+ alignOffset,
828
+ sideOffset,
829
+ className: cn("min-w-36 rounded-md bg-popover p-1 text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95", className),
830
+ ...props
831
+ });
832
+ }
833
+ function MenubarItem({
834
+ className,
835
+ inset,
836
+ variant = "default",
837
+ ...props
838
+ }) {
839
+ return /* @__PURE__ */ jsx7(DropdownMenuItem, {
840
+ "data-slot": "menubar-item",
841
+ "data-inset": inset,
842
+ "data-variant": variant,
843
+ className: cn("group/menubar-item gap-2 rounded-sm px-2 py-1.5 text-sm focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-inset:pl-8 data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:focus:text-destructive dark:data-[variant=destructive]:focus:bg-destructive/20 data-disabled:opacity-50 [&_svg:not([class*='size-'])]:size-4 data-[variant=destructive]:*:[svg]:text-destructive!", className),
844
+ ...props
845
+ });
846
+ }
847
+ function MenubarCheckboxItem({
848
+ className,
849
+ children,
850
+ checked,
851
+ inset,
852
+ ...props
853
+ }) {
854
+ return /* @__PURE__ */ jsxs3(MenuPrimitive2.CheckboxItem, {
855
+ "data-slot": "menubar-checkbox-item",
856
+ "data-inset": inset,
857
+ className: cn("relative flex cursor-default items-center gap-2 rounded-md py-1.5 pr-2 pl-8 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground data-inset:pl-8 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0", className),
858
+ checked,
859
+ ...props,
860
+ children: [
861
+ /* @__PURE__ */ jsx7("span", {
862
+ className: "pointer-events-none absolute left-2 flex size-4 items-center justify-center [&_svg:not([class*='size-'])]:size-4",
863
+ children: /* @__PURE__ */ jsx7(MenuPrimitive2.CheckboxItemIndicator, {
864
+ children: /* @__PURE__ */ jsx7(CheckIcon3, {})
865
+ })
866
+ }),
867
+ children
868
+ ]
869
+ });
870
+ }
871
+ function MenubarRadioGroup({
872
+ ...props
873
+ }) {
874
+ return /* @__PURE__ */ jsx7(DropdownMenuRadioGroup, {
875
+ "data-slot": "menubar-radio-group",
876
+ ...props
877
+ });
878
+ }
879
+ function MenubarRadioItem({
880
+ className,
881
+ children,
882
+ inset,
883
+ ...props
884
+ }) {
885
+ return /* @__PURE__ */ jsxs3(MenuPrimitive2.RadioItem, {
886
+ "data-slot": "menubar-radio-item",
887
+ "data-inset": inset,
888
+ className: cn("relative flex cursor-default items-center gap-2 rounded-md py-1.5 pr-2 pl-8 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground data-inset:pl-8 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", className),
889
+ ...props,
890
+ children: [
891
+ /* @__PURE__ */ jsx7("span", {
892
+ className: "pointer-events-none absolute left-2 flex size-4 items-center justify-center [&_svg:not([class*='size-'])]:size-4",
893
+ children: /* @__PURE__ */ jsx7(MenuPrimitive2.RadioItemIndicator, {
894
+ children: /* @__PURE__ */ jsx7(CheckIcon3, {})
895
+ })
896
+ }),
897
+ children
898
+ ]
899
+ });
900
+ }
901
+ function MenubarLabel({
902
+ className,
903
+ inset,
904
+ ...props
905
+ }) {
906
+ return /* @__PURE__ */ jsx7(DropdownMenuLabel, {
907
+ "data-slot": "menubar-label",
908
+ "data-inset": inset,
909
+ className: cn("px-2 py-1.5 text-sm font-medium data-inset:pl-8", className),
910
+ ...props
911
+ });
912
+ }
913
+ function MenubarSeparator({
914
+ className,
915
+ ...props
916
+ }) {
917
+ return /* @__PURE__ */ jsx7(DropdownMenuSeparator, {
918
+ "data-slot": "menubar-separator",
919
+ className: cn("-mx-1 my-1 h-px bg-border", className),
920
+ ...props
921
+ });
922
+ }
923
+ function MenubarSub({
924
+ ...props
925
+ }) {
926
+ return /* @__PURE__ */ jsx7(DropdownMenuSub, {
927
+ "data-slot": "menubar-sub",
928
+ ...props
929
+ });
930
+ }
931
+ function MenubarSubTrigger({
932
+ className,
933
+ inset,
934
+ ...props
935
+ }) {
936
+ return /* @__PURE__ */ jsx7(DropdownMenuSubTrigger, {
937
+ "data-slot": "menubar-sub-trigger",
938
+ "data-inset": inset,
939
+ className: cn("gap-2 rounded-sm px-2 py-1.5 text-sm focus:bg-accent focus:text-accent-foreground data-inset:pl-8 data-open:bg-accent data-open:text-accent-foreground [&_svg:not([class*='size-'])]:size-4", className),
940
+ ...props
941
+ });
942
+ }
943
+ function MenubarSubContent({
944
+ className,
945
+ ...props
946
+ }) {
947
+ return /* @__PURE__ */ jsx7(DropdownMenuSubContent, {
948
+ "data-slot": "menubar-sub-content",
949
+ className: cn("min-w-32 rounded-md bg-popover p-1 text-popover-foreground shadow-lg ring-1 ring-foreground/10 duration-100 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95", className),
950
+ ...props
951
+ });
952
+ }
953
+
816
954
  // ../../src/components/ui/pagination.tsx
817
955
  import {
818
956
  ChevronLeft,
@@ -823,10 +961,10 @@ import {
823
961
  import { useId } from "react";
824
962
 
825
963
  // ../../src/components/ui/label.tsx
826
- import { jsx as jsx7 } from "react/jsx-runtime";
964
+ import { jsx as jsx8 } from "react/jsx-runtime";
827
965
  "use client";
828
966
  function Label({ className, ...props }) {
829
- return /* @__PURE__ */ jsx7("label", {
967
+ return /* @__PURE__ */ jsx8("label", {
830
968
  "data-slot": "label",
831
969
  className: cn("flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50", className),
832
970
  ...props
@@ -835,12 +973,12 @@ function Label({ className, ...props }) {
835
973
 
836
974
  // ../../src/components/ui/select.tsx
837
975
  import { Select as SelectPrimitive } from "@base-ui/react/select";
838
- import { ChevronDownIcon, CheckIcon as CheckIcon3, ChevronUpIcon } from "lucide-react";
839
- import { jsx as jsx8, jsxs as jsxs3 } from "react/jsx-runtime";
976
+ import { ChevronDownIcon, CheckIcon as CheckIcon4, ChevronUpIcon } from "lucide-react";
977
+ import { jsx as jsx9, jsxs as jsxs4 } from "react/jsx-runtime";
840
978
  "use client";
841
979
  var Select = SelectPrimitive.Root;
842
980
  function SelectValue({ className, ...props }) {
843
- return /* @__PURE__ */ jsx8(SelectPrimitive.Value, {
981
+ return /* @__PURE__ */ jsx9(SelectPrimitive.Value, {
844
982
  "data-slot": "select-value",
845
983
  className: cn("flex flex-1 text-left", className),
846
984
  ...props
@@ -852,15 +990,15 @@ function SelectTrigger({
852
990
  children,
853
991
  ...props
854
992
  }) {
855
- return /* @__PURE__ */ jsxs3(SelectPrimitive.Trigger, {
993
+ return /* @__PURE__ */ jsxs4(SelectPrimitive.Trigger, {
856
994
  "data-slot": "select-trigger",
857
995
  "data-size": size,
858
996
  className: cn("flex w-fit items-center justify-between gap-1.5 rounded-md border border-input bg-transparent py-2 pr-2 pl-2.5 text-sm whitespace-nowrap shadow-xs transition-[color,box-shadow] outline-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 data-placeholder:text-muted-foreground data-[size=default]:h-9 data-[size=sm]:h-8 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-1.5 dark:bg-input/30 dark:hover:bg-input/50 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", className),
859
997
  ...props,
860
998
  children: [
861
999
  children,
862
- /* @__PURE__ */ jsx8(SelectPrimitive.Icon, {
863
- render: /* @__PURE__ */ jsx8(ChevronDownIcon, {
1000
+ /* @__PURE__ */ jsx9(SelectPrimitive.Icon, {
1001
+ render: /* @__PURE__ */ jsx9(ChevronDownIcon, {
864
1002
  className: "text-muted-foreground pointer-events-none size-4"
865
1003
  })
866
1004
  })
@@ -877,25 +1015,25 @@ function SelectContent({
877
1015
  alignItemWithTrigger = true,
878
1016
  ...props
879
1017
  }) {
880
- return /* @__PURE__ */ jsx8(SelectPrimitive.Portal, {
881
- children: /* @__PURE__ */ jsx8(SelectPrimitive.Positioner, {
1018
+ return /* @__PURE__ */ jsx9(SelectPrimitive.Portal, {
1019
+ children: /* @__PURE__ */ jsx9(SelectPrimitive.Positioner, {
882
1020
  side,
883
1021
  sideOffset,
884
1022
  align,
885
1023
  alignOffset,
886
1024
  alignItemWithTrigger,
887
1025
  className: "isolate z-50",
888
- children: /* @__PURE__ */ jsxs3(SelectPrimitive.Popup, {
1026
+ children: /* @__PURE__ */ jsxs4(SelectPrimitive.Popup, {
889
1027
  "data-slot": "select-content",
890
1028
  "data-align-trigger": alignItemWithTrigger,
891
1029
  className: cn("relative isolate z-50 max-h-(--available-height) w-(--anchor-width) min-w-36 origin-(--transform-origin) overflow-x-hidden overflow-y-auto rounded-md bg-popover text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 data-[align-trigger=true]:animate-none data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95", className),
892
1030
  ...props,
893
1031
  children: [
894
- /* @__PURE__ */ jsx8(SelectScrollUpButton, {}),
895
- /* @__PURE__ */ jsx8(SelectPrimitive.List, {
1032
+ /* @__PURE__ */ jsx9(SelectScrollUpButton, {}),
1033
+ /* @__PURE__ */ jsx9(SelectPrimitive.List, {
896
1034
  children
897
1035
  }),
898
- /* @__PURE__ */ jsx8(SelectScrollDownButton, {})
1036
+ /* @__PURE__ */ jsx9(SelectScrollDownButton, {})
899
1037
  ]
900
1038
  })
901
1039
  })
@@ -906,20 +1044,20 @@ function SelectItem({
906
1044
  children,
907
1045
  ...props
908
1046
  }) {
909
- return /* @__PURE__ */ jsxs3(SelectPrimitive.Item, {
1047
+ return /* @__PURE__ */ jsxs4(SelectPrimitive.Item, {
910
1048
  "data-slot": "select-item",
911
1049
  className: cn("relative flex w-full cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2", className),
912
1050
  ...props,
913
1051
  children: [
914
- /* @__PURE__ */ jsx8(SelectPrimitive.ItemText, {
1052
+ /* @__PURE__ */ jsx9(SelectPrimitive.ItemText, {
915
1053
  className: "flex flex-1 shrink-0 gap-2 whitespace-nowrap",
916
1054
  children
917
1055
  }),
918
- /* @__PURE__ */ jsx8(SelectPrimitive.ItemIndicator, {
919
- render: /* @__PURE__ */ jsx8("span", {
1056
+ /* @__PURE__ */ jsx9(SelectPrimitive.ItemIndicator, {
1057
+ render: /* @__PURE__ */ jsx9("span", {
920
1058
  className: "pointer-events-none absolute right-2 flex size-4 items-center justify-center"
921
1059
  }),
922
- children: /* @__PURE__ */ jsx8(CheckIcon3, {
1060
+ children: /* @__PURE__ */ jsx9(CheckIcon4, {
923
1061
  className: "pointer-events-none"
924
1062
  })
925
1063
  })
@@ -930,27 +1068,27 @@ function SelectScrollUpButton({
930
1068
  className,
931
1069
  ...props
932
1070
  }) {
933
- return /* @__PURE__ */ jsx8(SelectPrimitive.ScrollUpArrow, {
1071
+ return /* @__PURE__ */ jsx9(SelectPrimitive.ScrollUpArrow, {
934
1072
  "data-slot": "select-scroll-up-button",
935
1073
  className: cn("top-0 z-10 flex w-full cursor-default items-center justify-center bg-popover py-1 [&_svg:not([class*='size-'])]:size-4", className),
936
1074
  ...props,
937
- children: /* @__PURE__ */ jsx8(ChevronUpIcon, {})
1075
+ children: /* @__PURE__ */ jsx9(ChevronUpIcon, {})
938
1076
  });
939
1077
  }
940
1078
  function SelectScrollDownButton({
941
1079
  className,
942
1080
  ...props
943
1081
  }) {
944
- return /* @__PURE__ */ jsx8(SelectPrimitive.ScrollDownArrow, {
1082
+ return /* @__PURE__ */ jsx9(SelectPrimitive.ScrollDownArrow, {
945
1083
  "data-slot": "select-scroll-down-button",
946
1084
  className: cn("bottom-0 z-10 flex w-full cursor-default items-center justify-center bg-popover py-1 [&_svg:not([class*='size-'])]:size-4", className),
947
1085
  ...props,
948
- children: /* @__PURE__ */ jsx8(ChevronDownIcon, {})
1086
+ children: /* @__PURE__ */ jsx9(ChevronDownIcon, {})
949
1087
  });
950
1088
  }
951
1089
 
952
1090
  // ../../src/components/ui/pagination.tsx
953
- import { jsx as jsx9, jsxs as jsxs4 } from "react/jsx-runtime";
1091
+ import { jsx as jsx10, jsxs as jsxs5 } from "react/jsx-runtime";
954
1092
  var messages = {
955
1093
  en: {
956
1094
  pageSize: "Page size",
@@ -994,32 +1132,32 @@ function Pagination({
994
1132
  const pageSizeId = useId();
995
1133
  const canGoBack = page > 0;
996
1134
  const canGoForward = page + 1 < pageCount;
997
- return /* @__PURE__ */ jsxs4("div", {
1135
+ return /* @__PURE__ */ jsxs5("div", {
998
1136
  className: cn("flex flex-col gap-3 px-2 sm:flex-row sm:items-center sm:justify-between", compact && "gap-2 px-0 sm:flex-col sm:items-stretch"),
999
1137
  children: [
1000
- showResults ? /* @__PURE__ */ jsxs4("div", {
1138
+ showResults ? /* @__PURE__ */ jsxs5("div", {
1001
1139
  className: "text-muted-foreground flex flex-wrap items-center gap-x-3 gap-y-1 text-sm",
1002
1140
  children: [
1003
- /* @__PURE__ */ jsx9("span", {
1141
+ /* @__PURE__ */ jsx10("span", {
1004
1142
  children: labels2.results(totalRows)
1005
1143
  }),
1006
- selectedRows > 0 ? /* @__PURE__ */ jsx9("span", {
1144
+ selectedRows > 0 ? /* @__PURE__ */ jsx10("span", {
1007
1145
  children: labels2.selectedOf(selectedRows, totalRows)
1008
1146
  }) : null
1009
1147
  ]
1010
1148
  }) : null,
1011
- /* @__PURE__ */ jsxs4("div", {
1149
+ /* @__PURE__ */ jsxs5("div", {
1012
1150
  className: cn("flex items-center gap-4 sm:justify-end", compact && "flex-wrap justify-between gap-2 sm:justify-between"),
1013
1151
  children: [
1014
- /* @__PURE__ */ jsxs4("div", {
1152
+ /* @__PURE__ */ jsxs5("div", {
1015
1153
  className: "flex items-center gap-2",
1016
1154
  children: [
1017
- /* @__PURE__ */ jsx9(Label, {
1155
+ /* @__PURE__ */ jsx10(Label, {
1018
1156
  htmlFor: pageSizeId,
1019
1157
  className: cn("hidden text-sm sm:block", compact && "block"),
1020
1158
  children: labels2.pageSize
1021
1159
  }),
1022
- /* @__PURE__ */ jsxs4(Select, {
1160
+ /* @__PURE__ */ jsxs5(Select, {
1023
1161
  items: pageSizes.map((size) => ({
1024
1162
  label: size.toString(),
1025
1163
  value: size.toString()
@@ -1027,16 +1165,16 @@ function Pagination({
1027
1165
  value: `${pageSize}`,
1028
1166
  onValueChange: (value) => onPageSizeChange(Number(value)),
1029
1167
  children: [
1030
- /* @__PURE__ */ jsx9(SelectTrigger, {
1168
+ /* @__PURE__ */ jsx10(SelectTrigger, {
1031
1169
  className: "h-8 w-[70px]",
1032
1170
  id: pageSizeId,
1033
- children: /* @__PURE__ */ jsx9(SelectValue, {
1171
+ children: /* @__PURE__ */ jsx10(SelectValue, {
1034
1172
  placeholder: pageSize
1035
1173
  })
1036
1174
  }),
1037
- /* @__PURE__ */ jsx9(SelectContent, {
1175
+ /* @__PURE__ */ jsx10(SelectContent, {
1038
1176
  side: "top",
1039
- children: pageSizes.map((size) => /* @__PURE__ */ jsx9(SelectItem, {
1177
+ children: pageSizes.map((size) => /* @__PURE__ */ jsx10(SelectItem, {
1040
1178
  value: `${size}`,
1041
1179
  children: size
1042
1180
  }, size))
@@ -1045,66 +1183,66 @@ function Pagination({
1045
1183
  })
1046
1184
  ]
1047
1185
  }),
1048
- /* @__PURE__ */ jsxs4("div", {
1186
+ /* @__PURE__ */ jsxs5("div", {
1049
1187
  className: "flex items-center gap-2",
1050
1188
  children: [
1051
- /* @__PURE__ */ jsx9("div", {
1189
+ /* @__PURE__ */ jsx10("div", {
1052
1190
  className: "flex items-center justify-center text-sm font-medium sm:block",
1053
1191
  children: labels2.pageOf(page + 1, pageCount)
1054
1192
  }),
1055
- /* @__PURE__ */ jsxs4("div", {
1193
+ /* @__PURE__ */ jsxs5("div", {
1056
1194
  className: "flex items-center gap-1",
1057
1195
  children: [
1058
- /* @__PURE__ */ jsxs4(Button, {
1196
+ /* @__PURE__ */ jsxs5(Button, {
1059
1197
  className: cn("hidden h-8 w-8 p-0 lg:flex", compact && "!hidden"),
1060
1198
  disabled: !canGoBack,
1061
1199
  onClick: () => onPageChange(0),
1062
1200
  type: "button",
1063
1201
  children: [
1064
- /* @__PURE__ */ jsx9("span", {
1202
+ /* @__PURE__ */ jsx10("span", {
1065
1203
  className: "sr-only",
1066
1204
  children: labels2.goToFirstPage
1067
1205
  }),
1068
- /* @__PURE__ */ jsx9(ChevronsLeft, {})
1206
+ /* @__PURE__ */ jsx10(ChevronsLeft, {})
1069
1207
  ]
1070
1208
  }),
1071
- /* @__PURE__ */ jsxs4(Button, {
1209
+ /* @__PURE__ */ jsxs5(Button, {
1072
1210
  className: "h-8 w-8 p-0",
1073
1211
  disabled: !canGoBack,
1074
1212
  onClick: () => onPageChange(page - 1),
1075
1213
  type: "button",
1076
1214
  children: [
1077
- /* @__PURE__ */ jsx9("span", {
1215
+ /* @__PURE__ */ jsx10("span", {
1078
1216
  className: "sr-only",
1079
1217
  children: labels2.goToPreviousPage
1080
1218
  }),
1081
- /* @__PURE__ */ jsx9(ChevronLeft, {})
1219
+ /* @__PURE__ */ jsx10(ChevronLeft, {})
1082
1220
  ]
1083
1221
  }),
1084
- /* @__PURE__ */ jsxs4(Button, {
1222
+ /* @__PURE__ */ jsxs5(Button, {
1085
1223
  className: "h-8 w-8 p-0",
1086
1224
  disabled: !canGoForward,
1087
1225
  onClick: () => onPageChange(page + 1),
1088
1226
  type: "button",
1089
1227
  children: [
1090
- /* @__PURE__ */ jsx9("span", {
1228
+ /* @__PURE__ */ jsx10("span", {
1091
1229
  className: "sr-only",
1092
1230
  children: labels2.goToNextPage
1093
1231
  }),
1094
- /* @__PURE__ */ jsx9(ChevronRight, {})
1232
+ /* @__PURE__ */ jsx10(ChevronRight, {})
1095
1233
  ]
1096
1234
  }),
1097
- /* @__PURE__ */ jsxs4(Button, {
1235
+ /* @__PURE__ */ jsxs5(Button, {
1098
1236
  className: cn("hidden h-8 w-8 p-0 lg:flex", compact && "!hidden"),
1099
1237
  disabled: !canGoForward,
1100
1238
  onClick: () => onPageChange(pageCount - 1),
1101
1239
  type: "button",
1102
1240
  children: [
1103
- /* @__PURE__ */ jsx9("span", {
1241
+ /* @__PURE__ */ jsx10("span", {
1104
1242
  className: "sr-only",
1105
1243
  children: labels2.goToLastPage
1106
1244
  }),
1107
- /* @__PURE__ */ jsx9(ChevronsRight, {})
1245
+ /* @__PURE__ */ jsx10(ChevronsRight, {})
1108
1246
  ]
1109
1247
  })
1110
1248
  ]
@@ -1119,15 +1257,15 @@ function Pagination({
1119
1257
 
1120
1258
  // ../../src/components/ui/popover.tsx
1121
1259
  import { Popover as PopoverPrimitive } from "@base-ui/react/popover";
1122
- import { jsx as jsx10 } from "react/jsx-runtime";
1260
+ import { jsx as jsx11 } from "react/jsx-runtime";
1123
1261
  function Popover({ ...props }) {
1124
- return /* @__PURE__ */ jsx10(PopoverPrimitive.Root, {
1262
+ return /* @__PURE__ */ jsx11(PopoverPrimitive.Root, {
1125
1263
  "data-slot": "popover",
1126
1264
  ...props
1127
1265
  });
1128
1266
  }
1129
1267
  function PopoverTrigger({ ...props }) {
1130
- return /* @__PURE__ */ jsx10(PopoverPrimitive.Trigger, {
1268
+ return /* @__PURE__ */ jsx11(PopoverPrimitive.Trigger, {
1131
1269
  "data-slot": "popover-trigger",
1132
1270
  ...props
1133
1271
  });
@@ -1140,14 +1278,14 @@ function PopoverContent({
1140
1278
  sideOffset = 4,
1141
1279
  ...props
1142
1280
  }) {
1143
- return /* @__PURE__ */ jsx10(PopoverPrimitive.Portal, {
1144
- children: /* @__PURE__ */ jsx10(PopoverPrimitive.Positioner, {
1281
+ return /* @__PURE__ */ jsx11(PopoverPrimitive.Portal, {
1282
+ children: /* @__PURE__ */ jsx11(PopoverPrimitive.Positioner, {
1145
1283
  align,
1146
1284
  alignOffset,
1147
1285
  side,
1148
1286
  sideOffset,
1149
1287
  className: "isolate z-50",
1150
- children: /* @__PURE__ */ jsx10(PopoverPrimitive.Popup, {
1288
+ children: /* @__PURE__ */ jsx11(PopoverPrimitive.Popup, {
1151
1289
  "data-slot": "popover-content",
1152
1290
  className: cn("z-50 flex w-72 origin-(--transform-origin) flex-col gap-4 rounded-md bg-popover p-4 text-sm text-popover-foreground shadow-md ring-1 ring-foreground/10 outline-hidden duration-100 data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95", className),
1153
1291
  ...props
@@ -1158,24 +1296,24 @@ function PopoverContent({
1158
1296
 
1159
1297
  // ../../src/components/ui/scroll-area.tsx
1160
1298
  import { ScrollArea as ScrollAreaPrimitive } from "@base-ui/react/scroll-area";
1161
- import { jsx as jsx11, jsxs as jsxs5 } from "react/jsx-runtime";
1299
+ import { jsx as jsx12, jsxs as jsxs6 } from "react/jsx-runtime";
1162
1300
  function ScrollArea({
1163
1301
  className,
1164
1302
  children,
1165
1303
  ...props
1166
1304
  }) {
1167
- return /* @__PURE__ */ jsxs5(ScrollAreaPrimitive.Root, {
1305
+ return /* @__PURE__ */ jsxs6(ScrollAreaPrimitive.Root, {
1168
1306
  "data-slot": "scroll-area",
1169
1307
  className: cn("relative", className),
1170
1308
  ...props,
1171
1309
  children: [
1172
- /* @__PURE__ */ jsx11(ScrollAreaPrimitive.Viewport, {
1310
+ /* @__PURE__ */ jsx12(ScrollAreaPrimitive.Viewport, {
1173
1311
  "data-slot": "scroll-area-viewport",
1174
1312
  className: "focus-visible:ring-ring/50 size-full rounded-[inherit] transition-[color,box-shadow] outline-none focus-visible:ring-[3px] focus-visible:outline-1",
1175
1313
  children
1176
1314
  }),
1177
- /* @__PURE__ */ jsx11(ScrollBar, {}),
1178
- /* @__PURE__ */ jsx11(ScrollAreaPrimitive.Corner, {})
1315
+ /* @__PURE__ */ jsx12(ScrollBar, {}),
1316
+ /* @__PURE__ */ jsx12(ScrollAreaPrimitive.Corner, {})
1179
1317
  ]
1180
1318
  });
1181
1319
  }
@@ -1184,13 +1322,13 @@ function ScrollBar({
1184
1322
  orientation = "vertical",
1185
1323
  ...props
1186
1324
  }) {
1187
- return /* @__PURE__ */ jsx11(ScrollAreaPrimitive.Scrollbar, {
1325
+ return /* @__PURE__ */ jsx12(ScrollAreaPrimitive.Scrollbar, {
1188
1326
  "data-slot": "scroll-area-scrollbar",
1189
1327
  "data-orientation": orientation,
1190
1328
  orientation,
1191
1329
  className: cn("flex touch-none p-px transition-colors select-none data-horizontal:h-2.5 data-horizontal:flex-col data-horizontal:border-t data-horizontal:border-t-transparent data-vertical:h-full data-vertical:w-2.5 data-vertical:border-l data-vertical:border-l-transparent", className),
1192
1330
  ...props,
1193
- children: /* @__PURE__ */ jsx11(ScrollAreaPrimitive.Thumb, {
1331
+ children: /* @__PURE__ */ jsx12(ScrollAreaPrimitive.Thumb, {
1194
1332
  "data-slot": "scroll-area-thumb",
1195
1333
  className: "bg-border relative flex-1 rounded-full"
1196
1334
  })
@@ -1198,12 +1336,12 @@ function ScrollBar({
1198
1336
  }
1199
1337
 
1200
1338
  // ../../src/components/ui/table.tsx
1201
- import { jsx as jsx12 } from "react/jsx-runtime";
1339
+ import { jsx as jsx13 } from "react/jsx-runtime";
1202
1340
  function Table({ className, ...props }) {
1203
- return /* @__PURE__ */ jsx12("div", {
1341
+ return /* @__PURE__ */ jsx13("div", {
1204
1342
  "data-slot": "table-container",
1205
1343
  className: "relative w-full overflow-x-auto",
1206
- children: /* @__PURE__ */ jsx12("table", {
1344
+ children: /* @__PURE__ */ jsx13("table", {
1207
1345
  "data-slot": "table",
1208
1346
  className: cn("w-full caption-bottom text-sm", className),
1209
1347
  ...props
@@ -1211,35 +1349,35 @@ function Table({ className, ...props }) {
1211
1349
  });
1212
1350
  }
1213
1351
  function TableHeader({ className, ...props }) {
1214
- return /* @__PURE__ */ jsx12("thead", {
1352
+ return /* @__PURE__ */ jsx13("thead", {
1215
1353
  "data-slot": "table-header",
1216
1354
  className: cn("[&_tr]:border-b", className),
1217
1355
  ...props
1218
1356
  });
1219
1357
  }
1220
1358
  function TableBody({ className, ...props }) {
1221
- return /* @__PURE__ */ jsx12("tbody", {
1359
+ return /* @__PURE__ */ jsx13("tbody", {
1222
1360
  "data-slot": "table-body",
1223
1361
  className: cn("[&_tr:last-child]:border-0", className),
1224
1362
  ...props
1225
1363
  });
1226
1364
  }
1227
1365
  function TableRow({ className, ...props }) {
1228
- return /* @__PURE__ */ jsx12("tr", {
1366
+ return /* @__PURE__ */ jsx13("tr", {
1229
1367
  "data-slot": "table-row",
1230
1368
  className: cn("border-b transition-colors hover:bg-muted/50 has-aria-expanded:bg-muted/50 data-[state=selected]:bg-muted", className),
1231
1369
  ...props
1232
1370
  });
1233
1371
  }
1234
1372
  function TableHead({ className, ...props }) {
1235
- return /* @__PURE__ */ jsx12("th", {
1373
+ return /* @__PURE__ */ jsx13("th", {
1236
1374
  "data-slot": "table-head",
1237
1375
  className: cn("h-10 px-2 text-left align-middle font-medium whitespace-nowrap text-foreground [&:has([role=checkbox])]:pr-0", className),
1238
1376
  ...props
1239
1377
  });
1240
1378
  }
1241
1379
  function TableCell({ className, ...props }) {
1242
- return /* @__PURE__ */ jsx12("td", {
1380
+ return /* @__PURE__ */ jsx13("td", {
1243
1381
  "data-slot": "table-cell",
1244
1382
  className: cn("p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0", className),
1245
1383
  ...props
@@ -1248,26 +1386,26 @@ function TableCell({ className, ...props }) {
1248
1386
 
1249
1387
  // ../../src/components/ui/tooltip.tsx
1250
1388
  import { Tooltip as TooltipPrimitive } from "@base-ui/react/tooltip";
1251
- import { jsx as jsx13, jsxs as jsxs6 } from "react/jsx-runtime";
1389
+ import { jsx as jsx14, jsxs as jsxs7 } from "react/jsx-runtime";
1252
1390
  "use client";
1253
1391
  function TooltipProvider({
1254
1392
  delay = 0,
1255
1393
  ...props
1256
1394
  }) {
1257
- return /* @__PURE__ */ jsx13(TooltipPrimitive.Provider, {
1395
+ return /* @__PURE__ */ jsx14(TooltipPrimitive.Provider, {
1258
1396
  "data-slot": "tooltip-provider",
1259
1397
  delay,
1260
1398
  ...props
1261
1399
  });
1262
1400
  }
1263
1401
  function Tooltip({ ...props }) {
1264
- return /* @__PURE__ */ jsx13(TooltipPrimitive.Root, {
1402
+ return /* @__PURE__ */ jsx14(TooltipPrimitive.Root, {
1265
1403
  "data-slot": "tooltip",
1266
1404
  ...props
1267
1405
  });
1268
1406
  }
1269
1407
  function TooltipTrigger({ ...props }) {
1270
- return /* @__PURE__ */ jsx13(TooltipPrimitive.Trigger, {
1408
+ return /* @__PURE__ */ jsx14(TooltipPrimitive.Trigger, {
1271
1409
  "data-slot": "tooltip-trigger",
1272
1410
  ...props
1273
1411
  });
@@ -1281,20 +1419,20 @@ function TooltipContent({
1281
1419
  children,
1282
1420
  ...props
1283
1421
  }) {
1284
- return /* @__PURE__ */ jsx13(TooltipPrimitive.Portal, {
1285
- children: /* @__PURE__ */ jsx13(TooltipPrimitive.Positioner, {
1422
+ return /* @__PURE__ */ jsx14(TooltipPrimitive.Portal, {
1423
+ children: /* @__PURE__ */ jsx14(TooltipPrimitive.Positioner, {
1286
1424
  align,
1287
1425
  alignOffset,
1288
1426
  side,
1289
1427
  sideOffset,
1290
1428
  className: "isolate z-50",
1291
- children: /* @__PURE__ */ jsxs6(TooltipPrimitive.Popup, {
1429
+ children: /* @__PURE__ */ jsxs7(TooltipPrimitive.Popup, {
1292
1430
  "data-slot": "tooltip-content",
1293
1431
  className: cn("z-50 inline-flex w-fit max-w-xs origin-(--transform-origin) items-center gap-1.5 rounded-md bg-foreground px-3 py-1.5 text-xs text-background has-data-[slot=kbd]:pr-1.5 data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 **:data-[slot=kbd]:relative **:data-[slot=kbd]:isolate **:data-[slot=kbd]:z-50 **:data-[slot=kbd]:rounded-sm data-[state=delayed-open]:animate-in data-[state=delayed-open]:fade-in-0 data-[state=delayed-open]:zoom-in-95 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95", className),
1294
1432
  ...props,
1295
1433
  children: [
1296
1434
  children,
1297
- /* @__PURE__ */ jsx13(TooltipPrimitive.Arrow, {
1435
+ /* @__PURE__ */ jsx14(TooltipPrimitive.Arrow, {
1298
1436
  className: "bg-foreground fill-foreground z-50 size-2.5 translate-y-[calc(-50%-2px)] rotate-45 rounded-[2px] data-[side=bottom]:top-1 data-[side=inline-end]:top-1/2! data-[side=inline-end]:-left-1 data-[side=inline-end]:-translate-y-1/2 data-[side=inline-start]:top-1/2! data-[side=inline-start]:-right-1 data-[side=inline-start]:-translate-y-1/2 data-[side=left]:top-1/2! data-[side=left]:-right-1 data-[side=left]:-translate-y-1/2 data-[side=right]:top-1/2! data-[side=right]:-left-1 data-[side=right]:-translate-y-1/2 data-[side=top]:-bottom-2.5"
1299
1437
  })
1300
1438
  ]
@@ -1316,11 +1454,6 @@ import {
1316
1454
 
1317
1455
  // ../../src/components/ui/input-group.tsx
1318
1456
  import { cva as cva3 } from "class-variance-authority";
1319
-
1320
- // ../../src/components/ui/textarea.tsx
1321
- import { jsx as jsx14 } from "react/jsx-runtime";
1322
-
1323
- // ../../src/components/ui/input-group.tsx
1324
1457
  import { jsx as jsx15 } from "react/jsx-runtime";
1325
1458
  function InputGroup({ className, ...props }) {
1326
1459
  return /* @__PURE__ */ jsx15("div", {
@@ -1364,7 +1497,7 @@ function InputGroupInput({
1364
1497
  }
1365
1498
 
1366
1499
  // ../../src/components/ui/virtualized-combobox.tsx
1367
- import { jsx as jsx16, jsxs as jsxs7 } from "react/jsx-runtime";
1500
+ import { jsx as jsx16, jsxs as jsxs8 } from "react/jsx-runtime";
1368
1501
  "use client";
1369
1502
  var messages2 = {
1370
1503
  en: {
@@ -1476,7 +1609,7 @@ var VirtualizedComboboxList = ({
1476
1609
  })
1477
1610
  }, entry.key);
1478
1611
  }
1479
- return /* @__PURE__ */ jsxs7(ComboboxPrimitive.Item, {
1612
+ return /* @__PURE__ */ jsxs8(ComboboxPrimitive.Item, {
1480
1613
  "aria-posinset": entry.index + 1,
1481
1614
  "aria-setsize": filteredItems.length,
1482
1615
  className: "data-highlighted:bg-accent data-highlighted:text-accent-foreground absolute top-0 left-0 flex w-full cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50",
@@ -1517,7 +1650,7 @@ var VirtualizedComboboxContent = ({
1517
1650
  className: "isolate z-50",
1518
1651
  side: "bottom",
1519
1652
  sideOffset: 6,
1520
- children: /* @__PURE__ */ jsxs7(ComboboxPrimitive.Popup, {
1653
+ children: /* @__PURE__ */ jsxs8(ComboboxPrimitive.Popup, {
1521
1654
  className: cn("relative max-h-(--available-height) w-(--anchor-width) max-w-(--available-width) min-w-0 origin-(--transform-origin) overflow-hidden rounded-md bg-popover text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 data-[side=bottom]:slide-in-from-top-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-in-95", contentClassName),
1522
1655
  children: [
1523
1656
  /* @__PURE__ */ jsx16("div", {
@@ -1544,7 +1677,7 @@ var VirtualizedComboboxContent = ({
1544
1677
  })
1545
1678
  });
1546
1679
  };
1547
- var defaultTrigger = (ariaLabel, ariaInvalid, disabled, label, triggerId) => /* @__PURE__ */ jsxs7(Button, {
1680
+ var defaultTrigger = (ariaLabel, ariaInvalid, disabled, label, triggerId) => /* @__PURE__ */ jsxs8(Button, {
1548
1681
  "aria-label": ariaLabel,
1549
1682
  "aria-invalid": ariaInvalid,
1550
1683
  className: "w-full max-w-full min-w-0 justify-between overflow-hidden",
@@ -1584,7 +1717,7 @@ var VirtualizedComboboxSingle = (props) => {
1584
1717
  const virtualizerRef = useComboboxVirtualizerRef(props.virtualizerRef);
1585
1718
  const itemIndexRef = useRef(new Map);
1586
1719
  const labels2 = virtualizedComboboxMessages(props.messages);
1587
- return /* @__PURE__ */ jsxs7(ComboboxPrimitive.Root, {
1720
+ return /* @__PURE__ */ jsxs8(ComboboxPrimitive.Root, {
1588
1721
  disabled: props.disabled,
1589
1722
  inputValue: props.searchValue,
1590
1723
  items: [...props.items],
@@ -1602,7 +1735,7 @@ var VirtualizedComboboxSingle = (props) => {
1602
1735
  value: props.value,
1603
1736
  virtualized: true,
1604
1737
  children: [
1605
- /* @__PURE__ */ jsxs7("div", {
1738
+ /* @__PURE__ */ jsxs8("div", {
1606
1739
  className: "relative",
1607
1740
  children: [
1608
1741
  /* @__PURE__ */ jsx16(ComboboxPrimitive.Trigger, {
@@ -1625,7 +1758,7 @@ var VirtualizedComboboxMultiple = (props) => {
1625
1758
  const virtualizerRef = useComboboxVirtualizerRef(props.virtualizerRef);
1626
1759
  const itemIndexRef = useRef(new Map);
1627
1760
  const labels2 = virtualizedComboboxMessages(props.messages);
1628
- return /* @__PURE__ */ jsxs7(ComboboxPrimitive.Root, {
1761
+ return /* @__PURE__ */ jsxs8(ComboboxPrimitive.Root, {
1629
1762
  disabled: props.disabled,
1630
1763
  inputValue: props.searchValue,
1631
1764
  items: [...props.items],
@@ -1644,7 +1777,7 @@ var VirtualizedComboboxMultiple = (props) => {
1644
1777
  value: [...props.value],
1645
1778
  virtualized: true,
1646
1779
  children: [
1647
- /* @__PURE__ */ jsxs7("div", {
1780
+ /* @__PURE__ */ jsxs8("div", {
1648
1781
  className: "relative",
1649
1782
  children: [
1650
1783
  /* @__PURE__ */ jsx16(ComboboxPrimitive.Trigger, {
@@ -1671,275 +1804,8 @@ function VirtualizedCombobox(props) {
1671
1804
  });
1672
1805
  }
1673
1806
 
1674
- // ../../src/lib/query.ts
1675
- import {
1676
- Effect,
1677
- Option,
1678
- Schema,
1679
- SchemaIssue,
1680
- SchemaTransformation
1681
- } from "effect";
1682
- var parseSortParam = (sort) => {
1683
- const id = sort.startsWith("-") ? sort.slice(1) : sort;
1684
- if (!id || id.includes(",") || id.includes(":")) {
1685
- return null;
1686
- }
1687
- return { id, direction: sort.startsWith("-") ? "desc" : "asc" };
1688
- };
1689
- var SortDirection = Schema.Union([
1690
- Schema.Literal("asc"),
1691
- Schema.Literal("desc")
1692
- ]).pipe(Schema.annotate({
1693
- identifier: "SortDirection",
1694
- title: "Sort Direction",
1695
- description: "Sort direction for list query results.",
1696
- examples: ["asc", "desc"]
1697
- }));
1698
- var SortParam = Schema.Struct({
1699
- id: Schema.NonEmptyString,
1700
- direction: SortDirection
1701
- }).pipe(Schema.annotate({
1702
- identifier: "SortParam",
1703
- title: "Sort Parameter",
1704
- description: "Decoded sort parameter with a field id and direction.",
1705
- examples: [{ id: "publicName", direction: "asc" }]
1706
- }));
1707
- var SortParamFromString = Schema.String.pipe(Schema.decodeTo(SortParam, SchemaTransformation.transformOrFail({
1708
- decode: (sort) => {
1709
- const sortParam = parseSortParam(sort);
1710
- if (!sortParam) {
1711
- return Effect.fail(new SchemaIssue.InvalidValue(Option.some(sort), {
1712
- message: 'Expected sort in the format "field" or "-field"'
1713
- }));
1714
- }
1715
- return Effect.succeed(sortParam);
1716
- },
1717
- encode: (sort) => Effect.succeed(sort.direction === "desc" ? `-${sort.id}` : sort.id)
1718
- })), Schema.annotate({
1719
- identifier: "SortParamFromString",
1720
- title: "Sort Parameter From String",
1721
- description: 'URL encoded single sort parameter where descending fields are prefixed with "-".',
1722
- examples: [{ id: "publicName", direction: "asc" }]
1723
- }));
1724
- var SortParamsFromString = Schema.String.pipe(Schema.decodeTo(Schema.Array(SortParam), SchemaTransformation.transformOrFail({
1725
- decode: (sort) => {
1726
- const parts = sort.split(",");
1727
- const sortParams = [];
1728
- for (const part of parts) {
1729
- const sortParam = parseSortParam(part);
1730
- if (!sortParam) {
1731
- return Effect.fail(new SchemaIssue.InvalidValue(Option.some(sort), {
1732
- message: 'Expected sort in the format "field,-otherField"'
1733
- }));
1734
- }
1735
- sortParams.push(sortParam);
1736
- }
1737
- return Effect.succeed(sortParams);
1738
- },
1739
- encode: (sort) => Effect.succeed(sort.map((part) => Schema.encodeSync(SortParamFromString)(part)).join(","))
1740
- })), Schema.annotate({
1741
- identifier: "SortParamsFromString",
1742
- title: "Sort Parameters From String",
1743
- description: 'URL encoded sort parameters where descending fields are prefixed with "-" and multiple fields are comma-separated.',
1744
- examples: [
1745
- [
1746
- { id: "name", direction: "desc" },
1747
- { id: "age", direction: "asc" }
1748
- ]
1749
- ]
1750
- }));
1751
- var SortParamSearch = SortParamsFromString.pipe(Schema.decodeTo(Schema.String, SchemaTransformation.transform({
1752
- decode: (sort) => Schema.encodeSync(SortParamsFromString)(sort),
1753
- encode: (sort) => Schema.decodeUnknownSync(SortParamsFromString)(sort)
1754
- })), Schema.annotate({
1755
- identifier: "SortParamSearch",
1756
- title: "Sort Search Parameter",
1757
- description: 'Search parameter sort value normalized to the compact "-field,otherField" URL format.',
1758
- examples: ["-name,age"]
1759
- }));
1760
- var Query = Schema.Struct({
1761
- page: Schema.Int.check(Schema.isGreaterThanOrEqualTo(0)),
1762
- pageSize: Schema.Int.check(Schema.isBetween({ minimum: 1, maximum: 100 })),
1763
- globalFilter: Schema.optional(Schema.String),
1764
- sort: Schema.optional(SortParamSearch)
1765
- }).annotate({
1766
- identifier: "Query",
1767
- title: "Query",
1768
- description: "Zero-based page request parameters with optional filtering and sorting for list endpoints.",
1769
- examples: [
1770
- {
1771
- page: 0,
1772
- pageSize: 10,
1773
- globalFilter: "housing",
1774
- sort: "-publicName,createdAt"
1775
- }
1776
- ]
1777
- });
1778
- var PaginationMeta = Schema.Struct({
1779
- page: Schema.Int,
1780
- pageSize: Schema.Int,
1781
- total: Schema.Int,
1782
- pageCount: Schema.Int
1783
- }).pipe(Schema.annotate({
1784
- identifier: "PaginationMeta",
1785
- title: "Pagination Metadata",
1786
- description: "Pagination metadata returned with a paginated list response.",
1787
- examples: [{ page: 0, pageSize: 10, total: 125, pageCount: 13 }]
1788
- }));
1789
-
1790
1807
  // ../../src/components/ui/data-table.tsx
1791
- import { useAtom } from "@effect/atom-react";
1792
- import { BrowserKeyValueStore } from "@effect/platform-browser";
1793
- import {
1794
- DndContext,
1795
- DragOverlay,
1796
- PointerSensor,
1797
- useDraggable,
1798
- useDroppable,
1799
- useSensor,
1800
- useSensors
1801
- } from "@dnd-kit/core";
1802
- import {
1803
- arrayMove,
1804
- SortableContext,
1805
- useSortable,
1806
- verticalListSortingStrategy
1807
- } from "@dnd-kit/sortable";
1808
- import { CSS } from "@dnd-kit/utilities";
1809
- import { Effect as Effect2, Layer, Option as Option2, Schema as Schema2 } from "effect";
1810
- import { KeyValueStore } from "effect/unstable/persistence";
1811
- import { Atom } from "effect/unstable/reactivity";
1812
- import {
1813
- ArrowDown,
1814
- ArrowUp,
1815
- ChevronDown,
1816
- ChevronRight as ChevronRight2,
1817
- ChevronsUpDown as ChevronsUpDown2,
1818
- Download,
1819
- EyeOff,
1820
- FileJson,
1821
- FileText,
1822
- GripVertical,
1823
- LayoutGrid,
1824
- MoreHorizontal,
1825
- RefreshCw,
1826
- Rows3,
1827
- Search,
1828
- Settings2,
1829
- X as X2
1830
- } from "lucide-react";
1831
- import {
1832
- isValidElement,
1833
- useEffect as useEffect2,
1834
- useMemo,
1835
- useState
1836
- } from "react";
1837
- import {
1838
- useNavigate,
1839
- useRouterState
1840
- } from "@tanstack/react-router";
1841
- import {
1842
- columnFilteringFeature,
1843
- columnResizingFeature,
1844
- columnSizingFeature,
1845
- columnVisibilityFeature,
1846
- createFilteredRowModel,
1847
- createPaginatedRowModel,
1848
- createSortedRowModel,
1849
- createTableHook,
1850
- globalFilteringFeature,
1851
- rowPaginationFeature,
1852
- rowSelectionFeature,
1853
- rowSortingFeature,
1854
- tableFeatures,
1855
- flexRender
1856
- } from "@tanstack/react-table";
1857
- import { jsx as jsx17, jsxs as jsxs8, Fragment } from "react/jsx-runtime";
1858
- var DEFAULT_COLUMN_MIN_SIZE = 128;
1859
- var DEFAULT_COLUMN_SIZE = 224;
1860
- var DEFAULT_COLUMN_MAX_SIZE = 640;
1861
- var COLUMN_RESIZE_STEP = 8;
1862
- var dataTableColumnMeta = {};
1863
- var dataTableFeatures = tableFeatures({
1864
- columnFilteringFeature,
1865
- columnResizingFeature,
1866
- columnSizingFeature,
1867
- columnVisibilityFeature,
1868
- globalFilteringFeature,
1869
- rowPaginationFeature,
1870
- rowSelectionFeature,
1871
- rowSortingFeature,
1872
- filteredRowModel: createFilteredRowModel(),
1873
- paginatedRowModel: createPaginatedRowModel(),
1874
- sortedRowModel: createSortedRowModel(),
1875
- columnMeta: dataTableColumnMeta
1876
- });
1877
- var {
1878
- createAppColumnHelper: createDataTableColumnHelper,
1879
- useAppTable: useDataTable,
1880
- useCellContext: useDataTableCellContext,
1881
- useHeaderContext: useDataTableHeaderContext,
1882
- useTableContext: useDataTableContext
1883
- } = createTableHook({
1884
- features: dataTableFeatures,
1885
- defaultColumn: {
1886
- minSize: DEFAULT_COLUMN_MIN_SIZE,
1887
- size: DEFAULT_COLUMN_SIZE,
1888
- maxSize: DEFAULT_COLUMN_MAX_SIZE
1889
- },
1890
- columnResizeMode: "onChange",
1891
- enableColumnResizing: true,
1892
- tableComponents: {},
1893
- cellComponents: {},
1894
- headerComponents: {}
1895
- });
1896
- var TableSearchSchema = Schema2.Struct({
1897
- page: Schema2.optional(Query.fields.page),
1898
- pageSize: Schema2.optional(Query.fields.pageSize),
1899
- globalFilter: Query.fields.globalFilter,
1900
- sort: Query.fields.sort,
1901
- grouping: Schema2.optional(Schema2.Array(Schema2.String))
1902
- }).annotate({ identifier: "TableSearch" });
1903
- var TableSearchSchemaStandard = Schema2.toStandardSchemaV1(TableSearchSchema);
1904
- var compactDataTableStorage = Layer.effect(KeyValueStore.KeyValueStore, Effect2.map(KeyValueStore.KeyValueStore, (store) => KeyValueStore.make({
1905
- clear: store.clear,
1906
- get: (key) => Effect2.flatMap(store.get(key), (value) => value === "{}" ? Effect2.as(store.remove(key), undefined) : Effect2.succeed(value)),
1907
- getUint8Array: store.getUint8Array,
1908
- remove: store.remove,
1909
- set: (key, value) => value === "{}" ? store.remove(key) : store.set(key, value),
1910
- size: store.size
1911
- }))).pipe(Layer.provide(BrowserKeyValueStore.layerLocalStorage));
1912
- var dataTableStorageRuntime = Atom.runtime(compactDataTableStorage);
1913
- var DataTableViewSchema = Schema2.Union([
1914
- Schema2.Literal("table"),
1915
- Schema2.Literal("gallery")
1916
- ]).annotate({ identifier: "DataTableView" });
1917
- var ColumnVisibilitySchema = Schema2.Record(Schema2.String, Schema2.Boolean).annotate({ identifier: "DataTableColumnVisibility" });
1918
- var ColumnSizingSchema = Schema2.Record(Schema2.String, Schema2.Number).annotate({
1919
- identifier: "DataTableColumnSizing"
1920
- });
1921
- var RowDragDataSchema = Schema2.Struct({
1922
- type: Schema2.Literal("row"),
1923
- label: Schema2.optional(Schema2.String),
1924
- rowId: Schema2.String
1925
- }).annotate({ identifier: "DataTableRowDragData" });
1926
- var RowReorderDragDataSchema = Schema2.Struct({
1927
- type: Schema2.Literal("row-reorder")
1928
- }).annotate({ identifier: "DataTableRowReorderDragData" });
1929
- var GroupDropDataSchema = Schema2.Struct({
1930
- type: Schema2.Literal("group-target"),
1931
- fieldId: Schema2.String,
1932
- groupId: Schema2.String
1933
- }).annotate({ identifier: "DataTableGroupDropData" });
1934
- var decodeTableSearch = Schema2.decodeUnknownOption(TableSearchSchema);
1935
- var decodeDataTableView = Schema2.decodeUnknownOption(DataTableViewSchema);
1936
- var decodeRowDragData = Schema2.decodeUnknownOption(RowDragDataSchema);
1937
- var decodeRowReorderDragData = Schema2.decodeUnknownOption(RowReorderDragDataSchema);
1938
- var decodeGroupDropData = Schema2.decodeUnknownOption(GroupDropDataSchema);
1939
- var validateTableSearchUpdate = (search) => ({
1940
- ...search,
1941
- ...Schema2.decodeUnknownSync(TableSearchSchema)(search)
1942
- });
1808
+ import { jsx as jsx17, jsxs as jsxs9, Fragment } from "react/jsx-runtime";
1943
1809
  var messages3 = {
1944
1810
  en: {
1945
1811
  ...paginationMessages("en"),
@@ -1956,11 +1822,11 @@ var messages3 = {
1956
1822
  galleryView: "Gallery",
1957
1823
  columns: "Columns",
1958
1824
  groupBy: "Group by",
1959
- sortAsc: "Asc",
1960
- sortDesc: "Desc",
1961
- sortHide: "Hide",
1962
- sortClear: "Clear",
1825
+ sortAsc: "Ascending",
1826
+ sortDesc: "Descending",
1827
+ sortClear: "Clear sorting",
1963
1828
  sortBy: "Sort by",
1829
+ hideColumn: "Hide column",
1964
1830
  reorder: "Drag to reorder",
1965
1831
  resizeColumn: (column) => `Resize ${column} column`,
1966
1832
  listOthers: (count) => count === 1 ? "and 1 other" : `and ${count} others`,
@@ -1985,9 +1851,9 @@ var messages3 = {
1985
1851
  groupBy: "Grouper par",
1986
1852
  sortAsc: "Croissant",
1987
1853
  sortDesc: "Décroissant",
1988
- sortHide: "Cacher",
1989
- sortClear: "Effacer",
1854
+ sortClear: "Effacer le tri",
1990
1855
  sortBy: "Trier par",
1856
+ hideColumn: "Masquer la colonne",
1991
1857
  reorder: "Glisser pour réordonner",
1992
1858
  resizeColumn: (column) => `Redimensionner la colonne ${column}`,
1993
1859
  listOthers: (count) => count === 1 ? "et 1 autre" : `et ${count} autres`,
@@ -2000,63 +1866,318 @@ var dataTableMessages = (overrides) => ({
2000
1866
  ...getLocale().startsWith("fr") ? messages3.fr : messages3.en,
2001
1867
  ...overrides
2002
1868
  });
2003
- var GROUP_INDENT_PX = 20;
2004
- var GROUP_ROW_INDENT_OFFSET_PX = 44;
2005
- var snapDragOverlayVerticalCenterToCursor = ({
2006
- activatorEvent,
2007
- activeNodeRect,
2008
- overlayNodeRect,
2009
- transform
2010
- }) => {
2011
- if (!globalThis.window || !(activatorEvent instanceof globalThis.window.MouseEvent) || !activeNodeRect || !overlayNodeRect) {
2012
- return transform;
1869
+ var DEFAULT_MIN_WIDTH = 96;
1870
+ var DEFAULT_WIDTH = 208;
1871
+ var DEFAULT_MAX_WIDTH = 640;
1872
+ var DEFAULT_STATE = {
1873
+ globalFilter: "",
1874
+ sorting: [],
1875
+ pagination: { pageIndex: 0, pageSize: 10 },
1876
+ columnVisibility: {},
1877
+ columnSizing: {},
1878
+ rowSelection: {},
1879
+ grouping: [],
1880
+ collapsedGroups: {},
1881
+ view: "table"
1882
+ };
1883
+ var clampWidth = (column, width) => Math.min(column.maxWidth ?? DEFAULT_MAX_WIDTH, Math.max(column.minWidth ?? DEFAULT_MIN_WIDTH, width));
1884
+ var normalizeDataTableColumns = (columnDefs, columnSizing = {}) => {
1885
+ const ids = new Set;
1886
+ return columnDefs.map((colDef) => {
1887
+ const id = colDef.field ?? colDef.colId;
1888
+ if (!id) {
1889
+ throw new Error("DataTable columns require a field or colId");
1890
+ }
1891
+ if (ids.has(id)) {
1892
+ throw new Error(`DataTable column IDs must be unique: ${id}`);
1893
+ }
1894
+ ids.add(id);
1895
+ return {
1896
+ id,
1897
+ colDef,
1898
+ width: clampWidth(colDef, columnSizing[id] ?? colDef.width ?? DEFAULT_WIDTH)
1899
+ };
1900
+ });
1901
+ };
1902
+ var getDataTableWidth = (columns, utilityColumns = 0) => columns.reduce((total, column) => total + column.width, 0) + utilityColumns * 40;
1903
+ var buildDataTableRows = (rowData, columns, getRowId) => {
1904
+ const ids = new Set;
1905
+ return rowData.map((data, index) => {
1906
+ const id = getRowId?.(data) ?? String(index);
1907
+ if (ids.has(id))
1908
+ throw new Error(`DataTable row IDs must be unique: ${id}`);
1909
+ ids.add(id);
1910
+ return {
1911
+ id,
1912
+ data,
1913
+ index,
1914
+ values: new Map(columns.map((column) => {
1915
+ const { colDef } = column;
1916
+ const value = colDef.valueGetter ? colDef.valueGetter({ data, rowId: id, rowIndex: index, colDef }) : colDef.field ? data[colDef.field] : undefined;
1917
+ return [column.id, value];
1918
+ }))
1919
+ };
1920
+ });
1921
+ };
1922
+ var filterDataTableRows = (rows, columns, globalFilter) => {
1923
+ const query = globalFilter.trim().toLocaleLowerCase();
1924
+ if (!query)
1925
+ return [...rows];
1926
+ const searchable = columns.filter(({ colDef }) => colDef.searchable !== false);
1927
+ return rows.filter((row) => searchable.some((column) => String(row.values.get(column.id) ?? "").toLocaleLowerCase().includes(query)));
1928
+ };
1929
+ var sortDataTableRows = (rows, columns, sorting) => {
1930
+ const byId = new Map(columns.map((column) => [column.id, column]));
1931
+ return rows.map((row, stableIndex) => ({ row, stableIndex })).sort((left, right) => {
1932
+ for (const sort of sorting) {
1933
+ const column = byId.get(sort.id);
1934
+ if (!column)
1935
+ continue;
1936
+ const leftValue = left.row.values.get(sort.id);
1937
+ const rightValue = right.row.values.get(sort.id);
1938
+ const comparison = column.colDef.comparator ? column.colDef.comparator(leftValue, rightValue, left.row.data, right.row.data) : Object.is(leftValue, rightValue) ? 0 : leftValue === null || leftValue === undefined ? 1 : rightValue === null || rightValue === undefined ? -1 : Schema.is(Schema.Number)(leftValue) && Schema.is(Schema.Number)(rightValue) ? leftValue - rightValue : String(leftValue).localeCompare(String(rightValue), undefined, { numeric: true, sensitivity: "base" });
1939
+ if (comparison !== 0)
1940
+ return sort.desc ? -comparison : comparison;
1941
+ }
1942
+ return left.stableIndex - right.stableIndex;
1943
+ }).map(({ row }) => row);
1944
+ };
1945
+ var paginateDataTableRows = (rows, pagination) => {
1946
+ const pageSize = Math.max(1, pagination.pageSize);
1947
+ const lastPageIndex = Math.max(0, Math.ceil(rows.length / pageSize) - 1);
1948
+ const pageIndex = Math.min(lastPageIndex, Math.max(0, pagination.pageIndex));
1949
+ const start = pageIndex * pageSize;
1950
+ return rows.slice(start, start + pageSize);
1951
+ };
1952
+ var mergeDataTableState = (state, controlledState = {}) => ({
1953
+ globalFilter: controlledState.globalFilter ?? state.globalFilter,
1954
+ sorting: controlledState.sorting ?? state.sorting,
1955
+ pagination: controlledState.pagination ?? state.pagination,
1956
+ columnVisibility: controlledState.columnVisibility ?? state.columnVisibility,
1957
+ columnSizing: controlledState.columnSizing ?? state.columnSizing,
1958
+ rowSelection: controlledState.rowSelection ?? state.rowSelection,
1959
+ grouping: controlledState.grouping ?? state.grouping,
1960
+ collapsedGroups: controlledState.collapsedGroups ?? state.collapsedGroups,
1961
+ view: controlledState.view ?? state.view
1962
+ });
1963
+ var sameDataTableState = (left, right) => left.globalFilter === right.globalFilter && left.sorting === right.sorting && left.pagination === right.pagination && left.columnVisibility === right.columnVisibility && left.columnSizing === right.columnSizing && left.rowSelection === right.rowSelection && left.grouping === right.grouping && left.collapsedGroups === right.collapsedGroups && left.view === right.view;
1964
+ var reorderDataTableRows = (rows, sourceRowId, targetRowId) => {
1965
+ const sourceIndex = rows.findIndex((row) => row.id === sourceRowId);
1966
+ const targetIndex = rows.findIndex((row) => row.id === targetRowId);
1967
+ const reordered = rows.map((row) => row.data);
1968
+ if (sourceIndex === -1 || targetIndex === -1 || sourceIndex === targetIndex) {
1969
+ return reordered;
2013
1970
  }
1971
+ const [source] = reordered.splice(sourceIndex, 1);
1972
+ if (source)
1973
+ reordered.splice(targetIndex, 0, source);
1974
+ return reordered;
1975
+ };
1976
+ var RowIdContext = createContext(null);
1977
+ var ColumnIdContext = createContext(null);
1978
+ var useRequiredId = (context) => {
1979
+ const id = useContext(context);
1980
+ if (!id)
1981
+ throw new Error("DataTable internal ID context is missing");
1982
+ return id;
1983
+ };
1984
+ var getGroupDropKey = (fieldId, groupId) => `${encodeURIComponent(fieldId)}:${encodeURIComponent(groupId)}`;
1985
+ var parseGroupDropKey = (key) => {
1986
+ const separator = key.indexOf(":");
1987
+ if (separator === -1)
1988
+ return null;
2014
1989
  return {
2015
- ...transform,
2016
- y: transform.y + activatorEvent.clientY - activeNodeRect.top - overlayNodeRect.height / 2
1990
+ fieldId: decodeURIComponent(key.slice(0, separator)),
1991
+ groupId: decodeURIComponent(key.slice(separator + 1))
2017
1992
  };
2018
1993
  };
2019
- var getDefaultGrouping = (grouping) => {
2020
- if (!grouping) {
2021
- return [];
1994
+ var findTableDragTarget = (elements, selector, root) => {
1995
+ for (const element of elements) {
1996
+ const target = element.closest(selector);
1997
+ if (target instanceof HTMLElement && root?.contains(target))
1998
+ return target;
2022
1999
  }
2023
- const validInitial = grouping.initial?.filter((id) => grouping.fields.some((field) => field.id === id));
2024
- if (validInitial?.length) {
2025
- return validInitial;
2000
+ return null;
2001
+ };
2002
+ var clearDragPresentation = (root) => {
2003
+ root?.querySelectorAll("[data-drag-source], [data-drop-target], [data-drop-position]").forEach((element) => {
2004
+ element.removeAttribute("data-drag-source");
2005
+ element.removeAttribute("data-drop-target");
2006
+ element.removeAttribute("data-drop-position");
2007
+ });
2008
+ };
2009
+ var resolveConfig = (props) => {
2010
+ const features = props.features ?? {};
2011
+ const selection = features.selection;
2012
+ const getRowId = selection && selection.getRowId || props.getRowId || undefined;
2013
+ if ((selection || features.reordering) && !getRowId) {
2014
+ throw new Error("DataTable requires getRowId when selection or reordering is enabled");
2026
2015
  }
2027
- return grouping.fields[0] ? [grouping.fields[0].id] : [];
2016
+ return {
2017
+ getRowId,
2018
+ onStateChange: props.onStateChange,
2019
+ status: props.status ?? {},
2020
+ features,
2021
+ onRowClicked: props.onRowClicked,
2022
+ labels: dataTableMessages(props.messages)
2023
+ };
2024
+ };
2025
+ var initialPublicState = (props) => {
2026
+ const grouping = props.features?.grouping;
2027
+ const groupingInitial = grouping && grouping.initial ? grouping.initial : [];
2028
+ return {
2029
+ ...DEFAULT_STATE,
2030
+ grouping: groupingInitial,
2031
+ ...props.initialState,
2032
+ ...props.state
2033
+ };
2034
+ };
2035
+ var buildDataTableModel = (store) => {
2036
+ const columns = normalizeDataTableColumns(store.columnDefs, store.state.columnSizing);
2037
+ const selection = store.config.features.selection;
2038
+ const rowId = selection && selection.getRowId || store.config.getRowId || undefined;
2039
+ const rows = buildDataTableRows(store.rowData, columns, rowId);
2040
+ const pagination = store.config.features.pagination ?? { mode: "client" };
2041
+ const server = pagination !== false && pagination.mode === "server";
2042
+ const filteredRows = server ? [...rows] : filterDataTableRows(rows, columns, store.state.globalFilter);
2043
+ const sortedRows = server ? filteredRows : sortDataTableRows(filteredRows, columns, store.state.sorting);
2044
+ const pageRows = pagination === false || server ? sortedRows : paginateDataTableRows(sortedRows, store.state.pagination);
2045
+ const totalRows = server ? pagination.rowCount : sortedRows.length;
2046
+ return {
2047
+ columns,
2048
+ visibleColumns: columns.filter(({ id }) => store.state.columnVisibility[id] !== false),
2049
+ rows,
2050
+ filteredRows,
2051
+ sortedRows,
2052
+ pageRows,
2053
+ pageCount: Math.max(1, Math.ceil(totalRows / Math.max(1, store.state.pagination.pageSize))),
2054
+ totalRows
2055
+ };
2056
+ };
2057
+ var useTableAtom = (tableAtom) => useAtom(tableAtom);
2058
+ var changeState = (setStore, update) => {
2059
+ setStore((store) => {
2060
+ const proposed = update(store.state);
2061
+ store.config.onStateChange?.(proposed);
2062
+ const state = mergeDataTableState(proposed, store.controlledState);
2063
+ if (sameDataTableState(state, store.state))
2064
+ return store;
2065
+ const next = { ...store, state };
2066
+ return { ...next, model: buildDataTableModel(next) };
2067
+ });
2068
+ };
2069
+ var deriveModel = (store) => store.model;
2070
+ var groupDataTableRows = (rows, fields, depth = 0, parentKey = "") => {
2071
+ const field = fields[0];
2072
+ if (!field)
2073
+ return [];
2074
+ const groups = new Map;
2075
+ field.getGroupIds?.().forEach((id) => groups.set(id, []));
2076
+ rows.forEach((row) => {
2077
+ const ids = field.getRowGroupIds?.(row.data) ?? [
2078
+ field.getGroupId(row.data)
2079
+ ];
2080
+ ids.forEach((id) => groups.set(id, [...groups.get(id) ?? [], row]));
2081
+ });
2082
+ return Array.from(groups, ([groupId, groupRows]) => {
2083
+ const segment = `${encodeURIComponent(field.id)}:${encodeURIComponent(groupId)}`;
2084
+ const key = `${parentKey}${parentKey ? "/" : ""}${segment}`;
2085
+ return {
2086
+ key,
2087
+ groupId,
2088
+ depth,
2089
+ field,
2090
+ rows: groupRows,
2091
+ children: groupDataTableRows(groupRows, fields.slice(1), depth + 1, key)
2092
+ };
2093
+ });
2094
+ };
2095
+ var getDataTableSelectableRows = (model, grouped, isRowSelectable) => (grouped ? model.sortedRows : model.pageRows).filter((row) => isRowSelectable?.(row.data) ?? true);
2096
+ var getActiveGrouping = (store) => {
2097
+ const grouping = store.config.features.grouping;
2098
+ if (!grouping)
2099
+ return [];
2100
+ return store.state.grouping.flatMap((id) => {
2101
+ const field = grouping.fields.find((candidate) => candidate.id === id);
2102
+ return field ? [field] : [];
2103
+ });
2104
+ };
2105
+ var canReorderRows = (store) => {
2106
+ const pagination = store.config.features.pagination;
2107
+ return !!store.config.features.reordering && !getActiveGrouping(store).length && !store.state.globalFilter && !store.state.sorting.length && !(pagination && pagination.mode === "server");
2108
+ };
2109
+ var canMoveRowsToGroups = (store) => getActiveGrouping(store).some((field) => !!field.onMoveToGroup);
2110
+ var canDragRows = (store) => getActiveGrouping(store).length ? canMoveRowsToGroups(store) : canReorderRows(store);
2111
+ var getSelectedRows = (store, model) => model.rows.filter((row) => store.state.rowSelection[row.id]).map((row) => row.data);
2112
+ var renderCell = (row, column) => {
2113
+ const value = row.values.get(column.id);
2114
+ const params = {
2115
+ data: row.data,
2116
+ value,
2117
+ rowId: row.id,
2118
+ rowIndex: row.index,
2119
+ colDef: column.colDef
2120
+ };
2121
+ const CellRenderer = column.colDef.cellRenderer;
2122
+ if (CellRenderer)
2123
+ return /* @__PURE__ */ jsx17(CellRenderer, {
2124
+ ...params
2125
+ });
2126
+ return column.colDef.valueFormatter?.(params) ?? (value === null || value === undefined ? null : String(value));
2127
+ };
2128
+ var nodeText = (node) => {
2129
+ if (Schema.is(Schema.String)(node) || Schema.is(Schema.Number)(node))
2130
+ return String(node);
2131
+ if (!isValidElement(node))
2132
+ return "";
2133
+ if (Schema.is(Schema.String)(node.props.title))
2134
+ return node.props.title;
2135
+ return nodeText(node.props.children);
2136
+ };
2137
+ var columnLabel = (column) => nodeText(column.colDef.headerName) || column.id;
2138
+ var withExtension = (fileName, extension) => fileName.includes(".") ? fileName.replace(/\.[^/.]+$/, `.${extension}`) : `${fileName}.${extension}`;
2139
+ var escapeCsvValue = (value) => {
2140
+ if (value === null || value === undefined)
2141
+ return "";
2142
+ const text = String(value);
2143
+ return /[",\n]/.test(text) ? `"${text.replace(/"/g, '""')}"` : text;
2028
2144
  };
2029
- var getGroupTargetDropId = (key) => `group-target:${key}`;
2030
- var getRowDragId = (rowId) => `row:${rowId}`;
2031
- var getSortableRowId = (rowId) => `sortable-row:${rowId}`;
2032
- var getGroupLabels = (section) => {
2033
- const rows = section.rows.map((row) => row.original);
2034
- const label = section.field.getGroupLabel?.(section.groupId, rows) ?? section.groupId;
2035
- return section.field.renderGroupLabel?.(section.groupId, rows) ?? label;
2145
+ var downloadCsv = (headers, data, fileName = "data.csv") => {
2146
+ const content = [headers, ...data].map((row) => row.map(escapeCsvValue).join(",")).join(`
2147
+ `);
2148
+ downloadBlob(content, "text/csv;charset=utf-8", withExtension(fileName, "csv"));
2149
+ };
2150
+ var downloadJson = (data, fileName = "data.json") => downloadBlob(JSON.stringify(data, null, 2), "application/json;charset=utf-8", withExtension(fileName, "json"));
2151
+ var downloadBlob = (content, type, fileName) => {
2152
+ const url = window.URL.createObjectURL(new Blob([content], { type }));
2153
+ const link = document.createElement("a");
2154
+ link.href = url;
2155
+ link.download = fileName;
2156
+ document.body.appendChild(link);
2157
+ link.click();
2158
+ link.remove();
2159
+ requestAnimationFrame(() => window.URL.revokeObjectURL(url));
2036
2160
  };
2037
2161
  var DataTableRowActions = ({
2038
2162
  actions,
2039
- contentClassName,
2040
2163
  row,
2041
2164
  title
2042
2165
  }) => {
2043
- const resolvedTitle = title ?? dataTableMessages().actions;
2044
- const visibleActions = actions.filter((action) => !action.visible || action.visible(row));
2045
- if (visibleActions.length === 0) {
2166
+ const visible = actions.filter((action) => !action.visible || action.visible(row));
2167
+ if (!visible.length)
2046
2168
  return null;
2047
- }
2048
- return /* @__PURE__ */ jsxs8(DropdownMenu, {
2169
+ return /* @__PURE__ */ jsxs9(DropdownMenu, {
2049
2170
  children: [
2050
2171
  /* @__PURE__ */ jsx17(DropdownMenuTrigger, {
2051
2172
  onClick: (event) => event.stopPropagation(),
2052
- render: /* @__PURE__ */ jsxs8(Button, {
2173
+ render: /* @__PURE__ */ jsxs9(Button, {
2053
2174
  className: "size-8 focus-visible:ring-inset [&_svg:not([class*='size-'])]:size-4",
2054
- variant: "ghost",
2055
2175
  size: "icon",
2176
+ variant: "ghost",
2056
2177
  children: [
2057
2178
  /* @__PURE__ */ jsx17("span", {
2058
2179
  className: "sr-only",
2059
- children: resolvedTitle
2180
+ children: title
2060
2181
  }),
2061
2182
  /* @__PURE__ */ jsx17(MoreHorizontal, {})
2062
2183
  ]
@@ -2064,20 +2185,19 @@ var DataTableRowActions = ({
2064
2185
  }),
2065
2186
  /* @__PURE__ */ jsx17(DropdownMenuContent, {
2066
2187
  align: "end",
2067
- className: cn("w-max", contentClassName),
2068
- children: /* @__PURE__ */ jsxs8(DropdownMenuGroup, {
2188
+ className: "w-max",
2189
+ children: /* @__PURE__ */ jsxs9(DropdownMenuGroup, {
2069
2190
  children: [
2070
2191
  /* @__PURE__ */ jsx17(DropdownMenuLabel, {
2071
- children: resolvedTitle
2192
+ children: title
2072
2193
  }),
2073
2194
  /* @__PURE__ */ jsx17(DropdownMenuSeparator, {}),
2074
- visibleActions.map((action) => /* @__PURE__ */ jsxs8(DropdownMenuItem, {
2075
- className: "whitespace-nowrap",
2195
+ visible.map((action) => /* @__PURE__ */ jsxs9(DropdownMenuItem, {
2076
2196
  onClick: (event) => {
2077
2197
  event.stopPropagation();
2078
2198
  action.onClick(row);
2079
2199
  },
2080
- ...action.variant ? { variant: action.variant } : {},
2200
+ variant: action.variant,
2081
2201
  children: [
2082
2202
  action.icon,
2083
2203
  action.name
@@ -2089,1609 +2209,1291 @@ var DataTableRowActions = ({
2089
2209
  ]
2090
2210
  });
2091
2211
  };
2092
- var DataTableBulkActions = ({
2093
- actions,
2094
- label,
2095
- selectedLabel: selectedLabel2,
2096
- rows
2212
+ var DataTableToolbar = ({
2213
+ tableAtom
2097
2214
  }) => {
2098
- const visibleActions = actions.filter((action) => !action.visible || action.visible(rows));
2099
- if (visibleActions.length === 0)
2215
+ const [store, setStore] = useTableAtom(tableAtom);
2216
+ const { features, labels: labels2 } = store.config;
2217
+ const model = deriveModel(store);
2218
+ const selectedRows = getSelectedRows(store, model);
2219
+ const grouping = features.grouping;
2220
+ const bulkActions = features.selection && features.selection.bulkActions;
2221
+ const hasToolbar = features.search !== false || features.sorting !== false || features.columnVisibility !== false || !!features.export || !!features.gallery || !!grouping || !!features.refresh || !!bulkActions && selectedRows.length > 0;
2222
+ if (!hasToolbar)
2100
2223
  return null;
2101
- return /* @__PURE__ */ jsxs8(DropdownMenu, {
2224
+ const update = (next) => changeState(setStore, next);
2225
+ const visibleBulkActions = bulkActions ? bulkActions.items.filter((action) => !action.visible || action.visible(selectedRows)) : [];
2226
+ const exportRows = features.export && features.export.scope === "filteredRows" ? model.filteredRows : model.pageRows;
2227
+ return /* @__PURE__ */ jsxs9("div", {
2228
+ className: "flex flex-col gap-2 pb-4",
2102
2229
  children: [
2103
- /* @__PURE__ */ jsx17(DropdownMenuTrigger, {
2104
- render: /* @__PURE__ */ jsxs8(Button, {
2105
- className: "h-9",
2106
- size: "sm",
2107
- variant: "default",
2108
- children: [
2109
- selectedLabel2,
2110
- /* @__PURE__ */ jsx17(Badge, {
2111
- className: "bg-primary-foreground/15 text-primary-foreground min-w-5 justify-center rounded-full border-0 px-1.5 tabular-nums",
2112
- variant: "secondary",
2113
- children: rows.length
2114
- }),
2115
- /* @__PURE__ */ jsx17(ChevronRight2, {
2116
- className: "rotate-90"
2117
- })
2118
- ]
2119
- })
2120
- }),
2121
- /* @__PURE__ */ jsx17(DropdownMenuContent, {
2122
- align: "start",
2123
- className: "w-max max-w-56",
2124
- children: /* @__PURE__ */ jsxs8(DropdownMenuGroup, {
2230
+ features.search !== false ? /* @__PURE__ */ jsxs9("div", {
2231
+ className: "relative min-w-0",
2232
+ children: [
2233
+ /* @__PURE__ */ jsx17(Search, {
2234
+ className: "text-muted-foreground pointer-events-none absolute top-1/2 left-3 size-4 -translate-y-1/2"
2235
+ }),
2236
+ /* @__PURE__ */ jsx17(Input, {
2237
+ className: "px-9",
2238
+ onChange: (event) => update((state) => ({
2239
+ ...state,
2240
+ globalFilter: event.target.value,
2241
+ pagination: { ...state.pagination, pageIndex: 0 }
2242
+ })),
2243
+ placeholder: labels2.filter,
2244
+ value: store.state.globalFilter
2245
+ }),
2246
+ store.state.globalFilter ? /* @__PURE__ */ jsx17(Button, {
2247
+ "aria-label": labels2.filter,
2248
+ className: "absolute top-1/2 right-1 size-7 -translate-y-1/2",
2249
+ onClick: () => update((state) => ({
2250
+ ...state,
2251
+ globalFilter: "",
2252
+ pagination: { ...state.pagination, pageIndex: 0 }
2253
+ })),
2254
+ size: "icon",
2255
+ variant: "ghost",
2256
+ children: /* @__PURE__ */ jsx17(X2, {})
2257
+ }) : null
2258
+ ]
2259
+ }) : null,
2260
+ /* @__PURE__ */ jsx17("div", {
2261
+ className: "-m-1 flex w-full overflow-x-auto p-1",
2262
+ children: /* @__PURE__ */ jsxs9(Menubar, {
2263
+ className: "h-auto w-max min-w-full justify-start bg-transparent shadow-none [&_[data-slot=menubar-trigger]]:gap-2 [&_[data-slot=menubar-trigger]_svg]:size-4",
2125
2264
  children: [
2126
- /* @__PURE__ */ jsx17(DropdownMenuLabel, {
2127
- children: label
2128
- }),
2129
- /* @__PURE__ */ jsx17(DropdownMenuSeparator, {}),
2130
- visibleActions.map((action) => /* @__PURE__ */ jsxs8(DropdownMenuItem, {
2131
- className: "whitespace-nowrap",
2132
- onClick: () => action.onClick(rows),
2133
- ...action.variant ? { variant: action.variant } : {},
2265
+ visibleBulkActions.length ? /* @__PURE__ */ jsxs9(MenubarMenu, {
2134
2266
  children: [
2135
- action.icon,
2136
- action.name
2267
+ /* @__PURE__ */ jsxs9(MenubarTrigger, {
2268
+ className: "bg-primary text-primary-foreground hover:bg-primary/90 aria-expanded:bg-primary/90",
2269
+ children: [
2270
+ labels2.selected,
2271
+ /* @__PURE__ */ jsx17(Badge, {
2272
+ variant: "secondary",
2273
+ children: selectedRows.length
2274
+ }),
2275
+ /* @__PURE__ */ jsx17(ChevronDown, {})
2276
+ ]
2277
+ }),
2278
+ /* @__PURE__ */ jsx17(MenubarContent, {
2279
+ align: "end",
2280
+ className: "w-max",
2281
+ children: /* @__PURE__ */ jsxs9(MenubarGroup, {
2282
+ children: [
2283
+ /* @__PURE__ */ jsx17(MenubarLabel, {
2284
+ children: bulkActions && bulkActions.label ? bulkActions.label : labels2.actions
2285
+ }),
2286
+ /* @__PURE__ */ jsx17(MenubarSeparator, {}),
2287
+ visibleBulkActions.map((action) => /* @__PURE__ */ jsxs9(MenubarItem, {
2288
+ onClick: () => action.onClick(selectedRows),
2289
+ variant: action.variant,
2290
+ children: [
2291
+ action.icon,
2292
+ action.name
2293
+ ]
2294
+ }, action.id ?? action.name))
2295
+ ]
2296
+ })
2297
+ })
2137
2298
  ]
2138
- }, action.id ?? action.name))
2299
+ }) : null,
2300
+ grouping ? /* @__PURE__ */ jsxs9(MenubarMenu, {
2301
+ children: [
2302
+ /* @__PURE__ */ jsxs9(MenubarTrigger, {
2303
+ "aria-label": labels2.groupBy,
2304
+ children: [
2305
+ /* @__PURE__ */ jsx17(Rows3, {}),
2306
+ /* @__PURE__ */ jsx17("span", {
2307
+ className: "hidden sm:inline",
2308
+ children: labels2.groupBy
2309
+ })
2310
+ ]
2311
+ }),
2312
+ /* @__PURE__ */ jsx17(MenubarContent, {
2313
+ align: "end",
2314
+ children: /* @__PURE__ */ jsxs9(MenubarGroup, {
2315
+ children: [
2316
+ /* @__PURE__ */ jsx17(MenubarLabel, {
2317
+ children: labels2.groupBy
2318
+ }),
2319
+ /* @__PURE__ */ jsx17(MenubarSeparator, {}),
2320
+ grouping.fields.map((field) => /* @__PURE__ */ jsx17(MenubarCheckboxItem, {
2321
+ checked: store.state.grouping.includes(field.id),
2322
+ onCheckedChange: (checked) => update((state) => ({
2323
+ ...state,
2324
+ grouping: checked ? [...state.grouping, field.id] : state.grouping.filter((id) => id !== field.id)
2325
+ })),
2326
+ children: field.label
2327
+ }, field.id))
2328
+ ]
2329
+ })
2330
+ })
2331
+ ]
2332
+ }) : null,
2333
+ features.sorting !== false ? /* @__PURE__ */ jsx17(SortMenu, {
2334
+ tableAtom
2335
+ }) : null,
2336
+ features.gallery ? /* @__PURE__ */ jsx17(ViewMenu, {
2337
+ tableAtom
2338
+ }) : null,
2339
+ features.columnVisibility !== false ? /* @__PURE__ */ jsx17(ColumnMenu, {
2340
+ tableAtom
2341
+ }) : null,
2342
+ features.refresh ? /* @__PURE__ */ jsx17(MenubarMenu, {
2343
+ children: /* @__PURE__ */ jsxs9(MenubarTrigger, {
2344
+ "aria-label": labels2.refresh,
2345
+ onClick: features.refresh,
2346
+ children: [
2347
+ /* @__PURE__ */ jsx17(RefreshCw, {}),
2348
+ /* @__PURE__ */ jsx17("span", {
2349
+ className: "hidden sm:inline",
2350
+ children: labels2.refresh
2351
+ })
2352
+ ]
2353
+ })
2354
+ }) : null,
2355
+ features.export ? /* @__PURE__ */ jsxs9(MenubarMenu, {
2356
+ children: [
2357
+ /* @__PURE__ */ jsxs9(MenubarTrigger, {
2358
+ "aria-label": labels2.export,
2359
+ disabled: !exportRows.length,
2360
+ children: [
2361
+ /* @__PURE__ */ jsx17(Download, {}),
2362
+ /* @__PURE__ */ jsx17("span", {
2363
+ className: "hidden sm:inline",
2364
+ children: labels2.export
2365
+ })
2366
+ ]
2367
+ }),
2368
+ /* @__PURE__ */ jsx17(MenubarContent, {
2369
+ align: "end",
2370
+ children: /* @__PURE__ */ jsxs9(MenubarGroup, {
2371
+ children: [
2372
+ /* @__PURE__ */ jsx17(MenubarLabel, {
2373
+ children: labels2.export
2374
+ }),
2375
+ /* @__PURE__ */ jsx17(MenubarSeparator, {}),
2376
+ /* @__PURE__ */ jsxs9(MenubarItem, {
2377
+ onClick: () => downloadCsv(model.visibleColumns.map(columnLabel), exportRows.map((row) => model.visibleColumns.map((column) => String(row.values.get(column.id) ?? ""))), features.export ? features.export.baseName : "table"),
2378
+ children: [
2379
+ /* @__PURE__ */ jsx17(FileText, {}),
2380
+ labels2.exportCsv
2381
+ ]
2382
+ }),
2383
+ /* @__PURE__ */ jsxs9(MenubarItem, {
2384
+ onClick: () => downloadJson(exportRows.map((row) => Object.fromEntries(model.visibleColumns.map((column) => [
2385
+ column.id,
2386
+ row.values.get(column.id)
2387
+ ]))), features.export ? features.export.baseName : "table"),
2388
+ children: [
2389
+ /* @__PURE__ */ jsx17(FileJson, {}),
2390
+ labels2.exportJson
2391
+ ]
2392
+ })
2393
+ ]
2394
+ })
2395
+ })
2396
+ ]
2397
+ }) : null
2139
2398
  ]
2140
2399
  })
2141
2400
  })
2142
2401
  ]
2143
2402
  });
2144
2403
  };
2145
- var buildGroupedSections = (rows, fields, depth = 0, parentKey = "") => {
2146
- if (fields.length === 0) {
2147
- return [];
2148
- }
2149
- const [field, ...remainingFields] = fields;
2150
- const groups = new Map;
2151
- field.getGroupIds?.().forEach((groupId) => {
2152
- groups.set(groupId, []);
2153
- });
2154
- rows.forEach((row) => {
2155
- const groupIds = field.getRowGroupIds?.(row.original) ?? [
2156
- field.getGroupId(row.original)
2157
- ];
2158
- for (const groupId of groupIds) {
2159
- const currentRows = groups.get(groupId) ?? [];
2160
- currentRows.push(row);
2161
- groups.set(groupId, currentRows);
2162
- }
2163
- });
2164
- return Array.from(groups.entries()).map(([groupId, groupRows]) => {
2165
- const key = parentKey ? `${parentKey}::${field.id}:${groupId}` : `${field.id}:${groupId}`;
2166
- return {
2167
- key,
2168
- groupId,
2169
- depth,
2170
- field,
2171
- rows: groupRows,
2172
- children: groupRows.length > 0 ? buildGroupedSections(groupRows, remainingFields, depth + 1, key) : []
2173
- };
2174
- });
2175
- };
2176
- var GroupHeaderRow = ({
2177
- collapsed,
2178
- colSpan,
2179
- onToggle,
2180
- section
2404
+ var SortMenu = ({
2405
+ tableAtom
2181
2406
  }) => {
2182
- return /* @__PURE__ */ jsx17(TableRow, {
2183
- children: /* @__PURE__ */ jsx17(TableCell, {
2184
- className: "relative p-0",
2185
- colSpan,
2186
- onClick: onToggle,
2187
- children: /* @__PURE__ */ jsxs8("div", {
2188
- className: "flex cursor-pointer items-center gap-3 px-2 py-2 font-medium transition-colors",
2189
- style: {
2190
- paddingLeft: `calc(0.5rem + ${section.depth * GROUP_INDENT_PX}px)`
2191
- },
2407
+ const [store, setStore] = useTableAtom(tableAtom);
2408
+ const columns = deriveModel(store).columns.filter(({ colDef }) => colDef.sortable !== false);
2409
+ if (!columns.length)
2410
+ return null;
2411
+ const current = store.state.sorting[0];
2412
+ const sort = (id, desc) => changeState(setStore, (state) => ({
2413
+ ...state,
2414
+ sorting: [{ id, desc }],
2415
+ pagination: { ...state.pagination, pageIndex: 0 }
2416
+ }));
2417
+ return /* @__PURE__ */ jsxs9(MenubarMenu, {
2418
+ children: [
2419
+ /* @__PURE__ */ jsxs9(MenubarTrigger, {
2420
+ "aria-label": store.config.labels.sortBy,
2192
2421
  children: [
2193
- collapsed ? /* @__PURE__ */ jsx17(ChevronRight2, {
2194
- className: "size-4"
2195
- }) : /* @__PURE__ */ jsx17(ChevronDown, {
2196
- className: "size-4"
2197
- }),
2198
- /* @__PURE__ */ jsx17("div", {
2199
- className: "min-w-0 flex-1 text-left",
2200
- children: getGroupLabels(section)
2201
- }),
2202
- /* @__PURE__ */ jsx17(Badge, {
2203
- variant: "secondary",
2204
- className: "ml-auto",
2205
- children: section.rows.length
2206
- }),
2207
- /* @__PURE__ */ jsx17(DataTableGroupActions, {
2208
- actions: section.field.actions,
2209
- groupId: section.groupId,
2210
- title: section.field.actionsTitle
2422
+ current ? current.desc ? /* @__PURE__ */ jsx17(ArrowDown, {}) : /* @__PURE__ */ jsx17(ArrowUp, {}) : /* @__PURE__ */ jsx17(ChevronsUpDown2, {}),
2423
+ /* @__PURE__ */ jsx17("span", {
2424
+ className: "hidden sm:inline",
2425
+ children: store.config.labels.sortBy
2211
2426
  })
2212
2427
  ]
2428
+ }),
2429
+ /* @__PURE__ */ jsx17(MenubarContent, {
2430
+ align: "end",
2431
+ className: "w-52",
2432
+ children: columns.map((column) => {
2433
+ const sortState = store.state.sorting.find(({ id }) => id === column.id);
2434
+ return /* @__PURE__ */ jsxs9(MenubarSub, {
2435
+ children: [
2436
+ /* @__PURE__ */ jsxs9(MenubarSubTrigger, {
2437
+ children: [
2438
+ sortState ? sortState.desc ? /* @__PURE__ */ jsx17(ArrowDown, {}) : /* @__PURE__ */ jsx17(ArrowUp, {}) : null,
2439
+ columnLabel(column)
2440
+ ]
2441
+ }),
2442
+ /* @__PURE__ */ jsxs9(MenubarSubContent, {
2443
+ children: [
2444
+ /* @__PURE__ */ jsxs9(MenubarItem, {
2445
+ onClick: () => sort(column.id, false),
2446
+ children: [
2447
+ /* @__PURE__ */ jsx17(ArrowUp, {}),
2448
+ " ",
2449
+ store.config.labels.sortAsc
2450
+ ]
2451
+ }),
2452
+ /* @__PURE__ */ jsxs9(MenubarItem, {
2453
+ onClick: () => sort(column.id, true),
2454
+ children: [
2455
+ /* @__PURE__ */ jsx17(ArrowDown, {}),
2456
+ " ",
2457
+ store.config.labels.sortDesc
2458
+ ]
2459
+ }),
2460
+ sortState ? /* @__PURE__ */ jsxs9(Fragment, {
2461
+ children: [
2462
+ /* @__PURE__ */ jsx17(MenubarSeparator, {}),
2463
+ /* @__PURE__ */ jsxs9(MenubarItem, {
2464
+ onClick: () => changeState(setStore, (state) => ({
2465
+ ...state,
2466
+ sorting: state.sorting.filter(({ id }) => id !== column.id)
2467
+ })),
2468
+ children: [
2469
+ /* @__PURE__ */ jsx17(X2, {}),
2470
+ " ",
2471
+ store.config.labels.sortClear
2472
+ ]
2473
+ })
2474
+ ]
2475
+ }) : null
2476
+ ]
2477
+ })
2478
+ ]
2479
+ }, column.id);
2480
+ })
2213
2481
  })
2214
- })
2215
- });
2216
- };
2217
- var GroupTableSection = ({
2218
- children,
2219
- section
2220
- }) => {
2221
- const { isOver, setNodeRef } = useDroppable({
2222
- id: getGroupTargetDropId(section.key),
2223
- disabled: !section.field.onMoveToGroup,
2224
- data: {
2225
- type: "group-target",
2226
- fieldId: section.field.id,
2227
- groupId: section.groupId
2228
- }
2229
- });
2230
- return /* @__PURE__ */ jsx17(TableBody, {
2231
- className: cn("relative px-2", isOver && "ring-primary ring-1 ring-inset"),
2232
- ref: setNodeRef,
2233
- children
2482
+ ]
2234
2483
  });
2235
2484
  };
2236
- var GroupHeaderCard = ({
2237
- collapsed,
2238
- onToggle,
2239
- section
2485
+ var ViewMenu = ({
2486
+ tableAtom
2240
2487
  }) => {
2241
- const { isOver, setNodeRef } = useDroppable({
2242
- id: getGroupTargetDropId(section.key),
2243
- disabled: !section.field.onMoveToGroup,
2244
- data: {
2245
- type: "group-target",
2246
- fieldId: section.field.id,
2247
- groupId: section.groupId
2248
- }
2249
- });
2250
- return /* @__PURE__ */ jsxs8("div", {
2251
- className: cn("flex w-full items-center gap-3 rounded-lg border px-3 py-2 text-left font-medium transition-colors", isOver && "outline outline-primary"),
2252
- ref: setNodeRef,
2488
+ const [store, setStore] = useTableAtom(tableAtom);
2489
+ return /* @__PURE__ */ jsxs9(MenubarMenu, {
2253
2490
  children: [
2254
- /* @__PURE__ */ jsxs8("button", {
2255
- className: "flex min-w-0 flex-1 items-center gap-3 text-left",
2256
- onClick: onToggle,
2257
- type: "button",
2491
+ /* @__PURE__ */ jsxs9(MenubarTrigger, {
2492
+ "aria-label": store.config.labels.view,
2258
2493
  children: [
2259
- collapsed ? /* @__PURE__ */ jsx17(ChevronRight2, {
2260
- className: "size-4"
2261
- }) : /* @__PURE__ */ jsx17(ChevronDown, {
2262
- className: "size-4"
2263
- }),
2264
- /* @__PURE__ */ jsx17("div", {
2265
- className: "min-w-0 flex-1",
2266
- children: getGroupLabels(section)
2267
- }),
2268
- /* @__PURE__ */ jsx17(Badge, {
2269
- variant: "secondary",
2270
- className: "ml-auto",
2271
- children: section.rows.length
2494
+ store.state.view === "gallery" ? /* @__PURE__ */ jsx17(LayoutGrid, {}) : /* @__PURE__ */ jsx17(Rows3, {}),
2495
+ /* @__PURE__ */ jsx17("span", {
2496
+ className: "hidden sm:inline",
2497
+ children: store.config.labels.view
2272
2498
  })
2273
2499
  ]
2274
2500
  }),
2275
- /* @__PURE__ */ jsx17(DataTableGroupActions, {
2276
- actions: section.field.actions,
2277
- groupId: section.groupId,
2278
- title: section.field.actionsTitle
2501
+ /* @__PURE__ */ jsx17(MenubarContent, {
2502
+ align: "end",
2503
+ children: /* @__PURE__ */ jsxs9(MenubarRadioGroup, {
2504
+ onValueChange: (view) => {
2505
+ if (view === "table" || view === "gallery") {
2506
+ changeState(setStore, (state) => ({ ...state, view }));
2507
+ }
2508
+ },
2509
+ value: store.state.view,
2510
+ children: [
2511
+ /* @__PURE__ */ jsxs9(MenubarRadioItem, {
2512
+ value: "table",
2513
+ children: [
2514
+ /* @__PURE__ */ jsx17(Rows3, {}),
2515
+ " ",
2516
+ store.config.labels.tableView
2517
+ ]
2518
+ }),
2519
+ /* @__PURE__ */ jsxs9(MenubarRadioItem, {
2520
+ value: "gallery",
2521
+ children: [
2522
+ /* @__PURE__ */ jsx17(LayoutGrid, {}),
2523
+ " ",
2524
+ store.config.labels.galleryView
2525
+ ]
2526
+ })
2527
+ ]
2528
+ })
2279
2529
  })
2280
2530
  ]
2281
2531
  });
2282
2532
  };
2283
- var DataTableGroupActions = ({
2284
- actions,
2285
- groupId,
2286
- title
2533
+ var ColumnMenu = ({
2534
+ tableAtom
2287
2535
  }) => {
2288
- const visibleActions = actions?.filter((action) => !action.visible || action.visible(groupId));
2289
- if (!visibleActions?.length)
2536
+ const [store, setStore] = useTableAtom(tableAtom);
2537
+ const columns = deriveModel(store).columns.filter(({ colDef }) => colDef.hideable !== false);
2538
+ if (!columns.length)
2290
2539
  return null;
2291
- return /* @__PURE__ */ jsxs8(DropdownMenu, {
2540
+ return /* @__PURE__ */ jsxs9(MenubarMenu, {
2292
2541
  children: [
2293
- /* @__PURE__ */ jsx17(DropdownMenuTrigger, {
2294
- onClick: (event) => event.stopPropagation(),
2295
- render: /* @__PURE__ */ jsxs8(Button, {
2296
- className: "size-7 shadow-md [&_svg:not([class*='size-'])]:size-3.5",
2297
- size: "icon",
2298
- variant: "ghost",
2299
- children: [
2300
- /* @__PURE__ */ jsx17("span", {
2301
- className: "sr-only",
2302
- children: title
2303
- }),
2304
- /* @__PURE__ */ jsx17(MoreHorizontal, {})
2305
- ]
2306
- })
2542
+ /* @__PURE__ */ jsxs9(MenubarTrigger, {
2543
+ "aria-label": store.config.labels.columns,
2544
+ children: [
2545
+ /* @__PURE__ */ jsx17(Settings2, {}),
2546
+ /* @__PURE__ */ jsx17("span", {
2547
+ className: "hidden sm:inline",
2548
+ children: store.config.labels.columns
2549
+ })
2550
+ ]
2307
2551
  }),
2308
- /* @__PURE__ */ jsx17(DropdownMenuContent, {
2552
+ /* @__PURE__ */ jsx17(MenubarContent, {
2309
2553
  align: "end",
2310
- className: "w-max",
2311
- children: /* @__PURE__ */ jsxs8(DropdownMenuGroup, {
2554
+ children: /* @__PURE__ */ jsxs9(MenubarGroup, {
2312
2555
  children: [
2313
- /* @__PURE__ */ jsx17(DropdownMenuLabel, {
2314
- children: title
2556
+ /* @__PURE__ */ jsx17(MenubarLabel, {
2557
+ children: store.config.labels.columns
2315
2558
  }),
2316
- /* @__PURE__ */ jsx17(DropdownMenuSeparator, {}),
2317
- visibleActions.map((action) => /* @__PURE__ */ jsxs8(DropdownMenuItem, {
2318
- className: "whitespace-nowrap",
2319
- onClick: (event) => {
2320
- event.stopPropagation();
2321
- action.onClick(groupId);
2322
- },
2323
- ...action.variant ? { variant: action.variant } : {},
2324
- children: [
2325
- action.icon,
2326
- action.name
2327
- ]
2328
- }, action.name))
2559
+ /* @__PURE__ */ jsx17(MenubarSeparator, {}),
2560
+ columns.map((column) => /* @__PURE__ */ jsx17(MenubarCheckboxItem, {
2561
+ checked: store.state.columnVisibility[column.id] !== false,
2562
+ onCheckedChange: (visible) => changeState(setStore, (state) => ({
2563
+ ...state,
2564
+ columnVisibility: {
2565
+ ...state.columnVisibility,
2566
+ [column.id]: visible
2567
+ }
2568
+ })),
2569
+ children: columnLabel(column)
2570
+ }, column.id))
2329
2571
  ]
2330
2572
  })
2331
2573
  })
2332
2574
  ]
2333
2575
  });
2334
2576
  };
2335
- var DataTableRow = ({
2336
- canDrag,
2337
- canReorder,
2338
- dragLabel,
2339
- indentDepth = 0,
2340
- reorderHandleLabel,
2341
- onRowClick,
2342
- row,
2343
- rowActions,
2344
- rowActionsLabel,
2345
- selectRowLabel,
2346
- selectable,
2347
- table
2577
+ var ResizeHandle = ({
2578
+ tableAtom
2348
2579
  }) => {
2349
- const sortable = useSortable({
2350
- id: getSortableRowId(row.id),
2351
- disabled: !canReorder,
2352
- data: {
2353
- type: "row-reorder",
2354
- row: row.original,
2355
- label: dragLabel
2580
+ const [store, setStore] = useTableAtom(tableAtom);
2581
+ const columnId = useRequiredId(ColumnIdContext);
2582
+ const column = deriveModel(store).columns.find(({ id }) => id === columnId);
2583
+ if (!column || column.colDef.resizable === false)
2584
+ return null;
2585
+ const resize = (width) => changeState(setStore, (state) => ({
2586
+ ...state,
2587
+ columnSizing: {
2588
+ ...state.columnSizing,
2589
+ [column.id]: clampWidth(column.colDef, width)
2356
2590
  }
2591
+ }));
2592
+ const onPointerDown = (event) => {
2593
+ event.preventDefault();
2594
+ event.currentTarget.setPointerCapture(event.pointerId);
2595
+ event.currentTarget.dataset.startX = String(event.clientX);
2596
+ event.currentTarget.dataset.startWidth = String(column.width);
2597
+ };
2598
+ const onPointerMove = (event) => {
2599
+ if (!event.currentTarget.hasPointerCapture(event.pointerId))
2600
+ return;
2601
+ const startX = Number(event.currentTarget.dataset.startX);
2602
+ const startWidth = Number(event.currentTarget.dataset.startWidth);
2603
+ resize(startWidth + event.clientX - startX);
2604
+ };
2605
+ return /* @__PURE__ */ jsx17("button", {
2606
+ "aria-label": store.config.labels.resizeColumn(columnLabel(column)),
2607
+ "aria-orientation": "vertical",
2608
+ "aria-valuemax": column.colDef.maxWidth ?? DEFAULT_MAX_WIDTH,
2609
+ "aria-valuemin": column.colDef.minWidth ?? DEFAULT_MIN_WIDTH,
2610
+ "aria-valuenow": column.width,
2611
+ className: "hover:bg-primary/60 absolute inset-y-0 right-0 z-10 w-1 cursor-col-resize touch-none",
2612
+ onDoubleClick: () => resize(column.colDef.width ?? DEFAULT_WIDTH),
2613
+ onKeyDown: (event) => {
2614
+ const delta = event.key === "ArrowLeft" ? -8 : event.key === "ArrowRight" ? 8 : 0;
2615
+ if (delta) {
2616
+ event.preventDefault();
2617
+ resize(column.width + delta);
2618
+ }
2619
+ },
2620
+ onPointerDown,
2621
+ onPointerMove,
2622
+ role: "separator",
2623
+ type: "button"
2357
2624
  });
2358
- const draggable = useDraggable({
2359
- id: getRowDragId(row.id),
2360
- disabled: !canDrag || canReorder,
2361
- data: {
2362
- type: "row",
2363
- rowId: row.id,
2364
- label: dragLabel
2625
+ };
2626
+ var DragHandle = ({
2627
+ tableAtom
2628
+ }) => {
2629
+ const [store, setStore] = useTableAtom(tableAtom);
2630
+ const rowId = useRequiredId(RowIdContext);
2631
+ const dragRef = useRef2(null);
2632
+ const [overlay, setOverlay] = useState(null);
2633
+ const reset = (element) => {
2634
+ clearDragPresentation(element.closest("[data-table-root]"));
2635
+ dragRef.current = null;
2636
+ setOverlay(null);
2637
+ };
2638
+ const onPointerDown = (event) => {
2639
+ event.stopPropagation();
2640
+ event.currentTarget.setPointerCapture(event.pointerId);
2641
+ const row = deriveModel(store).rows.find((candidate) => candidate.id === rowId);
2642
+ const grouping = store.config.features.grouping;
2643
+ const reordering = store.config.features.reordering;
2644
+ dragRef.current = {
2645
+ pointerId: event.pointerId,
2646
+ rowId,
2647
+ label: row && grouping && grouping.getRowLabel?.(row.data) || row && reordering && reordering.getRowLabel?.(row.data) || rowId,
2648
+ startX: event.clientX,
2649
+ startY: event.clientY,
2650
+ active: false
2651
+ };
2652
+ };
2653
+ const onPointerMove = (event) => {
2654
+ const drag = dragRef.current;
2655
+ if (!drag || drag.pointerId !== event.pointerId)
2656
+ return;
2657
+ const root = event.currentTarget.closest("[data-table-root]");
2658
+ const active = drag.active || Math.hypot(event.clientX - drag.startX, event.clientY - drag.startY) >= 8;
2659
+ drag.active = active;
2660
+ clearDragPresentation(root);
2661
+ if (!active)
2662
+ return;
2663
+ const elements = document.elementsFromPoint(event.clientX, event.clientY);
2664
+ const rowTarget = findTableDragTarget(elements, "[data-table-row]", root);
2665
+ const groupTarget = findTableDragTarget(elements, "[data-table-group]", root);
2666
+ event.currentTarget.closest("[data-table-row]")?.setAttribute("data-drag-source", "true");
2667
+ if (canMoveRowsToGroups(store)) {
2668
+ groupTarget?.setAttribute("data-drop-target", "true");
2669
+ } else if (rowTarget?.dataset.tableRow !== drag.rowId) {
2670
+ const rows = deriveModel(store).pageRows;
2671
+ const sourceIndex = rows.findIndex((row) => row.id === drag.rowId);
2672
+ const targetIndex = rows.findIndex((row) => row.id === rowTarget?.dataset.tableRow);
2673
+ if (sourceIndex !== -1 && targetIndex !== -1) {
2674
+ rowTarget?.setAttribute("data-drop-position", sourceIndex < targetIndex ? "after" : "before");
2675
+ }
2365
2676
  }
2366
- });
2367
- const attributes = canReorder ? sortable.attributes : draggable.attributes;
2368
- const listeners = canReorder ? sortable.listeners : draggable.listeners;
2369
- const isDragging = canReorder ? sortable.isDragging : draggable.isDragging;
2370
- const setRowNodeRef = canReorder ? sortable.setNodeRef : draggable.setNodeRef;
2371
- const transform = canReorder ? CSS.Transform.toString(sortable.transform) : undefined;
2372
- const firstCellIndent = indentDepth > 0 ? `calc(0.5rem + ${(indentDepth - 1) * GROUP_INDENT_PX + GROUP_ROW_INDENT_OFFSET_PX}px)` : undefined;
2373
- const rowAttributes = canReorder ? onRowClick ? { role: "button", tabIndex: 0 } : {} : onRowClick ? { ...attributes, role: "button", tabIndex: 0 } : attributes;
2374
- const visibleCells = row.getVisibleCells();
2375
- return /* @__PURE__ */ jsxs8(TableRow, {
2376
- className: cn("group/row h-16 focus-visible:outline-ring focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-solid", onRowClick && "cursor-pointer", isDragging && "opacity-50"),
2377
- "data-state": row.getIsSelected() && "selected",
2378
- onClick: () => {
2379
- if (onRowClick) {
2380
- onRowClick(row.original);
2677
+ setOverlay({ label: drag.label, x: event.clientX, y: event.clientY });
2678
+ };
2679
+ const finish = (event) => {
2680
+ const drag = dragRef.current;
2681
+ if (!drag || drag.pointerId !== event.pointerId)
2682
+ return;
2683
+ const root = event.currentTarget.closest("[data-table-root]");
2684
+ const elements = document.elementsFromPoint(event.clientX, event.clientY);
2685
+ const rowTarget = findTableDragTarget(elements, "[data-table-row]", root);
2686
+ const groupTarget = findTableDragTarget(elements, "[data-table-group]", root);
2687
+ setStore((current) => {
2688
+ const targetRowId = rowTarget?.dataset.tableRow;
2689
+ const targetGroupKey = groupTarget?.dataset.tableGroup;
2690
+ const model = deriveModel(current);
2691
+ const source = model.sortedRows.find((row) => row.id === drag.rowId);
2692
+ const grouping = current.config.features.grouping;
2693
+ const reordering = current.config.features.reordering;
2694
+ if (drag.active && source && targetGroupKey && grouping) {
2695
+ const target = parseGroupDropKey(targetGroupKey);
2696
+ const field = grouping.fields.find(({ id }) => id === target?.fieldId);
2697
+ if (target && field?.onMoveToGroup && field.getGroupId(source.data) !== target.groupId) {
2698
+ field.onMoveToGroup(source.data, target.groupId);
2699
+ }
2700
+ } else if (drag.active && source && targetRowId && reordering && canReorderRows(current) && source.id !== targetRowId) {
2701
+ reordering.onReorder(reorderDataTableRows(model.rows, source.id, targetRowId));
2381
2702
  }
2382
- },
2703
+ return current;
2704
+ });
2705
+ reset(event.currentTarget);
2706
+ };
2707
+ const cancel = (event) => {
2708
+ if (dragRef.current?.pointerId === event.pointerId) {
2709
+ reset(event.currentTarget);
2710
+ }
2711
+ };
2712
+ const reorderWithKeyboard = (direction) => {
2713
+ const reordering = store.config.features.reordering;
2714
+ if (!reordering || !canReorderRows(store))
2715
+ return;
2716
+ const model = deriveModel(store);
2717
+ const visibleRows = model.pageRows;
2718
+ const sourceIndex = visibleRows.findIndex((row) => row.id === rowId);
2719
+ const target = visibleRows[sourceIndex + direction];
2720
+ if (sourceIndex !== -1 && target) {
2721
+ reordering.onReorder(reorderDataTableRows(model.rows, rowId, target.id));
2722
+ }
2723
+ };
2724
+ return /* @__PURE__ */ jsxs9(Fragment, {
2725
+ children: [
2726
+ /* @__PURE__ */ jsx17(Button, {
2727
+ "aria-label": store.config.features.reordering && store.config.features.reordering.handleLabel ? store.config.features.reordering.handleLabel : store.config.labels.reorder,
2728
+ className: "size-8 cursor-grab touch-none active:cursor-grabbing",
2729
+ onClick: (event) => event.stopPropagation(),
2730
+ onKeyDown: (event) => {
2731
+ if (event.key === "ArrowUp" || event.key === "ArrowDown") {
2732
+ event.preventDefault();
2733
+ event.stopPropagation();
2734
+ reorderWithKeyboard(event.key === "ArrowUp" ? -1 : 1);
2735
+ }
2736
+ },
2737
+ onPointerCancel: cancel,
2738
+ onPointerDown,
2739
+ onLostPointerCapture: cancel,
2740
+ onPointerMove,
2741
+ onPointerUp: finish,
2742
+ size: "icon",
2743
+ variant: "ghost",
2744
+ children: /* @__PURE__ */ jsx17(GripVertical, {})
2745
+ }),
2746
+ overlay ? createPortal(/* @__PURE__ */ jsx17("div", {
2747
+ "aria-hidden": "true",
2748
+ className: "bg-background pointer-events-none fixed z-[100] rounded-md border px-3 py-2 text-sm shadow-lg",
2749
+ style: { left: overlay.x + 12, top: overlay.y + 12 },
2750
+ children: overlay.label
2751
+ }), document.body) : null
2752
+ ]
2753
+ });
2754
+ };
2755
+ var toggleRow = (store, setStore, rowId, selected) => changeState(setStore, (state) => {
2756
+ const rowSelection = { ...state.rowSelection, [rowId]: selected };
2757
+ const selection = store.config.features.selection;
2758
+ if (selection) {
2759
+ const model = deriveModel(store);
2760
+ selection.onSelectionChange?.(model.rows.filter((row) => rowSelection[row.id]).map((row) => row.data));
2761
+ }
2762
+ return { ...state, rowSelection };
2763
+ });
2764
+ var TableDataRow = ({
2765
+ tableAtom
2766
+ }) => {
2767
+ const [store, setStore] = useTableAtom(tableAtom);
2768
+ const rowId = useRequiredId(RowIdContext);
2769
+ const model = deriveModel(store);
2770
+ const row = model.sortedRows.find((candidate) => candidate.id === rowId);
2771
+ if (!row)
2772
+ return null;
2773
+ const selection = store.config.features.selection;
2774
+ const selectable = !!selection && (selection.isRowSelectable?.(row.data) ?? true);
2775
+ const rowActions = store.config.features.rowActions;
2776
+ const draggable = canDragRows(store);
2777
+ return /* @__PURE__ */ jsxs9(TableRow, {
2778
+ className: cn("group/row h-16 data-[drag-source=true]:opacity-40 data-[drop-position=before]:[&>td]:border-t-2 data-[drop-position=before]:[&>td]:border-primary data-[drop-position=after]:[&>td]:border-b-2 data-[drop-position=after]:[&>td]:border-primary", store.config.onRowClicked && "cursor-pointer"),
2779
+ "data-state": store.state.rowSelection[row.id] && "selected",
2780
+ "data-table-row": row.id,
2781
+ onClick: () => store.config.onRowClicked?.(row.data),
2383
2782
  onKeyDown: (event) => {
2384
- if (!onRowClick || event.key !== "Enter" && event.key !== " ") {
2385
- return;
2783
+ if (event.target === event.currentTarget && store.config.onRowClicked && (event.key === "Enter" || event.key === " ")) {
2784
+ event.preventDefault();
2785
+ store.config.onRowClicked(row.data);
2386
2786
  }
2387
- event.preventDefault();
2388
- onRowClick(row.original);
2389
- },
2390
- ref: setRowNodeRef,
2391
- style: {
2392
- transform,
2393
- transition: sortable.transition
2394
2787
  },
2395
- ...rowAttributes,
2396
- ...!canReorder ? listeners : {},
2788
+ tabIndex: store.config.onRowClicked ? 0 : undefined,
2397
2789
  children: [
2398
- selectable ? /* @__PURE__ */ jsx17(TableCell, {
2399
- className: "w-10 min-w-10 cursor-default pr-0",
2790
+ selection ? /* @__PURE__ */ jsx17(TableCell, {
2791
+ className: "w-10 pr-0",
2400
2792
  onClick: (event) => event.stopPropagation(),
2401
2793
  children: /* @__PURE__ */ jsx17(Checkbox, {
2402
- "aria-label": selectRowLabel,
2403
- checked: row.getIsSelected(),
2404
- disabled: !row.getCanSelect(),
2405
- onCheckedChange: (checked, eventDetails) => row.getToggleSelectedHandler()({
2406
- nativeEvent: eventDetails.event,
2407
- target: { checked }
2408
- }),
2409
- onClick: (event) => event.stopPropagation()
2794
+ "aria-label": store.config.labels.selectRow,
2795
+ checked: !!store.state.rowSelection[row.id],
2796
+ disabled: !selectable,
2797
+ onCheckedChange: (checked) => toggleRow(store, setStore, row.id, checked)
2410
2798
  })
2411
2799
  }) : null,
2412
- canReorder ? /* @__PURE__ */ jsx17(TableCell, {
2413
- className: "w-10 min-w-10 pr-0",
2414
- children: /* @__PURE__ */ jsx17(Button, {
2415
- "aria-label": reorderHandleLabel,
2416
- className: "size-8 cursor-grab active:cursor-grabbing",
2417
- onClick: (event) => event.stopPropagation(),
2418
- size: "icon",
2419
- type: "button",
2420
- variant: "ghost",
2421
- ...attributes,
2422
- ...listeners,
2423
- children: /* @__PURE__ */ jsx17(GripVertical, {})
2800
+ draggable ? /* @__PURE__ */ jsx17(TableCell, {
2801
+ className: "w-10 pr-0",
2802
+ children: /* @__PURE__ */ jsx17(DragHandle, {
2803
+ tableAtom
2424
2804
  })
2425
2805
  }) : null,
2426
- visibleCells.map((cell, index) => {
2427
- return /* @__PURE__ */ jsx17(table.AppCell, {
2428
- cell,
2429
- children: (appCell) => /* @__PURE__ */ jsx17(TableCell, {
2430
- className: cn("align-center min-w-32 overflow-hidden [&:has([data-slot=relationship-cell])]:relative [&:has([data-slot=relationship-cell])]:p-0 [&:has([data-slot=relationship-cell])>div]:absolute [&:has([data-slot=relationship-cell])>div]:inset-0", cell.column.columnDef.meta?.truncate ? "whitespace-nowrap" : "whitespace-normal"),
2431
- style: index === 0 && firstCellIndent ? {
2432
- paddingLeft: firstCellIndent,
2433
- width: cell.column.getSize()
2434
- } : { width: cell.column.getSize() },
2435
- children: /* @__PURE__ */ jsx17("div", {
2436
- className: cn("w-full max-w-full min-w-0 overflow-hidden break-words [&:has([data-slot=list-summary])]:line-clamp-none", cell.column.columnDef.meta?.truncate ? "truncate" : "line-clamp-3"),
2437
- children: /* @__PURE__ */ jsx17(appCell.FlexRender, {})
2438
- })
2439
- })
2440
- }, cell.id);
2441
- }),
2806
+ model.visibleColumns.map((column) => /* @__PURE__ */ jsx17(TableCell, {
2807
+ className: cn("min-w-24 overflow-hidden", column.colDef.truncate ? "whitespace-nowrap" : "whitespace-normal"),
2808
+ style: { width: column.width },
2809
+ children: /* @__PURE__ */ jsx17("div", {
2810
+ className: cn("min-w-0", column.colDef.truncate && "truncate"),
2811
+ children: renderCell(row, column)
2812
+ })
2813
+ }, column.id)),
2442
2814
  rowActions ? /* @__PURE__ */ jsx17(TableCell, {
2443
2815
  className: "bg-background group-data-[state=selected]/row:bg-muted sticky right-0 z-20 w-10 min-w-10 cursor-default p-0 transition-colors group-hover/row:bg-[color-mix(in_oklab,var(--muted)_50%,var(--background))]",
2444
2816
  onClick: (event) => event.stopPropagation(),
2445
2817
  children: /* @__PURE__ */ jsx17("div", {
2446
2818
  className: "flex h-16 items-center justify-center",
2447
2819
  children: /* @__PURE__ */ jsx17(DataTableRowActions, {
2448
- actions: rowActions,
2449
- row: row.original,
2450
- title: rowActionsLabel
2820
+ actions: rowActions.items,
2821
+ row: row.data,
2822
+ title: rowActions.label ?? store.config.labels.actions
2451
2823
  })
2452
2824
  })
2453
2825
  }) : null
2454
2826
  ]
2455
- }, row.id);
2827
+ });
2456
2828
  };
2457
- var DataTableGalleryCard = ({
2458
- canDrag,
2459
- dragLabel,
2460
- gallery,
2461
- onRowClick,
2462
- row,
2463
- rowActions,
2464
- rowActionsLabel,
2465
- selectRowLabel,
2466
- selectable,
2467
- table
2829
+ var GroupActions = ({
2830
+ actions,
2831
+ groupId,
2832
+ title
2468
2833
  }) => {
2469
- const { attributes, listeners, setNodeRef, isDragging } = useDraggable({
2470
- id: getRowDragId(row.id),
2471
- disabled: !canDrag,
2472
- data: {
2473
- type: "row",
2474
- rowId: row.id,
2475
- label: dragLabel
2476
- }
2477
- });
2478
- const nameCell = gallery ? row.getVisibleCells().find((cell) => cell.column.id === gallery.name) : null;
2479
- const descriptionCell = gallery?.description ? row.getVisibleCells().find((cell) => cell.column.id === gallery.description) : null;
2480
- const tagCell = gallery?.tag ? row.getVisibleCells().find((cell) => cell.column.id === gallery.tag) : null;
2481
- if (gallery) {
2482
- const tagValue = gallery.tag ? row.getValue(gallery.tag) : null;
2483
- const tagLabel = tagValue === null || tagValue === undefined ? null : String(tagValue);
2484
- return /* @__PURE__ */ jsxs8(Card, {
2485
- className: cn("relative mx-auto w-full max-w-sm transition-colors", onRowClick && "cursor-pointer hover:bg-accent/20", isDragging && "opacity-50"),
2486
- "data-state": row.getIsSelected() && "selected",
2487
- onClick: () => {
2488
- if (onRowClick) {
2489
- onRowClick(row.original);
2490
- }
2491
- },
2492
- ref: setNodeRef,
2493
- ...attributes,
2494
- ...listeners,
2495
- children: [
2496
- selectable ? /* @__PURE__ */ jsx17("div", {
2497
- className: "absolute top-4 left-4 z-10",
2498
- onClick: (event) => event.stopPropagation(),
2499
- children: /* @__PURE__ */ jsx17(Checkbox, {
2500
- "aria-label": selectRowLabel,
2501
- checked: row.getIsSelected(),
2502
- disabled: !row.getCanSelect(),
2503
- onCheckedChange: (checked, eventDetails) => row.getToggleSelectedHandler()({
2504
- nativeEvent: eventDetails.event,
2505
- target: { checked }
2506
- })
2507
- })
2508
- }) : null,
2509
- rowActions ? /* @__PURE__ */ jsx17("div", {
2510
- className: "absolute top-4 right-4 z-10",
2511
- onClick: (event) => event.stopPropagation(),
2512
- children: /* @__PURE__ */ jsx17(DataTableRowActions, {
2513
- actions: rowActions,
2514
- row: row.original,
2515
- title: rowActionsLabel
2516
- })
2517
- }) : null,
2518
- /* @__PURE__ */ jsxs8(CardHeader, {
2519
- className: cn(rowActions && "pr-14", selectable && "pl-12"),
2520
- children: [
2521
- tagCell && tagLabel ? /* @__PURE__ */ jsxs8(Badge, {
2522
- variant: "secondary",
2523
- className: "mb-1 w-fit gap-1",
2524
- children: [
2525
- gallery.tagIcon,
2526
- tagLabel
2527
- ]
2528
- }) : null,
2529
- nameCell ? /* @__PURE__ */ jsx17(CardTitle, {
2530
- className: "min-w-0 text-base",
2531
- children: flexRender(nameCell.column.columnDef.cell, nameCell.getContext())
2532
- }) : null,
2533
- descriptionCell ? /* @__PURE__ */ jsx17(CardDescription, {
2534
- className: "line-clamp-2 min-w-0",
2535
- children: flexRender(descriptionCell.column.columnDef.cell, descriptionCell.getContext())
2536
- }) : null
2537
- ]
2538
- })
2539
- ]
2540
- });
2541
- }
2542
- const contentCells = row.getVisibleCells();
2543
- return /* @__PURE__ */ jsxs8(Card, {
2544
- className: cn("relative gap-3 transition-colors", onRowClick && "cursor-pointer hover:bg-accent/20", isDragging && "opacity-50"),
2545
- "data-state": row.getIsSelected() && "selected",
2546
- onClick: () => {
2547
- if (onRowClick) {
2548
- onRowClick(row.original);
2549
- }
2550
- },
2551
- ref: setNodeRef,
2552
- ...attributes,
2553
- ...listeners,
2834
+ const visible = actions?.filter((action) => !action.visible || action.visible(groupId));
2835
+ if (!visible?.length)
2836
+ return null;
2837
+ return /* @__PURE__ */ jsxs9(DropdownMenu, {
2554
2838
  children: [
2555
- selectable ? /* @__PURE__ */ jsx17("div", {
2556
- className: "absolute top-4 left-4 z-10",
2839
+ /* @__PURE__ */ jsx17(DropdownMenuTrigger, {
2557
2840
  onClick: (event) => event.stopPropagation(),
2558
- children: /* @__PURE__ */ jsx17(Checkbox, {
2559
- "aria-label": selectRowLabel,
2560
- checked: row.getIsSelected(),
2561
- disabled: !row.getCanSelect(),
2562
- onCheckedChange: (checked, eventDetails) => row.getToggleSelectedHandler()({
2563
- nativeEvent: eventDetails.event,
2564
- target: { checked }
2565
- })
2566
- })
2567
- }) : null,
2568
- /* @__PURE__ */ jsxs8(CardHeader, {
2569
- children: [
2570
- rowActions ? /* @__PURE__ */ jsx17(CardAction, {
2571
- onClick: (event) => event.stopPropagation(),
2572
- children: /* @__PURE__ */ jsx17(DataTableRowActions, {
2573
- actions: rowActions,
2574
- row: row.original,
2575
- title: rowActionsLabel
2576
- })
2577
- }) : null,
2578
- contentCells.length > 0 && /* @__PURE__ */ jsxs8("div", {
2579
- className: "grid min-w-0 gap-3",
2580
- children: [
2581
- /* @__PURE__ */ jsx17(CardDescription, {
2582
- className: "text-muted-foreground text-xs font-medium tracking-wide uppercase",
2583
- children: getColumnDisplayName(table, contentCells[0].column.id)
2584
- }),
2585
- /* @__PURE__ */ jsx17(CardTitle, {
2586
- className: "text-base",
2587
- children: flexRender(contentCells[0].column.columnDef.cell, contentCells[0].getContext())
2588
- })
2589
- ]
2590
- })
2591
- ]
2592
- }),
2593
- contentCells.length > 1 && /* @__PURE__ */ jsx17(CardContent, {
2594
- className: "grid gap-3",
2595
- children: contentCells.slice(1).map((cell) => /* @__PURE__ */ jsxs8("div", {
2596
- className: "grid gap-1",
2841
+ render: /* @__PURE__ */ jsxs9(Button, {
2842
+ size: "icon",
2843
+ variant: "ghost",
2597
2844
  children: [
2598
- /* @__PURE__ */ jsx17("div", {
2599
- className: "text-muted-foreground text-xs font-medium tracking-wide uppercase",
2600
- children: getColumnDisplayName(table, cell.column.id)
2845
+ /* @__PURE__ */ jsx17("span", {
2846
+ className: "sr-only",
2847
+ children: title
2601
2848
  }),
2602
- /* @__PURE__ */ jsx17("div", {
2603
- className: "min-w-0 text-sm",
2604
- children: flexRender(cell.column.columnDef.cell, cell.getContext())
2605
- })
2849
+ /* @__PURE__ */ jsx17(MoreHorizontal, {})
2606
2850
  ]
2607
- }, cell.id))
2851
+ })
2852
+ }),
2853
+ /* @__PURE__ */ jsx17(DropdownMenuContent, {
2854
+ align: "end",
2855
+ children: /* @__PURE__ */ jsx17(DropdownMenuGroup, {
2856
+ children: visible.map((action) => /* @__PURE__ */ jsxs9(DropdownMenuItem, {
2857
+ onClick: () => action.onClick(groupId),
2858
+ variant: action.variant,
2859
+ children: [
2860
+ action.icon,
2861
+ " ",
2862
+ action.name
2863
+ ]
2864
+ }, action.name))
2865
+ })
2608
2866
  })
2609
2867
  ]
2610
2868
  });
2611
2869
  };
2612
- var extractTextFromElement = (element) => {
2613
- if (Schema2.is(Schema2.String)(element))
2614
- return element;
2615
- if (Schema2.is(Schema2.Number)(element))
2616
- return String(element);
2617
- if (!isValidElement(element)) {
2618
- return null;
2619
- }
2620
- const { props } = element;
2621
- if (Schema2.is(Schema2.String)(props.title))
2622
- return props.title;
2623
- return extractTextFromElement(props.children);
2624
- };
2625
- var getColumnLabels = (table) => new Map(table.getFlatHeaders().map((header) => [header.column.id, getHeaderName(header)]));
2626
- var getHeaderName = (header) => {
2627
- const columnDef = header.column.columnDef;
2628
- if (columnDef.header instanceof Function) {
2629
- const headerContext = columnDef.header(header.getContext());
2630
- if (Schema2.is(Schema2.String)(headerContext)) {
2631
- return headerContext;
2632
- }
2633
- return extractTextFromElement(headerContext) ?? header.id;
2634
- }
2635
- return String(columnDef.header ?? header.id);
2636
- };
2637
- var getHeaderNames = (headers) => headers.map((header) => getHeaderName(header));
2638
- var getColumnDisplayName = (table, columnId) => {
2639
- const header = table.getFlatHeaders().find((currentHeader) => currentHeader.column.id === columnId);
2640
- return header ? getHeaderName(header) : columnId;
2641
- };
2642
- var withFileExtension = (fileName, extension) => {
2643
- const normalizedExtension = extension.startsWith(".") ? extension : `.${extension}`;
2644
- return fileName.includes(".") ? fileName.replace(/\.[^/.]+$/, normalizedExtension) : `${fileName}${normalizedExtension}`;
2645
- };
2646
- var escapeCsvValue = (value) => {
2647
- if (value === null || value === undefined)
2648
- return "";
2649
- const stringValue = String(value);
2650
- if (stringValue.includes(",") || stringValue.includes('"') || stringValue.includes(`
2651
- `)) {
2652
- return `"${stringValue.replace(/"/g, '""')}"`;
2653
- }
2654
- return stringValue;
2655
- };
2656
- var downloadCsv = (headers, data, fileName = "data.csv") => {
2657
- const csvContent = [headers, ...data].map((row) => row.map(escapeCsvValue).join(",")).join(`
2658
- `);
2659
- const blob = new Blob([csvContent], { type: "text/csv;charset=utf-8;" });
2660
- const link = document.createElement("a");
2661
- const url = window.URL.createObjectURL(blob);
2662
- link.href = url;
2663
- link.setAttribute("download", withFileExtension(fileName, "csv"));
2664
- document.body.appendChild(link);
2665
- link.click();
2666
- link.remove();
2667
- requestAnimationFrame(() => window.URL.revokeObjectURL(url));
2668
- };
2669
- var downloadJson = (data, fileName = "data.json") => {
2670
- const jsonContent = JSON.stringify(data, null, 2);
2671
- const blob = new Blob([jsonContent], {
2672
- type: "application/json;charset=utf-8;"
2870
+ var GroupedTable = ({
2871
+ tableAtom
2872
+ }) => {
2873
+ const [store, setStore] = useTableAtom(tableAtom);
2874
+ const model = deriveModel(store);
2875
+ const sections = groupDataTableRows(model.sortedRows, getActiveGrouping(store));
2876
+ const extra = (store.config.features.selection ? 1 : 0) + (store.config.features.rowActions ? 1 : 0) + (canDragRows(store) ? 1 : 0);
2877
+ const renderSections = (items) => items.flatMap((section) => {
2878
+ const collapsed = !!store.state.collapsedGroups[section.key];
2879
+ const targetKey = getGroupDropKey(section.field.id, section.groupId);
2880
+ const body = /* @__PURE__ */ jsxs9(TableBody, {
2881
+ className: "data-[drop-target=true]:outline-primary relative data-[drop-target=true]:z-30 data-[drop-target=true]:outline-2 data-[drop-target=true]:-outline-offset-2 data-[drop-target=true]:[&>tr]:border-transparent data-[drop-target=true]:[&>tr>td:last-child]:z-0",
2882
+ "data-table-group": section.field.onMoveToGroup ? targetKey : undefined,
2883
+ children: [
2884
+ /* @__PURE__ */ jsx17(TableRow, {
2885
+ className: "bg-muted/40",
2886
+ children: /* @__PURE__ */ jsx17(TableCell, {
2887
+ colSpan: model.visibleColumns.length + extra,
2888
+ children: /* @__PURE__ */ jsxs9("div", {
2889
+ className: "flex items-center gap-2",
2890
+ style: { paddingLeft: section.depth * 20 },
2891
+ children: [
2892
+ /* @__PURE__ */ jsxs9("button", {
2893
+ "aria-expanded": !collapsed,
2894
+ className: "flex flex-1 items-center gap-2 text-left",
2895
+ onClick: () => changeState(setStore, (state) => ({
2896
+ ...state,
2897
+ collapsedGroups: {
2898
+ ...state.collapsedGroups,
2899
+ [section.key]: !collapsed
2900
+ }
2901
+ })),
2902
+ type: "button",
2903
+ children: [
2904
+ collapsed ? /* @__PURE__ */ jsx17(ChevronRight2, {
2905
+ className: "size-4"
2906
+ }) : /* @__PURE__ */ jsx17(ChevronDown, {
2907
+ className: "size-4"
2908
+ }),
2909
+ /* @__PURE__ */ jsx17("span", {
2910
+ className: "flex-1",
2911
+ children: section.field.renderGroupLabel?.(section.groupId, section.rows.map((row) => row.data)) ?? section.groupId
2912
+ })
2913
+ ]
2914
+ }),
2915
+ /* @__PURE__ */ jsx17(Badge, {
2916
+ variant: "secondary",
2917
+ children: section.rows.length
2918
+ }),
2919
+ /* @__PURE__ */ jsx17(GroupActions, {
2920
+ actions: section.field.actions,
2921
+ groupId: section.groupId,
2922
+ title: section.field.actionsLabel ?? store.config.labels.actions
2923
+ })
2924
+ ]
2925
+ })
2926
+ })
2927
+ }),
2928
+ !collapsed && !section.children.length ? section.rows.length ? section.rows.map((row) => /* @__PURE__ */ jsx17(RowIdContext.Provider, {
2929
+ value: row.id,
2930
+ children: /* @__PURE__ */ jsx17(TableDataRow, {
2931
+ tableAtom
2932
+ })
2933
+ }, `${section.key}:${row.id}`)) : [
2934
+ /* @__PURE__ */ jsx17(TableRow, {
2935
+ children: /* @__PURE__ */ jsx17(TableCell, {
2936
+ className: "text-muted-foreground h-16",
2937
+ colSpan: model.visibleColumns.length + extra,
2938
+ children: section.field.renderEmptyGroup?.(section.groupId) ?? store.config.labels.empty
2939
+ })
2940
+ }, `${section.key}:empty`)
2941
+ ] : null
2942
+ ]
2943
+ }, section.key);
2944
+ return !collapsed && section.children.length ? [body, renderSections(section.children)] : [body];
2945
+ });
2946
+ return /* @__PURE__ */ jsx17(Fragment, {
2947
+ children: renderSections(sections)
2673
2948
  });
2674
- const link = document.createElement("a");
2675
- const url = window.URL.createObjectURL(blob);
2676
- link.href = url;
2677
- link.setAttribute("download", withFileExtension(fileName, "json"));
2678
- document.body.appendChild(link);
2679
- link.click();
2680
- link.remove();
2681
- requestAnimationFrame(() => window.URL.revokeObjectURL(url));
2682
- };
2683
- var exportTableToCsv = (table, rows, fileName = "data.csv") => {
2684
- const exportableColumns = table.getVisibleLeafColumns();
2685
- const headerNames = exportableColumns.map((column) => getColumnDisplayName(table, column.id));
2686
- const data = rows.map((row) => exportableColumns.map((column) => {
2687
- const value = row.getValue(column.id);
2688
- return value === null || value === undefined ? "" : String(value);
2689
- }));
2690
- downloadCsv(headerNames, data, fileName);
2691
- };
2692
- var exportTableToJson = (table, rows, fileName = "data.json") => {
2693
- const exportableColumns = table.getVisibleLeafColumns();
2694
- const data = rows.map((row) => Object.fromEntries(exportableColumns.map((column) => [column.id, row.getValue(column.id)])));
2695
- downloadJson(data, fileName);
2696
2949
  };
2697
- var DataTableToolbar = ({
2698
- activeGrouping,
2699
- bulkActions,
2700
- exportBaseName,
2701
- exportRows,
2702
- grouping,
2703
- labels: labels2,
2704
- onRefresh,
2705
- onToggleGrouping,
2706
- onViewChange,
2707
- selectedRows,
2708
- showColumnVisibility,
2709
- showExport,
2710
- showGallery,
2711
- showSearch,
2712
- showSorting,
2713
- table,
2714
- view
2950
+ var ColumnHeaderMenu = ({
2951
+ tableAtom
2715
2952
  }) => {
2716
- const [refreshSpinCount, setRefreshSpinCount] = useState(0);
2717
- const [searchInput, setSearchInput] = useState(table.state.globalFilter);
2718
- const hasToolbar = Boolean(showSearch || grouping?.fields.length || showSorting || showGallery || showColumnVisibility || onRefresh || showExport || selectedRows.length > 0 && bulkActions?.items.length);
2719
- useEffect2(() => {
2720
- setSearchInput(table.state.globalFilter);
2721
- }, [table.state.globalFilter]);
2722
- if (!hasToolbar)
2953
+ const [store, setStore] = useTableAtom(tableAtom);
2954
+ const columnId = useRequiredId(ColumnIdContext);
2955
+ const column = deriveModel(store).columns.find(({ id }) => id === columnId);
2956
+ if (!column)
2723
2957
  return null;
2724
- return /* @__PURE__ */ jsx17("div", {
2725
- className: "flex flex-col gap-3 pb-4",
2726
- children: /* @__PURE__ */ jsxs8("div", {
2727
- className: "flex flex-col gap-2 sm:flex-row sm:flex-wrap sm:items-center sm:justify-between",
2728
- children: [
2729
- showSearch ? /* @__PURE__ */ jsxs8("div", {
2730
- className: "relative w-full min-w-0 flex-1 sm:min-w-sm",
2958
+ const sortingEnabled = store.config.features.sorting !== false && column.colDef.sortable !== false;
2959
+ const hidingEnabled = store.config.features.columnVisibility !== false && column.colDef.hideable !== false;
2960
+ const sort = store.state.sorting.find(({ id }) => id === column.id);
2961
+ const update = (next) => changeState(setStore, next);
2962
+ const setSort = (desc) => update((state) => ({
2963
+ ...state,
2964
+ sorting: [{ id: column.id, desc }],
2965
+ pagination: { ...state.pagination, pageIndex: 0 }
2966
+ }));
2967
+ const label = columnLabel(column);
2968
+ if (!sortingEnabled && !hidingEnabled) {
2969
+ return /* @__PURE__ */ jsx17("div", {
2970
+ className: "truncate",
2971
+ children: column.colDef.headerName
2972
+ });
2973
+ }
2974
+ return /* @__PURE__ */ jsxs9(DropdownMenu, {
2975
+ children: [
2976
+ /* @__PURE__ */ jsx17(DropdownMenuTrigger, {
2977
+ render: /* @__PURE__ */ jsxs9(Button, {
2978
+ "aria-label": label,
2979
+ className: "h-8 max-w-full justify-start px-2",
2980
+ size: "sm",
2981
+ variant: "ghost",
2731
2982
  children: [
2732
- /* @__PURE__ */ jsx17(Search, {
2733
- className: "text-muted-foreground pointer-events-none absolute top-1/2 left-3 size-4 -translate-y-1/2"
2734
- }),
2735
- /* @__PURE__ */ jsx17(Input, {
2736
- className: "px-9",
2737
- onChange: (event) => {
2738
- setSearchInput(event.target.value);
2739
- table.setGlobalFilter(event.target.value);
2740
- },
2741
- placeholder: labels2.filter,
2742
- value: searchInput
2983
+ /* @__PURE__ */ jsx17("span", {
2984
+ className: "truncate",
2985
+ children: column.colDef.headerName
2743
2986
  }),
2744
- searchInput ? /* @__PURE__ */ jsx17(Button, {
2745
- "aria-label": labels2.filter,
2746
- className: "text-muted-foreground hover:text-foreground absolute top-1/2 right-1 size-7 -translate-y-1/2 active:!-translate-y-1/2",
2747
- onClick: () => {
2748
- setSearchInput("");
2749
- table.setGlobalFilter("");
2750
- },
2751
- size: "icon",
2752
- type: "button",
2753
- variant: "ghost",
2754
- children: /* @__PURE__ */ jsx17(X2, {
2755
- className: "size-4"
2756
- })
2757
- }) : null
2987
+ sort ? sort.desc ? /* @__PURE__ */ jsx17(ArrowDown, {}) : /* @__PURE__ */ jsx17(ArrowUp, {}) : sortingEnabled ? /* @__PURE__ */ jsx17(ChevronsUpDown2, {}) : null
2758
2988
  ]
2759
- }) : /* @__PURE__ */ jsx17("div", {}),
2760
- /* @__PURE__ */ jsxs8("div", {
2761
- className: "-m-1 flex items-center gap-2 overflow-x-auto p-1",
2989
+ })
2990
+ }),
2991
+ /* @__PURE__ */ jsx17(DropdownMenuContent, {
2992
+ align: "start",
2993
+ className: "w-48",
2994
+ children: /* @__PURE__ */ jsxs9(DropdownMenuGroup, {
2762
2995
  children: [
2763
- bulkActions && selectedRows.length > 0 ? /* @__PURE__ */ jsx17(DataTableBulkActions, {
2764
- actions: bulkActions.items,
2765
- label: bulkActions.label ?? labels2.actions,
2766
- rows: selectedRows,
2767
- selectedLabel: labels2.selected
2768
- }) : null,
2769
- grouping?.fields.length ? /* @__PURE__ */ jsxs8(DropdownMenu, {
2996
+ sortingEnabled ? /* @__PURE__ */ jsxs9(Fragment, {
2770
2997
  children: [
2771
- /* @__PURE__ */ jsx17(DropdownMenuTrigger, {
2772
- render: /* @__PURE__ */ jsxs8(Button, {
2773
- "aria-label": labels2.groupBy,
2774
- className: "h-9",
2775
- size: "sm",
2776
- variant: "outline",
2777
- children: [
2778
- /* @__PURE__ */ jsx17(Rows3, {}),
2779
- /* @__PURE__ */ jsx17("span", {
2780
- className: "hidden sm:inline",
2781
- children: labels2.groupBy
2782
- })
2783
- ]
2784
- })
2998
+ /* @__PURE__ */ jsxs9(DropdownMenuItem, {
2999
+ onClick: () => setSort(false),
3000
+ children: [
3001
+ /* @__PURE__ */ jsx17(ArrowUp, {}),
3002
+ " ",
3003
+ store.config.labels.sortAsc
3004
+ ]
2785
3005
  }),
2786
- /* @__PURE__ */ jsx17(DropdownMenuContent, {
2787
- align: "end",
2788
- className: "w-[200px]",
2789
- children: /* @__PURE__ */ jsxs8(DropdownMenuGroup, {
2790
- children: [
2791
- /* @__PURE__ */ jsx17(DropdownMenuLabel, {
2792
- children: labels2.groupBy
2793
- }),
2794
- /* @__PURE__ */ jsx17(DropdownMenuSeparator, {}),
2795
- grouping.fields.map((field) => /* @__PURE__ */ jsx17(DropdownMenuCheckboxItem, {
2796
- checked: activeGrouping.includes(field.id),
2797
- onCheckedChange: (value) => onToggleGrouping(field.id, !!value),
2798
- children: field.label
2799
- }, field.id))
2800
- ]
2801
- })
2802
- })
2803
- ]
2804
- }) : null,
2805
- showSorting ? /* @__PURE__ */ jsx17(DataTableSortDropdown, {
2806
- messages: labels2,
2807
- table
2808
- }) : null,
2809
- showGallery ? /* @__PURE__ */ jsx17(DataTableDisplayModeSwitch, {
2810
- messages: labels2,
2811
- onChange: onViewChange,
2812
- value: view
2813
- }) : null,
2814
- showColumnVisibility ? /* @__PURE__ */ jsx17(DataTableViewOptions, {
2815
- messages: labels2,
2816
- table
2817
- }) : null,
2818
- onRefresh ? /* @__PURE__ */ jsxs8(Button, {
2819
- "aria-label": labels2.refresh,
2820
- className: "h-9",
2821
- onClick: () => {
2822
- setRefreshSpinCount((count) => count + 1);
2823
- onRefresh();
2824
- },
2825
- size: "sm",
2826
- type: "button",
2827
- variant: "outline",
2828
- children: [
2829
- /* @__PURE__ */ jsx17(RefreshCw, {
2830
- className: cn(refreshSpinCount > 0 && "animate-[spin_500ms_ease-in-out_1]")
2831
- }, refreshSpinCount),
2832
- /* @__PURE__ */ jsx17("span", {
2833
- className: "hidden sm:inline",
2834
- children: labels2.refresh
2835
- })
3006
+ /* @__PURE__ */ jsxs9(DropdownMenuItem, {
3007
+ onClick: () => setSort(true),
3008
+ children: [
3009
+ /* @__PURE__ */ jsx17(ArrowDown, {}),
3010
+ " ",
3011
+ store.config.labels.sortDesc
3012
+ ]
3013
+ }),
3014
+ sort ? /* @__PURE__ */ jsxs9(DropdownMenuItem, {
3015
+ onClick: () => update((state) => ({
3016
+ ...state,
3017
+ sorting: state.sorting.filter(({ id }) => id !== column.id)
3018
+ })),
3019
+ children: [
3020
+ /* @__PURE__ */ jsx17(X2, {}),
3021
+ " ",
3022
+ store.config.labels.sortClear
3023
+ ]
3024
+ }) : null
2836
3025
  ]
2837
3026
  }) : null,
2838
- showExport ? /* @__PURE__ */ jsxs8(DropdownMenu, {
3027
+ sortingEnabled && hidingEnabled ? /* @__PURE__ */ jsx17(DropdownMenuSeparator, {}) : null,
3028
+ hidingEnabled ? /* @__PURE__ */ jsxs9(DropdownMenuItem, {
3029
+ onClick: () => update((state) => ({
3030
+ ...state,
3031
+ columnVisibility: {
3032
+ ...state.columnVisibility,
3033
+ [column.id]: false
3034
+ }
3035
+ })),
2839
3036
  children: [
2840
- /* @__PURE__ */ jsx17(DropdownMenuTrigger, {
2841
- render: /* @__PURE__ */ jsxs8(Button, {
2842
- "aria-label": labels2.export,
2843
- className: "h-9",
2844
- disabled: exportRows.length === 0,
2845
- size: "sm",
2846
- variant: "outline",
2847
- children: [
2848
- /* @__PURE__ */ jsx17(Download, {}),
2849
- /* @__PURE__ */ jsx17("span", {
2850
- className: "hidden sm:inline",
2851
- children: labels2.export
2852
- })
2853
- ]
2854
- })
2855
- }),
2856
- /* @__PURE__ */ jsx17(DropdownMenuContent, {
2857
- align: "end",
2858
- className: "w-[180px]",
2859
- children: /* @__PURE__ */ jsxs8(DropdownMenuGroup, {
2860
- children: [
2861
- /* @__PURE__ */ jsx17(DropdownMenuLabel, {
2862
- children: labels2.export
2863
- }),
2864
- /* @__PURE__ */ jsx17(DropdownMenuSeparator, {}),
2865
- /* @__PURE__ */ jsxs8(DropdownMenuItem, {
2866
- onClick: () => exportTableToCsv(table, exportRows, exportBaseName),
2867
- children: [
2868
- /* @__PURE__ */ jsx17(FileText, {}),
2869
- labels2.exportCsv
2870
- ]
2871
- }),
2872
- /* @__PURE__ */ jsxs8(DropdownMenuItem, {
2873
- onClick: () => exportTableToJson(table, exportRows, exportBaseName),
2874
- children: [
2875
- /* @__PURE__ */ jsx17(FileJson, {}),
2876
- labels2.exportJson
2877
- ]
2878
- })
2879
- ]
2880
- })
2881
- })
3037
+ /* @__PURE__ */ jsx17(EyeOff, {}),
3038
+ " ",
3039
+ store.config.labels.hideColumn
2882
3040
  ]
2883
3041
  }) : null
2884
3042
  ]
2885
3043
  })
2886
- ]
2887
- })
3044
+ })
3045
+ ]
2888
3046
  });
2889
3047
  };
2890
- function DataTable({
2891
- columns,
2892
- data,
2893
- state,
2894
- search: controlledSearch,
2895
- onSearchChange,
2896
- searchState = "url",
2897
- emptyLabel,
2898
- messages: messages4,
2899
- exportFileName,
2900
- isLoading: legacyIsLoading,
2901
- onRefresh,
2902
- onRowClick,
2903
- from,
2904
- routeFrom,
2905
- grouping,
2906
- gallery,
2907
- rowActions: legacyRowActions,
2908
- reordering,
2909
- serverPagination,
2910
- features
2911
- }) {
2912
- const labels2 = dataTableMessages(messages4);
2913
- const isLoading = state?.loading ?? legacyIsLoading ?? false;
2914
- const emptyContent = state?.error ?? state?.empty ?? emptyLabel ?? labels2.empty;
2915
- const paginationFeature = features?.pagination ?? (serverPagination ? { mode: "server", rowCount: serverPagination.rowCount } : { mode: "client" });
2916
- const exportFeature = features?.export ?? (exportFileName ? { baseName: exportFileName, scope: "currentPage" } : false);
2917
- const exportBaseName = exportFeature ? exportFeature.baseName : "table";
2918
- const galleryConfig = features?.gallery === false ? undefined : features?.gallery ?? gallery;
2919
- const rowActionsFeature = features?.rowActions === false ? undefined : features?.rowActions ?? (legacyRowActions?.length ? {
2920
- items: legacyRowActions.map((action) => ({
2921
- ...action,
2922
- id: action.id ?? action.name
2923
- }))
2924
- } : undefined);
2925
- const rowActions = rowActionsFeature?.items.length ? rowActionsFeature.items : undefined;
2926
- const rowActionsLabel = rowActionsFeature?.label ?? labels2.actions;
2927
- const showPagination = paginationFeature !== false;
2928
- const pageSizes = paginationFeature ? paginationFeature.pageSizes : undefined;
2929
- const showSearch = features?.search ?? true;
2930
- const showExport = exportFeature !== false;
2931
- const columnVisibilityFeature2 = features?.columnVisibility ?? true;
2932
- const showColumnVisibility = columnVisibilityFeature2 !== false;
2933
- const defaultColumnVisibility = Schema2.is(Schema2.Struct({ default: ColumnVisibilitySchema }))(columnVisibilityFeature2) ? columnVisibilityFeature2.default : undefined;
2934
- const showGallery = !!galleryConfig;
2935
- const showSorting = features?.sorting ?? true;
2936
- const selectionFeature = features?.selection === false ? undefined : features?.selection;
2937
- const selectable = !!selectionFeature;
2938
- const bulkActions = selectionFeature?.bulkActions === false ? undefined : selectionFeature?.bulkActions;
2939
- const isServerMode = paginationFeature !== false && paginationFeature.mode === "server";
2940
- const serverRowCount = isServerMode ? paginationFeature.rowCount : undefined;
2941
- const location = useRouterState({
2942
- select: (state2) => state2.location
2943
- });
2944
- const search = Option2.getOrUndefined(decodeTableSearch(location.search));
2945
- const pathname = location.pathname;
2946
- const resolvedRouteFrom = routeFrom ?? from;
2947
- const [storagePath] = useState(() => resolvedRouteFrom ?? pathname);
2948
- const navigate = useNavigate(resolvedRouteFrom ? { from: resolvedRouteFrom } : undefined);
2949
- const [localSearch, setLocalSearch] = useState({
2950
- globalFilter: ""
2951
- });
2952
- const tableSearch = controlledSearch ?? (searchState === "local" ? localSearch : search);
2953
- const {
2954
- page = 0,
2955
- pageSize = 10,
2956
- sort,
2957
- globalFilter = "",
2958
- grouping: urlGrouping
2959
- } = tableSearch ?? {};
2960
- const pagination = { pageIndex: page, pageSize };
2961
- const decodedSort = sort ? Schema2.decodeSync(SortParamsFromString)(sort) : [];
2962
- const sorting = decodedSort.map((sortParam) => ({
2963
- id: sortParam.id,
2964
- desc: sortParam.direction === "desc"
2965
- }));
2966
- const tableStorageId = useMemo(() => {
2967
- const columnIds = columns.map((column, index) => {
2968
- if ("id" in column && Schema2.is(Schema2.String)(column.id)) {
2969
- return column.id;
2970
- }
2971
- if ("accessorKey" in column && Schema2.is(Schema2.String)(column.accessorKey)) {
2972
- return column.accessorKey;
2973
- }
2974
- return String(index);
2975
- }).join(",");
2976
- return `${storagePath}:${columnIds}`;
2977
- }, [columns, storagePath]);
2978
- const columnVisibilityAtom = useMemo(() => Atom.kvs({
2979
- runtime: dataTableStorageRuntime,
2980
- key: `data-table:column-visibility:${tableStorageId}`,
2981
- schema: ColumnVisibilitySchema,
2982
- defaultValue: () => defaultColumnVisibility ?? {}
2983
- }), [defaultColumnVisibility, tableStorageId]);
2984
- const columnSizingAtom = useMemo(() => Atom.kvs({
2985
- runtime: dataTableStorageRuntime,
2986
- key: `data-table:column-sizing:${tableStorageId}`,
2987
- schema: ColumnSizingSchema,
2988
- defaultValue: () => ({})
2989
- }), [tableStorageId]);
2990
- const viewAtom = useMemo(() => Atom.kvs({
2991
- runtime: dataTableStorageRuntime,
2992
- key: `data-table:view:${tableStorageId}`,
2993
- schema: DataTableViewSchema,
2994
- defaultValue: () => "table"
2995
- }), [tableStorageId]);
2996
- const [columnVisibility, setColumnVisibility] = useAtom(columnVisibilityAtom);
2997
- const [columnSizing, setColumnSizing] = useAtom(columnSizingAtom);
2998
- const [storedView, setStoredView] = useAtom(viewAtom);
2999
- const currentView = showGallery ? storedView : "table";
3000
- const isGalleryView = currentView === "gallery";
3001
- const [rowSelection, setRowSelection] = useState({});
3002
- const [collapsedGroups, setCollapsedGroups] = useState({});
3003
- const [activeDragLabel, setActiveDragLabel] = useState(null);
3004
- const availableGroupFieldIds = grouping?.fields.map((field) => field.id) ?? [];
3005
- const activeGrouping = urlGrouping?.filter((groupId) => availableGroupFieldIds.includes(groupId)) ?? getDefaultGrouping(grouping);
3006
- const sensors = useSensors(useSensor(PointerSensor, {
3007
- activationConstraint: {
3008
- distance: 8
3009
- }
3010
- }));
3011
- const updateTableSearch = (updater, options) => {
3012
- if (controlledSearch || onSearchChange || searchState === "local") {
3013
- const nextSearch = Schema2.decodeUnknownSync(TableSearchSchema)(updater(controlledSearch ?? localSearch));
3014
- if (onSearchChange) {
3015
- onSearchChange(nextSearch);
3016
- } else {
3017
- setLocalSearch(nextSearch);
3018
- }
3019
- return;
3020
- }
3021
- navigate({
3022
- to: ".",
3023
- replace: options?.replace ?? false,
3024
- resetScroll: false,
3025
- search: (current) => validateTableSearchUpdate(updater(current))
3026
- });
3027
- };
3028
- const table = useDataTable({
3029
- key: tableStorageId,
3030
- data,
3031
- columns,
3032
- onColumnSizingChange: (updater) => {
3033
- const nextColumnSizing = updater instanceof Function ? updater(columnSizing) : updater;
3034
- setColumnSizing(nextColumnSizing);
3035
- },
3036
- ...selectionFeature ? { getRowId: selectionFeature.getRowId } : reordering ? { getRowId: reordering.getRowId } : {},
3037
- enableRowSelection: selectionFeature?.isRowSelectable ? (row) => selectionFeature.isRowSelectable?.(row.original) ?? true : selectable,
3038
- enableMultiRowSelection: selectable,
3039
- onPaginationChange: (updater) => {
3040
- const newPagination = updater instanceof Function ? updater(pagination) : updater;
3041
- if (pagination.pageIndex === newPagination.pageIndex && pagination.pageSize === newPagination.pageSize) {
3042
- return;
3043
- }
3044
- updateTableSearch((current) => ({
3045
- ...current,
3046
- page: newPagination.pageIndex,
3047
- pageSize: newPagination.pageSize
3048
- }));
3049
- },
3050
- onSortingChange: (updater) => {
3051
- const newSorting = updater instanceof Function ? updater([...sorting]) : updater;
3052
- if (sorting.length === newSorting.length && sorting.every((sortState, i) => sortState.id === newSorting[i]?.id && sortState.desc === newSorting[i]?.desc)) {
3053
- return;
3054
- }
3055
- const nextSort = newSorting.length ? Schema2.encodeSync(SortParamsFromString)(newSorting.map((sortState) => ({
3056
- id: sortState.id,
3057
- direction: sortState.desc ? "desc" : "asc"
3058
- }))) : undefined;
3059
- updateTableSearch((current) => ({
3060
- ...current,
3061
- sort: nextSort,
3062
- page: 0
3063
- }));
3064
- },
3065
- onGlobalFilterChange: (updater) => {
3066
- const newGlobalFilter = updater instanceof Function ? updater(globalFilter) : updater;
3067
- if (globalFilter === newGlobalFilter) {
3068
- return;
3069
- }
3070
- updateTableSearch((current) => ({
3071
- ...current,
3072
- page: 0,
3073
- globalFilter: newGlobalFilter
3074
- }), { replace: true });
3075
- },
3076
- manualSorting: isServerMode || undefined,
3077
- manualFiltering: isServerMode || undefined,
3078
- ...paginationFeature !== false && paginationFeature.mode === "server" ? { manualPagination: true, rowCount: paginationFeature.rowCount } : paginationFeature === false ? { manualPagination: true } : {},
3079
- autoResetPageIndex: false,
3080
- onColumnVisibilityChange: (updater) => {
3081
- const nextColumnVisibility = updater instanceof Function ? updater(columnVisibility) : updater;
3082
- setColumnVisibility(nextColumnVisibility);
3083
- },
3084
- onRowSelectionChange: (updater) => {
3085
- setRowSelection((current) => {
3086
- const next = updater instanceof Function ? updater(current) : updater;
3087
- selectionFeature?.onSelectionChange?.(data.filter((row) => next[selectionFeature.getRowId(row)]));
3088
- return next;
3089
- });
3090
- },
3091
- state: {
3092
- sorting,
3093
- pagination,
3094
- globalFilter,
3095
- columnVisibility,
3096
- columnSizing,
3097
- rowSelection
3098
- }
3099
- });
3100
- const activeGroupingFields = useMemo(() => activeGrouping.map((groupId) => grouping?.fields.find((field) => field.id === groupId)).filter((field) => !!field), [activeGrouping, grouping]);
3101
- const hasActiveGrouping = activeGroupingFields.length > 0;
3102
- const filteredRows = table.getPrePaginatedRowModel().rows;
3103
- const selectedRows = selectionFeature ? data.filter((row) => rowSelection[selectionFeature.getRowId(row)]) : [];
3104
- const exportRows = exportFeature && exportFeature.scope === "filteredRows" ? filteredRows : table.getRowModel().rows;
3105
- const bodyRows = hasActiveGrouping ? filteredRows : table.getRowModel().rows;
3106
- const sortableRowIds = bodyRows.map((row) => getSortableRowId(row.id));
3107
- const groupedSections = useMemo(() => buildGroupedSections(bodyRows, activeGroupingFields), [activeGroupingFields, bodyRows]);
3108
- const canReorderRows = Boolean(reordering) && !hasActiveGrouping;
3109
- const colSpan = Math.max(table.getVisibleLeafColumns().length, 1) + (rowActions ? 1 : 0) + (selectable ? 1 : 0) + (canReorderRows ? 1 : 0);
3110
- const canDragRows = activeGroupingFields.some((field) => !!field.onMoveToGroup);
3111
- const addGroupingField = (fieldId) => {
3112
- if (activeGrouping.includes(fieldId))
3113
- return;
3114
- updateTableSearch((current) => ({
3115
- ...current,
3116
- grouping: [...activeGrouping, fieldId]
3117
- }));
3118
- };
3119
- const removeGroupingField = (fieldId) => {
3120
- updateTableSearch((current) => ({
3121
- ...current,
3122
- grouping: activeGrouping.filter((currentId) => currentId !== fieldId)
3123
- }));
3124
- };
3125
- const toggleGroupingField = (fieldId, enabled) => {
3126
- if (enabled) {
3127
- addGroupingField(fieldId);
3128
- return;
3129
- }
3130
- removeGroupingField(fieldId);
3131
- };
3132
- const toggleGroup = (groupKey) => {
3133
- setCollapsedGroups((current) => ({
3134
- ...current,
3135
- [groupKey]: !current[groupKey]
3136
- }));
3137
- };
3138
- const setView = (nextView) => {
3139
- if (nextView === currentView) {
3140
- return;
3141
- }
3142
- setStoredView(nextView);
3143
- };
3144
- const renderLoadingState = () => /* @__PURE__ */ jsx17(Loading, {
3145
- label: labels2.loading
3146
- });
3147
- const renderEmptyContent = () => state?.error ?? (isLoading ? renderLoadingState() : emptyContent);
3148
- const renderTableEmptyState = () => /* @__PURE__ */ jsx17(TableRow, {
3149
- children: /* @__PURE__ */ jsx17(TableCell, {
3150
- className: "h-24 text-center",
3151
- colSpan,
3152
- children: renderEmptyContent()
3153
- })
3154
- });
3155
- const renderGalleryEmptyState = (message) => /* @__PURE__ */ jsx17("div", {
3156
- className: "text-muted-foreground rounded-xl border border-dashed px-4 py-10 text-center text-sm",
3157
- children: message ?? renderEmptyContent()
3158
- });
3159
- const renderGalleryRows = (rows, canDrag) => /* @__PURE__ */ jsx17("div", {
3160
- className: "grid gap-3 sm:grid-cols-2 xl:grid-cols-3",
3161
- children: rows.map((row) => /* @__PURE__ */ jsx17(DataTableGalleryCard, {
3162
- canDrag,
3163
- dragLabel: grouping?.getRowLabel?.(row.original),
3164
- gallery: galleryConfig,
3165
- onRowClick,
3166
- row,
3167
- rowActions,
3168
- rowActionsLabel,
3169
- selectRowLabel: labels2.selectRow,
3170
- selectable,
3171
- table
3172
- }, row.id))
3173
- });
3174
- const renderGroupedTableSections = (sections) => sections.flatMap((section) => {
3175
- const isCollapsed = collapsedGroups[section.key] ?? false;
3176
- const hasChildren = section.children.length > 0;
3177
- const sectionBody = /* @__PURE__ */ jsxs8(GroupTableSection, {
3178
- section,
3048
+ var DataTableHeader = ({
3049
+ tableAtom
3050
+ }) => {
3051
+ const [store, setStore] = useTableAtom(tableAtom);
3052
+ const model = deriveModel(store);
3053
+ const selection = store.config.features.selection;
3054
+ const grouped = getActiveGrouping(store).length > 0;
3055
+ const draggable = canDragRows(store);
3056
+ const selectableRows = getDataTableSelectableRows(model, grouped, selection ? selection.isRowSelectable : undefined);
3057
+ const allSelected = selectableRows.length > 0 && selectableRows.every((row) => store.state.rowSelection[row.id]);
3058
+ const someSelected = selectableRows.some((row) => store.state.rowSelection[row.id]);
3059
+ return /* @__PURE__ */ jsx17(TableHeader, {
3060
+ children: /* @__PURE__ */ jsxs9(TableRow, {
3179
3061
  children: [
3180
- /* @__PURE__ */ jsx17(GroupHeaderRow, {
3181
- collapsed: isCollapsed,
3182
- colSpan,
3183
- onToggle: () => toggleGroup(section.key),
3184
- section
3185
- }),
3186
- !isCollapsed && !hasChildren && (section.rows.length > 0 ? section.rows.map((row) => /* @__PURE__ */ jsx17(DataTableRow, {
3187
- canDrag: canDragRows,
3188
- canReorder: false,
3189
- dragLabel: grouping?.getRowLabel?.(row.original),
3190
- indentDepth: section.depth + 1,
3191
- onRowClick,
3192
- row,
3193
- rowActions,
3194
- rowActionsLabel,
3195
- selectRowLabel: labels2.selectRow,
3196
- selectable,
3197
- table
3198
- }, row.id)) : /* @__PURE__ */ jsx17(TableRow, {
3199
- children: /* @__PURE__ */ jsx17(TableCell, {
3200
- className: "text-muted-foreground h-16",
3201
- colSpan,
3202
- style: {
3203
- paddingLeft: `calc(0.5rem + ${section.depth * GROUP_INDENT_PX + GROUP_ROW_INDENT_OFFSET_PX}px)`
3204
- },
3205
- children: isLoading ? renderLoadingState() : section.field.renderEmptyGroup?.(section.groupId) ?? labels2.empty
3062
+ selection ? /* @__PURE__ */ jsx17(TableHead, {
3063
+ className: "w-10 pr-0",
3064
+ children: /* @__PURE__ */ jsx17(Checkbox, {
3065
+ "aria-label": store.config.labels.selectAllRows,
3066
+ checked: allSelected,
3067
+ indeterminate: someSelected && !allSelected,
3068
+ onCheckedChange: (checked) => {
3069
+ changeState(setStore, (state) => {
3070
+ const rowSelection = { ...state.rowSelection };
3071
+ selectableRows.forEach((row) => rowSelection[row.id] = checked);
3072
+ selection.onSelectionChange?.(model.rows.filter((row) => rowSelection[row.id]).map((row) => row.data));
3073
+ return { ...state, rowSelection };
3074
+ });
3075
+ }
3206
3076
  })
3207
- }))
3208
- ]
3209
- }, section.key);
3210
- return !isCollapsed && hasChildren ? [sectionBody, renderGroupedTableSections(section.children)] : [sectionBody];
3211
- });
3212
- const renderGroupedGallerySections = (sections) => sections.map((section) => {
3213
- const isCollapsed = collapsedGroups[section.key] ?? false;
3214
- const hasChildren = section.children.length > 0;
3215
- return /* @__PURE__ */ jsxs8("div", {
3216
- className: "space-y-3",
3217
- children: [
3218
- /* @__PURE__ */ jsx17(GroupHeaderCard, {
3219
- collapsed: isCollapsed,
3220
- onToggle: () => toggleGroup(section.key),
3221
- section
3222
- }),
3223
- !isCollapsed && (hasChildren ? renderGroupedGallerySections(section.children) : section.rows.length > 0 ? renderGalleryRows(section.rows, canDragRows) : renderGalleryEmptyState(isLoading ? renderLoadingState() : section.field.renderEmptyGroup?.(section.groupId) ?? labels2.empty))
3224
- ]
3225
- }, section.key);
3226
- });
3227
- const handleDragEnd = ({ active, over }) => {
3228
- setActiveDragLabel(null);
3229
- if (!over)
3230
- return;
3231
- const reorderData = decodeRowReorderDragData(active.data.current);
3232
- if (Option2.isSome(reorderData) && reordering && canReorderRows) {
3233
- const sourceRowId = String(active.id).replace(/^sortable-row:/, "");
3234
- const targetRowId = String(over.id).replace(/^sortable-row:/, "");
3235
- const currentIndex = bodyRows.findIndex((row2) => row2.id === sourceRowId);
3236
- const nextIndex = bodyRows.findIndex((row2) => row2.id === targetRowId);
3237
- if (currentIndex !== -1 && nextIndex !== -1 && currentIndex !== nextIndex) {
3238
- reordering.onReorder(arrayMove(bodyRows.map((row2) => row2.original), currentIndex, nextIndex));
3239
- }
3240
- return;
3241
- }
3242
- const rowData = decodeRowDragData(active.data.current);
3243
- const groupData = decodeGroupDropData(over.data.current);
3244
- if (Option2.isNone(rowData) || Option2.isNone(groupData))
3245
- return;
3246
- const row = bodyRows.find(({ id }) => id === rowData.value.rowId)?.original;
3247
- const field = grouping?.fields.find((currentField) => currentField.id === groupData.value.fieldId);
3248
- const nextGroupId = groupData.value.groupId;
3249
- if (row && field?.onMoveToGroup && field.getGroupId(row) !== nextGroupId) {
3250
- field.onMoveToGroup(row, nextGroupId);
3251
- }
3252
- };
3253
- const handleDragStart = ({ active }) => {
3254
- const rowData = decodeRowDragData(active.data.current);
3255
- setActiveDragLabel(Option2.isSome(rowData) ? rowData.value.label ?? null : null);
3256
- };
3257
- return /* @__PURE__ */ jsxs8("div", {
3258
- className: "w-full max-w-full min-w-0 rounded-md",
3259
- children: [
3260
- /* @__PURE__ */ jsx17(DataTableToolbar, {
3261
- activeGrouping,
3262
- bulkActions,
3263
- exportBaseName,
3264
- exportRows,
3265
- grouping,
3266
- labels: labels2,
3267
- onRefresh,
3268
- onToggleGrouping: toggleGroupingField,
3269
- onViewChange: setView,
3270
- selectedRows,
3271
- showColumnVisibility,
3272
- showExport,
3273
- showGallery,
3274
- showSearch,
3275
- showSorting,
3276
- table,
3277
- view: currentView
3278
- }),
3279
- /* @__PURE__ */ jsx17(DndContext, {
3280
- onDragCancel: () => setActiveDragLabel(null),
3281
- onDragEnd: handleDragEnd,
3282
- onDragStart: handleDragStart,
3283
- sensors,
3284
- children: /* @__PURE__ */ jsxs8(table.AppTable, {
3285
- children: [
3286
- isGalleryView ? hasActiveGrouping ? groupedSections.length > 0 ? /* @__PURE__ */ jsx17("div", {
3287
- className: "space-y-4",
3288
- children: renderGroupedGallerySections(groupedSections)
3289
- }) : renderGalleryEmptyState() : bodyRows.length > 0 ? renderGalleryRows(bodyRows, false) : renderGalleryEmptyState() : /* @__PURE__ */ jsxs8(ScrollArea, {
3290
- className: "-m-1 max-w-full min-w-0",
3077
+ }) : null,
3078
+ draggable ? /* @__PURE__ */ jsx17(TableHead, {
3079
+ className: "w-10"
3080
+ }) : null,
3081
+ model.visibleColumns.map((column) => {
3082
+ return /* @__PURE__ */ jsx17(TableHead, {
3083
+ className: "relative h-12",
3084
+ style: { width: column.width },
3085
+ children: /* @__PURE__ */ jsxs9(ColumnIdContext.Provider, {
3086
+ value: column.id,
3291
3087
  children: [
3292
- /* @__PURE__ */ jsx17("div", {
3293
- className: "max-w-full min-w-0 p-1",
3294
- children: /* @__PURE__ */ jsxs8(Table, {
3295
- className: "table-fixed",
3296
- style: {
3297
- width: `max(100%, ${table.getTotalSize() + (canReorderRows ? 40 : 0) + (selectable ? 40 : 0) + (rowActions ? 40 : 0)}px)`
3298
- },
3299
- children: [
3300
- /* @__PURE__ */ jsx17(TableHeader, {
3301
- children: table.getHeaderGroups().map((headerGroup) => /* @__PURE__ */ jsxs8(TableRow, {
3302
- className: "p-4",
3303
- children: [
3304
- selectable ? /* @__PURE__ */ jsx17(TableHead, {
3305
- className: "w-10 min-w-10 pr-0",
3306
- children: /* @__PURE__ */ jsx17(Checkbox, {
3307
- "aria-label": labels2.selectAllRows,
3308
- checked: table.getIsAllPageRowsSelected(),
3309
- indeterminate: table.getIsSomePageRowsSelected() && !table.getIsAllPageRowsSelected(),
3310
- onCheckedChange: (checked) => table.toggleAllPageRowsSelected(checked)
3311
- })
3312
- }) : null,
3313
- canReorderRows ? /* @__PURE__ */ jsx17(TableHead, {
3314
- className: "w-10 min-w-10 p-0"
3315
- }) : null,
3316
- headerGroup.headers.map((header) => /* @__PURE__ */ jsx17(table.AppHeader, {
3317
- header,
3318
- children: (appHeader) => /* @__PURE__ */ jsxs8(TableHead, {
3319
- className: "relative h-12 min-w-32 p-0",
3320
- style: { width: header.getSize() },
3321
- children: [
3322
- header.isPlaceholder ? null : /* @__PURE__ */ jsx17(appHeader.FlexRender, {}),
3323
- header.column.getCanResize() ? /* @__PURE__ */ jsx17("button", {
3324
- "aria-label": labels2.resizeColumn(getHeaderName(header)),
3325
- "aria-orientation": "vertical",
3326
- "aria-valuemax": header.column.columnDef.maxSize ?? DEFAULT_COLUMN_MAX_SIZE,
3327
- "aria-valuemin": header.column.columnDef.minSize ?? DEFAULT_COLUMN_MIN_SIZE,
3328
- "aria-valuenow": header.column.getSize(),
3329
- className: cn("hover:bg-primary/60 absolute inset-y-0 right-0 z-10 w-1 cursor-col-resize touch-none bg-transparent p-0 select-none", header.column.getIsResizing() && "bg-primary"),
3330
- onKeyDown: (event) => {
3331
- const minSize = header.column.columnDef.minSize ?? DEFAULT_COLUMN_MIN_SIZE;
3332
- const maxSize = header.column.columnDef.maxSize ?? DEFAULT_COLUMN_MAX_SIZE;
3333
- const currentSize = header.column.getSize();
3334
- const nextSize = event.key === "ArrowLeft" ? currentSize - COLUMN_RESIZE_STEP : event.key === "ArrowRight" ? currentSize + COLUMN_RESIZE_STEP : event.key === "Home" ? minSize : event.key === "End" ? maxSize : undefined;
3335
- if (nextSize === undefined)
3336
- return;
3337
- event.preventDefault();
3338
- table.setColumnSizing((current) => ({
3339
- ...current,
3340
- [header.column.id]: Math.min(maxSize, Math.max(minSize, nextSize))
3341
- }));
3342
- },
3343
- role: "separator",
3344
- type: "button",
3345
- onDoubleClick: () => header.column.resetSize(),
3346
- onMouseDown: header.getResizeHandler(),
3347
- onTouchStart: header.getResizeHandler()
3348
- }) : null
3349
- ]
3350
- })
3351
- }, header.id)),
3352
- rowActions ? /* @__PURE__ */ jsx17(TableHead, {
3353
- className: "w-10 min-w-10 p-0"
3354
- }) : null
3355
- ]
3356
- }, headerGroup.id))
3357
- }),
3358
- hasActiveGrouping ? groupedSections.length > 0 ? renderGroupedTableSections(groupedSections) : /* @__PURE__ */ jsx17(TableBody, {
3359
- className: "px-2",
3360
- children: renderTableEmptyState()
3361
- }) : /* @__PURE__ */ jsx17(TableBody, {
3362
- className: "px-2",
3363
- children: bodyRows.length > 0 ? canReorderRows ? /* @__PURE__ */ jsx17(SortableContext, {
3364
- items: sortableRowIds,
3365
- strategy: verticalListSortingStrategy,
3366
- children: bodyRows.map((row) => /* @__PURE__ */ jsx17(DataTableRow, {
3367
- canDrag: false,
3368
- canReorder: true,
3369
- dragLabel: reordering?.getRowLabel?.(row.original),
3370
- onRowClick,
3371
- reorderHandleLabel: reordering?.handleLabel ?? labels2.reorder,
3372
- row,
3373
- rowActions,
3374
- rowActionsLabel,
3375
- selectRowLabel: labels2.selectRow,
3376
- selectable,
3377
- table
3378
- }, row.id))
3379
- }) : bodyRows.map((row) => /* @__PURE__ */ jsx17(DataTableRow, {
3380
- canDrag: false,
3381
- canReorder: false,
3382
- onRowClick,
3383
- row,
3384
- rowActions,
3385
- rowActionsLabel,
3386
- selectRowLabel: labels2.selectRow,
3387
- selectable,
3388
- table
3389
- }, row.id)) : renderTableEmptyState()
3390
- })
3391
- ]
3392
- })
3088
+ /* @__PURE__ */ jsx17(ColumnHeaderMenu, {
3089
+ tableAtom
3393
3090
  }),
3394
- /* @__PURE__ */ jsx17(ScrollBar, {
3395
- orientation: "horizontal"
3091
+ /* @__PURE__ */ jsx17(ResizeHandle, {
3092
+ tableAtom
3396
3093
  })
3397
3094
  ]
3398
- }),
3399
- /* @__PURE__ */ jsx17(DragOverlay, {
3400
- modifiers: [snapDragOverlayVerticalCenterToCursor],
3401
- children: activeDragLabel ? /* @__PURE__ */ jsx17("div", {
3402
- className: "bg-background rounded-md border px-3 py-2 text-sm shadow-sm",
3403
- children: activeDragLabel
3404
- }) : null
3405
3095
  })
3406
- ]
3407
- })
3408
- }),
3409
- showPagination && !hasActiveGrouping && /* @__PURE__ */ jsx17("div", {
3410
- className: "p-2",
3411
- children: /* @__PURE__ */ jsx17(DataTablePagination, {
3412
- messages: labels2,
3413
- pageSizes,
3414
- rowCount: serverRowCount,
3415
- table
3096
+ }, column.id);
3097
+ }),
3098
+ store.config.features.rowActions ? /* @__PURE__ */ jsx17(TableHead, {
3099
+ className: "w-10"
3100
+ }) : null
3101
+ ]
3102
+ })
3103
+ });
3104
+ };
3105
+ var DataTableBody = ({
3106
+ tableAtom
3107
+ }) => {
3108
+ const [store] = useTableAtom(tableAtom);
3109
+ const model = deriveModel(store);
3110
+ const grouped = getActiveGrouping(store).length > 0;
3111
+ const rows = grouped ? model.sortedRows : model.pageRows;
3112
+ const colSpan = model.visibleColumns.length + (store.config.features.selection ? 1 : 0) + (store.config.features.rowActions ? 1 : 0) + (canDragRows(store) ? 1 : 0);
3113
+ if (grouped && rows.length && !store.config.status.error) {
3114
+ return /* @__PURE__ */ jsx17(GroupedTable, {
3115
+ tableAtom
3116
+ });
3117
+ }
3118
+ return /* @__PURE__ */ jsx17(TableBody, {
3119
+ children: store.config.status.error || !rows.length && !store.config.status.loading ? /* @__PURE__ */ jsx17(TableRow, {
3120
+ children: /* @__PURE__ */ jsx17(TableCell, {
3121
+ className: "h-24 text-center",
3122
+ colSpan: Math.max(colSpan, 1),
3123
+ children: store.config.status.error ?? store.config.status.empty ?? store.config.labels.empty
3124
+ })
3125
+ }) : store.config.status.loading && !rows.length ? /* @__PURE__ */ jsx17(TableRow, {
3126
+ children: /* @__PURE__ */ jsx17(TableCell, {
3127
+ className: "h-24 text-center",
3128
+ colSpan: Math.max(colSpan, 1),
3129
+ children: /* @__PURE__ */ jsx17(Loading, {
3130
+ label: store.config.labels.loading
3416
3131
  })
3417
3132
  })
3418
- ]
3133
+ }) : rows.map((row) => /* @__PURE__ */ jsx17(RowIdContext.Provider, {
3134
+ value: row.id,
3135
+ children: /* @__PURE__ */ jsx17(TableDataRow, {
3136
+ tableAtom
3137
+ })
3138
+ }, row.id))
3419
3139
  });
3420
- }
3421
- function DataTableDisplayModeSwitch({
3422
- messages: messages4,
3423
- value,
3424
- onChange
3425
- }) {
3426
- return /* @__PURE__ */ jsxs8(DropdownMenu, {
3427
- children: [
3428
- /* @__PURE__ */ jsx17(DropdownMenuTrigger, {
3429
- render: /* @__PURE__ */ jsxs8(Button, {
3430
- "aria-label": messages4.view,
3431
- className: "h-9",
3432
- size: "sm",
3433
- variant: "outline",
3140
+ };
3141
+ var GalleryCard = ({
3142
+ tableAtom
3143
+ }) => {
3144
+ const [store, setStore] = useTableAtom(tableAtom);
3145
+ const rowId = useRequiredId(RowIdContext);
3146
+ const model = deriveModel(store);
3147
+ const row = model.sortedRows.find((candidate) => candidate.id === rowId);
3148
+ const gallery = store.config.features.gallery;
3149
+ if (!row || !gallery)
3150
+ return null;
3151
+ const find = (id) => id ? model.visibleColumns.find((column) => column.id === id) : undefined;
3152
+ const name = find(gallery.name);
3153
+ const description = find(gallery.description);
3154
+ const tag = find(gallery.tag);
3155
+ const selection = store.config.features.selection;
3156
+ const selectable = !!selection && (selection.isRowSelectable?.(row.data) ?? true);
3157
+ const rowActions = store.config.features.rowActions;
3158
+ const draggable = canDragRows(store);
3159
+ return /* @__PURE__ */ jsx17(Card, {
3160
+ className: cn("relative gap-3 data-[drag-source=true]:opacity-40 data-[drop-position=before]:border-t-2 data-[drop-position=before]:border-t-primary data-[drop-position=after]:border-b-2 data-[drop-position=after]:border-b-primary", store.config.onRowClicked && "cursor-pointer"),
3161
+ "data-table-row": row.id,
3162
+ onClick: () => store.config.onRowClicked?.(row.data),
3163
+ onKeyDown: (event) => {
3164
+ if (event.target === event.currentTarget && store.config.onRowClicked && (event.key === "Enter" || event.key === " ")) {
3165
+ event.preventDefault();
3166
+ store.config.onRowClicked(row.data);
3167
+ }
3168
+ },
3169
+ tabIndex: store.config.onRowClicked ? 0 : undefined,
3170
+ children: /* @__PURE__ */ jsxs9(CardHeader, {
3171
+ className: "pr-12",
3172
+ children: [
3173
+ /* @__PURE__ */ jsxs9("div", {
3174
+ className: "flex items-center gap-2",
3434
3175
  children: [
3435
- value === "gallery" ? /* @__PURE__ */ jsx17(LayoutGrid, {}) : /* @__PURE__ */ jsx17(Rows3, {}),
3436
- /* @__PURE__ */ jsx17("span", {
3437
- className: "hidden sm:inline",
3438
- children: messages4.view
3439
- })
3176
+ selection ? /* @__PURE__ */ jsx17(Checkbox, {
3177
+ "aria-label": store.config.labels.selectRow,
3178
+ checked: !!store.state.rowSelection[row.id],
3179
+ disabled: !selectable,
3180
+ onCheckedChange: (checked) => toggleRow(store, setStore, row.id, checked),
3181
+ onClick: (event) => event.stopPropagation()
3182
+ }) : null,
3183
+ draggable ? /* @__PURE__ */ jsx17(DragHandle, {
3184
+ tableAtom
3185
+ }) : null,
3186
+ tag ? /* @__PURE__ */ jsxs9(Badge, {
3187
+ variant: "secondary",
3188
+ children: [
3189
+ gallery.tagIcon,
3190
+ renderCell(row, tag)
3191
+ ]
3192
+ }) : null
3440
3193
  ]
3194
+ }),
3195
+ /* @__PURE__ */ jsx17(CardTitle, {
3196
+ children: name ? renderCell(row, name) : row.id
3197
+ }),
3198
+ description ? /* @__PURE__ */ jsx17("div", {
3199
+ className: "text-muted-foreground line-clamp-3 text-sm",
3200
+ children: renderCell(row, description)
3201
+ }) : null,
3202
+ rowActions ? /* @__PURE__ */ jsx17("div", {
3203
+ className: "absolute top-4 right-4",
3204
+ onClick: (event) => event.stopPropagation(),
3205
+ children: /* @__PURE__ */ jsx17(DataTableRowActions, {
3206
+ actions: rowActions.items,
3207
+ row: row.data,
3208
+ title: rowActions.label ?? store.config.labels.actions
3209
+ })
3210
+ }) : null
3211
+ ]
3212
+ })
3213
+ });
3214
+ };
3215
+ var DataTableGallery = ({
3216
+ tableAtom
3217
+ }) => {
3218
+ const [store, setStore] = useTableAtom(tableAtom);
3219
+ const model = deriveModel(store);
3220
+ const fields = getActiveGrouping(store);
3221
+ const rows = fields.length ? model.sortedRows : model.pageRows;
3222
+ if (store.config.status.error) {
3223
+ return /* @__PURE__ */ jsx17("div", {
3224
+ className: "text-destructive rounded-lg border border-dashed p-10 text-center",
3225
+ children: store.config.status.error
3226
+ });
3227
+ }
3228
+ if (store.config.status.loading && !rows.length) {
3229
+ return /* @__PURE__ */ jsx17("div", {
3230
+ className: "rounded-lg border border-dashed p-10 text-center",
3231
+ children: /* @__PURE__ */ jsx17(Loading, {
3232
+ label: store.config.labels.loading
3233
+ })
3234
+ });
3235
+ }
3236
+ if (!rows.length) {
3237
+ return /* @__PURE__ */ jsx17("div", {
3238
+ className: "text-muted-foreground rounded-lg border border-dashed p-10 text-center",
3239
+ children: store.config.status.empty ?? store.config.labels.empty
3240
+ });
3241
+ }
3242
+ if (!fields.length) {
3243
+ return /* @__PURE__ */ jsx17("div", {
3244
+ className: "grid gap-3 sm:grid-cols-2 xl:grid-cols-3",
3245
+ children: rows.map((row) => /* @__PURE__ */ jsx17(RowIdContext.Provider, {
3246
+ value: row.id,
3247
+ children: /* @__PURE__ */ jsx17(GalleryCard, {
3248
+ tableAtom
3441
3249
  })
3442
- }),
3443
- /* @__PURE__ */ jsx17(DropdownMenuContent, {
3444
- align: "end",
3445
- className: "w-[160px]",
3446
- children: /* @__PURE__ */ jsxs8(DropdownMenuRadioGroup, {
3447
- value,
3448
- onValueChange: (nextValue) => {
3449
- const view = decodeDataTableView(nextValue);
3450
- if (Option2.isSome(view))
3451
- onChange(view.value);
3452
- },
3250
+ }, row.id))
3251
+ });
3252
+ }
3253
+ const renderSections = (sections) => sections.map((section) => {
3254
+ const collapsed = !!store.state.collapsedGroups[section.key];
3255
+ const targetKey = getGroupDropKey(section.field.id, section.groupId);
3256
+ return /* @__PURE__ */ jsxs9("section", {
3257
+ className: "data-[drop-target=true]:ring-primary space-y-3 rounded-lg transition-shadow data-[drop-target=true]:ring-2",
3258
+ "data-table-group": section.field.onMoveToGroup ? targetKey : undefined,
3259
+ children: [
3260
+ /* @__PURE__ */ jsxs9("div", {
3261
+ className: "flex items-center gap-2 rounded-lg border p-3",
3453
3262
  children: [
3454
- /* @__PURE__ */ jsxs8(DropdownMenuRadioItem, {
3455
- value: "table",
3263
+ /* @__PURE__ */ jsxs9("button", {
3264
+ "aria-expanded": !collapsed,
3265
+ className: "flex flex-1 items-center gap-2 text-left",
3266
+ onClick: () => changeState(setStore, (state) => ({
3267
+ ...state,
3268
+ collapsedGroups: {
3269
+ ...state.collapsedGroups,
3270
+ [section.key]: !collapsed
3271
+ }
3272
+ })),
3273
+ type: "button",
3456
3274
  children: [
3457
- /* @__PURE__ */ jsx17(Rows3, {}),
3458
- messages4.tableView
3275
+ collapsed ? /* @__PURE__ */ jsx17(ChevronRight2, {
3276
+ className: "size-4"
3277
+ }) : /* @__PURE__ */ jsx17(ChevronDown, {
3278
+ className: "size-4"
3279
+ }),
3280
+ /* @__PURE__ */ jsx17("span", {
3281
+ className: "flex-1",
3282
+ children: section.field.renderGroupLabel?.(section.groupId, section.rows.map((row) => row.data)) ?? section.groupId
3283
+ }),
3284
+ /* @__PURE__ */ jsx17(Badge, {
3285
+ variant: "secondary",
3286
+ children: section.rows.length
3287
+ })
3459
3288
  ]
3460
3289
  }),
3461
- /* @__PURE__ */ jsxs8(DropdownMenuRadioItem, {
3462
- value: "gallery",
3463
- children: [
3464
- /* @__PURE__ */ jsx17(LayoutGrid, {}),
3465
- messages4.galleryView
3466
- ]
3290
+ /* @__PURE__ */ jsx17(GroupActions, {
3291
+ actions: section.field.actions,
3292
+ groupId: section.groupId,
3293
+ title: section.field.actionsLabel ?? store.config.labels.actions
3467
3294
  })
3468
3295
  ]
3469
- })
3470
- })
3471
- ]
3296
+ }),
3297
+ !collapsed ? section.children.length ? renderSections(section.children) : section.rows.length ? /* @__PURE__ */ jsx17("div", {
3298
+ className: "grid gap-3 sm:grid-cols-2 xl:grid-cols-3",
3299
+ children: section.rows.map((row) => /* @__PURE__ */ jsx17(RowIdContext.Provider, {
3300
+ value: row.id,
3301
+ children: /* @__PURE__ */ jsx17(GalleryCard, {
3302
+ tableAtom
3303
+ })
3304
+ }, `${section.key}:${row.id}`))
3305
+ }) : /* @__PURE__ */ jsx17("div", {
3306
+ className: "text-muted-foreground rounded-lg border border-dashed p-8 text-center",
3307
+ children: section.field.renderEmptyGroup?.(section.groupId) ?? store.config.labels.empty
3308
+ }) : null
3309
+ ]
3310
+ }, section.key);
3472
3311
  });
3473
- }
3474
- function DataTableSortDropdown({
3475
- messages: messages4,
3476
- table
3477
- }) {
3478
- const sorting = table.state.sorting;
3479
- const sortableColumns = table.getAllColumns().filter((column) => column.getCanSort());
3480
- const columnLabels = getColumnLabels(table);
3481
- if (sortableColumns.length === 0) {
3312
+ return /* @__PURE__ */ jsx17("div", {
3313
+ className: "space-y-4",
3314
+ children: renderSections(groupDataTableRows(rows, fields))
3315
+ });
3316
+ };
3317
+ var DataTablePagination = ({
3318
+ tableAtom
3319
+ }) => {
3320
+ const [store, setStore] = useTableAtom(tableAtom);
3321
+ const model = deriveModel(store);
3322
+ const pagination = store.config.features.pagination ?? { mode: "client" };
3323
+ const clientGrouping = pagination !== false && pagination.mode === "client" && getActiveGrouping(store).length > 0;
3324
+ const paginationVisible = pagination !== false && !clientGrouping;
3325
+ const pageIndex = store.state.pagination.pageIndex;
3326
+ const maxPageIndex = model.pageCount - 1;
3327
+ useLayoutEffect(() => {
3328
+ if (paginationVisible && pageIndex > maxPageIndex) {
3329
+ changeState(setStore, (state) => ({
3330
+ ...state,
3331
+ pagination: { ...state.pagination, pageIndex: maxPageIndex }
3332
+ }));
3333
+ }
3334
+ }, [maxPageIndex, pageIndex, paginationVisible, setStore]);
3335
+ if (!paginationVisible)
3482
3336
  return null;
3337
+ const selected = model.rows.filter((row) => store.state.rowSelection[row.id]).length;
3338
+ const setPagination = (next) => changeState(setStore, (state) => ({ ...state, pagination: next }));
3339
+ return /* @__PURE__ */ jsx17("div", {
3340
+ className: "pt-4",
3341
+ children: /* @__PURE__ */ jsx17(Pagination, {
3342
+ messages: store.config.labels,
3343
+ onPageChange: (pageIndex2) => setPagination({ ...store.state.pagination, pageIndex: pageIndex2 }),
3344
+ onPageSizeChange: (pageSize) => setPagination({ pageIndex: 0, pageSize }),
3345
+ page: Math.min(store.state.pagination.pageIndex, model.pageCount - 1),
3346
+ pageCount: model.pageCount,
3347
+ pageSize: store.state.pagination.pageSize,
3348
+ pageSizes: pagination.pageSizes,
3349
+ selectedRows: selected,
3350
+ totalRows: model.totalRows
3351
+ })
3352
+ });
3353
+ };
3354
+ var DataTable = (props) => {
3355
+ const validatedConfig = resolveConfig(props);
3356
+ const atomRef = useRef2(null);
3357
+ if (!atomRef.current) {
3358
+ const initial = {
3359
+ rowData: props.rowData,
3360
+ columnDefs: props.columnDefs,
3361
+ config: validatedConfig,
3362
+ state: initialPublicState(props),
3363
+ controlledState: props.state ?? {}
3364
+ };
3365
+ atomRef.current = Atom.make({
3366
+ ...initial,
3367
+ model: buildDataTableModel(initial)
3368
+ });
3483
3369
  }
3484
- const activeSortColumn = sorting.length > 0 ? sorting[0] : null;
3485
- return /* @__PURE__ */ jsxs8(DropdownMenu, {
3370
+ const tableAtom = atomRef.current;
3371
+ const setStore = useAtomSet(tableAtom);
3372
+ useLayoutEffect(() => {
3373
+ setStore((store) => {
3374
+ const features = props.features ?? {};
3375
+ const selection = features.selection;
3376
+ const config = {
3377
+ getRowId: selection && selection.getRowId || props.getRowId || undefined,
3378
+ onStateChange: props.onStateChange,
3379
+ status: props.status ?? {},
3380
+ features,
3381
+ onRowClicked: props.onRowClicked,
3382
+ labels: dataTableMessages(props.messages)
3383
+ };
3384
+ const state = mergeDataTableState(store.state, props.state);
3385
+ const modelChanged = store.rowData !== props.rowData || store.columnDefs !== props.columnDefs || !sameDataTableState(store.state, state) || store.config.getRowId !== config.getRowId || store.config.features.pagination !== config.features.pagination;
3386
+ const next = {
3387
+ ...store,
3388
+ rowData: props.rowData,
3389
+ columnDefs: props.columnDefs,
3390
+ config,
3391
+ controlledState: props.state ?? {},
3392
+ state
3393
+ };
3394
+ return modelChanged ? { ...next, model: buildDataTableModel(next) } : next;
3395
+ });
3396
+ }, [
3397
+ props.columnDefs,
3398
+ props.features,
3399
+ props.getRowId,
3400
+ props.messages,
3401
+ props.onRowClicked,
3402
+ props.onStateChange,
3403
+ props.rowData,
3404
+ props.state,
3405
+ props.status,
3406
+ setStore
3407
+ ]);
3408
+ return /* @__PURE__ */ jsxs9("div", {
3409
+ className: "w-full max-w-full min-w-0 rounded-md",
3410
+ "data-table-root": "",
3486
3411
  children: [
3487
- /* @__PURE__ */ jsx17(DropdownMenuTrigger, {
3488
- render: /* @__PURE__ */ jsxs8(Button, {
3489
- "aria-label": messages4.sortBy,
3490
- className: "h-9",
3491
- size: "sm",
3492
- variant: "outline",
3493
- children: [
3494
- activeSortColumn ? activeSortColumn.desc ? /* @__PURE__ */ jsx17(ArrowDown, {}) : /* @__PURE__ */ jsx17(ArrowUp, {}) : /* @__PURE__ */ jsx17(ChevronsUpDown2, {}),
3495
- /* @__PURE__ */ jsx17("span", {
3496
- className: "hidden sm:inline",
3497
- children: messages4.sortBy
3498
- })
3499
- ]
3500
- })
3412
+ /* @__PURE__ */ jsx17(DataTableToolbar, {
3413
+ tableAtom
3501
3414
  }),
3502
- /* @__PURE__ */ jsx17(DropdownMenuContent, {
3503
- align: "end",
3504
- className: "w-[200px]",
3505
- children: /* @__PURE__ */ jsxs8(DropdownMenuGroup, {
3506
- children: [
3507
- /* @__PURE__ */ jsx17(DropdownMenuLabel, {
3508
- children: messages4.sortBy
3509
- }),
3510
- /* @__PURE__ */ jsx17(DropdownMenuSeparator, {}),
3511
- sortableColumns.map((column) => {
3512
- const sortState = sorting.find((s) => s.id === column.id);
3513
- const label = columnLabels.get(column.id) ?? column.id;
3514
- return /* @__PURE__ */ jsxs8(DropdownMenuSub, {
3515
- children: [
3516
- /* @__PURE__ */ jsxs8(DropdownMenuSubTrigger, {
3517
- inset: !!sortState,
3518
- children: [
3519
- sortState ? /* @__PURE__ */ jsx17("span", {
3520
- className: "pointer-events-none absolute left-3 flex size-4 items-center justify-center",
3521
- children: sortState.desc ? /* @__PURE__ */ jsx17(ArrowDown, {}) : /* @__PURE__ */ jsx17(ArrowUp, {})
3522
- }) : null,
3523
- label
3524
- ]
3525
- }),
3526
- /* @__PURE__ */ jsxs8(DropdownMenuSubContent, {
3527
- children: [
3528
- /* @__PURE__ */ jsxs8(DropdownMenuItem, {
3529
- onClick: () => column.toggleSorting(false),
3530
- children: [
3531
- /* @__PURE__ */ jsx17(ArrowUp, {}),
3532
- messages4.sortAsc
3533
- ]
3534
- }),
3535
- /* @__PURE__ */ jsxs8(DropdownMenuItem, {
3536
- onClick: () => column.toggleSorting(true),
3537
- children: [
3538
- /* @__PURE__ */ jsx17(ArrowDown, {}),
3539
- messages4.sortDesc
3540
- ]
3541
- }),
3542
- sortState && /* @__PURE__ */ jsxs8(Fragment, {
3543
- children: [
3544
- /* @__PURE__ */ jsx17(DropdownMenuSeparator, {}),
3545
- /* @__PURE__ */ jsx17(DropdownMenuItem, {
3546
- onClick: () => column.clearSorting(),
3547
- children: messages4.sortClear
3548
- })
3549
- ]
3550
- })
3551
- ]
3552
- })
3553
- ]
3554
- }, column.id);
3555
- })
3556
- ]
3557
- })
3415
+ /* @__PURE__ */ jsx17(DataTableContent, {
3416
+ tableAtom
3417
+ }),
3418
+ /* @__PURE__ */ jsx17(DataTablePagination, {
3419
+ tableAtom
3558
3420
  })
3559
3421
  ]
3560
3422
  });
3561
- }
3562
- function DataTableViewOptions({
3563
- messages: messages4,
3564
- table
3565
- }) {
3566
- const columnLabels = getColumnLabels(table);
3567
- const columns = table.getAllColumns().filter((column) => column.accessorFn !== undefined && column.getCanHide());
3568
- if (columns.length === 0) {
3569
- return null;
3423
+ };
3424
+ var DataTableContent = ({
3425
+ tableAtom
3426
+ }) => {
3427
+ const [store] = useTableAtom(tableAtom);
3428
+ if (store.config.features.gallery && store.state.view === "gallery") {
3429
+ return /* @__PURE__ */ jsx17(DataTableGallery, {
3430
+ tableAtom
3431
+ });
3570
3432
  }
3571
- return /* @__PURE__ */ jsxs8(DropdownMenu, {
3433
+ const model = deriveModel(store);
3434
+ const width = getDataTableWidth(model.visibleColumns, (store.config.features.selection ? 1 : 0) + (store.config.features.rowActions ? 1 : 0) + (canDragRows(store) ? 1 : 0));
3435
+ return /* @__PURE__ */ jsxs9(ScrollArea, {
3436
+ className: "max-w-full min-w-0",
3572
3437
  children: [
3573
- /* @__PURE__ */ jsx17(DropdownMenuTrigger, {
3574
- render: /* @__PURE__ */ jsxs8(Button, {
3575
- "aria-label": messages4.columns,
3576
- className: "h-9",
3577
- size: "sm",
3578
- variant: "outline",
3579
- children: [
3580
- /* @__PURE__ */ jsx17(Settings2, {}),
3581
- /* @__PURE__ */ jsx17("span", {
3582
- className: "hidden sm:inline",
3583
- children: messages4.columns
3584
- })
3585
- ]
3586
- })
3438
+ /* @__PURE__ */ jsxs9(Table, {
3439
+ className: "table-fixed",
3440
+ style: { width: `max(100%, ${width}px)` },
3441
+ children: [
3442
+ /* @__PURE__ */ jsx17(DataTableHeader, {
3443
+ tableAtom
3444
+ }),
3445
+ /* @__PURE__ */ jsx17(DataTableBody, {
3446
+ tableAtom
3447
+ })
3448
+ ]
3587
3449
  }),
3588
- /* @__PURE__ */ jsx17(DropdownMenuContent, {
3589
- align: "end",
3590
- className: "w-[180px]",
3591
- children: /* @__PURE__ */ jsxs8(DropdownMenuGroup, {
3592
- children: [
3593
- /* @__PURE__ */ jsx17(DropdownMenuLabel, {
3594
- children: messages4.columns
3595
- }),
3596
- /* @__PURE__ */ jsx17(DropdownMenuSeparator, {}),
3597
- columns.map((column) => /* @__PURE__ */ jsx17(DropdownMenuCheckboxItem, {
3598
- checked: column.getIsVisible(),
3599
- className: "capitalize",
3600
- onCheckedChange: (value) => column.toggleVisibility(!!value),
3601
- children: columnLabels.get(column.id) ?? column.id
3602
- }, column.id))
3603
- ]
3604
- })
3450
+ /* @__PURE__ */ jsx17(ScrollBar, {
3451
+ orientation: "horizontal"
3605
3452
  })
3606
3453
  ]
3607
3454
  });
3608
- }
3609
- function DataTablePagination({
3610
- messages: messages4,
3611
- pageSizes = [10, 20, 30, 40, 50],
3612
- rowCount,
3613
- table
3614
- }) {
3615
- const labels2 = dataTableMessages(messages4);
3616
- const selectedRows = table.getFilteredSelectedRowModel().rows.length;
3617
- const filteredRows = table.getFilteredRowModel().rows.length;
3618
- const totalRows = rowCount ?? filteredRows;
3619
- return /* @__PURE__ */ jsx17(Pagination, {
3620
- messages: {
3621
- pageSize: labels2.pageSize,
3622
- results: labels2.results,
3623
- selectedOf: labels2.selectedOf,
3624
- pageOf: labels2.pageOf,
3625
- goToFirstPage: labels2.goToFirstPage,
3626
- goToPreviousPage: labels2.goToPreviousPage,
3627
- goToNextPage: labels2.goToNextPage,
3628
- goToLastPage: labels2.goToLastPage
3629
- },
3630
- onPageChange: (page) => table.setPageIndex(page),
3631
- onPageSizeChange: (pageSize) => table.setPageSize(pageSize),
3632
- page: table.state.pagination.pageIndex,
3633
- pageCount: table.getPageCount(),
3634
- pageSize: table.state.pagination.pageSize,
3635
- pageSizes,
3636
- selectedRows,
3637
- totalRows
3638
- });
3639
- }
3640
- function DataTableRelationshipCell({
3455
+ };
3456
+ var DataTableRelationshipCell = ({
3641
3457
  emptyLabel,
3642
3458
  manageLabel,
3643
3459
  onAdd,
3644
3460
  onRemove,
3645
3461
  options,
3646
3462
  value
3647
- }) {
3648
- const [selectedOptions, setSelectedOptions] = useState(() => [...value]);
3649
- const selectedValues = new Set(selectedOptions.map(({ value: value2 }) => value2));
3650
- const orderedOptions = [...options].sort((a, b) => Number(selectedValues.has(b.value)) - Number(selectedValues.has(a.value)));
3651
- useEffect2(() => {
3652
- setSelectedOptions([...value]);
3653
- }, [value]);
3463
+ }) => {
3464
+ const [selected, setSelected] = useState([...value]);
3465
+ useLayoutEffect(() => setSelected([...value]), [value]);
3466
+ const selectedValues = new Set(selected.map((item) => item.value));
3654
3467
  return /* @__PURE__ */ jsx17(VirtualizedCombobox, {
3655
3468
  ariaLabel: manageLabel,
3656
3469
  emptyLabel,
3657
- items: orderedOptions,
3470
+ items: [...options].sort((left, right) => Number(selectedValues.has(right.value)) - Number(selectedValues.has(left.value))),
3658
3471
  messages: { search: manageLabel },
3659
3472
  multiple: true,
3660
- onValueChange: (nextOptions) => {
3661
- const nextValues = new Set(nextOptions.map(({ value: value2 }) => value2));
3662
- for (const option of selectedOptions) {
3663
- if (!nextValues.has(option.value))
3664
- onRemove?.(option.value);
3665
- }
3666
- for (const option of nextOptions) {
3667
- if (!selectedValues.has(option.value))
3668
- onAdd?.(option.value);
3669
- }
3670
- setSelectedOptions(nextOptions);
3473
+ onValueChange: (next) => {
3474
+ const nextValues = new Set(next.map((item) => item.value));
3475
+ selected.forEach((item) => !nextValues.has(item.value) && onRemove?.(item.value));
3476
+ next.forEach((item) => !selectedValues.has(item.value) && onAdd?.(item.value));
3477
+ setSelected(next);
3671
3478
  },
3672
3479
  placeholder: emptyLabel,
3673
- trigger: /* @__PURE__ */ jsxs8(Button, {
3674
- "aria-label": manageLabel,
3675
- className: "h-full min-h-16 w-full min-w-0 justify-between gap-2 overflow-hidden rounded-none px-2 py-2 text-left font-normal",
3676
- "data-slot": "relationship-cell",
3677
- type: "button",
3480
+ trigger: /* @__PURE__ */ jsxs9(Button, {
3481
+ className: "h-full min-h-16 w-full justify-between rounded-none",
3678
3482
  variant: "ghost",
3679
3483
  children: [
3680
3484
  /* @__PURE__ */ jsx17(DataTableListSummary, {
3681
3485
  emptyLabel,
3682
3486
  expandable: false,
3683
- items: selectedOptions,
3684
- variant: selectedOptions.some(({ icon }) => icon) ? "icon" : "text"
3487
+ items: selected,
3488
+ variant: selected.some((item) => item.icon) ? "icon" : "text"
3685
3489
  }),
3686
- /* @__PURE__ */ jsx17(ChevronDown, {
3687
- className: "text-muted-foreground size-4 shrink-0"
3688
- })
3490
+ /* @__PURE__ */ jsx17(ChevronDown, {})
3689
3491
  ]
3690
3492
  }),
3691
- value: selectedOptions
3493
+ value: selected
3692
3494
  });
3693
- }
3694
- function DataTableListSummary({
3495
+ };
3496
+ var DataTableListSummary = ({
3695
3497
  emptyLabel,
3696
3498
  expandable = true,
3697
3499
  items,
@@ -3699,52 +3501,38 @@ function DataTableListSummary({
3699
3501
  totalCount = items.length,
3700
3502
  variant = "text",
3701
3503
  visibleCount = 3
3702
- }) {
3504
+ }) => {
3703
3505
  const labels2 = dataTableMessages();
3704
- const normalizedItems = items.map((item) => Schema2.is(Schema2.String)(item) ? { label: item } : item);
3705
- const visibleItems = normalizedItems.slice(0, visibleCount);
3706
- const visibleLabels = visibleItems.map(({ label }) => label).join(", ");
3707
- const remaining = Math.max(totalCount - visibleItems.length, 0);
3708
- const remainingLabel = overflowLabel?.(remaining) ?? labels2.listOthers(remaining);
3709
- const expandedItems = /* @__PURE__ */ jsx17(PopoverContent, {
3710
- align: "start",
3711
- className: "max-h-72 w-72 overflow-y-auto p-2",
3712
- onClick: (event) => event.stopPropagation(),
3713
- children: /* @__PURE__ */ jsx17("ul", {
3714
- className: "grid gap-1",
3715
- children: normalizedItems.map((item, index) => /* @__PURE__ */ jsxs8("li", {
3716
- className: "flex items-center gap-2 rounded-sm px-2 py-1.5 break-words",
3717
- children: [
3718
- item.icon ? /* @__PURE__ */ jsx17("span", {
3719
- className: "bg-muted flex size-6 shrink-0 items-center justify-center overflow-hidden rounded-full text-[9px] font-semibold",
3720
- children: item.icon
3721
- }) : null,
3722
- /* @__PURE__ */ jsx17("span", {
3723
- className: "min-w-0",
3724
- children: item.label
3725
- })
3726
- ]
3727
- }, item.value ?? `${item.label}-${index}`))
3728
- })
3729
- });
3730
- if (normalizedItems.length === 0) {
3506
+ const normalized = items.map((item) => Schema.is(Schema.String)(item) ? { label: item } : item);
3507
+ if (!normalized.length)
3731
3508
  return /* @__PURE__ */ jsx17("span", {
3732
- className: "text-muted-foreground text-sm",
3509
+ className: "text-muted-foreground",
3733
3510
  children: emptyLabel
3734
3511
  });
3735
- }
3512
+ const visible = normalized.slice(0, visibleCount);
3513
+ const remaining = Math.max(totalCount - visible.length, 0);
3514
+ const details = /* @__PURE__ */ jsx17(PopoverContent, {
3515
+ align: "start",
3516
+ className: "max-h-72 w-72 overflow-y-auto p-2",
3517
+ children: normalized.map((item, index) => /* @__PURE__ */ jsxs9("div", {
3518
+ className: "flex items-center gap-2 p-2",
3519
+ children: [
3520
+ item.icon,
3521
+ item.label
3522
+ ]
3523
+ }, item.value ?? `${item.label}-${index}`))
3524
+ });
3736
3525
  if (variant === "icon") {
3737
3526
  return /* @__PURE__ */ jsx17(TooltipProvider, {
3738
- children: /* @__PURE__ */ jsxs8("span", {
3739
- className: "flex min-w-0 items-center pl-2",
3527
+ children: /* @__PURE__ */ jsxs9("span", {
3528
+ className: "flex items-center",
3740
3529
  children: [
3741
- visibleItems.map((item, index) => /* @__PURE__ */ jsxs8(Tooltip, {
3530
+ visible.map((item) => /* @__PURE__ */ jsxs9(Tooltip, {
3742
3531
  children: [
3743
3532
  /* @__PURE__ */ jsx17(TooltipTrigger, {
3744
3533
  render: /* @__PURE__ */ jsx17("span", {
3745
3534
  "aria-label": item.label,
3746
- className: "bg-muted border-background relative flex size-8 shrink-0 items-center justify-center overflow-hidden rounded-full border-2 text-[10px] font-semibold",
3747
- style: { marginLeft: index ? -8 : 0 },
3535
+ className: "bg-muted -ml-1 flex size-8 items-center justify-center rounded-full",
3748
3536
  children: item.icon ?? item.label.slice(0, 2).toUpperCase()
3749
3537
  })
3750
3538
  }),
@@ -3753,14 +3541,12 @@ function DataTableListSummary({
3753
3541
  })
3754
3542
  ]
3755
3543
  }, item.value ?? item.label)),
3756
- remaining ? expandable ? /* @__PURE__ */ jsxs8(Popover, {
3544
+ remaining && expandable ? /* @__PURE__ */ jsxs9(Popover, {
3757
3545
  children: [
3758
3546
  /* @__PURE__ */ jsx17(PopoverTrigger, {
3759
- render: /* @__PURE__ */ jsxs8("button", {
3547
+ render: /* @__PURE__ */ jsxs9("button", {
3760
3548
  "aria-label": labels2.listOthers(remaining),
3761
- className: "bg-muted border-background relative -ml-2 flex size-8 shrink-0 items-center justify-center rounded-full border-2 text-[10px] font-semibold tabular-nums",
3762
- onClick: (event) => event.stopPropagation(),
3763
- onPointerDown: (event) => event.stopPropagation(),
3549
+ className: "bg-muted -ml-1 flex size-8 items-center justify-center rounded-full",
3764
3550
  type: "button",
3765
3551
  children: [
3766
3552
  "+",
@@ -3768,10 +3554,10 @@ function DataTableListSummary({
3768
3554
  ]
3769
3555
  })
3770
3556
  }),
3771
- expandedItems
3557
+ details
3772
3558
  ]
3773
- }) : /* @__PURE__ */ jsxs8("span", {
3774
- className: "bg-muted border-background relative -ml-2 flex size-8 shrink-0 items-center justify-center rounded-full border-2 text-[10px] font-semibold tabular-nums",
3559
+ }) : remaining ? /* @__PURE__ */ jsxs9("span", {
3560
+ className: "bg-muted -ml-1 flex size-8 items-center justify-center rounded-full",
3775
3561
  children: [
3776
3562
  "+",
3777
3563
  remaining
@@ -3781,135 +3567,44 @@ function DataTableListSummary({
3781
3567
  })
3782
3568
  });
3783
3569
  }
3784
- return remaining > 0 ? /* @__PURE__ */ jsxs8("span", {
3785
- className: "block min-w-0 text-sm whitespace-normal",
3786
- "data-slot": "list-summary",
3570
+ const summary = /* @__PURE__ */ jsxs9(Fragment, {
3787
3571
  children: [
3788
- /* @__PURE__ */ jsx17("span", {
3789
- children: visibleLabels
3790
- }),
3791
- " ",
3792
- /* @__PURE__ */ jsx17("span", {
3793
- className: "inline-block whitespace-nowrap",
3794
- children: expandable ? /* @__PURE__ */ jsxs8(Popover, {
3795
- children: [
3796
- /* @__PURE__ */ jsx17(PopoverTrigger, {
3797
- render: /* @__PURE__ */ jsx17("button", {
3798
- className: "text-muted-foreground hover:text-foreground underline decoration-dotted underline-offset-2",
3799
- onClick: (event) => event.stopPropagation(),
3800
- onPointerDown: (event) => event.stopPropagation(),
3801
- type: "button",
3802
- children: remainingLabel
3803
- })
3804
- }),
3805
- expandedItems
3806
- ]
3807
- }) : remainingLabel
3808
- })
3572
+ visible.map((item) => item.label).join(", "),
3573
+ remaining ? ` ${overflowLabel?.(remaining) ?? labels2.listOthers(remaining)}` : ""
3809
3574
  ]
3810
- }) : /* @__PURE__ */ jsx17("span", {
3811
- className: "block min-w-0 text-sm",
3812
- "data-slot": "list-summary",
3813
- children: visibleLabels
3814
3575
  });
3815
- }
3816
- function DataTableColumnHeader({
3817
- column,
3818
- messages: messages4,
3819
- title,
3820
- className
3821
- }) {
3822
- const labels2 = dataTableMessages(messages4);
3823
- const sortDirection = column.getIsSorted();
3824
- if (!column.getCanSort()) {
3825
- return /* @__PURE__ */ jsx17("div", {
3826
- className: cn("flex h-12 items-center truncate px-2 text-sm", className),
3827
- children: title
3828
- });
3829
- }
3830
- return /* @__PURE__ */ jsx17("div", {
3831
- className: cn("flex h-12 items-center", className),
3832
- children: /* @__PURE__ */ jsxs8(DropdownMenu, {
3833
- children: [
3834
- /* @__PURE__ */ jsx17(DropdownMenuTrigger, {
3835
- render: /* @__PURE__ */ jsxs8(Button, {
3836
- variant: "ghost",
3837
- size: "sm",
3838
- className: "data-[state=open]:bg-accent h-8 max-w-full justify-start px-2",
3839
- children: [
3840
- /* @__PURE__ */ jsx17("span", {
3841
- className: "min-w-0 truncate text-sm",
3842
- children: title
3843
- }),
3844
- sortDirection === "desc" ? /* @__PURE__ */ jsx17(ArrowDown, {}) : sortDirection === "asc" ? /* @__PURE__ */ jsx17(ArrowUp, {}) : /* @__PURE__ */ jsx17(ChevronsUpDown2, {})
3845
- ]
3846
- })
3847
- }),
3848
- /* @__PURE__ */ jsx17(DropdownMenuContent, {
3849
- align: "start",
3850
- className: "max-w-56",
3851
- children: /* @__PURE__ */ jsxs8(DropdownMenuGroup, {
3852
- children: [
3853
- /* @__PURE__ */ jsxs8(DropdownMenuItem, {
3854
- onClick: () => column.toggleSorting(false),
3855
- children: [
3856
- /* @__PURE__ */ jsx17(ArrowUp, {
3857
- className: "text-muted-foreground/70 h-3.5 w-3.5"
3858
- }),
3859
- labels2.sortAsc
3860
- ]
3861
- }),
3862
- /* @__PURE__ */ jsxs8(DropdownMenuItem, {
3863
- onClick: () => column.toggleSorting(true),
3864
- children: [
3865
- /* @__PURE__ */ jsx17(ArrowDown, {
3866
- className: "text-muted-foreground/70 h-3.5 w-3.5"
3867
- }),
3868
- labels2.sortDesc
3869
- ]
3870
- }),
3871
- sortDirection ? /* @__PURE__ */ jsxs8(DropdownMenuItem, {
3872
- onClick: () => column.clearSorting(),
3873
- children: [
3874
- /* @__PURE__ */ jsx17(X2, {
3875
- className: "text-muted-foreground/70 h-3.5 w-3.5"
3876
- }),
3877
- labels2.sortClear
3878
- ]
3879
- }) : null,
3880
- /* @__PURE__ */ jsx17(DropdownMenuSeparator, {}),
3881
- /* @__PURE__ */ jsxs8(DropdownMenuItem, {
3882
- onClick: () => column.toggleVisibility(false),
3883
- children: [
3884
- /* @__PURE__ */ jsx17(EyeOff, {
3885
- className: "text-muted-foreground/70 h-3.5 w-3.5"
3886
- }),
3887
- labels2.sortHide
3888
- ]
3889
- })
3890
- ]
3891
- })
3576
+ return remaining && expandable ? /* @__PURE__ */ jsxs9(Popover, {
3577
+ children: [
3578
+ /* @__PURE__ */ jsx17(PopoverTrigger, {
3579
+ render: /* @__PURE__ */ jsx17("button", {
3580
+ className: "text-left text-sm",
3581
+ type: "button",
3582
+ children: summary
3892
3583
  })
3893
- ]
3894
- })
3584
+ }),
3585
+ details
3586
+ ]
3587
+ }) : /* @__PURE__ */ jsx17("span", {
3588
+ className: "text-sm",
3589
+ children: summary
3895
3590
  });
3896
- }
3591
+ };
3897
3592
  export {
3898
- useDataTableHeaderContext,
3899
- useDataTableContext,
3900
- useDataTableCellContext,
3901
- useDataTable,
3902
- getHeaderNames,
3903
- downloadJson,
3904
- downloadCsv,
3905
- dataTableMessages,
3906
- createDataTableColumnHelper,
3907
- TableSearchSchemaStandard,
3908
- TableSearchSchema,
3909
- DataTableRowActions,
3910
- DataTableRelationshipCell,
3911
- DataTablePagination,
3593
+ DataTable,
3912
3594
  DataTableListSummary,
3913
- DataTableColumnHeader,
3914
- DataTable
3595
+ DataTableRelationshipCell,
3596
+ DataTableRowActions,
3597
+ buildDataTableRows,
3598
+ dataTableMessages,
3599
+ downloadCsv,
3600
+ downloadJson,
3601
+ filterDataTableRows,
3602
+ getDataTableSelectableRows,
3603
+ getDataTableWidth,
3604
+ groupDataTableRows,
3605
+ mergeDataTableState,
3606
+ normalizeDataTableColumns,
3607
+ paginateDataTableRows,
3608
+ reorderDataTableRows,
3609
+ sortDataTableRows
3915
3610
  };