@nextlyhq/ui 0.0.2-alpha.34 → 0.0.2-alpha.35

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -6,8 +6,8 @@ import { clsx } from 'clsx';
6
6
  import { twMerge } from 'tailwind-merge';
7
7
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
8
8
  import { Root as Root$2 } from '@radix-ui/react-label';
9
- import { Info, Minus, Check, ChevronDown, X, ChevronRight, Circle, Search, Loader2, ChevronUp, XCircle, AlertTriangle, AlertCircle, CheckCircle2, FileQuestion, ChevronsLeft, ChevronLeft, ChevronsRight } from 'lucide-react';
10
- import { Content, Provider, Root, Trigger } from '@radix-ui/react-tooltip';
9
+ import { Info, Minus, Check, ChevronDown, X, ChevronRight, Circle, Search, Loader2, ChevronUp, XCircle, AlertTriangle, AlertCircle, CheckCircle2, FileQuestion } from 'lucide-react';
10
+ import { Portal, Content, Provider, Root, Trigger } from '@radix-ui/react-tooltip';
11
11
  import * as SeparatorPrimitive from '@radix-ui/react-separator';
12
12
  import * as CheckboxPrimitive from '@radix-ui/react-checkbox';
13
13
  import * as RadioGroupPrimitive from '@radix-ui/react-radio-group';
@@ -43,13 +43,13 @@ var buttonVariants = cva(
43
43
  link: "text-primary border border-transparent underline-offset-4 hover:underline"
44
44
  },
45
45
  size: {
46
- default: "h-[var(--control-height)] px-6 py-2",
47
- sm: "h-[var(--control-height-md)] px-4 text-[13px]",
48
- md: "h-[var(--control-height)] px-6 text-sm",
49
- lg: "h-[var(--control-height-lg)] px-8 text-base",
50
- icon: "h-[var(--control-height)] w-[var(--control-height)] p-0",
51
- "icon-sm": "h-[var(--control-height-md)] w-[var(--control-height-md)] p-0",
52
- "icon-lg": "h-[var(--control-height-lg)] w-[var(--control-height-lg)] p-0"
46
+ default: "h-[var(--nx-control-height)] px-6 py-2",
47
+ sm: "h-[var(--nx-control-height-md)] px-4 text-[13px]",
48
+ md: "h-[var(--nx-control-height)] px-6 text-sm",
49
+ lg: "h-[var(--nx-control-height-lg)] px-8 text-base",
50
+ icon: "h-[var(--nx-control-height)] w-[var(--nx-control-height)] p-0",
51
+ "icon-sm": "h-[var(--nx-control-height-md)] w-[var(--nx-control-height-md)] p-0",
52
+ "icon-lg": "h-[var(--nx-control-height-lg)] w-[var(--nx-control-height-lg)] p-0"
53
53
  }
54
54
  },
