@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.cjs CHANGED
@@ -73,13 +73,13 @@ var buttonVariants = classVarianceAuthority.cva(
73
73
  link: "text-primary border border-transparent underline-offset-4 hover:underline"
74
74
  },
75
75
  size: {
76
- default: "h-[var(--control-height)] px-6 py-2",
77
- sm: "h-[var(--control-height-md)] px-4 text-[13px]",
78
- md: "h-[var(--control-height)] px-6 text-sm",
79
- lg: "h-[var(--control-height-lg)] px-8 text-base",
80
- icon: "h-[var(--control-height)] w-[var(--control-height)] p-0",
81
- "icon-sm": "h-[var(--control-height-md)] w-[var(--control-height-md)] p-0",
82
- "icon-lg": "h-[var(--control-height-lg)] w-[var(--control-height-lg)] p-0"
76
+ default: "h-[var(--nx-control-height)] px-6 py-2",
77
+ sm: "h-[var(--nx-control-height-md)] px-4 text-[13px]",
78
+ md: "h-[var(--nx-control-height)] px-6 text-sm",
79
+ lg: "h-[var(--nx-control-height-lg)] px-8 text-base",
80
+ icon: "h-[var(--nx-control-height)] w-[var(--nx-control-height)] p-0",
81
+ "icon-sm": "h-[var(--nx-control-height-md)] w-[var(--nx-control-height-md)] p-0",
82
+ "icon-lg": "h-[var(--nx-control-height-lg)] w-[var(--nx-control-height-lg)] p-0"
83
83
  }
84
84
  },
