@undevy-org/tablewright 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (170) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +262 -0
  3. package/dist/es/components/dashboard/ReportSummaryCard.js +67 -0
  4. package/dist/es/components/data-table/AppliedStateChips.js +113 -0
  5. package/dist/es/components/data-table/ColumnFilterPopover.js +548 -0
  6. package/dist/es/components/data-table/ColumnHeaderMenu.js +144 -0
  7. package/dist/es/components/data-table/CompoundFilterPopover.js +508 -0
  8. package/dist/es/components/data-table/CopyButton.js +35 -0
  9. package/dist/es/components/data-table/CopyableText.js +26 -0
  10. package/dist/es/components/data-table/DataTableShell.js +145 -0
  11. package/dist/es/components/data-table/DrawerActionGroup.js +59 -0
  12. package/dist/es/components/data-table/DrawerEntityCard.js +21 -0
  13. package/dist/es/components/data-table/DrawerField.js +10 -0
  14. package/dist/es/components/data-table/DrawerFlagItem.js +20 -0
  15. package/dist/es/components/data-table/DrawerSection.js +26 -0
  16. package/dist/es/components/data-table/DrawerShell.js +141 -0
  17. package/dist/es/components/data-table/DrawerSummaryCard.js +11 -0
  18. package/dist/es/components/data-table/EmptyState.js +14 -0
  19. package/dist/es/components/data-table/ExpiryTimestampCell.js +43 -0
  20. package/dist/es/components/data-table/FilterChip.js +47 -0
  21. package/dist/es/components/data-table/FilterFormPanel.js +357 -0
  22. package/dist/es/components/data-table/FilterFormToggle.js +77 -0
  23. package/dist/es/components/data-table/FilterPopoverFooter.js +19 -0
  24. package/dist/es/components/data-table/FilterToolbar.js +131 -0
  25. package/dist/es/components/data-table/FlatColumnToggle.js +46 -0
  26. package/dist/es/components/data-table/GapIndicator.js +29 -0
  27. package/dist/es/components/data-table/GroupedColumnToggle.js +112 -0
  28. package/dist/es/components/data-table/RowActionsMenu.js +74 -0
  29. package/dist/es/components/data-table/RowControlCell.js +104 -0
  30. package/dist/es/components/data-table/SortableHeader.js +102 -0
  31. package/dist/es/components/data-table/TableFooter.js +132 -0
  32. package/dist/es/components/data-table/TableLayout.js +14 -0
  33. package/dist/es/components/data-table/TimestampCell.js +16 -0
  34. package/dist/es/components/data-table/TwoPanelMenu.js +64 -0
  35. package/dist/es/components/data-table/ViewChip.js +25 -0
  36. package/dist/es/components/data-table/cells/AmountCell.js +127 -0
  37. package/dist/es/components/data-table/cells/ConfirmedAmountCell.js +115 -0
  38. package/dist/es/components/data-table/cells/CurrencyAmountCell.js +26 -0
  39. package/dist/es/components/data-table/cells/DualLineCell.js +59 -0
  40. package/dist/es/components/data-table/cells/EnumBadgeCell.js +9 -0
  41. package/dist/es/components/data-table/cells/MonoIdCell.js +31 -0
  42. package/dist/es/components/data-table/hooks/use-column-resize.js +39 -0
  43. package/dist/es/components/data-table/hooks/use-row-drag.js +40 -0
  44. package/dist/es/components/data-table/hooks/use-table-pagination.js +14 -0
  45. package/dist/es/components/data-table/hooks/use-table-sort.js +35 -0
  46. package/dist/es/components/data-table/managed-filters.js +34 -0
  47. package/dist/es/components/data-table/sticky-utils.js +25 -0
  48. package/dist/es/components/layout/AppShell.js +113 -0
  49. package/dist/es/components/layout/Sidebar.js +128 -0
  50. package/dist/es/components/layout/SidebarAccountMenu.js +129 -0
  51. package/dist/es/components/layout/SidebarUser.js +38 -0
  52. package/dist/es/components/layout/TopBar.js +25 -0
  53. package/dist/es/components/layout/app-shell-context.js +9 -0
  54. package/dist/es/components/ui/badge.js +31 -0
  55. package/dist/es/components/ui/button-footer.js +25 -0
  56. package/dist/es/components/ui/button.js +44 -0
  57. package/dist/es/components/ui/checkbox.js +24 -0
  58. package/dist/es/components/ui/combobox.js +179 -0
  59. package/dist/es/components/ui/dialog.js +80 -0
  60. package/dist/es/components/ui/dropdown-menu.js +66 -0
  61. package/dist/es/components/ui/input.js +24 -0
  62. package/dist/es/components/ui/popover.js +33 -0
  63. package/dist/es/components/ui/segmented-control.js +60 -0
  64. package/dist/es/components/ui/select.js +66 -0
  65. package/dist/es/components/ui/tabs.js +41 -0
  66. package/dist/es/components/ui/theme-switch.js +47 -0
  67. package/dist/es/constants/drawer.js +4 -0
  68. package/dist/es/context/drawer-expand-context.js +10 -0
  69. package/dist/es/context/portal-container-context.js +10 -0
  70. package/dist/es/hooks/table-orchestration-store.js +165 -0
  71. package/dist/es/hooks/use-scroll-activity.js +33 -0
  72. package/dist/es/hooks/useRowDragOverride.js +18 -0
  73. package/dist/es/hooks/useTableOrchestration.js +452 -0
  74. package/dist/es/index.js +199 -0
  75. package/dist/es/lib/column-gaps.js +23 -0
  76. package/dist/es/lib/filter-stats.js +67 -0
  77. package/dist/es/lib/format-enum.js +6 -0
  78. package/dist/es/lib/format-timestamp.js +37 -0
  79. package/dist/es/lib/style-scope.js +4 -0
  80. package/dist/es/lib/utils.js +8 -0
  81. package/dist/fonts.css +5 -0
  82. package/dist/preflight.css +502 -0
  83. package/dist/styles.css +1731 -0
  84. package/dist/tablewright.cjs +5473 -0
  85. package/dist/tablewright.css +1579 -0
  86. package/dist/tokens.css +150 -0
  87. package/dist/types/components/dashboard/ReportSummaryCard.d.ts +15 -0
  88. package/dist/types/components/data-table/AppliedStateChips.d.ts +28 -0
  89. package/dist/types/components/data-table/ColumnFilterPopover.d.ts +14 -0
  90. package/dist/types/components/data-table/ColumnHeaderMenu.d.ts +27 -0
  91. package/dist/types/components/data-table/CompoundFilterPopover.d.ts +14 -0
  92. package/dist/types/components/data-table/CopyButton.d.ts +8 -0
  93. package/dist/types/components/data-table/CopyableText.d.ts +10 -0
  94. package/dist/types/components/data-table/DataTableShell.d.ts +30 -0
  95. package/dist/types/components/data-table/DrawerActionGroup.d.ts +8 -0
  96. package/dist/types/components/data-table/DrawerEntityCard.d.ts +13 -0
  97. package/dist/types/components/data-table/DrawerField.d.ts +7 -0
  98. package/dist/types/components/data-table/DrawerFlagItem.d.ts +10 -0
  99. package/dist/types/components/data-table/DrawerSection.d.ts +8 -0
  100. package/dist/types/components/data-table/DrawerShell.d.ts +33 -0
  101. package/dist/types/components/data-table/DrawerSummaryCard.d.ts +7 -0
  102. package/dist/types/components/data-table/EmptyState.d.ts +6 -0
  103. package/dist/types/components/data-table/ExpiryTimestampCell.d.ts +6 -0
  104. package/dist/types/components/data-table/FilterChip.d.ts +8 -0
  105. package/dist/types/components/data-table/FilterFormPanel.d.ts +34 -0
  106. package/dist/types/components/data-table/FilterFormToggle.d.ts +18 -0
  107. package/dist/types/components/data-table/FilterPopoverFooter.d.ts +9 -0
  108. package/dist/types/components/data-table/FilterToolbar.d.ts +29 -0
  109. package/dist/types/components/data-table/FlatColumnToggle.d.ts +10 -0
  110. package/dist/types/components/data-table/GapIndicator.d.ts +11 -0
  111. package/dist/types/components/data-table/GroupedColumnToggle.d.ts +12 -0
  112. package/dist/types/components/data-table/RowActionsMenu.d.ts +10 -0
  113. package/dist/types/components/data-table/RowControlCell.d.ts +16 -0
  114. package/dist/types/components/data-table/SortableHeader.d.ts +16 -0
  115. package/dist/types/components/data-table/TableFooter.d.ts +31 -0
  116. package/dist/types/components/data-table/TableLayout.d.ts +12 -0
  117. package/dist/types/components/data-table/TimestampCell.d.ts +3 -0
  118. package/dist/types/components/data-table/TwoPanelMenu.d.ts +22 -0
  119. package/dist/types/components/data-table/ViewChip.d.ts +6 -0
  120. package/dist/types/components/data-table/cells/AmountCell.d.ts +11 -0
  121. package/dist/types/components/data-table/cells/ConfirmedAmountCell.d.ts +10 -0
  122. package/dist/types/components/data-table/cells/CurrencyAmountCell.d.ts +8 -0
  123. package/dist/types/components/data-table/cells/DualLineCell.d.ts +44 -0
  124. package/dist/types/components/data-table/cells/EnumBadgeCell.d.ts +9 -0
  125. package/dist/types/components/data-table/cells/MonoIdCell.d.ts +19 -0
  126. package/dist/types/components/data-table/filter-types.d.ts +79 -0
  127. package/dist/types/components/data-table/hooks/use-column-resize.d.ts +7 -0
  128. package/dist/types/components/data-table/hooks/use-row-drag.d.ts +14 -0
  129. package/dist/types/components/data-table/hooks/use-table-pagination.d.ts +10 -0
  130. package/dist/types/components/data-table/hooks/use-table-sort.d.ts +6 -0
  131. package/dist/types/components/data-table/managed-filters.d.ts +18 -0
  132. package/dist/types/components/data-table/sticky-utils.d.ts +4 -0
  133. package/dist/types/components/data-table/types.d.ts +35 -0
  134. package/dist/types/components/layout/AppShell.d.ts +23 -0
  135. package/dist/types/components/layout/Sidebar.d.ts +16 -0
  136. package/dist/types/components/layout/SidebarAccountMenu.d.ts +20 -0
  137. package/dist/types/components/layout/SidebarUser.d.ts +8 -0
  138. package/dist/types/components/layout/TopBar.d.ts +7 -0
  139. package/dist/types/components/layout/app-shell-context.d.ts +8 -0
  140. package/dist/types/components/layout/index.d.ts +10 -0
  141. package/dist/types/components/layout/types.d.ts +11 -0
  142. package/dist/types/components/ui/badge.d.ts +9 -0
  143. package/dist/types/components/ui/button-footer.d.ts +7 -0
  144. package/dist/types/components/ui/button.d.ts +11 -0
  145. package/dist/types/components/ui/checkbox.d.ts +4 -0
  146. package/dist/types/components/ui/combobox.d.ts +92 -0
  147. package/dist/types/components/ui/dialog.d.ts +15 -0
  148. package/dist/types/components/ui/dropdown-menu.d.ts +10 -0
  149. package/dist/types/components/ui/input.d.ts +6 -0
  150. package/dist/types/components/ui/popover.d.ts +7 -0
  151. package/dist/types/components/ui/segmented-control.d.ts +17 -0
  152. package/dist/types/components/ui/select.d.ts +8 -0
  153. package/dist/types/components/ui/tabs.d.ts +10 -0
  154. package/dist/types/components/ui/theme-switch.d.ts +12 -0
  155. package/dist/types/constants/drawer.d.ts +1 -0
  156. package/dist/types/context/drawer-expand-context.d.ts +7 -0
  157. package/dist/types/context/portal-container-context.d.ts +14 -0
  158. package/dist/types/hooks/table-orchestration-store.d.ts +75 -0
  159. package/dist/types/hooks/use-scroll-activity.d.ts +1 -0
  160. package/dist/types/hooks/useDemoTheme.d.ts +8 -0
  161. package/dist/types/hooks/useRowDragOverride.d.ts +6 -0
  162. package/dist/types/hooks/useTableOrchestration.d.ts +115 -0
  163. package/dist/types/index.d.ts +107 -0
  164. package/dist/types/lib/column-gaps.d.ts +3 -0
  165. package/dist/types/lib/filter-stats.d.ts +2 -0
  166. package/dist/types/lib/format-enum.d.ts +1 -0
  167. package/dist/types/lib/format-timestamp.d.ts +4 -0
  168. package/dist/types/lib/style-scope.d.ts +19 -0
  169. package/dist/types/lib/utils.d.ts +2 -0
  170. package/package.json +114 -0