55
55
  defaultVariants: {
@@ -90,9 +90,9 @@ var inputVariants = cva(
90
90
  {
91
91
  variants: {
92
92
  size: {
93
- sm: "h-[var(--control-height-sm)] px-2.5 py-2 text-sm",
94
- default: "h-[var(--control-height)] px-3 py-2.5 text-sm",
95
- lg: "h-[var(--control-height-lg)] px-4 py-3 text-base"
93
+ sm: "h-[var(--nx-control-height-sm)] px-2.5 py-2 text-sm",
94
+ default: "h-[var(--nx-control-height)] px-3 py-2.5 text-sm",
95
+ lg: "h-[var(--nx-control-height-lg)] px-4 py-3 text-base"
96
96
  }
97
97
  },
98
98
  defaultVariants: {
@@ -144,22 +144,41 @@ function Label({ className, ...props }) {
144
144
  }
145
145
  );
146
146
  }
147
+ var PortalContext = createContext({ container: null });
148
+ function PortalProvider({ container, children }) {
149
+ return /* @__PURE__ */ jsx(PortalContext.Provider, { value: { container }, children });
150
+ }
151
+ function usePortalContainer() {
152
+ const { container } = useContext(PortalContext);
153
+ return container ?? void 0;
154
+ }
147
155
  var TooltipProvider = Provider;
148
156
  var Tooltip = Root;
149
157
  var TooltipTrigger = Trigger;
150
- var TooltipContent = forwardRef(({ className, sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx(
151
- Content,
152
- {
153
- ref,
154
- sideOffset,
155
- "data-slot": "tooltip-content",
156
- className: cn(
157
- "z-50 overflow-hidden rounded-none px-3 py-1.5 text-xs shadow-lg border border-border bg-popover text-popover-foreground animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 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",
158
- className
159
- ),
160
- ...props
161
- }
162
- ));
158
+ var TooltipContent = forwardRef(({ className, sideOffset = 4, ...props }, ref) => {
159
+ const portalContainer = usePortalContainer();
160
+ return (
161
+ // Portalled for the same reason as every other overlay here, plus one
162
+ // specific to the tooltip: the positioner measures against the nearest
163
+ // containing block, and it counts `container-type` as one while the
164
+ // browser does not. Left inline under a `@container` element, the content
165
+ // is offset by that element's own position. Portalling lifts it out of any
166
+ // such ancestor, so the two agree again.
167
+ /* @__PURE__ */ jsx(Portal, { container: portalContainer, children: /* @__PURE__ */ jsx(
168
+ Content,
169
+ {
170
+ ref,
171
+ sideOffset,
172
+ "data-slot": "tooltip-content",
173
+ className: cn(
174
+ "z-50 overflow-hidden rounded-none px-3 py-1.5 text-xs shadow-lg border border-border bg-popover text-popover-foreground animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 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",
175
+ className
176
+ ),
177
+ ...props
178
+ }
179
+ ) })
180
+ );
181
+ });
163
182
  TooltipContent.displayName = Content.displayName;
164
183
  var FormLabelWithTooltip = React6.forwardRef(
165
184
  ({
@@ -214,9 +233,9 @@ var badgeVariants = cva(
214
233
  // which was nearly invisible on dark backgrounds).
215
234
  default: "bg-muted text-foreground",
216
235
  primary: "bg-primary/10 text-primary dark:bg-primary/20",
217
- success: "bg-green-100 text-green-700 dark:bg-green-900 dark:text-green-100",
218
- warning: "bg-amber-100 text-amber-700 dark:bg-amber-900 dark:text-amber-100",
219
- destructive: "bg-red-100 text-red-700 dark:bg-red-900 dark:text-red-100",
236
+ success: "bg-success-100 text-success-700 dark:bg-success-900 dark:text-success-100",
237
+ warning: "bg-warning-100 text-warning-700 dark:bg-warning-900 dark:text-warning-100",
238
+ destructive: "bg-destructive-100 text-destructive-700 dark:bg-destructive-900 dark:text-destructive-100",
220
239
  outline: "border border-border! bg-transparent text-foreground dark:text-muted-foreground dark:border-border!"
221
240
  }
222
241
  },
@@ -361,9 +380,9 @@ var alertVariants = cva(
361
380
  variants: {
362
381
  variant: {
363
382
  info: "border-border bg-primary/5 text-primary dark:border-primary/30 dark:bg-primary/5 dark:text-primary-foreground/90",
364
- success: "border-green-200 bg-green-50 text-green-900 border-l-4 border-l-success dark:border-green-900 dark:bg-green-950 dark:text-green-100",
365
- warning: "border-amber-200 bg-amber-50 text-amber-900 border-l-4 border-l-warning dark:border-amber-900 dark:bg-amber-950 dark:text-amber-100",
366
- destructive: "border-red-200 bg-red-50 text-red-900 border-l-4 border-l-destructive dark:border-red-900 dark:bg-red-950 dark:text-red-100"
383
+ success: "border-success-200 bg-success-50 text-success-900 border-l-4 border-l-success dark:border-success-900 dark:bg-success-950 dark:text-success-100",
384
+ warning: "border-warning-200 bg-warning-50 text-warning-900 border-l-4 border-l-warning dark:border-warning-900 dark:bg-warning-950 dark:text-warning-100",
385
+ destructive: "border-destructive-200 bg-destructive-50 text-destructive-900 border-l-4 border-l-destructive dark:border-destructive-900 dark:bg-destructive-950 dark:text-destructive-100"
367
386
  }
368
387
  },
369
388
  defaultVariants: {
@@ -459,7 +478,7 @@ var progressVariants = cva("h-full rounded-none transition-all", {
459
478
  variants: {
460
479
  variant: {
461
480
  default: "bg-primary-500",
462
- success: "bg-green-500",
481
+ success: "bg-success-500",
463
482
  error: "bg-destructive"
464
483
  }
465
484
  },
@@ -513,11 +532,22 @@ var Checkbox = forwardRef(({ className, indeterminate, ...props }, ref) => /* @_
513
532
  ref,
514
533
  "data-slot": "checkbox",
515
534
  className: cn(
516
- // Unchecked outline uses primary/40 (clearly visible, monochrome) instead of
517
- // primary/5, which rendered at ~5% opacity and was effectively invisible.
535
+ // Unchecked outline uses primary/50: measured 3.95:1 on the light row and
536
+ // 5.32:1 on the dark one. WCAG 1.4.11 asks 3:1 of a control's boundary and
537
+ // the earlier values did not reach it — primary/40 came out at 2.85, close
538
+ // enough to look deliberate and still short. Callers must not override the
539
+ // border: passing `border-border` puts the divider token here, which
540
+ // measured 1.35:1 and 1.14:1, and a divider is meant to go unnoticed.
518
541
  // Checked and indeterminate share the filled appearance; declaring both
519
542
  // here keeps the control self-sufficient without host overrides.
520
- "peer h-4 w-4 shrink-0 rounded-none border border-primary/40 ring-offset-background focus:border-primary! focus-visible:border-primary! focus:outline-none focus-visible:outline-none aria-invalid:border-destructive aria-invalid:focus:border-destructive! aria-invalid:focus-visible:border-destructive! disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground data-[state=checked]:border-primary data-[state=indeterminate]:bg-primary data-[state=indeterminate]:text-primary-foreground data-[state=indeterminate]:border-primary transition-all duration-200",
543
+ //
544
+ // The box stays 16px and the target does not: `before` stretches an
545
+ // invisible 24px square from the centre, which is WCAG 2.5.8's floor.
546
+ // The exemption for a bare browser checkbox does not cover a styled one,
547
+ // and this is styled. Growing the box instead would make every dense
548
+ // table heavier for a rule about pointers, so the box and the thing you
549
+ // can hit are allowed to differ.
550
+ "peer relative h-4 w-4 shrink-0 rounded-none border border-primary/50 ring-offset-background before:absolute before:left-1/2 before:top-1/2 before:h-6 before:w-6 before:-translate-x-1/2 before:-translate-y-1/2 before:content-[''] focus:border-primary! focus-visible:border-primary! focus:outline-none focus-visible:outline-none aria-invalid:border-destructive aria-invalid:focus:border-destructive! aria-invalid:focus-visible:border-destructive! disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground data-[state=checked]:border-primary data-[state=indeterminate]:bg-primary data-[state=indeterminate]:text-primary-foreground data-[state=indeterminate]:border-primary transition-all duration-200",
521
551
  className
522
552
  ),
523
553
  ...props,
@@ -758,14 +788,6 @@ var TabsContent = forwardRef(
758
788
  )
759
789
  );
760
790
  TabsContent.displayName = Content$1.displayName;
761
- var PortalContext = createContext({ container: null });
762
- function PortalProvider({ container, children }) {
763
- return /* @__PURE__ */ jsx(PortalContext.Provider, { value: { container }, children });
764
- }
765
- function usePortalContainer() {
766
- const { container } = useContext(PortalContext);
767
- return container ?? void 0;
768
- }
769
791
  var Popover = PopoverPrimitive.Root;
770
792
  var PopoverTrigger = PopoverPrimitive.Trigger;
771
793
  var PopoverAnchor = PopoverPrimitive.Anchor;
@@ -1013,12 +1035,14 @@ var DropdownMenuGroup = DropdownMenuPrimitive.Group;
1013
1035
  var DropdownMenuPortal = DropdownMenuPrimitive.Portal;
1014
1036
  var DropdownMenuSub = DropdownMenuPrimitive.Sub;
1015
1037
  var DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup;
1038
+ var menuItemBase = "cursor-pointer transition-colors data-[highlighted]:bg-muted data-[highlighted]:text-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50";
1016
1039
  var DropdownMenuSubTrigger = React6.forwardRef(({ className, inset, children, ...props }, ref) => /* @__PURE__ */ jsxs(
1017
1040
  DropdownMenuPrimitive.SubTrigger,
1018
1041
  {
1019
1042
  ref,
1020
1043
  className: cn(
1021
- "flex cursor-default select-none items-center gap-2 rounded-none px-2 py-1.5 text-sm outline-none hover-unified focus:bg-primary/5 focus:text-primary data-[state=open]:bg-primary/5 data-[state=open]:text-primary [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
1044
+ "flex select-none items-center gap-2 rounded-none px-2 py-1.5 text-sm outline-none data-[state=open]:bg-muted data-[state=open]:text-foreground [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
1045
+ menuItemBase,
1022
1046
  inset && "pl-8",
1023
1047
  className
1024
1048
  ),
@@ -1063,7 +1087,8 @@ var DropdownMenuItem = React6.forwardRef(({ className, inset, ...props }, ref) =
1063
1087
  {
1064
1088
  ref,
1065
1089
  className: cn(
1066
- "relative flex cursor-pointer select-none items-center gap-2 rounded-none px-2 py-1.5 text-sm outline-none transition-colors hover-unified focus:bg-primary/5 focus:text-primary data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
1090
+ "relative flex select-none items-center gap-2 rounded-none px-2 py-1.5 text-sm outline-none [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
1091
+ menuItemBase,
1067
1092
  inset && "pl-8",
1068
1093
  className
1069
1094
  ),
@@ -1076,7 +1101,8 @@ var DropdownMenuCheckboxItem = React6.forwardRef(({ className, children, checked
1076
1101
  {
1077
1102
  ref,
1078
1103
  className: cn(
1079
- "relative flex cursor-default select-none items-center rounded-none py-1.5 pl-8 pr-2 text-sm outline-none transition-colors hover-primary-light focus:bg-primary/5 focus:text-primary data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
1104
+ "relative flex select-none items-center rounded-none py-1.5 pl-8 pr-2 text-sm outline-none",
1105
+ menuItemBase,
1080
1106
  className
1081
1107
  ),
1082
1108
  checked,
@@ -1093,7 +1119,8 @@ var DropdownMenuRadioItem = React6.forwardRef(({ className, children, ...props }
1093
1119
  {
1094
1120
  ref,
1095
1121
  className: cn(
1096
- "relative flex cursor-default select-none items-center rounded-none py-1.5 pl-8 pr-2 text-sm outline-none transition-colors hover-primary-light focus:bg-primary/5 focus:text-primary data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
1122
+ "relative flex select-none items-center rounded-none py-1.5 pl-8 pr-2 text-sm outline-none",
1123
+ menuItemBase,
1097
1124
  className
1098
1125
  ),
1099
1126
  ...props,
@@ -1155,9 +1182,9 @@ var selectTriggerVariants = cva(
1155
1182
  {
1156
1183
  variants: {
1157
1184
  size: {
1158
- sm: "h-[var(--control-height-sm)] text-sm",
1159
- default: "h-[var(--control-height)] text-sm",
1160
- lg: "h-[var(--control-height-lg)] text-base"
1185
+ sm: "h-[var(--nx-control-height-sm)] text-sm",
1186
+ default: "h-[var(--nx-control-height)] text-sm",
1187
+ lg: "h-[var(--nx-control-height-lg)] text-base"
1161
1188
  }
1162
1189
  },
1163
1190
  defaultVariants: {
@@ -1640,9 +1667,9 @@ function Toaster({ theme = "system", ...props }) {
1640
1667
  loading: /* @__PURE__ */ jsx(Loader2, { className: "h-4 w-4 animate-spin" })
1641
1668
  },
1642
1669
  style: {
1643
- "--normal-bg": "var(--popover)",
1644
- "--normal-text": "var(--popover-foreground)",
1645
- "--normal-border": "var(--border)",
1670
+ "--normal-bg": "var(--nx-popover)",
1671
+ "--normal-text": "var(--nx-popover-foreground)",
1672
+ "--normal-border": "var(--nx-border)",
1646
1673
  "--border-radius": "0px"
1647
1674
  },
1648
1675
  ...props
@@ -1790,213 +1817,6 @@ function TableEmpty({ message = "No records found" }) {
1790
1817
  /* @__PURE__ */ jsx("span", { className: "text-sm font-medium", children: message })
1791
1818
  ] });
1792
1819
  }
1793
- function renderPageNumbers(currentPage, totalPages, maxVisiblePages, onPageChange) {
1794
- const getBtnClass = (active) => `flex h-8 w-8 items-center justify-center border-y border-border border-r border-border text-xs z-10 -ml-px transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring ${active ? "bg-primary! text-primary-foreground! border-primary! z-20" : "bg-background! border-border! hover-muted disabled:opacity-50"}`;
1795
- if (totalPages <= maxVisiblePages) {
1796
- return Array.from({ length: totalPages }).map((_, i) => /* @__PURE__ */ jsx(
1797
- "button",
1798
- {
1799
- onClick: () => onPageChange(i),
1800
- "aria-label": `Go to page ${i + 1}`,
1801
- "aria-current": currentPage === i ? "page" : void 0,
1802
- className: getBtnClass(currentPage === i),
1803
- children: i + 1
1804
- },
1805
- `page-${i}`
1806
- ));
1807
- }
1808
- const pages = [];
1809
- const startPage = Math.max(0, currentPage - Math.floor(maxVisiblePages / 2));
1810
- const endPage = Math.min(totalPages - 1, startPage + maxVisiblePages - 1);
1811
- if (startPage > 0) {
1812
- pages.push(
1813
- /* @__PURE__ */ jsx(
1814
- "button",
1815
- {
1816
- onClick: () => onPageChange(0),
1817
- "aria-label": "Go to page 1",
1818
- className: getBtnClass(currentPage === 0),
1819
- children: "1"
1820
- },
1821
- "page-0"
1822
- )
1823
- );
1824
- if (startPage > 1) {
1825
- pages.push(
1826
- /* @__PURE__ */ jsx(
1827
- "span",
1828
- {
1829
- className: "flex h-8 w-8 items-center justify-center border-y border-border border-r border-border border-border! bg-background! text-muted-foreground text-xs -ml-px",
1830
- "aria-hidden": "true",
1831
- children: "..."
1832
- },
1833
- "ellipsis-start"
1834
- )
1835
- );
1836
- }
1837
- }
1838
- for (let i = startPage; i <= endPage; i++) {
1839
- pages.push(
1840
- /* @__PURE__ */ jsx(
1841
- "button",
1842
- {
1843
- onClick: () => onPageChange(i),
1844
- "aria-label": `Go to page ${i + 1}`,
1845
- "aria-current": currentPage === i ? "page" : void 0,
1846
- className: getBtnClass(currentPage === i),
1847
- children: i + 1
1848
- },
1849
- i
1850
- )
1851
- );
1852
- }
1853
- if (endPage < totalPages - 1) {
1854
- if (endPage < totalPages - 2) {
1855
- pages.push(
1856
- /* @__PURE__ */ jsx(
1857
- "span",
1858
- {
1859
- className: "flex h-8 w-8 items-center justify-center border-y border-border border-r border-border border-border! bg-background! text-muted-foreground text-xs -ml-px",
1860
- "aria-hidden": "true",
1861
- children: "..."
1862
- },
1863
- "ellipsis-end"
1864
- )
1865
- );
1866
- }
1867
- pages.push(
1868
- /* @__PURE__ */ jsx(
1869
- "button",
1870
- {
1871
- onClick: () => onPageChange(totalPages - 1),
1872
- "aria-label": `Go to page ${totalPages}`,
1873
- className: getBtnClass(currentPage === totalPages - 1),
1874
- children: totalPages
1875
- },
1876
- totalPages - 1
1877
- )
1878
- );
1879
- }
1880
- return pages;
1881
- }
1882
- function TablePagination({
1883
- meta,
1884
- onPageChange,
1885
- onPageSizeChange,
1886
- config,
1887
- isLoading = false
1888
- }) {
1889
- const {
1890
- showPageSizeSelector = true,
1891
- pageSizeOptions = [10, 20, 30, 50],
1892
- maxVisiblePages = 5
1893
- } = config || {};
1894
- const pageIndex = meta.page - 1;
1895
- return /* @__PURE__ */ jsxs("div", { className: "flex flex-col sm:flex-row w-full items-center justify-between gap-4 text-xs sm:text-sm text-muted-foreground p-4 border-t border-border", children: [
1896
- /* @__PURE__ */ jsxs("div", { className: "whitespace-nowrap order-2 sm:order-1", children: [
1897
- "Showing ",
1898
- (meta.page - 1) * meta.limit + 1,
1899
- "-",
1900
- Math.min(meta.page * meta.limit, meta.total),
1901
- " of ",
1902
- meta.total,
1903
- " entries"
1904
- ] }),
1905
- /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center justify-center gap-4 sm:gap-6 lg:gap-8 order-1 sm:order-2", children: [
1906
- showPageSizeSelector && /* @__PURE__ */ jsxs("div", { className: "flex items-center space-x-2", children: [
1907
- /* @__PURE__ */ jsx("span", { className: "whitespace-nowrap hidden sm:inline-block", children: "Rows per page" }),
1908
- /* @__PURE__ */ jsxs("div", { className: "relative", children: [
1909
- /* @__PURE__ */ jsx(
1910
- "select",
1911
- {
1912
- id: "pageSize",
1913
- value: meta.limit,
1914
- onChange: (e) => {
1915
- const newPageSize = Number(e.target.value);
1916
- onPageSizeChange(newPageSize);
1917
- },
1918
- className: "h-8 w-[70px] appearance-none rounded-none border border-border bg-background px-2 py-1 text-sm font-medium focus-visible:outline-none focus:ring-1 focus:ring-ring disabled:opacity-50 hover-muted cursor-pointer",
1919
- disabled: isLoading,
1920
- children: pageSizeOptions.map((size) => /* @__PURE__ */ jsx("option", { value: size, children: size }, size))
1921
- }
1922
- ),
1923
- /* @__PURE__ */ jsx("div", { className: "pointer-events-none absolute inset-y-0 right-0 flex items-center px-2 text-muted-foreground", children: /* @__PURE__ */ jsx(
1924
- "svg",
1925
- {
1926
- className: "h-3 w-3",
1927
- fill: "none",
1928
- viewBox: "0 0 24 24",
1929
- stroke: "currentColor",
1930
- children: /* @__PURE__ */ jsx(
1931
- "path",
1932
- {
1933
- strokeLinecap: "round",
1934
- strokeLinejoin: "round",
1935
- strokeWidth: 2,
1936
- d: "M19 9l-7 7-7-7"
1937
- }
1938
- )
1939
- }
1940
- ) })
1941
- ] })
1942
- ] }),
1943
- /* @__PURE__ */ jsxs("div", { className: "flex items-center -space-x-px", children: [
1944
- /* @__PURE__ */ jsx(
1945
- "button",
1946
- {
1947
- onClick: () => onPageChange(0),
1948
- disabled: pageIndex === 0 || isLoading,
1949
- className: "hidden sm:flex h-8 w-8 items-center justify-center rounded-none border border-border bg-background hover-muted disabled:opacity-50 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring z-10",
1950
- "aria-label": "First page",
1951
- children: /* @__PURE__ */ jsx(ChevronsLeft, { className: "h-4 w-4" })
1952
- }
1953
- ),
1954
- /* @__PURE__ */ jsx(
1955
- "button",
1956
- {
1957
- onClick: () => onPageChange(pageIndex - 1),
1958
- disabled: pageIndex === 0 || isLoading,
1959
- className: "flex h-8 w-8 items-center justify-center rounded-none sm:rounded-none border border-border bg-background hover-muted disabled:opacity-50 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring z-10",
1960
- "aria-label": "Previous page",
1961
- children: /* @__PURE__ */ jsx(ChevronLeft, { className: "h-4 w-4" })
1962
- }
1963
- ),
1964
- /* @__PURE__ */ jsx("div", { className: "flex", children: renderPageNumbers(
1965
- pageIndex,
1966
- meta.totalPages,
1967
- maxVisiblePages,
1968
- onPageChange
1969
- ) }),
1970
- /* @__PURE__ */ jsx(
1971
- "button",
1972
- {
1973
- onClick: () => onPageChange(pageIndex + 1),
1974
- disabled: pageIndex >= meta.totalPages - 1 || isLoading,
1975
- className: "flex h-8 w-8 items-center justify-center rounded-none sm:rounded-none border-y border-border border-x border-border sm:border-r border-border bg-background hover-muted disabled:opacity-50 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring z-10",
1976
- "aria-label": "Next page",
1977
- children: /* @__PURE__ */ jsx(ChevronRight, { className: "h-4 w-4" })
1978
- }
1979
- ),
1980
- /* @__PURE__ */ jsx(
1981
- "button",
1982
- {
1983
- onClick: () => onPageChange(meta.totalPages - 1),
1984
- disabled: pageIndex >= meta.totalPages - 1 || isLoading,
1985
- className: "hidden sm:flex h-8 w-8 items-center justify-center rounded-none border border-border bg-background hover-muted disabled:opacity-50 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring z-10",
1986
- "aria-label": "Last page",
1987
- children: /* @__PURE__ */ jsx(ChevronsRight, { className: "h-4 w-4" })
1988
- }
1989
- )
1990
- ] }),
1991
- /* @__PURE__ */ jsxs("div", { className: "whitespace-nowrap hidden sm:block", children: [
1992
- "Page ",
1993
- meta.page,
1994
- " of ",
1995
- meta.totalPages
1996
- ] })
1997
- ] })
1998
- ] });
1999
- }
2000
1820
  var GrayBar = ({ className }) => /* @__PURE__ */ jsx(Skeleton, { className });
2001
1821
  var TableSkeleton = ({
2002
1822
  columns = 5,
@@ -2039,219 +1859,52 @@ var TableSkeleton = ({
2039
1859
  return /* @__PURE__ */ jsx("div", { className: "table-wrapper rounded-none border border-border bg-card overflow-hidden", children: content });
2040
1860
  };
2041
1861
  TableSkeleton.displayName = "TableSkeleton";
2042
- function ResponsiveTableInner({
2043
- data,
2044
- columns,
2045
- onRowClick,
2046
- renderMobileCard,
2047
- className,
2048
- emptyMessage = "No results found.",
2049
- ariaLabel,
2050
- tableWrapperClassName,
2051
- footer
2052
- }, ref) {
2053
- const visibleMobileColumns = React6.useMemo(
2054
- () => columns.filter((col) => !col.hideOnMobile),
2055
- [columns]
2056
- );
2057
- const primaryColumn = React6.useMemo(() => {
2058
- return visibleMobileColumns.find(
2059
- (col) => col.key !== "select" && col.key !== "actions"
2060
- ) || visibleMobileColumns[0];
2061
- }, [visibleMobileColumns]);
2062
- const secondaryColumns = React6.useMemo(
2063
- () => visibleMobileColumns.filter((col) => col.key !== primaryColumn?.key),
2064
- [visibleMobileColumns, primaryColumn]
2065
- );
2066
- React6.useEffect(() => {
2067
- const isDev = typeof globalThis !== "undefined" && globalThis.process && globalThis.process.env?.NODE_ENV === "development";
2068
- if (isDev && visibleMobileColumns.length === 0) {
2069
- console.warn(
2070
- "ResponsiveTable: All columns are hidden on mobile (hideOnMobile: true). Consider showing at least one column for better mobile UX. Users will see empty card borders on mobile devices."
2071
- );
2072
- }
2073
- }, [visibleMobileColumns.length]);
2074
- const handleItemClick = React6.useCallback(
2075
- (item, e) => {
2076
- if (!onRowClick) return;
2077
- if (e) {
2078
- const target = e.target;
2079
- if (target.closest('[role="checkbox"]') || target.closest("button") || target.closest("a") || target.closest('[role^="menuitem"]') || target.closest("[data-actions]")) {
2080
- return;
2081
- }
2082
- }
2083
- onRowClick(item);
2084
- },
2085
- [onRowClick]
2086
- );
2087
- const handleCardKeyDown = React6.useCallback(
2088
- (item) => (e) => {
2089
- if (onRowClick && (e.key === "Enter" || e.key === " ")) {
2090
- e.preventDefault();
2091
- handleItemClick(item, e);
2092
- }
2093
- },
2094
- [handleItemClick, onRowClick]
2095
- );
2096
- if (data.length === 0) {
2097
- return /* @__PURE__ */ jsx("div", { ref, className: cn("p-8 text-center", className), children: /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: emptyMessage }) });
2098
- }
2099
- return /* @__PURE__ */ jsxs("div", { ref, className: cn("w-full", className), children: [
2100
- /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-4 md:hidden", children: data.map((item) => {
2101
- const primaryValue = primaryColumn ? String(item[primaryColumn.key]) : String(item.id);
2102
- if (renderMobileCard) {
2103
- return /* @__PURE__ */ jsx(
2104
- "div",
2105
- {
2106
- onClick: (e) => handleItemClick(item, e),
2107
- role: onRowClick ? "button" : void 0,
2108
- tabIndex: onRowClick ? 0 : void 0,
2109
- onKeyDown: onRowClick ? handleCardKeyDown(item) : void 0,
2110
- className: onRowClick ? "cursor-pointer" : void 0,
2111
- "aria-label": onRowClick ? `View details for ${primaryValue}` : void 0,
2112
- children: renderMobileCard(item, visibleMobileColumns)
2113
- },
2114
- item.id
2115
- );
2116
- }
2117
- return /* @__PURE__ */ jsxs(
2118
- Card,
2119
- {
2120
- variant: onRowClick ? "interactive" : "default",
2121
- className: cn(
2122
- onRowClick && "cursor-pointer",
2123
- "transition-all duration-150"
2124
- ),
2125
- onClick: (e) => handleItemClick(item, e),
2126
- role: onRowClick ? "button" : void 0,
2127
- tabIndex: onRowClick ? 0 : void 0,
2128
- onKeyDown: onRowClick ? handleCardKeyDown(item) : void 0,
2129
- "aria-label": onRowClick ? `View details for ${primaryValue}` : void 0,
2130
- children: [
2131
- primaryColumn ? /* @__PURE__ */ jsx(CardHeader, { className: "pb-3", children: /* @__PURE__ */ jsx(CardTitle, { className: "text-base", children: primaryColumn.render ? primaryColumn.render(item[primaryColumn.key], item) : String(item[primaryColumn.key]) }) }) : null,
2132
- secondaryColumns.length > 0 && /* @__PURE__ */ jsx(CardContent, { className: "pb-3", children: /* @__PURE__ */ jsx("dl", { className: "flex flex-col gap-2", children: secondaryColumns.map((column) => /* @__PURE__ */ jsxs(
2133
- "div",
2134
- {
2135
- className: "flex items-start justify-between gap-4 text-sm",
2136
- children: [
2137
- !column.hideLabelOnMobile && /* @__PURE__ */ jsxs("dt", { className: "text-muted-foreground min-w-[80px] shrink-0", children: [
2138
- column.label,
2139
- ":"
2140
- ] }),
2141
- /* @__PURE__ */ jsx(
2142
- "dd",
2143
- {
2144
- className: cn(
2145
- "font-medium flex-1",
2146
- !column.hideLabelOnMobile ? "text-right" : "text-left"
2147
- ),
2148
- children: column.render ? column.render(item[column.key], item) : String(item[column.key])
2149
- }
2150
- )
2151
- ]
2152
- },
2153
- String(column.key)
2154
- )) }) })
2155
- ]
2156
- },
2157
- item.id
2158
- );
2159
- }) }),
2160
- /* @__PURE__ */ jsx(
2161
- "div",
2162
- {
2163
- className: cn(
2164
- "table-wrapper hidden md:block overflow-hidden rounded-none border border-border",
2165
- tableWrapperClassName
2166
- ),
2167
- children: /* @__PURE__ */ jsxs(Table, { "aria-label": ariaLabel || "Data table", children: [
2168
- /* @__PURE__ */ jsx(TableHeader, { className: "bg-[var(--table-header-bg)]", children: /* @__PURE__ */ jsx(TableRow, { children: columns.map((column) => /* @__PURE__ */ jsx(
2169
- TableHead,
2170
- {
2171
- className: column.headerClassName,
2172
- children: column.label
2173
- },
2174
- String(column.key)
2175
- )) }) }),
2176
- /* @__PURE__ */ jsx(TableBody, { children: data.map((item) => {
2177
- const primaryValue = primaryColumn ? String(item[primaryColumn.key]) : String(item.id);
2178
- return /* @__PURE__ */ jsx(
2179
- TableRow,
2180
- {
2181
- className: cn(
2182
- "hover-unified-table-row",
2183
- onRowClick && "cursor-pointer"
2184
- ),
2185
- onClick: (e) => handleItemClick(item, e),
2186
- role: onRowClick ? "button" : void 0,
2187
- tabIndex: onRowClick ? 0 : void 0,
2188
- onKeyDown: onRowClick ? handleCardKeyDown(item) : void 0,
2189
- "aria-label": onRowClick ? `View details for ${primaryValue}` : void 0,
2190
- children: columns.map((column) => /* @__PURE__ */ jsx(
2191
- TableCell,
2192
- {
2193
- className: column.cellClassName,
2194
- children: column.render ? column.render(item[column.key], item) : String(item[column.key])
2195
- },
2196
- String(column.key)
2197
- ))
2198
- },
2199
- item.id
2200
- );
2201
- }) })
2202
- ] })
2203
- }
2204
- ),
2205
- footer && /* @__PURE__ */ jsx("div", { className: "table-footer border-t border-border bg-[var(--table-header-bg)]", children: footer })
2206
- ] });
2207
- }
2208
- var ResponsiveTable = React6.forwardRef(ResponsiveTableInner);
2209
1862
 
2210
1863
  // src/tailwind-preset.ts
2211
1864
  var uiPreset = {
2212
1865
  theme: {
2213
1866
  extend: {
2214
1867
  colors: {
2215
- border: "var(--border)",
2216
- input: "var(--input)",
2217
- ring: "var(--ring)",
2218
- background: "var(--background)",
2219
- foreground: "var(--foreground)",
1868
+ border: "var(--nx-border)",
1869
+ input: "var(--nx-input)",
1870
+ ring: "var(--nx-ring)",
1871
+ background: "var(--nx-background)",
1872
+ foreground: "var(--nx-foreground)",
2220
1873
  primary: {
2221
- DEFAULT: "var(--primary)",
2222
- foreground: "var(--primary-foreground)"
1874
+ DEFAULT: "var(--nx-primary)",
1875
+ foreground: "var(--nx-primary-foreground)"
2223
1876
  },
2224
1877
  secondary: {
2225
- DEFAULT: "var(--secondary)",
2226
- foreground: "var(--secondary-foreground)"
1878
+ DEFAULT: "var(--nx-secondary)",
1879
+ foreground: "var(--nx-secondary-foreground)"
2227
1880
  },
2228
1881
  destructive: {
2229
- DEFAULT: "var(--destructive)",
2230
- foreground: "var(--destructive-foreground)"
1882
+ DEFAULT: "var(--nx-destructive)",
1883
+ foreground: "var(--nx-destructive-foreground)"
2231
1884
  },
2232
1885
  success: {
2233
- DEFAULT: "var(--success)",
2234
- foreground: "var(--success-foreground)"
1886
+ DEFAULT: "var(--nx-success)",
1887
+ foreground: "var(--nx-success-foreground)"
2235
1888
  },
2236
1889
  warning: {
2237
- DEFAULT: "var(--warning)",
2238
- foreground: "var(--warning-foreground)"
1890
+ DEFAULT: "var(--nx-warning)",
1891
+ foreground: "var(--nx-warning-foreground)"
2239
1892
  },
2240
1893
  muted: {
2241
- DEFAULT: "var(--muted)",
2242
- foreground: "var(--muted-foreground)"
1894
+ DEFAULT: "var(--nx-muted)",
1895
+ foreground: "var(--nx-muted-foreground)"
2243
1896
  },
2244
1897
  accent: {
2245
- DEFAULT: "var(--accent)",
2246
- foreground: "var(--accent-foreground)"
1898
+ DEFAULT: "var(--nx-accent)",
1899
+ foreground: "var(--nx-accent-foreground)"
2247
1900
  },
2248
1901
  popover: {
2249
- DEFAULT: "var(--popover)",
2250
- foreground: "var(--popover-foreground)"
1902
+ DEFAULT: "var(--nx-popover)",
1903
+ foreground: "var(--nx-popover-foreground)"
2251
1904
  },
2252
1905
  card: {
2253
- DEFAULT: "var(--card)",
2254
- foreground: "var(--card-foreground)"
1906
+ DEFAULT: "var(--nx-card)",
1907
+ foreground: "var(--nx-card-foreground)"
2255
1908
  }
2256
1909
  },
2257
1910
  borderRadius: {
@@ -2278,6 +1931,6 @@ var uiPreset = {
2278
1931
  };
2279
1932
  var tailwind_preset_default = uiPreset;
2280
1933
 
2281
- export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, Alert, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AlertTitle, Avatar, AvatarFallback, AvatarImage, Badge, Button, Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Checkbox, Collapsible, CollapsibleContent2 as CollapsibleContent, CollapsibleTrigger2 as CollapsibleTrigger, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, FormLabelWithTooltip, Input, Label, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, PortalProvider, Progress, RadioGroup, RadioGroupItem, ResponsiveTable, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetOverlay, SheetPortal, SheetTitle, SheetTrigger, Skeleton, Spinner, Switch, Table, TableBody, TableCaption, TableCell, TableEmpty, TableError, TableFooter, TableHead, TableHeader, TableLoading, TablePagination, TableRow, TableSearch, TableSkeleton, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, Toaster, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, alertVariants, avatarVariants, badgeVariants, buttonVariants, cardVariants, cn, dialogContentVariants, inputVariants, progressVariants, selectTriggerVariants, sheetVariants, spinnerVariants, tailwind_preset_default as uiPreset, usePortalContainer };
1934
+ export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, Alert, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AlertTitle, Avatar, AvatarFallback, AvatarImage, Badge, Button, Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Checkbox, Collapsible, CollapsibleContent2 as CollapsibleContent, CollapsibleTrigger2 as CollapsibleTrigger, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, FormLabelWithTooltip, Input, Label, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, PortalProvider, Progress, RadioGroup, RadioGroupItem, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetOverlay, SheetPortal, SheetTitle, SheetTrigger, Skeleton, Spinner, Switch, Table, TableBody, TableCaption, TableCell, TableEmpty, TableError, TableFooter, TableHead, TableHeader, TableLoading, TableRow, TableSearch, TableSkeleton, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, Toaster, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, alertVariants, avatarVariants, badgeVariants, buttonVariants, cardVariants, cn, dialogContentVariants, inputVariants, progressVariants, selectTriggerVariants, sheetVariants, spinnerVariants, tailwind_preset_default as uiPreset, usePortalContainer };
2282
1935
  //# sourceMappingURL=index.mjs.map
2283
1936
  //# sourceMappingURL=index.mjs.map