85
85
  defaultVariants: {
@@ -120,9 +120,9 @@ var inputVariants = classVarianceAuthority.cva(
120
120
  {
121
121
  variants: {
122
122
  size: {
123
- sm: "h-[var(--control-height-sm)] px-2.5 py-2 text-sm",
124
- default: "h-[var(--control-height)] px-3 py-2.5 text-sm",
125
- lg: "h-[var(--control-height-lg)] px-4 py-3 text-base"
123
+ sm: "h-[var(--nx-control-height-sm)] px-2.5 py-2 text-sm",
124
+ default: "h-[var(--nx-control-height)] px-3 py-2.5 text-sm",
125
+ lg: "h-[var(--nx-control-height-lg)] px-4 py-3 text-base"
126
126
  }
127
127
  },
128
128
  defaultVariants: {
@@ -174,22 +174,41 @@ function Label({ className, ...props }) {
174
174
  }
175
175
  );
176
176
  }
177
+ var PortalContext = React6.createContext({ container: null });
178
+ function PortalProvider({ container, children }) {
179
+ return /* @__PURE__ */ jsxRuntime.jsx(PortalContext.Provider, { value: { container }, children });
180
+ }
181
+ function usePortalContainer() {
182
+ const { container } = React6.useContext(PortalContext);
183
+ return container ?? void 0;
184
+ }
177
185
  var TooltipProvider = reactTooltip.Provider;
178
186
  var Tooltip = reactTooltip.Root;
179
187
  var TooltipTrigger = reactTooltip.Trigger;
180
- var TooltipContent = React6.forwardRef(({ className, sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
181
- reactTooltip.Content,
182
- {
183
- ref,
184
- sideOffset,
185
- "data-slot": "tooltip-content",
186
- className: cn(
187
- "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",
188
- className
189
- ),
190
- ...props
191
- }
192
- ));
188
+ var TooltipContent = React6.forwardRef(({ className, sideOffset = 4, ...props }, ref) => {
189
+ const portalContainer = usePortalContainer();
190
+ return (
191
+ // Portalled for the same reason as every other overlay here, plus one
192
+ // specific to the tooltip: the positioner measures against the nearest
193
+ // containing block, and it counts `container-type` as one while the
194
+ // browser does not. Left inline under a `@container` element, the content
195
+ // is offset by that element's own position. Portalling lifts it out of any
196
+ // such ancestor, so the two agree again.
197
+ /* @__PURE__ */ jsxRuntime.jsx(reactTooltip.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsx(
198
+ reactTooltip.Content,
199
+ {
200
+ ref,
201
+ sideOffset,
202
+ "data-slot": "tooltip-content",
203
+ className: cn(
204
+ "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",
205
+ className
206
+ ),
207
+ ...props
208
+ }
209
+ ) })
210
+ );
211
+ });
193
212
  TooltipContent.displayName = reactTooltip.Content.displayName;
194
213
  var FormLabelWithTooltip = React6__namespace.forwardRef(
195
214
  ({
@@ -244,9 +263,9 @@ var badgeVariants = classVarianceAuthority.cva(
244
263
  // which was nearly invisible on dark backgrounds).
245
264
  default: "bg-muted text-foreground",
246
265
  primary: "bg-primary/10 text-primary dark:bg-primary/20",
247
- success: "bg-green-100 text-green-700 dark:bg-green-900 dark:text-green-100",
248
- warning: "bg-amber-100 text-amber-700 dark:bg-amber-900 dark:text-amber-100",
249
- destructive: "bg-red-100 text-red-700 dark:bg-red-900 dark:text-red-100",
266
+ success: "bg-success-100 text-success-700 dark:bg-success-900 dark:text-success-100",
267
+ warning: "bg-warning-100 text-warning-700 dark:bg-warning-900 dark:text-warning-100",
268
+ destructive: "bg-destructive-100 text-destructive-700 dark:bg-destructive-900 dark:text-destructive-100",
250
269
  outline: "border border-border! bg-transparent text-foreground dark:text-muted-foreground dark:border-border!"
251
270
  }
252
271
  },
@@ -391,9 +410,9 @@ var alertVariants = classVarianceAuthority.cva(
391
410
  variants: {
392
411
  variant: {
393
412
  info: "border-border bg-primary/5 text-primary dark:border-primary/30 dark:bg-primary/5 dark:text-primary-foreground/90",
394
- 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",
395
- 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",
396
- 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"
413
+ 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",
414
+ 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",
415
+ 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"
397
416
  }
398
417
  },
399
418
  defaultVariants: {
@@ -489,7 +508,7 @@ var progressVariants = classVarianceAuthority.cva("h-full rounded-none transitio
489
508
  variants: {
490
509
  variant: {
491
510
  default: "bg-primary-500",
492
- success: "bg-green-500",
511
+ success: "bg-success-500",
493
512
  error: "bg-destructive"
494
513
  }
495
514
  },
@@ -543,11 +562,22 @@ var Checkbox = React6.forwardRef(({ className, indeterminate, ...props }, ref) =
543
562
  ref,
544
563
  "data-slot": "checkbox",
545
564
  className: cn(
546
- // Unchecked outline uses primary/40 (clearly visible, monochrome) instead of
547
- // primary/5, which rendered at ~5% opacity and was effectively invisible.
565
+ // Unchecked outline uses primary/50: measured 3.95:1 on the light row and
566
+ // 5.32:1 on the dark one. WCAG 1.4.11 asks 3:1 of a control's boundary and
567
+ // the earlier values did not reach it — primary/40 came out at 2.85, close
568
+ // enough to look deliberate and still short. Callers must not override the
569
+ // border: passing `border-border` puts the divider token here, which
570
+ // measured 1.35:1 and 1.14:1, and a divider is meant to go unnoticed.
548
571
  // Checked and indeterminate share the filled appearance; declaring both
549
572
  // here keeps the control self-sufficient without host overrides.
550
- "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",
573
+ //
574
+ // The box stays 16px and the target does not: `before` stretches an
575
+ // invisible 24px square from the centre, which is WCAG 2.5.8's floor.
576
+ // The exemption for a bare browser checkbox does not cover a styled one,
577
+ // and this is styled. Growing the box instead would make every dense
578
+ // table heavier for a rule about pointers, so the box and the thing you
579
+ // can hit are allowed to differ.
580
+ "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",
551
581
  className
552
582
  ),
553
583
  ...props,
@@ -788,14 +818,6 @@ var TabsContent = React6.forwardRef(
788
818
  )
789
819
  );
790
820
  TabsContent.displayName = reactTabs.Content.displayName;
791
- var PortalContext = React6.createContext({ container: null });
792
- function PortalProvider({ container, children }) {
793
- return /* @__PURE__ */ jsxRuntime.jsx(PortalContext.Provider, { value: { container }, children });
794
- }
795
- function usePortalContainer() {
796
- const { container } = React6.useContext(PortalContext);
797
- return container ?? void 0;
798
- }
799
821
  var Popover = PopoverPrimitive__namespace.Root;
800
822
  var PopoverTrigger = PopoverPrimitive__namespace.Trigger;
801
823
  var PopoverAnchor = PopoverPrimitive__namespace.Anchor;
@@ -1043,12 +1065,14 @@ var DropdownMenuGroup = DropdownMenuPrimitive__namespace.Group;
1043
1065
  var DropdownMenuPortal = DropdownMenuPrimitive__namespace.Portal;
1044
1066
  var DropdownMenuSub = DropdownMenuPrimitive__namespace.Sub;
1045
1067
  var DropdownMenuRadioGroup = DropdownMenuPrimitive__namespace.RadioGroup;
1068
+ var menuItemBase = "cursor-pointer transition-colors data-[highlighted]:bg-muted data-[highlighted]:text-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50";
1046
1069
  var DropdownMenuSubTrigger = React6__namespace.forwardRef(({ className, inset, children, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsxs(
1047
1070
  DropdownMenuPrimitive__namespace.SubTrigger,
1048
1071
  {
1049
1072
  ref,
1050
1073
  className: cn(
1051
- "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",
1074
+ "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",
1075
+ menuItemBase,
1052
1076
  inset && "pl-8",
1053
1077
  className
1054
1078
  ),
@@ -1093,7 +1117,8 @@ var DropdownMenuItem = React6__namespace.forwardRef(({ className, inset, ...prop
1093
1117
  {
1094
1118
  ref,
1095
1119
  className: cn(
1096
- "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",
1120
+ "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",
1121
+ menuItemBase,
1097
1122
  inset && "pl-8",
1098
1123
  className
1099
1124
  ),
@@ -1106,7 +1131,8 @@ var DropdownMenuCheckboxItem = React6__namespace.forwardRef(({ className, childr
1106
1131
  {
1107
1132
  ref,
1108
1133
  className: cn(
1109
- "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",
1134
+ "relative flex select-none items-center rounded-none py-1.5 pl-8 pr-2 text-sm outline-none",
1135
+ menuItemBase,
1110
1136
  className
1111
1137
  ),
1112
1138
  checked,
@@ -1123,7 +1149,8 @@ var DropdownMenuRadioItem = React6__namespace.forwardRef(({ className, children,
1123
1149
  {
1124
1150
  ref,
1125
1151
  className: cn(
1126
- "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",
1152
+ "relative flex select-none items-center rounded-none py-1.5 pl-8 pr-2 text-sm outline-none",
1153
+ menuItemBase,
1127
1154
  className
1128
1155
  ),
1129
1156
  ...props,
@@ -1185,9 +1212,9 @@ var selectTriggerVariants = classVarianceAuthority.cva(
1185
1212
  {
1186
1213
  variants: {
1187
1214
  size: {
1188
- sm: "h-[var(--control-height-sm)] text-sm",
1189
- default: "h-[var(--control-height)] text-sm",
1190
- lg: "h-[var(--control-height-lg)] text-base"
1215
+ sm: "h-[var(--nx-control-height-sm)] text-sm",
1216
+ default: "h-[var(--nx-control-height)] text-sm",
1217
+ lg: "h-[var(--nx-control-height-lg)] text-base"
1191
1218
  }
1192
1219
  },
1193
1220
  defaultVariants: {
@@ -1670,9 +1697,9 @@ function Toaster({ theme = "system", ...props }) {
1670
1697
  loading: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "h-4 w-4 animate-spin" })
1671
1698
  },
1672
1699
  style: {
1673
- "--normal-bg": "var(--popover)",
1674
- "--normal-text": "var(--popover-foreground)",
1675
- "--normal-border": "var(--border)",
1700
+ "--normal-bg": "var(--nx-popover)",
1701
+ "--normal-text": "var(--nx-popover-foreground)",
1702
+ "--normal-border": "var(--nx-border)",
1676
1703
  "--border-radius": "0px"
1677
1704
  },
1678
1705
  ...props
@@ -1820,213 +1847,6 @@ function TableEmpty({ message = "No records found" }) {
1820
1847
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-medium", children: message })
1821
1848
  ] });
1822
1849
  }
1823
- function renderPageNumbers(currentPage, totalPages, maxVisiblePages, onPageChange) {
1824
- 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"}`;
1825
- if (totalPages <= maxVisiblePages) {
1826
- return Array.from({ length: totalPages }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsx(
1827
- "button",
1828
- {
1829
- onClick: () => onPageChange(i),
1830
- "aria-label": `Go to page ${i + 1}`,
1831
- "aria-current": currentPage === i ? "page" : void 0,
1832
- className: getBtnClass(currentPage === i),
1833
- children: i + 1
1834
- },
1835
- `page-${i}`
1836
- ));
1837
- }
1838
- const pages = [];
1839
- const startPage = Math.max(0, currentPage - Math.floor(maxVisiblePages / 2));
1840
- const endPage = Math.min(totalPages - 1, startPage + maxVisiblePages - 1);
1841
- if (startPage > 0) {
1842
- pages.push(
1843
- /* @__PURE__ */ jsxRuntime.jsx(
1844
- "button",
1845
- {
1846
- onClick: () => onPageChange(0),
1847
- "aria-label": "Go to page 1",
1848
- className: getBtnClass(currentPage === 0),
1849
- children: "1"
1850
- },
1851
- "page-0"
1852
- )
1853
- );
1854
- if (startPage > 1) {
1855
- pages.push(
1856
- /* @__PURE__ */ jsxRuntime.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-start"
1864
- )
1865
- );
1866
- }
1867
- }
1868
- for (let i = startPage; i <= endPage; i++) {
1869
- pages.push(
1870
- /* @__PURE__ */ jsxRuntime.jsx(
1871
- "button",
1872
- {
1873
- onClick: () => onPageChange(i),
1874
- "aria-label": `Go to page ${i + 1}`,
1875
- "aria-current": currentPage === i ? "page" : void 0,
1876
- className: getBtnClass(currentPage === i),
1877
- children: i + 1
1878
- },
1879
- i
1880
- )
1881
- );
1882
- }
1883
- if (endPage < totalPages - 1) {
1884
- if (endPage < totalPages - 2) {
1885
- pages.push(
1886
- /* @__PURE__ */ jsxRuntime.jsx(
1887
- "span",
1888
- {
1889
- 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",
1890
- "aria-hidden": "true",
1891
- children: "..."
1892
- },
1893
- "ellipsis-end"
1894
- )
1895
- );
1896
- }
1897
- pages.push(
1898
- /* @__PURE__ */ jsxRuntime.jsx(
1899
- "button",
1900
- {
1901
- onClick: () => onPageChange(totalPages - 1),
1902
- "aria-label": `Go to page ${totalPages}`,
1903
- className: getBtnClass(currentPage === totalPages - 1),
1904
- children: totalPages
1905
- },
1906
- totalPages - 1
1907
- )
1908
- );
1909
- }
1910
- return pages;
1911
- }
1912
- function TablePagination({
1913
- meta,
1914
- onPageChange,
1915
- onPageSizeChange,
1916
- config,
1917
- isLoading = false
1918
- }) {
1919
- const {
1920
- showPageSizeSelector = true,
1921
- pageSizeOptions = [10, 20, 30, 50],
1922
- maxVisiblePages = 5
1923
- } = config || {};
1924
- const pageIndex = meta.page - 1;
1925
- return /* @__PURE__ */ jsxRuntime.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: [
1926
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "whitespace-nowrap order-2 sm:order-1", children: [
1927
- "Showing ",
1928
- (meta.page - 1) * meta.limit + 1,
1929
- "-",
1930
- Math.min(meta.page * meta.limit, meta.total),
1931
- " of ",
1932
- meta.total,
1933
- " entries"
1934
- ] }),
1935
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center justify-center gap-4 sm:gap-6 lg:gap-8 order-1 sm:order-2", children: [
1936
- showPageSizeSelector && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center space-x-2", children: [
1937
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "whitespace-nowrap hidden sm:inline-block", children: "Rows per page" }),
1938
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
1939
- /* @__PURE__ */ jsxRuntime.jsx(
1940
- "select",
1941
- {
1942
- id: "pageSize",
1943
- value: meta.limit,
1944
- onChange: (e) => {
1945
- const newPageSize = Number(e.target.value);
1946
- onPageSizeChange(newPageSize);
1947
- },
1948
- 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",
1949
- disabled: isLoading,
1950
- children: pageSizeOptions.map((size) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: size, children: size }, size))
1951
- }
1952
- ),
1953
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pointer-events-none absolute inset-y-0 right-0 flex items-center px-2 text-muted-foreground", children: /* @__PURE__ */ jsxRuntime.jsx(
1954
- "svg",
1955
- {
1956
- className: "h-3 w-3",
1957
- fill: "none",
1958
- viewBox: "0 0 24 24",
1959
- stroke: "currentColor",
1960
- children: /* @__PURE__ */ jsxRuntime.jsx(
1961
- "path",
1962
- {
1963
- strokeLinecap: "round",
1964
- strokeLinejoin: "round",
1965
- strokeWidth: 2,
1966
- d: "M19 9l-7 7-7-7"
1967
- }
1968
- )
1969
- }
1970
- ) })
1971
- ] })
1972
- ] }),
1973
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center -space-x-px", children: [
1974
- /* @__PURE__ */ jsxRuntime.jsx(
1975
- "button",
1976
- {
1977
- onClick: () => onPageChange(0),
1978
- disabled: pageIndex === 0 || isLoading,
1979
- 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",
1980
- "aria-label": "First page",
1981
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronsLeft, { className: "h-4 w-4" })
1982
- }
1983
- ),
1984
- /* @__PURE__ */ jsxRuntime.jsx(
1985
- "button",
1986
- {
1987
- onClick: () => onPageChange(pageIndex - 1),
1988
- disabled: pageIndex === 0 || isLoading,
1989
- 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",
1990
- "aria-label": "Previous page",
1991
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronLeft, { className: "h-4 w-4" })
1992
- }
1993
- ),
1994
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex", children: renderPageNumbers(
1995
- pageIndex,
1996
- meta.totalPages,
1997
- maxVisiblePages,
1998
- onPageChange
1999
- ) }),
2000
- /* @__PURE__ */ jsxRuntime.jsx(
2001
- "button",
2002
- {
2003
- onClick: () => onPageChange(pageIndex + 1),
2004
- disabled: pageIndex >= meta.totalPages - 1 || isLoading,
2005
- 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",
2006
- "aria-label": "Next page",
2007
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { className: "h-4 w-4" })
2008
- }
2009
- ),
2010
- /* @__PURE__ */ jsxRuntime.jsx(
2011
- "button",
2012
- {
2013
- onClick: () => onPageChange(meta.totalPages - 1),
2014
- disabled: pageIndex >= meta.totalPages - 1 || isLoading,
2015
- 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",
2016
- "aria-label": "Last page",
2017
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronsRight, { className: "h-4 w-4" })
2018
- }
2019
- )
2020
- ] }),
2021
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "whitespace-nowrap hidden sm:block", children: [
2022
- "Page ",
2023
- meta.page,
2024
- " of ",
2025
- meta.totalPages
2026
- ] })
2027
- ] })
2028
- ] });
2029
- }
2030
1850
  var GrayBar = ({ className }) => /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className });