@@ -0,0 +1,80 @@
1
+ import { jsxs, jsx } from "react/jsx-runtime";
2
+ import * as React from "react";
3
+ import * as DialogPrimitive from "@radix-ui/react-dialog";
4
+ import { X } from "lucide-react";
5
+ import { cn } from "../../lib/utils.js";
6
+ import { STYLE_SCOPE } from "../../lib/style-scope.js";
7
+ import { usePortalContainer } from "../../context/portal-container-context.js";
8
+ const Dialog = DialogPrimitive.Root;
9
+ const DialogTrigger = DialogPrimitive.Trigger;
10
+ const DialogPortal = DialogPrimitive.Portal;
11
+ const DialogClose = DialogPrimitive.Close;
12
+ const DialogOverlay = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
13
+ DialogPrimitive.Overlay,
14
+ {
15
+ ref,
16
+ className: cn(STYLE_SCOPE, "fixed inset-0 z-50 bg-[var(--overlay-scrim)]", className),
17
+ ...props
18
+ }
19
+ ));
20
+ DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
21
+ const DialogContent = React.forwardRef(({ className, children, ...props }, ref) => {
22
+ const container = usePortalContainer();
23
+ return /* @__PURE__ */ jsxs(DialogPortal, { container, children: [
24
+ /* @__PURE__ */ jsx(DialogOverlay, {}),
25
+ /* @__PURE__ */ jsxs(
26
+ DialogPrimitive.Content,
27
+ {
28
+ ref,
29
+ className: cn(
30
+ STYLE_SCOPE,
31
+ "fixed left-1/2 top-1/2 z-50 w-full max-w-[var(--size-dialog-md)] -translate-x-1/2 -translate-y-1/2 rounded-lg bg-[var(--bg-surface)] p-6 [box-shadow:var(--shadow-dialog)]",
32
+ className
33
+ ),
34
+ ...props,
35
+ children: [
36
+ children,
37
+ /* @__PURE__ */ jsxs(DialogPrimitive.Close, { className: "absolute right-4 top-4 rounded-sm text-[var(--text-tertiary)] hover:text-[var(--text-primary)]", children: [
38
+ /* @__PURE__ */ jsx(X, { className: "h-4 w-4" }),
39
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Close" })
40
+ ] })
41
+ ]
42
+ }
43
+ )
44
+ ] });
45
+ });
46
+ DialogContent.displayName = DialogPrimitive.Content.displayName;
47
+ const DialogHeader = ({
48
+ className,
49
+ ...props
50
+ }) => /* @__PURE__ */ jsx("div", { className: cn("flex flex-col gap-1.5 text-left", className), ...props });
51
+ DialogHeader.displayName = "DialogHeader";
52
+ const DialogTitle = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
53
+ DialogPrimitive.Title,
54
+ {
55
+ ref,
56
+ className: cn("text-base font-semibold text-[var(--text-primary)]", className),
57
+ ...props
58
+ }
59
+ ));
60
+ DialogTitle.displayName = DialogPrimitive.Title.displayName;
61
+ const DialogDescription = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
62
+ DialogPrimitive.Description,
63
+ {
64
+ ref,
65
+ className: cn("text-xs text-[var(--text-secondary)]", className),
66
+ ...props
67
+ }
68
+ ));
69
+ DialogDescription.displayName = DialogPrimitive.Description.displayName;
70
+ export {
71
+ Dialog,
72
+ DialogClose,
73
+ DialogContent,
74
+ DialogDescription,
75
+ DialogHeader,
76
+ DialogOverlay,
77
+ DialogPortal,
78
+ DialogTitle,
79
+ DialogTrigger
80
+ };
@@ -0,0 +1,66 @@
1
+ import { jsxs, jsx } from "react/jsx-runtime";
2
+ import * as React from "react";
3
+ import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
4
+ import { Check } from "lucide-react";
5
+ import { cn } from "../../lib/utils.js";
6
+ import { STYLE_SCOPE } from "../../lib/style-scope.js";
7
+ import { usePortalContainer } from "../../context/portal-container-context.js";
8
+ const DropdownMenu = DropdownMenuPrimitive.Root;
9
+ const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger;
10
+ const DropdownMenuGroup = DropdownMenuPrimitive.Group;
11
+ const DropdownMenuPortal = DropdownMenuPrimitive.Portal;
12
+ const DropdownMenuContent = React.forwardRef(({ className, sideOffset = 6, ...props }, ref) => {
13
+ const container = usePortalContainer();
14
+ return /* @__PURE__ */ jsx(DropdownMenuPrimitive.Portal, { container, children: /* @__PURE__ */ jsx(
15
+ DropdownMenuPrimitive.Content,
16
+ {
17
+ ref,
18
+ sideOffset,
19
+ className: cn(
20
+ STYLE_SCOPE,
21
+ "z-50 min-w-[10rem] overflow-hidden rounded-md border border-[var(--border-subtle)] bg-[var(--bg-surface)] p-1 text-[var(--text-primary)] [box-shadow:var(--shadow-menu)]",
22
+ className
23
+ ),
24
+ ...props
25
+ }
26
+ ) });
27
+ });
28
+ DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName;
29
+ const DropdownMenuItem = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
30
+ DropdownMenuPrimitive.Item,
31
+ {
32
+ ref,
33
+ className: cn(
34
+ "relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-[13px] outline-none hover:bg-[var(--bg-hover)]",
35
+ className
36
+ ),
37
+ ...props
38
+ }
39
+ ));
40
+ DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName;
41
+ const DropdownMenuCheckboxItem = React.forwardRef(({ className, children, checked, ...props }, ref) => /* @__PURE__ */ jsxs(
42
+ DropdownMenuPrimitive.CheckboxItem,
43
+ {
44
+ ref,
45
+ className: cn(
46
+ "relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-[13px] outline-none hover:bg-[var(--bg-hover)]",
47
+ className
48
+ ),
49
+ checked,
50
+ ...props,
51
+ children: [
52
+ /* @__PURE__ */ jsx("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx(DropdownMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx(Check, { className: "h-3.5 w-3.5" }) }) }),
53
+ children
54
+ ]
55
+ }
56
+ ));
57
+ DropdownMenuCheckboxItem.displayName = DropdownMenuPrimitive.CheckboxItem.displayName;
58
+ export {
59
+ DropdownMenu,
60
+ DropdownMenuCheckboxItem,
61
+ DropdownMenuContent,
62
+ DropdownMenuGroup,
63
+ DropdownMenuItem,
64
+ DropdownMenuPortal,
65
+ DropdownMenuTrigger
66
+ };
@@ -0,0 +1,24 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import * as React from "react";
3
+ import { cn } from "../../lib/utils.js";
4
+ const Input = React.forwardRef(
5
+ ({ className, type, error, ...props }, ref) => {
6
+ return /* @__PURE__ */ jsx(
7
+ "input",
8
+ {
9
+ type,
10
+ className: cn(
11
+ "flex h-[var(--size-control-md)] w-full rounded-md border bg-[var(--bg-surface)] px-3 py-2 text-[13px] text-[var(--text-primary)] outline-none transition-colors placeholder:text-[var(--text-tertiary)] focus:border-[var(--border-focus)] disabled:cursor-not-allowed disabled:opacity-50",
12
+ error ? "border-[var(--border-danger)]" : "border-[var(--border-subtle)]",
13
+ className
14
+ ),
15
+ ref,
16
+ ...props
17
+ }
18
+ );
19
+ }
20
+ );
21
+ Input.displayName = "Input";
22
+ export {
23
+ Input
24
+ };
@@ -0,0 +1,33 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import * as React from "react";
3
+ import * as PopoverPrimitive from "@radix-ui/react-popover";
4
+ import { cn } from "../../lib/utils.js";
5
+ import { STYLE_SCOPE } from "../../lib/style-scope.js";
6
+ import { usePortalContainer } from "../../context/portal-container-context.js";
7
+ const Popover = PopoverPrimitive.Root;
8
+ const PopoverTrigger = PopoverPrimitive.Trigger;
9
+ const PopoverAnchor = PopoverPrimitive.Anchor;
10
+ const PopoverContent = React.forwardRef(({ className, align = "center", sideOffset = 4, ...props }, ref) => {
11
+ const container = usePortalContainer();
12
+ return /* @__PURE__ */ jsx(PopoverPrimitive.Portal, { container, children: /* @__PURE__ */ jsx(
13
+ PopoverPrimitive.Content,
14
+ {
15
+ ref,
16
+ align,
17
+ sideOffset,
18
+ className: cn(
19
+ STYLE_SCOPE,
20
+ "z-50 w-72 rounded-lg border border-[var(--border-subtle)] bg-[var(--bg-surface)] p-4 text-[var(--text-primary)] outline-none [box-shadow:var(--shadow-menu)]",
21
+ className
22
+ ),
23
+ ...props
24
+ }
25
+ ) });
26
+ });
27
+ PopoverContent.displayName = PopoverPrimitive.Content.displayName;
28
+ export {
29
+ Popover,
30
+ PopoverAnchor,
31
+ PopoverContent,
32
+ PopoverTrigger
33
+ };
@@ -0,0 +1,60 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import "react";
3
+ import { cn } from "../../lib/utils.js";
4
+ const shellClasses = {
5
+ toolbar: "inline-flex h-[var(--size-control-md)] items-center gap-1 rounded-lg border border-[var(--border-subtle)] bg-[var(--bg-surface)] px-1 py-1"
6
+ };
7
+ const segmentClasses = {
8
+ toolbar: "rounded-md px-3 self-stretch flex items-center text-[12px] font-medium"
9
+ };
10
+ const activeSegmentClasses = {
11
+ toolbar: "bg-[var(--bg-secondary)] text-[var(--text-primary)]"
12
+ };
13
+ function SegmentedControl({
14
+ value,
15
+ options,
16
+ onValueChange,
17
+ variant = "toolbar",
18
+ label,
19
+ className,
20
+ ...props
21
+ }) {
22
+ return /* @__PURE__ */ jsx(
23
+ "div",
24
+ {
25
+ role: "group",
26
+ "aria-label": label,
27
+ className: cn(shellClasses[variant], className),
28
+ ...props,
29
+ children: /* @__PURE__ */ jsx("div", { className: "inline-flex self-stretch items-center gap-1", children: options.map((option) => {
30
+ const active = option.value === value;
31
+ const isIconOnly = Boolean(option.icon) && !option.label;
32
+ const sharedClassName = cn(
33
+ "inline-flex items-center justify-center whitespace-nowrap transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--border-focus)] focus-visible:ring-offset-0",
34
+ variant === "toolbar" && isIconOnly ? "rounded-md px-2 self-stretch flex items-center text-[12px] font-medium" : segmentClasses[variant],
35
+ active ? activeSegmentClasses[variant] : "text-[var(--text-secondary)] hover:bg-[var(--bg-hover)] hover:text-[var(--text-primary)]"
36
+ );
37
+ const Icon = option.icon;
38
+ return /* @__PURE__ */ jsx(
39
+ "button",
40
+ {
41
+ type: "button",
42
+ "aria-pressed": active,
43
+ "aria-label": isIconOnly ? option.ariaLabel ?? option.value : void 0,
44
+ onClick: () => {
45
+ if (!active) {
46
+ onValueChange?.(option.value);
47
+ }
48
+ },
49
+ className: sharedClassName,
50
+ children: Icon ? /* @__PURE__ */ jsx(Icon, { className: "h-4 w-4" }) : option.label
51
+ },
52
+ option.value
53
+ );
54
+ }) })
55
+ }
56
+ );
57
+ }
58
+ export {
59
+ SegmentedControl
60
+ };
@@ -0,0 +1,66 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import * as React from "react";
3
+ import * as SelectPrimitive from "@radix-ui/react-select";
4
+ import { Check, ChevronDown } from "lucide-react";
5
+ import { cn } from "../../lib/utils.js";
6
+ import { STYLE_SCOPE } from "../../lib/style-scope.js";
7
+ import { usePortalContainer } from "../../context/portal-container-context.js";
8
+ const Select = SelectPrimitive.Root;
9
+ const SelectTrigger = React.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
10
+ SelectPrimitive.Trigger,
11
+ {
12
+ ref,
13
+ className: cn(
14
+ "flex h-[var(--size-control-md)] w-full items-center justify-between rounded-md border border-[var(--border-subtle)] bg-[var(--bg-surface)] px-3 py-2 text-[13px] text-[var(--text-primary)] outline-none placeholder:text-[var(--text-tertiary)] focus:border-[var(--border-focus)]",
15
+ className
16
+ ),
17
+ ...props,
18
+ children: [
19
+ children,
20
+ /* @__PURE__ */ jsx(SelectPrimitive.Icon, { asChild: true, children: /* @__PURE__ */ jsx(ChevronDown, { className: "h-4 w-4 text-[var(--text-tertiary)]" }) })
21
+ ]
22
+ }
23
+ ));
24
+ SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
25
+ const SelectContent = React.forwardRef(({ className, children, ...props }, ref) => {
26
+ const container = usePortalContainer();
27
+ return /* @__PURE__ */ jsx(SelectPrimitive.Portal, { container, children: /* @__PURE__ */ jsx(
28
+ SelectPrimitive.Content,
29
+ {
30
+ ref,
31
+ className: cn(
32
+ STYLE_SCOPE,
33
+ "z-50 min-w-[8rem] overflow-hidden rounded-md border border-[var(--border-subtle)] bg-[var(--bg-surface)] p-1 text-[var(--text-primary)] [box-shadow:var(--shadow-menu)]",
34
+ className
35
+ ),
36
+ position: "popper",
37
+ ...props,
38
+ children: /* @__PURE__ */ jsx(SelectPrimitive.Viewport, { className: "p-1", children })
39
+ }
40
+ ) });
41
+ });
42
+ SelectContent.displayName = SelectPrimitive.Content.displayName;
43
+ const SelectItem = React.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
44
+ SelectPrimitive.Item,
45
+ {
46
+ ref,
47
+ className: cn(
48
+ "relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-[13px] outline-none hover:bg-[var(--bg-hover)]",
49
+ className
50
+ ),
51
+ ...props,
52
+ children: [
53
+ /* @__PURE__ */ jsx("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx(SelectPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx(Check, { className: "h-3.5 w-3.5" }) }) }),
54
+ /* @__PURE__ */ jsx(SelectPrimitive.ItemText, { children })
55
+ ]
56
+ }
57
+ ));
58
+ SelectItem.displayName = SelectPrimitive.Item.displayName;
59
+ const SelectValue = SelectPrimitive.Value;
60
+ export {
61
+ Select,
62
+ SelectContent,
63
+ SelectItem,
64
+ SelectTrigger,
65
+ SelectValue
66
+ };
@@ -0,0 +1,41 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import * as React from "react";
3
+ import * as TabsPrimitive from "@radix-ui/react-tabs";
4
+ import { cn } from "../../lib/utils.js";
5
+ const Tabs = TabsPrimitive.Root;
6
+ const TabsList = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
7
+ TabsPrimitive.List,
8
+ {
9
+ ref,
10
+ className: cn(
11
+ "inline-flex h-auto max-w-full items-center gap-1 rounded-lg bg-[var(--bg-secondary)] p-1 text-[var(--text-secondary)]",
12
+ className
13
+ ),
14
+ ...props
15
+ }
16
+ ));
17
+ TabsList.displayName = TabsPrimitive.List.displayName;
18
+ const TabsTrigger = React.forwardRef(({ className, children, count, ...props }, ref) => /* @__PURE__ */ jsx(
19
+ TabsPrimitive.Trigger,
20
+ {
21
+ ref,
22
+ className: cn(
23
+ "group inline-flex shrink-0 items-center justify-center whitespace-nowrap rounded-md px-2.5 py-1.5 text-[12px] font-medium text-[var(--text-secondary)] transition-all hover:text-[var(--text-primary)] data-[state=active]:bg-[var(--bg-surface)] data-[state=active]:text-[var(--text-primary)] data-[state=active]:[box-shadow:var(--shadow-tab-active)]",
24
+ className
25
+ ),
26
+ ...props,
27
+ children: /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1.5", children: [
28
+ /* @__PURE__ */ jsx("span", { children }),
29
+ count !== void 0 ? /* @__PURE__ */ jsx("span", { className: "inline-flex min-w-5 items-center justify-center rounded-full bg-[var(--bg-tertiary)] px-1.5 py-0.5 text-[11px] font-semibold leading-none tabular-nums text-[var(--text-utility)] transition-colors group-data-[state=active]:bg-[var(--bg-secondary)] group-data-[state=active]:text-[var(--text-primary)]", children: count }) : null
30
+ ] })
31
+ }
32
+ ));
33
+ TabsTrigger.displayName = TabsPrimitive.Trigger.displayName;
34
+ const TabsContent = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(TabsPrimitive.Content, { ref, className: cn("outline-none", className), ...props }));
35
+ TabsContent.displayName = TabsPrimitive.Content.displayName;
36
+ export {
37
+ Tabs,
38
+ TabsContent,
39
+ TabsList,
40
+ TabsTrigger
41
+ };
@@ -0,0 +1,47 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import "react";
3
+ import { Sun, Moon } from "lucide-react";
4
+ import { SegmentedControl } from "./segmented-control.js";
5
+ const themeOptions = [
6
+ { value: "light", label: "Light" },
7
+ { value: "dark", label: "Dark" }
8
+ ];
9
+ const themeIconOptions = [
10
+ { value: "light", icon: Sun, ariaLabel: "Light" },
11
+ { value: "dark", icon: Moon, ariaLabel: "Dark" }
12
+ ];
13
+ function ThemeSwitch({
14
+ value,
15
+ variant = "toolbar",
16
+ label = "Theme",
17
+ onValueChange,
18
+ lightHref,
19
+ darkHref,
20
+ className,
21
+ ...props
22
+ }) {
23
+ const linkMode = Boolean(lightHref && darkHref);
24
+ const handleValueChange = (newValue) => {
25
+ if (linkMode) {
26
+ window.location.href = newValue === "light" ? lightHref : darkHref;
27
+ } else {
28
+ onValueChange?.(newValue);
29
+ }
30
+ };
31
+ const isIcon = variant === "icon";
32
+ return /* @__PURE__ */ jsx(
33
+ SegmentedControl,
34
+ {
35
+ value,
36
+ options: isIcon ? themeIconOptions : themeOptions,
37
+ variant: isIcon ? "toolbar" : variant,
38
+ label,
39
+ onValueChange: handleValueChange,
40
+ className,
41
+ ...props
42
+ }
43
+ );
44
+ }
45
+ export {
46
+ ThemeSwitch
47
+ };
@@ -0,0 +1,4 @@
1
+ const DRAWER_SIZE = "540px";
2
+ export {
3
+ DRAWER_SIZE
4
+ };
@@ -0,0 +1,10 @@
1
+ import { useContext, createContext } from "react";
2
+ const DrawerExpandContext = createContext(false);
3
+ DrawerExpandContext.displayName = "DrawerExpandContext";
4
+ function useDrawerExpanded() {
5
+ return useContext(DrawerExpandContext);
6
+ }
7
+ export {
8
+ DrawerExpandContext,
9
+ useDrawerExpanded
10
+ };
@@ -0,0 +1,10 @@
1
+ import { createContext, useContext } from "react";
2
+ const PortalContainerContext = createContext(null);
3
+ PortalContainerContext.displayName = "PortalContainerContext";
4
+ function usePortalContainer() {
5
+ return useContext(PortalContainerContext);
6
+ }
7
+ export {
8
+ PortalContainerContext,
9
+ usePortalContainer
10
+ };
@@ -0,0 +1,165 @@
1
+ import { createStore } from "zustand/vanilla";
2
+ const CUSTOM_VIEW_KEY = "custom";
3
+ const defaultValueForFilter = (cfg) => {
4
+ if (cfg.type === "compound") return {};
5
+ if (cfg.type === "enum") return [];
6
+ if (cfg.type === "number-range") return {};
7
+ if (cfg.type === "text") return [];
8
+ return "";
9
+ };
10
+ function createTableOrchestrationStore({
11
+ defaultViewKey,
12
+ initialColumnVisibility,
13
+ initialRowsPerPage
14
+ }) {
15
+ return createStore()((set, get) => {
16
+ const goCustom = () => {
17
+ const cur = get().activeView;
18
+ if (cur !== CUSTOM_VIEW_KEY) {
19
+ set({ activeView: CUSTOM_VIEW_KEY });
20
+ }
21
+ };
22
+ return {
23
+ // ── State ────────────────────────────────────────────────────────
24
+ searchInput: "",
25
+ searchQuery: "",
26
+ columnFilters: [],
27
+ newestFilterColumnId: null,
28
+ requestOpenFilterId: null,
29
+ currentSort: null,
30
+ columnVisibility: initialColumnVisibility ?? {},
31
+ page: 1,
32
+ rowsPerPage: initialRowsPerPage,
33
+ density: "normal",
34
+ isRefreshing: false,
35
+ selectedIds: /* @__PURE__ */ new Set(),
36
+ activeView: defaultViewKey,
37
+ columnsMenuOpen: false,
38
+ selectedRowId: null,
39
+ // ── Actions ──────────────────────────────────────────────────────
40
+ setSearchInput: (v) => set({ searchInput: v }),
41
+ submitSearch: () => set((s) => ({ searchQuery: s.searchInput, page: 1 })),
42
+ setColumnFilters: (filters) => {
43
+ set({ columnFilters: filters, page: 1 });
44
+ goCustom();
45
+ },
46
+ addColumnFilter: (columnId, defaultValue) => {
47
+ set((s) => ({
48
+ newestFilterColumnId: columnId,
49
+ columnVisibility: s.columnVisibility[columnId] === false ? { ...s.columnVisibility, [columnId]: true } : s.columnVisibility,
50
+ columnFilters: [...s.columnFilters, { columnId, value: defaultValue }],
51
+ page: 1
52
+ }));
53
+ goCustom();
54
+ },
55
+ removeColumnFilter: (columnId) => {
56
+ set((s) => ({
57
+ columnFilters: s.columnFilters.filter((f) => f.columnId !== columnId),
58
+ page: 1
59
+ }));
60
+ goCustom();
61
+ },
62
+ changeColumnFilter: (columnId, value) => {
63
+ set((s) => ({
64
+ columnFilters: s.columnFilters.map(
65
+ (f) => f.columnId === columnId ? { ...f, value } : f
66
+ ),
67
+ page: 1
68
+ }));
69
+ goCustom();
70
+ },
71
+ setColumnFilter: (columnId, value) => {
72
+ set((s) => {
73
+ const exists = s.columnFilters.some((f) => f.columnId === columnId);
74
+ return {
75
+ columnVisibility: s.columnVisibility[columnId] === false ? { ...s.columnVisibility, [columnId]: true } : s.columnVisibility,
76
+ columnFilters: exists ? s.columnFilters.map((f) => f.columnId === columnId ? { ...f, value } : f) : [...s.columnFilters, { columnId, value }],
77
+ page: 1
78
+ };
79
+ });
80
+ goCustom();
81
+ },
82
+ setNewestFilterColumnId: (v) => set({ newestFilterColumnId: v }),
83
+ setRequestOpenFilterId: (v) => set({ requestOpenFilterId: v }),
84
+ setCurrentSort: (next) => set({ currentSort: next }),
85
+ toggleSort: (columnId, direction) => {
86
+ set((s) => {
87
+ const same = s.currentSort?.columnId === columnId && s.currentSort.direction === direction;
88
+ return { currentSort: same ? null : { columnId, direction }, page: 1 };
89
+ });
90
+ goCustom();
91
+ },
92
+ removeSort: () => {
93
+ set({ currentSort: null, page: 1 });
94
+ goCustom();
95
+ },
96
+ setColumnVisibility: (next) => set((s) => ({
97
+ columnVisibility: typeof next === "function" ? next(s.columnVisibility) : next
98
+ })),
99
+ hideColumn: (columnId) => set((s) => ({
100
+ columnVisibility: { ...s.columnVisibility, [columnId]: false }
101
+ })),
102
+ showColumns: (columnIds) => set((s) => ({
103
+ columnVisibility: {
104
+ ...s.columnVisibility,
105
+ ...Object.fromEntries(columnIds.map((id) => [id, true]))
106
+ }
107
+ })),
108
+ resetColumns: () => {
109
+ set({ columnVisibility: {} });
110
+ goCustom();
111
+ },
112
+ setPage: (p) => set({ page: p }),
113
+ setRowsPerPage: (n) => set({ rowsPerPage: n, page: 1 }),
114
+ setDensity: (v) => set({ density: v }),
115
+ startRefresh: (durationMs = 700) => {
116
+ set({ isRefreshing: true });
117
+ if (typeof window !== "undefined") {
118
+ window.setTimeout(() => set({ isRefreshing: false }), durationMs);
119
+ }
120
+ },
121
+ setSelectedIds: (next) => set((s) => ({
122
+ selectedIds: typeof next === "function" ? next(s.selectedIds) : next
123
+ })),
124
+ toggleRowSelection: (id) => set((s) => {
125
+ const next = new Set(s.selectedIds);
126
+ if (next.has(id)) next.delete(id);
127
+ else next.add(id);
128
+ return { selectedIds: next };
129
+ }),
130
+ toggleHeaderCheck: (pageIds, allOnPageSelected) => set((s) => {
131
+ const next = new Set(s.selectedIds);
132
+ if (allOnPageSelected) pageIds.forEach((id) => next.delete(id));
133
+ else pageIds.forEach((id) => next.add(id));
134
+ return { selectedIds: next };
135
+ }),
136
+ setActiveView: (v) => set({ activeView: v }),
137
+ applyPreset: (preset) => set({
138
+ activeView: preset.key,
139
+ columnFilters: [...preset.filters],
140
+ currentSort: preset.sort,
141
+ columnVisibility: preset.columnVisibility ?? {},
142
+ page: 1,
143
+ newestFilterColumnId: null
144
+ }),
145
+ goCustom: () => goCustom(),
146
+ clearAll: (defaultKey) => set({
147
+ activeView: defaultKey,
148
+ columnFilters: [],
149
+ currentSort: null,
150
+ columnVisibility: {},
151
+ page: 1,
152
+ newestFilterColumnId: null
153
+ }),
154
+ setColumnsMenuOpen: (v) => set({ columnsMenuOpen: v }),
155
+ setSelectedRowId: (v) => set({ selectedRowId: v }),
156
+ toggleSelectedRowId: (id) => set((s) => ({
157
+ selectedRowId: s.selectedRowId === id ? null : id
158
+ }))
159
+ };
160
+ });
161
+ }
162
+ export {
163
+ createTableOrchestrationStore,
164
+ defaultValueForFilter
165
+ };
@@ -0,0 +1,33 @@
1
+ import { useRef, useState, useCallback, useEffect } from "react";
2
+ function useScrollActivity(idleMs = 700) {
3
+ const nodeRef = useRef(null);
4
+ const [nodeVersion, setNodeVersion] = useState(0);
5
+ const ref = useCallback((nextNode) => {
6
+ if (nodeRef.current === nextNode) return;
7
+ nodeRef.current = nextNode;
8
+ setNodeVersion((version) => version + 1);
9
+ }, []);
10
+ useEffect(() => {
11
+ const node = nodeRef.current;
12
+ if (!node) return;
13
+ let idleTimeout = 0;
14
+ const markActive = () => {
15
+ node.dataset.scrolling = "true";
16
+ window.clearTimeout(idleTimeout);
17
+ idleTimeout = window.setTimeout(() => {
18
+ node.dataset.scrolling = "false";
19
+ }, idleMs);
20
+ };
21
+ node.dataset.scrolling = "false";
22
+ node.addEventListener("scroll", markActive, { passive: true });
23
+ return () => {
24
+ window.clearTimeout(idleTimeout);
25
+ node.removeEventListener("scroll", markActive);
26
+ delete node.dataset.scrolling;
27
+ };
28
+ }, [idleMs, nodeVersion]);
29
+ return ref;
30
+ }
31
+ export {
32
+ useScrollActivity
33
+ };
@@ -0,0 +1,18 @@
1
+ import { useState, useRef } from "react";
2
+ import { useRowDrag } from "../components/data-table/hooks/use-row-drag.js";
3
+ function useRowDragOverride(paginatedRows) {
4
+ const [dragOverride, setDragOverride] = useState(null);
5
+ const prevPaginatedRef = useRef(paginatedRows);
6
+ if (prevPaginatedRef.current !== paginatedRows) {
7
+ prevPaginatedRef.current = paginatedRows;
8
+ if (dragOverride !== null) {
9
+ setDragOverride(null);
10
+ }
11
+ }
12
+ const displayRows = dragOverride ?? paginatedRows;
13
+ const rowDrag = useRowDrag(displayRows, setDragOverride);
14
+ return { displayRows, rowDrag };
15
+ }
16
+ export {
17
+ useRowDragOverride
18
+ };