2031
1851
  var TableSkeleton = ({
2032
1852
  columns = 5,
@@ -2069,219 +1889,52 @@ var TableSkeleton = ({
2069
1889
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "table-wrapper rounded-none border border-border bg-card overflow-hidden", children: content });
2070
1890
  };
2071
1891
  TableSkeleton.displayName = "TableSkeleton";
2072
- function ResponsiveTableInner({
2073
- data,
2074
- columns,
2075
- onRowClick,
2076
- renderMobileCard,
2077
- className,
2078
- emptyMessage = "No results found.",
2079
- ariaLabel,
2080
- tableWrapperClassName,
2081
- footer
2082
- }, ref) {
2083
- const visibleMobileColumns = React6__namespace.useMemo(
2084
- () => columns.filter((col) => !col.hideOnMobile),
2085
- [columns]
2086
- );
2087
- const primaryColumn = React6__namespace.useMemo(() => {
2088
- return visibleMobileColumns.find(
2089
- (col) => col.key !== "select" && col.key !== "actions"
2090
- ) || visibleMobileColumns[0];
2091
- }, [visibleMobileColumns]);
2092
- const secondaryColumns = React6__namespace.useMemo(
2093
- () => visibleMobileColumns.filter((col) => col.key !== primaryColumn?.key),
2094
- [visibleMobileColumns, primaryColumn]
2095
- );
2096
- React6__namespace.useEffect(() => {
2097
- const isDev = typeof globalThis !== "undefined" && globalThis.process && globalThis.process.env?.NODE_ENV === "development";
2098
- if (isDev && visibleMobileColumns.length === 0) {
2099
- console.warn(
2100
- "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."
2101
- );
2102
- }
2103
- }, [visibleMobileColumns.length]);
2104
- const handleItemClick = React6__namespace.useCallback(
2105
- (item, e) => {
2106
- if (!onRowClick) return;
2107
- if (e) {
2108
- const target = e.target;
2109
- if (target.closest('[role="checkbox"]') || target.closest("button") || target.closest("a") || target.closest('[role^="menuitem"]') || target.closest("[data-actions]")) {
2110
- return;
2111
- }
2112
- }
2113
- onRowClick(item);
2114
- },
2115
- [onRowClick]
2116
- );
2117
- const handleCardKeyDown = React6__namespace.useCallback(
2118
- (item) => (e) => {
2119
- if (onRowClick && (e.key === "Enter" || e.key === " ")) {
2120
- e.preventDefault();
2121
- handleItemClick(item, e);
2122
- }
2123
- },
2124
- [handleItemClick, onRowClick]
2125
- );
2126
- if (data.length === 0) {
2127
- return /* @__PURE__ */ jsxRuntime.jsx("div", { ref, className: cn("p-8 text-center", className), children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground", children: emptyMessage }) });
2128
- }
2129
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref, className: cn("w-full", className), children: [
2130
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-4 md:hidden", children: data.map((item) => {
2131
- const primaryValue = primaryColumn ? String(item[primaryColumn.key]) : String(item.id);
2132
- if (renderMobileCard) {
2133
- return /* @__PURE__ */ jsxRuntime.jsx(
2134
- "div",
2135
- {
2136
- onClick: (e) => handleItemClick(item, e),
2137
- role: onRowClick ? "button" : void 0,
2138
- tabIndex: onRowClick ? 0 : void 0,
2139
- onKeyDown: onRowClick ? handleCardKeyDown(item) : void 0,
2140
- className: onRowClick ? "cursor-pointer" : void 0,
2141
- "aria-label": onRowClick ? `View details for ${primaryValue}` : void 0,
2142
- children: renderMobileCard(item, visibleMobileColumns)
2143
- },
2144
- item.id
2145
- );
2146
- }
2147
- return /* @__PURE__ */ jsxRuntime.jsxs(
2148
- Card,
2149
- {
2150
- variant: onRowClick ? "interactive" : "default",
2151
- className: cn(
2152
- onRowClick && "cursor-pointer",
2153
- "transition-all duration-150"
2154
- ),
2155
- onClick: (e) => handleItemClick(item, e),
2156
- role: onRowClick ? "button" : void 0,
2157
- tabIndex: onRowClick ? 0 : void 0,
2158
- onKeyDown: onRowClick ? handleCardKeyDown(item) : void 0,
2159
- "aria-label": onRowClick ? `View details for ${primaryValue}` : void 0,
2160
- children: [
2161
- primaryColumn ? /* @__PURE__ */ jsxRuntime.jsx(CardHeader, { className: "pb-3", children: /* @__PURE__ */ jsxRuntime.jsx(CardTitle, { className: "text-base", children: primaryColumn.render ? primaryColumn.render(item[primaryColumn.key], item) : String(item[primaryColumn.key]) }) }) : null,
2162
- secondaryColumns.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(CardContent, { className: "pb-3", children: /* @__PURE__ */ jsxRuntime.jsx("dl", { className: "flex flex-col gap-2", children: secondaryColumns.map((column) => /* @__PURE__ */ jsxRuntime.jsxs(
2163
- "div",
2164
- {
2165
- className: "flex items-start justify-between gap-4 text-sm",
2166
- children: [
2167
- !column.hideLabelOnMobile && /* @__PURE__ */ jsxRuntime.jsxs("dt", { className: "text-muted-foreground min-w-[80px] shrink-0", children: [
2168
- column.label,
2169
- ":"
2170
- ] }),
2171
- /* @__PURE__ */ jsxRuntime.jsx(
2172
- "dd",
2173
- {
2174
- className: cn(
2175
- "font-medium flex-1",
2176
- !column.hideLabelOnMobile ? "text-right" : "text-left"
2177
- ),
2178
- children: column.render ? column.render(item[column.key], item) : String(item[column.key])
2179
- }
2180
- )
2181
- ]
2182
- },
2183
- String(column.key)
2184
- )) }) })
2185
- ]
2186
- },
2187
- item.id
2188
- );
2189
- }) }),
2190
- /* @__PURE__ */ jsxRuntime.jsx(
2191
- "div",
2192
- {
2193
- className: cn(
2194
- "table-wrapper hidden md:block overflow-hidden rounded-none border border-border",
2195
- tableWrapperClassName
2196
- ),
2197
- children: /* @__PURE__ */ jsxRuntime.jsxs(Table, { "aria-label": ariaLabel || "Data table", children: [
2198
- /* @__PURE__ */ jsxRuntime.jsx(TableHeader, { className: "bg-[var(--table-header-bg)]", children: /* @__PURE__ */ jsxRuntime.jsx(TableRow, { children: columns.map((column) => /* @__PURE__ */ jsxRuntime.jsx(
2199
- TableHead,
2200
- {
2201
- className: column.headerClassName,
2202
- children: column.label
2203
- },
2204
- String(column.key)
2205
- )) }) }),
2206
- /* @__PURE__ */ jsxRuntime.jsx(TableBody, { children: data.map((item) => {
2207
- const primaryValue = primaryColumn ? String(item[primaryColumn.key]) : String(item.id);
2208
- return /* @__PURE__ */ jsxRuntime.jsx(
2209
- TableRow,
2210
- {
2211
- className: cn(
2212
- "hover-unified-table-row",
2213
- onRowClick && "cursor-pointer"
2214
- ),
2215
- onClick: (e) => handleItemClick(item, e),
2216
- role: onRowClick ? "button" : void 0,
2217
- tabIndex: onRowClick ? 0 : void 0,
2218
- onKeyDown: onRowClick ? handleCardKeyDown(item) : void 0,
2219
- "aria-label": onRowClick ? `View details for ${primaryValue}` : void 0,
2220
- children: columns.map((column) => /* @__PURE__ */ jsxRuntime.jsx(
2221
- TableCell,
2222
- {
2223
- className: column.cellClassName,
2224
- children: column.render ? column.render(item[column.key], item) : String(item[column.key])
2225
- },
2226
- String(column.key)
2227
- ))
2228
- },
2229
- item.id
2230
- );
2231
- }) })
2232
- ] })
2233
- }
2234
- ),
2235
- footer && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "table-footer border-t border-border bg-[var(--table-header-bg)]", children: footer })
2236
- ] });
2237
- }
2238
- var ResponsiveTable = React6__namespace.forwardRef(ResponsiveTableInner);
2239
1892
 
2240
1893
  // src/tailwind-preset.ts
2241
1894
  var uiPreset = {
2242
1895
  theme: {
2243
1896
  extend: {
2244
1897
  colors: {
2245
- border: "var(--border)",
2246
- input: "var(--input)",
2247
- ring: "var(--ring)",
2248
- background: "var(--background)",
2249
- foreground: "var(--foreground)",
1898
+ border: "var(--nx-border)",
1899
+ input: "var(--nx-input)",
1900
+ ring: "var(--nx-ring)",
1901
+ background: "var(--nx-background)",
1902
+ foreground: "var(--nx-foreground)",
2250
1903
  primary: {
2251
- DEFAULT: "var(--primary)",
2252
- foreground: "var(--primary-foreground)"
1904
+ DEFAULT: "var(--nx-primary)",
1905
+ foreground: "var(--nx-primary-foreground)"
2253
1906
  },
2254
1907
  secondary: {
2255
- DEFAULT: "var(--secondary)",
2256
- foreground: "var(--secondary-foreground)"
1908
+ DEFAULT: "var(--nx-secondary)",
1909
+ foreground: "var(--nx-secondary-foreground)"
2257
1910
  },
2258
1911
  destructive: {
2259
- DEFAULT: "var(--destructive)",
2260
- foreground: "var(--destructive-foreground)"
1912
+ DEFAULT: "var(--nx-destructive)",
1913
+ foreground: "var(--nx-destructive-foreground)"
2261
1914
  },
2262
1915
  success: {
2263
- DEFAULT: "var(--success)",
2264
- foreground: "var(--success-foreground)"
1916
+ DEFAULT: "var(--nx-success)",
1917
+ foreground: "var(--nx-success-foreground)"
2265
1918
  },
2266
1919
  warning: {
2267
- DEFAULT: "var(--warning)",
2268
- foreground: "var(--warning-foreground)"
1920
+ DEFAULT: "var(--nx-warning)",
1921
+ foreground: "var(--nx-warning-foreground)"
2269
1922
  },
2270
1923
  muted: {
2271
- DEFAULT: "var(--muted)",
2272
- foreground: "var(--muted-foreground)"
1924
+ DEFAULT: "var(--nx-muted)",
1925
+ foreground: "var(--nx-muted-foreground)"
2273
1926
  },
2274
1927
  accent: {
2275
- DEFAULT: "var(--accent)",
2276
- foreground: "var(--accent-foreground)"
1928
+ DEFAULT: "var(--nx-accent)",
1929
+ foreground: "var(--nx-accent-foreground)"
2277
1930
  },
2278
1931
  popover: {
2279
- DEFAULT: "var(--popover)",
2280
- foreground: "var(--popover-foreground)"
1932
+ DEFAULT: "var(--nx-popover)",
1933
+ foreground: "var(--nx-popover-foreground)"
2281
1934
  },
2282
1935
  card: {
2283
- DEFAULT: "var(--card)",
2284
- foreground: "var(--card-foreground)"
1936
+ DEFAULT: "var(--nx-card)",
1937
+ foreground: "var(--nx-card-foreground)"
2285
1938
  }
2286
1939
  },
2287
1940
  borderRadius: {
@@ -2391,7 +2044,6 @@ exports.PortalProvider = PortalProvider;
2391
2044
  exports.Progress = Progress;
2392
2045
  exports.RadioGroup = RadioGroup;
2393
2046
  exports.RadioGroupItem = RadioGroupItem;
2394
- exports.ResponsiveTable = ResponsiveTable;
2395
2047
  exports.Select = Select;
2396
2048
  exports.SelectContent = SelectContent;
2397
2049
  exports.SelectGroup = SelectGroup;
@@ -2426,7 +2078,6 @@ exports.TableFooter = TableFooter;
2426
2078
  exports.TableHead = TableHead;
2427
2079
  exports.TableHeader = TableHeader;
2428
2080
  exports.TableLoading = TableLoading;
2429
- exports.TablePagination = TablePagination;
2430
2081
  exports.TableRow = TableRow;
2431
2082
  exports.TableSearch = TableSearch;
2432
2083
  exports.TableSkeleton = TableSkeleton;