@inf-monkeys-tech/monkeys-design 0.4.32 → 0.4.33

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.
@@ -1,6 +1,7 @@
1
- import { forwardRef, useRef, useState, useEffect, useId, useMemo, createContext, useLayoutEffect, Children, isValidElement, useCallback, useContext } from 'react';
1
+ import { forwardRef, useRef, useState, useEffect, useId, useMemo, createContext, useContext, useLayoutEffect, Children, isValidElement, useCallback } from 'react';
2
2
  import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
3
- import '@radix-ui/react-context-menu';
3
+ import * as ContextMenu from '@radix-ui/react-context-menu';
4
+ import { useSensors, useSensor, PointerSensor, DndContext, DragOverlay, useDroppable, useDraggable } from '@dnd-kit/core';
4
5
 
5
6
  // src/components/workbench/WorkbenchResizableSidebar.tsx
6
7
 
@@ -707,7 +708,41 @@ var baseSlots = {
707
708
  tableEmptyActions: "mt-4 flex flex-wrap items-center justify-center gap-2",
708
709
  tableLoadingRow: "border-b border-border/60",
709
710
  tableLoadingCell: "px-3 py-2",
710
- tableLoadingSkeleton: "h-4 w-full rounded-md bg-muted/70"
711
+ tableLoadingSkeleton: "h-4 w-full rounded-md bg-muted/70",
712
+ layoutRoot: cn(
713
+ "grid min-w-0 overflow-hidden grid-rows-[auto_minmax(0,1fr)_auto] gap-3 rounded-lg border border-border/70 bg-background p-3 text-foreground",
714
+ motionBase
715
+ ),
716
+ layoutRootFull: "h-full min-h-0",
717
+ layoutHeader: "min-w-0",
718
+ layoutBody: "grid min-h-0 min-w-0 overflow-hidden gap-3",
719
+ layoutSidebar: "min-h-0 min-w-0 overflow-hidden",
720
+ layoutMain: "min-h-0 min-w-0 overflow-hidden",
721
+ layoutAside: "min-h-0 min-w-0 overflow-hidden",
722
+ layoutFooter: "min-w-0",
723
+ layoutPane: cn(
724
+ "h-full max-h-full min-h-0 min-w-0 overflow-hidden rounded-lg bg-background text-foreground",
725
+ motionBase
726
+ ),
727
+ layoutPaneScrollable: "overflow-auto",
728
+ layoutPaneBordered: "border border-border/70",
729
+ layoutPaneMuted: "bg-muted/25",
730
+ layoutPaneSoft: "bg-background/95 shadow-sm",
731
+ layoutPaneTransparent: "bg-transparent shadow-none",
732
+ layoutSplitRoot: "grid min-h-0 min-w-0 overflow-hidden",
733
+ layoutSplitHorizontal: "grid-flow-col",
734
+ layoutSplitVertical: "grid-flow-row",
735
+ layoutSplitPane: "min-h-0 min-w-0 overflow-hidden",
736
+ layoutSplitPrimary: "",
737
+ layoutSplitSecondary: "",
738
+ layoutResizeHandle: cn(
739
+ "group/resize relative z-10 flex shrink-0 items-center justify-center bg-transparent text-muted-foreground hover:bg-border/60 active:bg-border/70 focus-visible:bg-border/60 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/30",
740
+ motionInteractive
741
+ ),
742
+ layoutResizeHandleHorizontal: "w-2 cursor-col-resize",
743
+ layoutResizeHandleVertical: "h-2 cursor-row-resize",
744
+ layoutResizeHandleDisabled: "cursor-default opacity-60",
745
+ layoutResizeHandleIndicator: "rounded-full bg-muted-foreground/45 group-hover/resize:bg-primary/70"
711
746
  };
712
747
  var densitySlots = {
713
748
  compact: {
@@ -781,7 +816,12 @@ var densitySlots = {
781
816
  tableCell: "px-2 py-1.5 text-xs",
782
817
  tableHeadLabel: "text-[11px]",
783
818
  tableHeadDescription: "text-[10px] leading-3",
784
- tableLoadingCell: "px-2 py-1.5"
819
+ tableLoadingCell: "px-2 py-1.5",
820
+ layoutRoot: "gap-2 p-2",
821
+ layoutBody: "gap-2",
822
+ layoutPane: "rounded-md text-xs",
823
+ layoutResizeHandleHorizontal: "w-1.5",
824
+ layoutResizeHandleVertical: "h-1.5"
785
825
  },
786
826
  default: {
787
827
  buttonBase: "h-9"
@@ -832,7 +872,12 @@ var densitySlots = {
832
872
  menuSubTrigger: "min-h-9 px-3 py-2",
833
873
  tableHead: "h-12 px-4 py-3",
834
874
  tableCell: "px-4 py-3",
835
- tableLoadingCell: "px-4 py-3"
875
+ tableLoadingCell: "px-4 py-3",
876
+ layoutRoot: "gap-4 p-4",
877
+ layoutBody: "gap-4",
878
+ layoutPane: "rounded-xl",
879
+ layoutResizeHandleHorizontal: "w-2.5",
880
+ layoutResizeHandleVertical: "h-2.5"
836
881
  }
837
882
  };
838
883
  var radiusSlots = {
@@ -876,7 +921,9 @@ var radiusSlots = {
876
921
  menuSubContent: "rounded-none",
877
922
  tableContainer: "rounded-none",
878
923
  tableEmptyIcon: "rounded-none",
879
- tableLoadingSkeleton: "rounded-none"
924
+ tableLoadingSkeleton: "rounded-none",
925
+ layoutRoot: "rounded-none",
926
+ layoutPane: "rounded-none"
880
927
  },
881
928
  sm: {
882
929
  buttonBase: "rounded-sm",
@@ -918,7 +965,9 @@ var radiusSlots = {
918
965
  menuSubContent: "rounded-sm",
919
966
  tableContainer: "rounded-sm",
920
967
  tableEmptyIcon: "rounded-sm",
921
- tableLoadingSkeleton: "rounded-sm"
968
+ tableLoadingSkeleton: "rounded-sm",
969
+ layoutRoot: "rounded-sm",
970
+ layoutPane: "rounded-sm"
922
971
  },
923
972
  md: {},
924
973
  lg: {
@@ -955,7 +1004,9 @@ var radiusSlots = {
955
1004
  menuSubContent: "rounded-lg",
956
1005
  tableContainer: "rounded-xl",
957
1006
  tableEmptyIcon: "rounded-xl",
958
- tableLoadingSkeleton: "rounded-lg"
1007
+ tableLoadingSkeleton: "rounded-lg",
1008
+ layoutRoot: "rounded-xl",
1009
+ layoutPane: "rounded-xl"
959
1010
  },
960
1011
  xl: {
961
1012
  buttonBase: "rounded-xl",
@@ -993,7 +1044,9 @@ var radiusSlots = {
993
1044
  menuSubContent: "rounded-xl",
994
1045
  tableContainer: "rounded-2xl",
995
1046
  tableEmptyIcon: "rounded-2xl",
996
- tableLoadingSkeleton: "rounded-xl"
1047
+ tableLoadingSkeleton: "rounded-xl",
1048
+ layoutRoot: "rounded-2xl",
1049
+ layoutPane: "rounded-2xl"
997
1050
  },
998
1051
  full: {
999
1052
  buttonBase: "rounded-full",
@@ -1035,7 +1088,9 @@ var radiusSlots = {
1035
1088
  menuSubContent: "rounded-2xl",
1036
1089
  tableContainer: "rounded-2xl",
1037
1090
  tableEmptyIcon: "rounded-full",
1038
- tableLoadingSkeleton: "rounded-full"
1091
+ tableLoadingSkeleton: "rounded-full",
1092
+ layoutRoot: "rounded-2xl",
1093
+ layoutPane: "rounded-2xl"
1039
1094
  }
1040
1095
  };
1041
1096
  var borderSlots = {
@@ -1077,7 +1132,10 @@ var borderSlots = {
1077
1132
  tableFooterBarAttached: "border-t border-transparent",
1078
1133
  tableRow: "border-transparent",
1079
1134
  tableEmptyRow: "border-transparent",
1080
- tableLoadingRow: "border-transparent"
1135
+ tableLoadingRow: "border-transparent",
1136
+ layoutRoot: "border-transparent",
1137
+ layoutPaneBordered: "border-transparent",
1138
+ layoutResizeHandle: "bg-transparent hover:bg-transparent active:bg-transparent focus-visible:bg-transparent"
1081
1139
  },
1082
1140
  subtle: {
1083
1141
  buttonDefault: "border-border/60",
@@ -1117,7 +1175,9 @@ var borderSlots = {
1117
1175
  tableFooterBarAttached: "border-t border-border/60",
1118
1176
  tableRow: "border-border/50",
1119
1177
  tableEmptyRow: "border-border/50",
1120
- tableLoadingRow: "border-border/50"
1178
+ tableLoadingRow: "border-border/50",
1179
+ layoutRoot: "border-border/60",
1180
+ layoutPaneBordered: "border-border/60"
1121
1181
  },
1122
1182
  solid: {},
1123
1183
  strong: {
@@ -1158,7 +1218,10 @@ var borderSlots = {
1158
1218
  tableFooterBarAttached: "border-t border-foreground/20",
1159
1219
  tableRow: "border-foreground/15",
1160
1220
  tableEmptyRow: "border-foreground/15",
1161
- tableLoadingRow: "border-foreground/15"
1221
+ tableLoadingRow: "border-foreground/15",
1222
+ layoutRoot: "border-foreground/20",
1223
+ layoutPaneBordered: "border-foreground/20",
1224
+ layoutResizeHandle: "hover:bg-foreground/15 active:bg-foreground/20 focus-visible:bg-foreground/15"
1162
1225
  }
1163
1226
  };
1164
1227
  var backgroundSlots = {
@@ -1200,7 +1263,11 @@ var backgroundSlots = {
1200
1263
  tableFooter: "bg-muted/35",
1201
1264
  tableFooterBar: "bg-muted/30 shadow-none",
1202
1265
  tableRowInteractive: "cursor-pointer hover:bg-muted/45",
1203
- tableLoadingSkeleton: "bg-muted"
1266
+ tableLoadingSkeleton: "bg-muted",
1267
+ layoutRoot: "bg-card",
1268
+ layoutPane: "bg-card",
1269
+ layoutPaneMuted: "bg-muted/35",
1270
+ layoutResizeHandle: "hover:bg-border/70 active:bg-border/80 focus-visible:bg-border/70"
1204
1271
  },
1205
1272
  soft: {
1206
1273
  buttonDefault: "bg-muted/30 hover:bg-muted/55",
@@ -1236,7 +1303,10 @@ var backgroundSlots = {
1236
1303
  tableFooter: "bg-muted/25",
1237
1304
  tableFooterBar: "bg-muted/25 shadow-none",
1238
1305
  tableRowInteractive: "cursor-pointer hover:bg-muted/35",
1239
- tableLoadingSkeleton: "bg-muted/65"
1306
+ tableLoadingSkeleton: "bg-muted/65",
1307
+ layoutRoot: "bg-background/95 shadow-sm",
1308
+ layoutPane: "bg-background/95 shadow-sm",
1309
+ layoutPaneSoft: "bg-background/95 shadow-md"
1240
1310
  },
1241
1311
  glass: {
1242
1312
  buttonBase: "backdrop-blur-md",
@@ -1297,7 +1367,13 @@ var backgroundSlots = {
1297
1367
  tableRow: "border-white/10",
1298
1368
  tableRowInteractive: "cursor-pointer hover:bg-white/[0.08]",
1299
1369
  tableHeadLabel: "text-foreground",
1300
- tableLoadingSkeleton: "bg-white/[0.16]"
1370
+ tableLoadingSkeleton: "bg-white/[0.16]",
1371
+ layoutRoot: "border-white/10 bg-white/[0.05] shadow-none backdrop-blur-md",
1372
+ layoutPane: "border-white/10 bg-white/[0.06] shadow-none backdrop-blur-md",
1373
+ layoutPaneMuted: "bg-white/[0.08]",
1374
+ layoutPaneSoft: "bg-white/[0.10] shadow-none backdrop-blur-md",
1375
+ layoutResizeHandle: "text-foreground/65 hover:bg-white/10 active:bg-white/15 focus-visible:bg-white/10",
1376
+ layoutResizeHandleIndicator: "bg-white/45 group-hover/resize:bg-white/75"
1301
1377
  },
1302
1378
  dark: {
1303
1379
  buttonBase: "border-white/15 text-white shadow-lg backdrop-blur",
@@ -1426,7 +1502,13 @@ var backgroundSlots = {
1426
1502
  menuSubTrigger: "text-white focus:bg-white/[0.10] focus:text-white data-[highlighted]:bg-white/[0.10] data-[highlighted]:text-white data-[state=open]:bg-white/[0.12]",
1427
1503
  menuSubTriggerIcon: "text-white/55",
1428
1504
  menuSubContent: "border-white/10 bg-slate-950 text-white shadow-2xl",
1429
- tableLoadingSkeleton: "bg-white/[0.14]"
1505
+ tableLoadingSkeleton: "bg-white/[0.14]",
1506
+ layoutRoot: "border-white/10 bg-slate-950 text-white shadow-none",
1507
+ layoutPane: "border-white/10 bg-slate-950 text-white shadow-none",
1508
+ layoutPaneMuted: "bg-white/[0.06]",
1509
+ layoutPaneSoft: "bg-white/[0.08] shadow-none",
1510
+ layoutResizeHandle: "text-white/65 hover:bg-white/10 active:bg-white/15 focus-visible:bg-white/10",
1511
+ layoutResizeHandleIndicator: "bg-white/45 group-hover/resize:bg-white/75"
1430
1512
  }
1431
1513
  };
1432
1514
  var presetDefaults = {
@@ -1579,6 +1661,16 @@ function getBaseButtonToneClassName(theme, tone = "default", active = false) {
1579
1661
  active && theme.slots.buttonActive
1580
1662
  );
1581
1663
  }
1664
+ function getBaseMenuItemToneClassName(theme, tone = "default") {
1665
+ return cn(
1666
+ tone === "default" && theme.slots.menuItemDefault,
1667
+ tone === "primary" && theme.slots.menuItemPrimary,
1668
+ tone === "success" && theme.slots.menuItemSuccess,
1669
+ tone === "warning" && theme.slots.menuItemWarning,
1670
+ tone === "danger" && theme.slots.menuItemDanger,
1671
+ tone === "muted" && theme.slots.menuItemMuted
1672
+ );
1673
+ }
1582
1674
  function LoadingIcon() {
1583
1675
  return /* @__PURE__ */ jsxs(
1584
1676
  "svg",
@@ -1799,6 +1891,198 @@ var BaseCheckbox = forwardRef(
1799
1891
  );
1800
1892
  }
1801
1893
  );
1894
+ function renderItemContent({
1895
+ label,
1896
+ icon,
1897
+ shortcut,
1898
+ children,
1899
+ classNames,
1900
+ inset,
1901
+ indicator
1902
+ }) {
1903
+ const resolvedLabel = children ?? label;
1904
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
1905
+ indicator ? indicator : null,
1906
+ hasRenderableNode(icon) ? /* @__PURE__ */ jsx("span", { className: cn(classNames?.icon), children: icon }) : inset ? /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "h-4 w-4 shrink-0" }) : null,
1907
+ hasRenderableNode(resolvedLabel) ? /* @__PURE__ */ jsx("span", { className: cn(classNames?.label), children: resolvedLabel }) : null,
1908
+ hasRenderableNode(shortcut) ? /* @__PURE__ */ jsx("span", { className: cn(classNames?.shortcut), children: shortcut }) : null
1909
+ ] });
1910
+ }
1911
+ function BaseContextMenu({
1912
+ children,
1913
+ trigger,
1914
+ content,
1915
+ disabled = false,
1916
+ modal = true,
1917
+ dir,
1918
+ appearance,
1919
+ className,
1920
+ classNames,
1921
+ onOpenChange
1922
+ }) {
1923
+ const theme = resolveBaseAppearance(appearance);
1924
+ return /* @__PURE__ */ jsxs(
1925
+ ContextMenu.Root,
1926
+ {
1927
+ onOpenChange,
1928
+ modal,
1929
+ dir,
1930
+ children: [
1931
+ trigger ? /* @__PURE__ */ jsx(
1932
+ ContextMenu.Trigger,
1933
+ {
1934
+ disabled,
1935
+ className: cn(
1936
+ theme.slots.menuTrigger,
1937
+ disabled && theme.slots.menuItemDisabled,
1938
+ classNames?.trigger,
1939
+ className
1940
+ ),
1941
+ children: trigger
1942
+ }
1943
+ ) : null,
1944
+ content ? /* @__PURE__ */ jsx(BaseContextMenuContent, { appearance, className: classNames?.content, children: content }) : null,
1945
+ children
1946
+ ]
1947
+ }
1948
+ );
1949
+ }
1950
+ function BaseContextMenuTrigger({
1951
+ children,
1952
+ disabled = false,
1953
+ asChild = false,
1954
+ appearance,
1955
+ className,
1956
+ style,
1957
+ ...triggerProps
1958
+ }) {
1959
+ const theme = resolveBaseAppearance(appearance);
1960
+ return /* @__PURE__ */ jsx(
1961
+ ContextMenu.Trigger,
1962
+ {
1963
+ ...triggerProps,
1964
+ asChild,
1965
+ disabled,
1966
+ className: cn(
1967
+ !asChild && theme.slots.menuTrigger,
1968
+ disabled && !asChild && theme.slots.menuItemDisabled,
1969
+ className
1970
+ ),
1971
+ style,
1972
+ children
1973
+ }
1974
+ );
1975
+ }
1976
+ function BaseContextMenuContent({
1977
+ children,
1978
+ appearance,
1979
+ className,
1980
+ classNames,
1981
+ style,
1982
+ ...contentProps
1983
+ }) {
1984
+ const theme = resolveBaseAppearance(appearance);
1985
+ return /* @__PURE__ */ jsx(ContextMenu.Portal, { children: /* @__PURE__ */ jsx(
1986
+ ContextMenu.Content,
1987
+ {
1988
+ ...contentProps,
1989
+ className: cn(theme.slots.menuContent, classNames?.root, className),
1990
+ style: {
1991
+ ...theme.styles.menuContent,
1992
+ ...style
1993
+ },
1994
+ children
1995
+ }
1996
+ ) });
1997
+ }
1998
+ function BaseContextMenuLabel({
1999
+ children,
2000
+ appearance,
2001
+ className,
2002
+ style,
2003
+ ...labelProps
2004
+ }) {
2005
+ const theme = resolveBaseAppearance(appearance);
2006
+ return /* @__PURE__ */ jsx(
2007
+ ContextMenu.Label,
2008
+ {
2009
+ ...labelProps,
2010
+ className: cn(theme.slots.menuLabel, className),
2011
+ style,
2012
+ children
2013
+ }
2014
+ );
2015
+ }
2016
+ function BaseContextMenuSeparator({
2017
+ appearance,
2018
+ className,
2019
+ style,
2020
+ ...separatorProps
2021
+ }) {
2022
+ const theme = resolveBaseAppearance(appearance);
2023
+ return /* @__PURE__ */ jsx(
2024
+ ContextMenu.Separator,
2025
+ {
2026
+ ...separatorProps,
2027
+ className: cn(theme.slots.menuSeparator, className),
2028
+ style
2029
+ }
2030
+ );
2031
+ }
2032
+ function BaseContextMenuItem({
2033
+ children,
2034
+ label,
2035
+ icon,
2036
+ shortcut,
2037
+ tone,
2038
+ disabled = false,
2039
+ inset = false,
2040
+ appearance,
2041
+ className,
2042
+ classNames,
2043
+ style,
2044
+ onSelect,
2045
+ ...itemProps
2046
+ }) {
2047
+ const theme = resolveBaseAppearance(appearance);
2048
+ return /* @__PURE__ */ jsx(
2049
+ ContextMenu.Item,
2050
+ {
2051
+ ...itemProps,
2052
+ disabled,
2053
+ className: cn(
2054
+ theme.slots.menuItem,
2055
+ getBaseMenuItemToneClassName(theme, tone),
2056
+ disabled && theme.slots.menuItemDisabled,
2057
+ classNames?.root,
2058
+ className
2059
+ ),
2060
+ style: {
2061
+ ...theme.styles.menuItem,
2062
+ ...style
2063
+ },
2064
+ onSelect: (event) => {
2065
+ if (disabled) {
2066
+ event.preventDefault();
2067
+ return;
2068
+ }
2069
+ onSelect?.(event);
2070
+ },
2071
+ children: renderItemContent({
2072
+ children,
2073
+ label,
2074
+ icon,
2075
+ shortcut,
2076
+ inset,
2077
+ classNames: {
2078
+ icon: cn(theme.slots.menuItemIcon, classNames?.icon),
2079
+ label: cn(theme.slots.menuItemLabel, classNames?.label),
2080
+ shortcut: cn(theme.slots.menuItemShortcut, classNames?.shortcut)
2081
+ }
2082
+ })
2083
+ }
2084
+ );
2085
+ }
1802
2086
  var columnClassNames = {
1803
2087
  1: "grid-cols-1",
1804
2088
  2: "md:grid-cols-2",
@@ -2697,7 +2981,7 @@ function BaseTableRow({
2697
2981
  }
2698
2982
  );
2699
2983
  }
2700
- function BaseTableHead({
2984
+ var BaseTableHead = forwardRef(function BaseTableHead2({
2701
2985
  columnId,
2702
2986
  align = "left",
2703
2987
  icon,
@@ -2725,10 +3009,18 @@ function BaseTableHead({
2725
3009
  onDragOver,
2726
3010
  onDrop,
2727
3011
  ...headProps
2728
- }) {
3012
+ }, forwardedRef) {
2729
3013
  const tableContext = useBaseTableContext(appearance);
2730
3014
  const { theme } = tableContext;
2731
3015
  const headRef = useRef(null);
3016
+ const setHeadRef = (node) => {
3017
+ headRef.current = node;
3018
+ if (typeof forwardedRef === "function") {
3019
+ forwardedRef(node);
3020
+ } else if (forwardedRef) {
3021
+ forwardedRef.current = node;
3022
+ }
3023
+ };
2732
3024
  const controlledWidth = columnId && tableContext.columnSizes?.[columnId] !== void 0 ? tableContext.columnSizes[columnId] : width;
2733
3025
  const canDrag = Boolean(
2734
3026
  columnId && draggable !== false && (draggable || tableContext.columnDragEnabled) && tableContext.columnOrder && tableContext.onColumnOrderChange
@@ -2883,7 +3175,7 @@ function BaseTableHead({
2883
3175
  "th",
2884
3176
  {
2885
3177
  ...headProps,
2886
- ref: headRef,
3178
+ ref: setHeadRef,
2887
3179
  scope: headProps.scope ?? "col",
2888
3180
  "aria-sort": ariaSort,
2889
3181
  className: cn(
@@ -2918,7 +3210,7 @@ function BaseTableHead({
2918
3210
  ]
2919
3211
  }
2920
3212
  );
2921
- }
3213
+ });
2922
3214
  function BaseTableCell({
2923
3215
  align = "left",
2924
3216
  appearance,
@@ -4310,6 +4602,659 @@ function WorkbenchTableView({
4310
4602
  }
4311
4603
  );
4312
4604
  }
4605
+ function toCssSize3(value) {
4606
+ if (value === void 0) return void 0;
4607
+ return typeof value === "number" ? `${value}px` : value;
4608
+ }
4609
+ function isBrowser() {
4610
+ return typeof window !== "undefined";
4611
+ }
4612
+ function defaultGetRowKey2(row, rowIndex) {
4613
+ return row?.id ?? row?.key ?? rowIndex;
4614
+ }
4615
+ function getColumnDefaultSize(column) {
4616
+ if (typeof column.width === "number") return column.width;
4617
+ if (typeof column.minWidth === "number") return column.minWidth;
4618
+ return 160;
4619
+ }
4620
+ function buildDefaultColumnSizes(columns, explicit) {
4621
+ return columns.reduce((acc, column) => {
4622
+ acc[column.key] = explicit?.[column.key] ?? getColumnDefaultSize(column);
4623
+ return acc;
4624
+ }, {});
4625
+ }
4626
+ function loadStoredColumnSizes(storageKey, defaults) {
4627
+ if (!storageKey || !isBrowser()) return defaults;
4628
+ try {
4629
+ const parsed = JSON.parse(window.localStorage.getItem(storageKey) || "{}");
4630
+ return Object.keys(defaults).reduce((acc, key) => {
4631
+ const value = Number(parsed?.[key]);
4632
+ acc[key] = Number.isFinite(value) ? value : defaults[key];
4633
+ return acc;
4634
+ }, {});
4635
+ } catch {
4636
+ return defaults;
4637
+ }
4638
+ }
4639
+ function persistColumnSizes(storageKey, sizes) {
4640
+ if (!storageKey || !isBrowser()) return;
4641
+ window.localStorage.setItem(storageKey, JSON.stringify(sizes));
4642
+ }
4643
+ function getFrozenColumnStorageKey(storageKey) {
4644
+ return storageKey ? `${storageKey}.frozenColumnCount` : void 0;
4645
+ }
4646
+ function getFrozenEndColumnStorageKey(storageKey) {
4647
+ return storageKey ? `${storageKey}.frozenEndColumnCount` : void 0;
4648
+ }
4649
+ function clampFrozenColumnCount(count, columnCount) {
4650
+ if (!Number.isFinite(count)) return 0;
4651
+ return Math.max(0, Math.min(Math.round(count), columnCount));
4652
+ }
4653
+ function normalizeFrozenColumnCounts(startCount, endCount, columnCount) {
4654
+ const normalizedStartCount = clampFrozenColumnCount(startCount, columnCount);
4655
+ const normalizedEndCount = clampFrozenColumnCount(endCount, Math.max(0, columnCount - normalizedStartCount));
4656
+ return {
4657
+ startCount: normalizedStartCount,
4658
+ endCount: normalizedEndCount
4659
+ };
4660
+ }
4661
+ function loadStoredFrozenColumnCount(storageKey, defaultCount, columnCount) {
4662
+ const fallback = clampFrozenColumnCount(defaultCount, columnCount);
4663
+ const frozenStorageKey = getFrozenColumnStorageKey(storageKey);
4664
+ if (!frozenStorageKey || !isBrowser()) return fallback;
4665
+ try {
4666
+ const storedValue = window.localStorage.getItem(frozenStorageKey);
4667
+ if (storedValue === null) return fallback;
4668
+ const value = Number(storedValue);
4669
+ return Number.isFinite(value) ? clampFrozenColumnCount(value, columnCount) : fallback;
4670
+ } catch {
4671
+ return fallback;
4672
+ }
4673
+ }
4674
+ function persistFrozenColumnCount(storageKey, count) {
4675
+ const frozenStorageKey = getFrozenColumnStorageKey(storageKey);
4676
+ if (!frozenStorageKey || !isBrowser()) return;
4677
+ window.localStorage.setItem(frozenStorageKey, String(count));
4678
+ }
4679
+ function loadStoredFrozenEndColumnCount(storageKey, defaultCount, columnCount) {
4680
+ const fallback = clampFrozenColumnCount(defaultCount, columnCount);
4681
+ const frozenStorageKey = getFrozenEndColumnStorageKey(storageKey);
4682
+ if (!frozenStorageKey || !isBrowser()) return fallback;
4683
+ try {
4684
+ const storedValue = window.localStorage.getItem(frozenStorageKey);
4685
+ if (storedValue === null) return fallback;
4686
+ const value = Number(storedValue);
4687
+ return Number.isFinite(value) ? clampFrozenColumnCount(value, columnCount) : fallback;
4688
+ } catch {
4689
+ return fallback;
4690
+ }
4691
+ }
4692
+ function persistFrozenEndColumnCount(storageKey, count) {
4693
+ const frozenStorageKey = getFrozenEndColumnStorageKey(storageKey);
4694
+ if (!frozenStorageKey || !isBrowser()) return;
4695
+ window.localStorage.setItem(frozenStorageKey, String(count));
4696
+ }
4697
+ function normalizeColumnOrder2(columnKeys, columnOrder) {
4698
+ const validColumnKeys = new Set(columnKeys);
4699
+ const orderedKeys = (columnOrder || []).filter((columnKey) => validColumnKeys.has(columnKey));
4700
+ const orderedKeySet = new Set(orderedKeys);
4701
+ const remainingKeys = columnKeys.filter((columnKey) => !orderedKeySet.has(columnKey));
4702
+ return [...orderedKeys, ...remainingKeys];
4703
+ }
4704
+ function getOrderedColumns2(columns, columnOrder) {
4705
+ const normalizedOrder = normalizeColumnOrder2(columns.map((column) => column.key), columnOrder);
4706
+ const columnMap = new Map(columns.map((column) => [column.key, column]));
4707
+ return normalizedOrder.map((columnKey) => columnMap.get(columnKey)).filter(Boolean);
4708
+ }
4709
+ function getColumnNumericWidth(column, columnSizes) {
4710
+ const controlledWidth = columnSizes[column.key];
4711
+ if (typeof controlledWidth === "number") return controlledWidth;
4712
+ return getColumnDefaultSize(column);
4713
+ }
4714
+ function buildFrozenOffsets(columns, columnSizes, frozenColumnCount) {
4715
+ const offsets = /* @__PURE__ */ new Map();
4716
+ let left = 0;
4717
+ columns.slice(0, Math.max(0, frozenColumnCount)).forEach((column) => {
4718
+ offsets.set(column.key, left);
4719
+ left += getColumnNumericWidth(column, columnSizes);
4720
+ });
4721
+ return offsets;
4722
+ }
4723
+ function buildFrozenEndOffsets(columns, columnSizes, frozenEndColumnCount) {
4724
+ const offsets = /* @__PURE__ */ new Map();
4725
+ let right = 0;
4726
+ columns.slice(Math.max(0, columns.length - frozenEndColumnCount)).reverse().forEach((column) => {
4727
+ offsets.set(column.key, right);
4728
+ right += getColumnNumericWidth(column, columnSizes);
4729
+ });
4730
+ return offsets;
4731
+ }
4732
+ function resolveRowClassName(rowClassName, row, rowIndex) {
4733
+ return typeof rowClassName === "function" ? rowClassName(row, rowIndex) : rowClassName;
4734
+ }
4735
+ function renderDefaultCell(column, row) {
4736
+ const value = row?.[column.key];
4737
+ if (value === void 0 || value === null || value === "") return "\u2014";
4738
+ return String(value);
4739
+ }
4740
+ function InteractiveTableCellContent({
4741
+ children,
4742
+ wrap
4743
+ }) {
4744
+ return /* @__PURE__ */ jsx(
4745
+ "div",
4746
+ {
4747
+ className: cn(
4748
+ "min-w-0 max-w-full overflow-auto overscroll-contain [scrollbar-width:thin]",
4749
+ wrap ? "max-h-20 whitespace-pre-wrap break-words leading-5" : "whitespace-nowrap"
4750
+ ),
4751
+ children
4752
+ }
4753
+ );
4754
+ }
4755
+ function PinIcon({ className }) {
4756
+ return /* @__PURE__ */ jsxs(
4757
+ "svg",
4758
+ {
4759
+ "aria-hidden": "true",
4760
+ viewBox: "0 0 16 16",
4761
+ className,
4762
+ fill: "none",
4763
+ stroke: "currentColor",
4764
+ strokeLinecap: "round",
4765
+ strokeLinejoin: "round",
4766
+ strokeWidth: "1.75",
4767
+ children: [
4768
+ /* @__PURE__ */ jsx("path", { d: "M5.25 2.75h5.5" }),
4769
+ /* @__PURE__ */ jsx("path", { d: "M6.25 2.75v4L4.5 9.25h7L9.75 6.75v-4" }),
4770
+ /* @__PURE__ */ jsx("path", { d: "M8 9.25v4" })
4771
+ ]
4772
+ }
4773
+ );
4774
+ }
4775
+ function InteractiveTable({
4776
+ rows = [],
4777
+ columns = [],
4778
+ pinnedTopRows = [],
4779
+ getRowKey = defaultGetRowKey2,
4780
+ getPinnedTopRowKey = defaultGetRowKey2,
4781
+ renderCell,
4782
+ renderPinnedTopCell,
4783
+ renderColumnHeader,
4784
+ onRowClick,
4785
+ getRowState,
4786
+ rowClassName,
4787
+ pinnedTopRowClassName,
4788
+ emptyState = "\u2014",
4789
+ columnMenuLabels,
4790
+ columnStorageKey,
4791
+ columnOrder,
4792
+ columnSizes,
4793
+ defaultColumnSizes,
4794
+ columnDragEnabled = false,
4795
+ columnResizeEnabled = true,
4796
+ frozenColumnCount = 0,
4797
+ frozenEndColumnCount = 0,
4798
+ tableMinWidth,
4799
+ bodyMaxHeight = "min(60vh, 42rem)",
4800
+ appearance,
4801
+ className,
4802
+ tableClassName,
4803
+ classNames,
4804
+ style,
4805
+ onColumnOrderChange,
4806
+ onColumnSizeChange,
4807
+ onResetColumnSizes,
4808
+ onFrozenColumnCountChange,
4809
+ onFrozenEndColumnCountChange,
4810
+ onSort
4811
+ }) {
4812
+ const columnKeySignature = columns.map((column) => column.key).join("");
4813
+ const defaultOrder = useMemo(
4814
+ () => columnKeySignature ? columnKeySignature.split("") : [],
4815
+ [columnKeySignature]
4816
+ );
4817
+ const defaultSizes = useMemo(
4818
+ () => buildDefaultColumnSizes(columns, defaultColumnSizes),
4819
+ [columns, defaultColumnSizes]
4820
+ );
4821
+ const [internalColumnOrder, setInternalColumnOrder] = useState(defaultOrder);
4822
+ const [internalColumnSizes, setInternalColumnSizes] = useState(() => loadStoredColumnSizes(columnStorageKey, defaultSizes));
4823
+ const [internalFrozenColumnCount, setInternalFrozenColumnCount] = useState(() => loadStoredFrozenColumnCount(columnStorageKey, frozenColumnCount, columns.length));
4824
+ const [internalFrozenEndColumnCount, setInternalFrozenEndColumnCount] = useState(() => loadStoredFrozenEndColumnCount(columnStorageKey, frozenEndColumnCount, columns.length));
4825
+ useEffect(() => {
4826
+ setInternalColumnOrder((current) => normalizeColumnOrder2(defaultOrder, current));
4827
+ }, [defaultOrder]);
4828
+ useEffect(() => {
4829
+ if (columnSizes) return;
4830
+ setInternalColumnSizes(loadStoredColumnSizes(columnStorageKey, defaultSizes));
4831
+ }, [columnSizes, columnStorageKey, defaultSizes]);
4832
+ useEffect(() => {
4833
+ setInternalFrozenColumnCount(loadStoredFrozenColumnCount(columnStorageKey, frozenColumnCount, columns.length));
4834
+ }, [columnStorageKey, columns.length, frozenColumnCount]);
4835
+ useEffect(() => {
4836
+ setInternalFrozenEndColumnCount(loadStoredFrozenEndColumnCount(columnStorageKey, frozenEndColumnCount, columns.length));
4837
+ }, [columnStorageKey, columns.length, frozenEndColumnCount]);
4838
+ const resolvedColumnOrder = columnOrder ? normalizeColumnOrder2(defaultOrder, columnOrder) : internalColumnOrder;
4839
+ const resolvedColumnSizes = columnSizes ?? internalColumnSizes;
4840
+ const orderedColumns = getOrderedColumns2(columns, resolvedColumnOrder);
4841
+ const {
4842
+ startCount: resolvedFrozenColumnCount,
4843
+ endCount: resolvedFrozenEndColumnCount
4844
+ } = normalizeFrozenColumnCounts(internalFrozenColumnCount, internalFrozenEndColumnCount, orderedColumns.length);
4845
+ const frozenOffsets = buildFrozenOffsets(orderedColumns, resolvedColumnSizes, resolvedFrozenColumnCount);
4846
+ const frozenEndOffsets = buildFrozenEndOffsets(orderedColumns, resolvedColumnSizes, resolvedFrozenEndColumnCount);
4847
+ const resolvedMinWidth = tableMinWidth ?? Math.max(760, orderedColumns.reduce((total, column) => total + getColumnNumericWidth(column, resolvedColumnSizes), 0));
4848
+ const labels = {
4849
+ columnActions: columnMenuLabels?.columnActions ?? "Column actions",
4850
+ freezeColumn: columnMenuLabels?.freezeColumn ?? "Freeze to left",
4851
+ freezeEndColumn: columnMenuLabels?.freezeEndColumn ?? "Freeze to right",
4852
+ unfreezeColumn: columnMenuLabels?.unfreezeColumn ?? "Unfreeze from left",
4853
+ unfreezeEndColumn: columnMenuLabels?.unfreezeEndColumn ?? "Unfreeze from right",
4854
+ unfreezeAllColumns: columnMenuLabels?.unfreezeAllColumns ?? "Unfreeze all columns",
4855
+ resetColumnWidth: columnMenuLabels?.resetColumnWidth ?? "Reset column width",
4856
+ frozenColumnTitle: columnMenuLabels?.frozenColumnTitle ?? "Frozen column"
4857
+ };
4858
+ const handleColumnOrderChange = useCallback((nextOrder, detail) => {
4859
+ const normalizedOrder = normalizeColumnOrder2(defaultOrder, nextOrder);
4860
+ if (!columnOrder) {
4861
+ setInternalColumnOrder(normalizedOrder);
4862
+ }
4863
+ onColumnOrderChange?.(normalizedOrder, detail);
4864
+ }, [columnOrder, defaultOrder, onColumnOrderChange]);
4865
+ const handleColumnSizeChange = useCallback((columnId, width, detail) => {
4866
+ const column = columns.find((item) => item.key === columnId);
4867
+ const minWidth = column?.minWidth;
4868
+ const maxWidth = column?.maxWidth;
4869
+ const nextWidth = Math.max(
4870
+ typeof minWidth === "number" ? minWidth : 0,
4871
+ Math.min(width, typeof maxWidth === "number" ? maxWidth : Number.POSITIVE_INFINITY)
4872
+ );
4873
+ const nextSizes = {
4874
+ ...resolvedColumnSizes,
4875
+ [columnId]: nextWidth
4876
+ };
4877
+ if (!columnSizes) {
4878
+ setInternalColumnSizes(nextSizes);
4879
+ }
4880
+ persistColumnSizes(columnStorageKey, nextSizes);
4881
+ onColumnSizeChange?.(columnId, nextWidth, detail);
4882
+ }, [columnSizes, columnStorageKey, columns, onColumnSizeChange, resolvedColumnSizes]);
4883
+ const handleResetColumnSize = useCallback((column) => {
4884
+ const nextWidth = defaultSizes[column.key] ?? getColumnDefaultSize(column);
4885
+ const previousWidth = getColumnNumericWidth(column, resolvedColumnSizes);
4886
+ const nextSizes = {
4887
+ ...resolvedColumnSizes,
4888
+ [column.key]: nextWidth
4889
+ };
4890
+ if (!columnSizes) {
4891
+ setInternalColumnSizes(nextSizes);
4892
+ }
4893
+ persistColumnSizes(columnStorageKey, nextSizes);
4894
+ onColumnSizeChange?.(column.key, nextWidth, {
4895
+ columnId: column.key,
4896
+ previousWidth,
4897
+ minWidth: column.minWidth,
4898
+ maxWidth: column.maxWidth
4899
+ });
4900
+ onResetColumnSizes?.(nextSizes);
4901
+ }, [columnSizes, columnStorageKey, defaultSizes, onColumnSizeChange, onResetColumnSizes, resolvedColumnSizes]);
4902
+ const setFrozenColumnCount = useCallback((nextCount) => {
4903
+ const normalizedCount = clampFrozenColumnCount(nextCount, Math.max(0, orderedColumns.length - resolvedFrozenEndColumnCount));
4904
+ setInternalFrozenColumnCount(normalizedCount);
4905
+ persistFrozenColumnCount(columnStorageKey, normalizedCount);
4906
+ onFrozenColumnCountChange?.(normalizedCount);
4907
+ }, [columnStorageKey, onFrozenColumnCountChange, orderedColumns.length, resolvedFrozenEndColumnCount]);
4908
+ const setFrozenEndColumnCount = useCallback((nextCount) => {
4909
+ const normalizedCount = clampFrozenColumnCount(nextCount, Math.max(0, orderedColumns.length - resolvedFrozenColumnCount));
4910
+ setInternalFrozenEndColumnCount(normalizedCount);
4911
+ persistFrozenEndColumnCount(columnStorageKey, normalizedCount);
4912
+ onFrozenEndColumnCountChange?.(normalizedCount);
4913
+ }, [columnStorageKey, onFrozenEndColumnCountChange, orderedColumns.length, resolvedFrozenColumnCount]);
4914
+ const getFrozenPosition = (columnIndex) => {
4915
+ if (columnIndex < resolvedFrozenColumnCount) return "start";
4916
+ if (columnIndex >= orderedColumns.length - resolvedFrozenEndColumnCount) return "end";
4917
+ return void 0;
4918
+ };
4919
+ const getFrozenClassName = (column, columnIndex, isHeader = false) => {
4920
+ const position = getFrozenPosition(columnIndex);
4921
+ if (!position) return void 0;
4922
+ return cn(
4923
+ "sticky",
4924
+ position === "start" ? "shadow-[1px_0_0_0_hsl(var(--border)/0.45)]" : "shadow-[-1px_0_0_0_hsl(var(--border)/0.45)]",
4925
+ isHeader ? "bg-muted/60" : "bg-inherit",
4926
+ isHeader ? "z-40" : "z-20",
4927
+ (columnIndex === 0 || columnIndex === orderedColumns.length - 1) && (isHeader ? "z-50" : "z-30")
4928
+ );
4929
+ };
4930
+ const getFrozenStyle = (column, columnIndex) => {
4931
+ const position = getFrozenPosition(columnIndex);
4932
+ if (position === "start") return { left: frozenOffsets.get(column.key) ?? 0 };
4933
+ if (position === "end") return { right: frozenEndOffsets.get(column.key) ?? 0 };
4934
+ return void 0;
4935
+ };
4936
+ return /* @__PURE__ */ jsx(
4937
+ BaseTableContainer,
4938
+ {
4939
+ appearance,
4940
+ className: cn("flex h-full min-h-0 flex-col overflow-hidden rounded-lg border border-border/60 bg-card", classNames?.root, className),
4941
+ style,
4942
+ children: /* @__PURE__ */ jsx(
4943
+ "div",
4944
+ {
4945
+ className: cn("min-h-0 flex-1 overflow-auto", classNames?.scrollArea),
4946
+ style: { maxHeight: toCssSize3(bodyMaxHeight) },
4947
+ children: /* @__PURE__ */ jsxs(
4948
+ BaseTable,
4949
+ {
4950
+ appearance,
4951
+ columnOrder: resolvedColumnOrder,
4952
+ columnSizes: resolvedColumnSizes,
4953
+ columnDragEnabled,
4954
+ columnResizeEnabled,
4955
+ onColumnOrderChange: handleColumnOrderChange,
4956
+ onColumnSizeChange: handleColumnSizeChange,
4957
+ className: cn("w-full table-fixed text-left text-xs", classNames?.table, tableClassName),
4958
+ style: { minWidth: resolvedMinWidth },
4959
+ children: [
4960
+ /* @__PURE__ */ jsx("colgroup", { children: orderedColumns.map((column) => /* @__PURE__ */ jsx(
4961
+ "col",
4962
+ {
4963
+ style: {
4964
+ width: toCssSize3(resolvedColumnSizes[column.key] ?? column.width),
4965
+ minWidth: toCssSize3(column.minWidth)
4966
+ }
4967
+ },
4968
+ column.key
4969
+ )) }),
4970
+ /* @__PURE__ */ jsx(BaseTableHeader, { appearance, className: cn("border-b border-border/60 bg-muted/60 text-[11px] font-medium text-muted-foreground", classNames?.tableHeader), children: /* @__PURE__ */ jsx(BaseTableRow, { appearance, className: cn("hover:bg-transparent", classNames?.headerRow), children: orderedColumns.map((column, columnIndex) => {
4971
+ const headerContent = renderColumnHeader ? renderColumnHeader(column, { column, columnIndex, columns: orderedColumns, rows }) : column.label;
4972
+ const sortable = Boolean(column.sortable);
4973
+ const handleSort = sortable && onSort ? () => onSort(column.key, column) : void 0;
4974
+ const isFrozenStart = columnIndex < resolvedFrozenColumnCount;
4975
+ const isFrozenEnd = columnIndex >= orderedColumns.length - resolvedFrozenEndColumnCount;
4976
+ const isFrozen = isFrozenStart || isFrozenEnd;
4977
+ const isColumnAtDefaultWidth = getColumnNumericWidth(column, resolvedColumnSizes) === (defaultSizes[column.key] ?? getColumnDefaultSize(column));
4978
+ return /* @__PURE__ */ jsxs(BaseContextMenu, { modal: false, children: [
4979
+ /* @__PURE__ */ jsx(BaseContextMenuTrigger, { asChild: true, appearance, children: /* @__PURE__ */ jsx(
4980
+ BaseTableHead,
4981
+ {
4982
+ appearance,
4983
+ columnId: column.key,
4984
+ align: column.align,
4985
+ label: headerContent,
4986
+ description: column.description,
4987
+ trailing: isFrozen ? /* @__PURE__ */ jsx("span", { title: labels.frozenColumnTitle, className: "inline-flex h-5 w-5 items-center justify-center rounded text-primary", children: /* @__PURE__ */ jsx(PinIcon, { className: "h-3.5 w-3.5" }) }) : null,
4988
+ sortable,
4989
+ sortDirection: column.sortDirection,
4990
+ sortLabel: column.sortLabel,
4991
+ onSort: handleSort,
4992
+ draggable: column.draggable,
4993
+ resizable: column.resizable,
4994
+ width: column.width,
4995
+ minWidth: column.minWidth,
4996
+ maxWidth: column.maxWidth,
4997
+ className: cn(
4998
+ "sticky top-0 h-9 whitespace-nowrap border-r border-border/50 bg-muted/60 px-2.5 py-2 backdrop-blur",
4999
+ getFrozenClassName(column, columnIndex, true),
5000
+ column.headerClassName,
5001
+ column.className,
5002
+ classNames?.headerCell
5003
+ ),
5004
+ style: getFrozenStyle(column, columnIndex)
5005
+ }
5006
+ ) }),
5007
+ /* @__PURE__ */ jsxs(BaseContextMenuContent, { appearance, alignOffset: -4, className: "min-w-44", children: [
5008
+ /* @__PURE__ */ jsx(BaseContextMenuLabel, { appearance, children: labels.columnActions }),
5009
+ isFrozen ? /* @__PURE__ */ jsx(
5010
+ BaseContextMenuItem,
5011
+ {
5012
+ appearance,
5013
+ onSelect: () => {
5014
+ if (isFrozenEnd) setFrozenEndColumnCount(orderedColumns.length - columnIndex - 1);
5015
+ else setFrozenColumnCount(columnIndex);
5016
+ },
5017
+ children: isFrozenEnd ? labels.unfreezeEndColumn : labels.unfreezeColumn
5018
+ }
5019
+ ) : /* @__PURE__ */ jsx(
5020
+ BaseContextMenuItem,
5021
+ {
5022
+ appearance,
5023
+ onSelect: () => setFrozenColumnCount(columnIndex + 1),
5024
+ children: labels.freezeColumn
5025
+ }
5026
+ ),
5027
+ !isFrozen ? /* @__PURE__ */ jsx(
5028
+ BaseContextMenuItem,
5029
+ {
5030
+ appearance,
5031
+ onSelect: () => setFrozenEndColumnCount(orderedColumns.length - columnIndex),
5032
+ children: labels.freezeEndColumn
5033
+ }
5034
+ ) : null,
5035
+ /* @__PURE__ */ jsx(
5036
+ BaseContextMenuItem,
5037
+ {
5038
+ appearance,
5039
+ disabled: resolvedFrozenColumnCount === 0 && resolvedFrozenEndColumnCount === 0,
5040
+ onSelect: () => {
5041
+ setFrozenColumnCount(0);
5042
+ setFrozenEndColumnCount(0);
5043
+ },
5044
+ children: labels.unfreezeAllColumns
5045
+ }
5046
+ ),
5047
+ /* @__PURE__ */ jsx(BaseContextMenuSeparator, { appearance }),
5048
+ /* @__PURE__ */ jsx(
5049
+ BaseContextMenuItem,
5050
+ {
5051
+ appearance,
5052
+ disabled: isColumnAtDefaultWidth,
5053
+ onSelect: () => handleResetColumnSize(column),
5054
+ children: labels.resetColumnWidth
5055
+ }
5056
+ )
5057
+ ] })
5058
+ ] }, column.key);
5059
+ }) }) }),
5060
+ /* @__PURE__ */ jsxs(BaseTableBody, { appearance, className: cn("divide-y divide-border/50", classNames?.body), children: [
5061
+ pinnedTopRows.map((row, rowIndex) => {
5062
+ const key = getPinnedTopRowKey(row, rowIndex);
5063
+ const resolvedRowClassName = resolveRowClassName(pinnedTopRowClassName, row, rowIndex);
5064
+ return /* @__PURE__ */ jsx(
5065
+ BaseTableRow,
5066
+ {
5067
+ appearance,
5068
+ className: cn("bg-card/95", classNames?.pinnedTopRow, resolvedRowClassName),
5069
+ children: orderedColumns.map((column, columnIndex) => /* @__PURE__ */ jsx(
5070
+ BaseTableCell,
5071
+ {
5072
+ appearance,
5073
+ align: column.align,
5074
+ className: cn(
5075
+ "h-[52px] border-r border-border/50 px-2.5 py-1.5 align-middle",
5076
+ column.wrap ? "whitespace-normal" : "whitespace-nowrap",
5077
+ getFrozenClassName(column, columnIndex),
5078
+ column.cellClassName,
5079
+ classNames?.cell
5080
+ ),
5081
+ style: getFrozenStyle(column, columnIndex),
5082
+ children: /* @__PURE__ */ jsx(InteractiveTableCellContent, { wrap: column.wrap, children: renderPinnedTopCell ? renderPinnedTopCell(column, row, { row, rowIndex, column, columnIndex, isPinnedTopRow: true }) : renderDefaultCell(column, row) })
5083
+ },
5084
+ `pinned-${key}-${column.key}`
5085
+ ))
5086
+ },
5087
+ `pinned-${key}`
5088
+ );
5089
+ }),
5090
+ rows.length ? rows.map((row, rowIndex) => {
5091
+ const key = getRowKey(row, rowIndex);
5092
+ const state = getRowState?.(row, rowIndex) || {};
5093
+ const resolvedRowClassName = resolveRowClassName(rowClassName, row, rowIndex);
5094
+ return /* @__PURE__ */ jsx(
5095
+ BaseTableRow,
5096
+ {
5097
+ appearance,
5098
+ interactive: Boolean(onRowClick) && !state.disabled,
5099
+ selected: state.selected,
5100
+ disabled: state.disabled,
5101
+ onClick: () => {
5102
+ if (!state.disabled) onRowClick?.(row, rowIndex);
5103
+ },
5104
+ className: cn(
5105
+ "min-h-[52px] bg-card transition-colors",
5106
+ state.saving && "bg-primary/5",
5107
+ state.pending && "opacity-80",
5108
+ onRowClick && !state.disabled ? "cursor-pointer hover:bg-muted/30" : "hover:bg-muted/30",
5109
+ classNames?.row,
5110
+ resolvedRowClassName
5111
+ ),
5112
+ children: orderedColumns.map((column, columnIndex) => /* @__PURE__ */ jsx(
5113
+ BaseTableCell,
5114
+ {
5115
+ appearance,
5116
+ align: column.align,
5117
+ className: cn(
5118
+ "h-[52px] border-r border-border/50 px-2.5 py-1.5 align-middle",
5119
+ column.wrap ? "whitespace-normal" : "whitespace-nowrap",
5120
+ getFrozenClassName(column, columnIndex),
5121
+ column.cellClassName,
5122
+ classNames?.cell
5123
+ ),
5124
+ style: getFrozenStyle(column, columnIndex),
5125
+ children: /* @__PURE__ */ jsx(InteractiveTableCellContent, { wrap: column.wrap, children: renderCell ? renderCell(column, row, { row, rowIndex, column, columnIndex, isPinnedTopRow: false }) : renderDefaultCell(column, row) })
5126
+ },
5127
+ `${key}-${column.key}`
5128
+ ))
5129
+ },
5130
+ key
5131
+ );
5132
+ }) : pinnedTopRows.length ? null : /* @__PURE__ */ jsx(
5133
+ BaseTableEmpty,
5134
+ {
5135
+ appearance,
5136
+ colSpan: Math.max(orderedColumns.length, 1),
5137
+ className: classNames?.empty,
5138
+ children: emptyState
5139
+ }
5140
+ )
5141
+ ] })
5142
+ ]
5143
+ }
5144
+ )
5145
+ }
5146
+ )
5147
+ }
5148
+ );
5149
+ }
5150
+ function InteractiveTableEditableTextCell({
5151
+ value,
5152
+ placeholder,
5153
+ disabled,
5154
+ multiline = false,
5155
+ commitOnBlur = true,
5156
+ className,
5157
+ inputClassName,
5158
+ onCommit
5159
+ }) {
5160
+ const initialValue = String(value || "");
5161
+ const [draft, setDraft] = useState(initialValue);
5162
+ useEffect(() => {
5163
+ setDraft(initialValue);
5164
+ }, [initialValue]);
5165
+ const commit = useCallback(async () => {
5166
+ const nextValue = String(draft || "").trim();
5167
+ const previousValue = String(initialValue || "").trim();
5168
+ if (nextValue === previousValue) return;
5169
+ try {
5170
+ await onCommit?.(nextValue);
5171
+ } catch {
5172
+ setDraft(initialValue);
5173
+ }
5174
+ }, [draft, initialValue, onCommit]);
5175
+ const controlClassName = cn(
5176
+ "w-full resize-none rounded-sm border border-transparent bg-transparent px-1.5 py-1 text-xs text-foreground outline-none transition-colors",
5177
+ "placeholder:text-muted-foreground/70 hover:border-border/60 hover:bg-background focus:border-primary/45 focus:bg-background",
5178
+ multiline ? "min-h-[42px] leading-5" : "h-8",
5179
+ disabled && "cursor-not-allowed text-muted-foreground hover:border-transparent hover:bg-transparent",
5180
+ inputClassName
5181
+ );
5182
+ if (multiline) {
5183
+ return /* @__PURE__ */ jsx(
5184
+ "textarea",
5185
+ {
5186
+ className: cn(controlClassName, className),
5187
+ disabled,
5188
+ value: draft,
5189
+ placeholder,
5190
+ onChange: (event) => setDraft(event.target.value),
5191
+ onBlur: () => {
5192
+ if (commitOnBlur) void commit();
5193
+ },
5194
+ onKeyDown: (event) => {
5195
+ if ((event.metaKey || event.ctrlKey) && event.key === "Enter") {
5196
+ event.currentTarget.blur();
5197
+ }
5198
+ if (event.key === "Escape") {
5199
+ setDraft(initialValue);
5200
+ event.currentTarget.blur();
5201
+ }
5202
+ }
5203
+ }
5204
+ );
5205
+ }
5206
+ return /* @__PURE__ */ jsx(
5207
+ "input",
5208
+ {
5209
+ className: cn(controlClassName, className),
5210
+ disabled,
5211
+ value: draft,
5212
+ placeholder,
5213
+ onChange: (event) => setDraft(event.target.value),
5214
+ onBlur: () => {
5215
+ if (commitOnBlur) void commit();
5216
+ },
5217
+ onKeyDown: (event) => {
5218
+ if (event.key === "Enter") event.currentTarget.blur();
5219
+ if (event.key === "Escape") {
5220
+ setDraft(initialValue);
5221
+ event.currentTarget.blur();
5222
+ }
5223
+ }
5224
+ }
5225
+ );
5226
+ }
5227
+ function InteractiveTableReadonlyCell({
5228
+ children,
5229
+ mono = false,
5230
+ className
5231
+ }) {
5232
+ return /* @__PURE__ */ jsx("div", { className: cn("min-w-0 text-xs text-muted-foreground", mono && "font-mono", className), children: hasRenderableNode(children) ? children : "\u2014" });
5233
+ }
5234
+ function InteractiveTableSelectCell({
5235
+ value,
5236
+ options,
5237
+ disabled,
5238
+ ariaLabel,
5239
+ children,
5240
+ className,
5241
+ onChange
5242
+ }) {
5243
+ return /* @__PURE__ */ jsxs("div", { className: cn("relative flex w-full items-center", className), children: [
5244
+ children,
5245
+ /* @__PURE__ */ jsx(
5246
+ "select",
5247
+ {
5248
+ "aria-label": ariaLabel,
5249
+ disabled,
5250
+ value,
5251
+ onChange: (event) => onChange?.(event.target.value),
5252
+ className: "absolute inset-0 h-full w-full cursor-pointer opacity-0 disabled:cursor-not-allowed",
5253
+ children: options.map((option) => /* @__PURE__ */ jsx("option", { value: option.value, children: option.label }, option.value))
5254
+ }
5255
+ )
5256
+ ] });
5257
+ }
4313
5258
  var imageExtPattern = /\.(png|jpe?g|webp|gif|svg|bmp|avif)$/i;
4314
5259
  var audioExtPattern = /\.(wav|mp3|ogg|m4a|flac|aac)$/i;
4315
5260
  var isLikelyUrl = (value) => /^https?:\/\//i.test(String(value || ""));
@@ -5496,7 +6441,174 @@ function WorkbenchGalleryView({
5496
6441
  }
5497
6442
  );
5498
6443
  }
6444
+ function toCssSize4(value) {
6445
+ if (value === void 0) return void 0;
6446
+ return typeof value === "number" ? `${value}px` : value;
6447
+ }
6448
+ function defaultGetRowId(row, rowIndex) {
6449
+ return String(row?.id ?? row?.key ?? rowIndex);
6450
+ }
6451
+ function defaultGetColumnId(row) {
6452
+ return String(row?.columnId ?? row?.status ?? "");
6453
+ }
6454
+ function defaultRenderCard(row) {
6455
+ const value = row?.title ?? row?.name ?? row?.id ?? "Untitled";
6456
+ return /* @__PURE__ */ jsx("div", { className: "rounded-lg border border-border/70 bg-card px-3 py-2 text-sm text-foreground shadow-sm", children: String(value) });
6457
+ }
6458
+ function WorkbenchLaneDraggableCard({
6459
+ row,
6460
+ rowId,
6461
+ rowIndex,
6462
+ column,
6463
+ classNames,
6464
+ renderCard
6465
+ }) {
6466
+ const { attributes, listeners, setNodeRef, isDragging } = useDraggable({ id: rowId });
6467
+ return /* @__PURE__ */ jsx(
6468
+ "div",
6469
+ {
6470
+ ref: setNodeRef,
6471
+ ...listeners,
6472
+ ...attributes,
6473
+ className: cn("touch-none", classNames?.cardWrapper),
6474
+ children: renderCard(row, { row, rowIndex, column, isDragging, isOverlay: false })
6475
+ }
6476
+ );
6477
+ }
6478
+ function WorkbenchLaneColumnView({
6479
+ column,
6480
+ columnRows,
6481
+ columnWidth,
6482
+ columnMinHeight,
6483
+ emptyColumn,
6484
+ classNames,
6485
+ renderCard
6486
+ }) {
6487
+ const { setNodeRef, isOver } = useDroppable({ id: column.id });
6488
+ return /* @__PURE__ */ jsxs(
6489
+ "section",
6490
+ {
6491
+ className: cn(
6492
+ "flex shrink-0 flex-col rounded-xl border border-border/60 bg-card p-2 shadow-sm",
6493
+ classNames?.column,
6494
+ column.className
6495
+ ),
6496
+ style: { width: toCssSize4(columnWidth) ?? "280px" },
6497
+ children: [
6498
+ /* @__PURE__ */ jsxs("div", { className: cn("flex h-10 items-center gap-2 px-1", classNames?.columnHeader, column.headerClassName), children: [
6499
+ column.icon ? /* @__PURE__ */ jsx("span", { className: cn("inline-flex h-4 w-4 items-center justify-center text-muted-foreground", classNames?.columnIcon, column.iconClassName), children: column.icon }) : null,
6500
+ /* @__PURE__ */ jsx("span", { className: cn("inline-flex items-center rounded px-2 py-0.5 text-xs font-semibold bg-muted text-muted-foreground", classNames?.columnBadge, column.badgeClassName), children: column.label ?? column.id }),
6501
+ /* @__PURE__ */ jsx("span", { className: cn("text-xs text-muted-foreground", classNames?.columnCount), children: columnRows.length })
6502
+ ] }),
6503
+ /* @__PURE__ */ jsx(
6504
+ "div",
6505
+ {
6506
+ ref: setNodeRef,
6507
+ className: cn(
6508
+ "mt-1 flex min-h-[200px] flex-1 flex-col gap-2 overflow-y-auto rounded-lg p-1 transition-colors [scrollbar-width:thin]",
6509
+ isOver && "bg-accent/60",
6510
+ classNames?.columnBody,
6511
+ column.bodyClassName
6512
+ ),
6513
+ style: { minHeight: toCssSize4(columnMinHeight) },
6514
+ children: columnRows.length ? columnRows.map(({ row, rowIndex, rowId }) => /* @__PURE__ */ jsx(
6515
+ WorkbenchLaneDraggableCard,
6516
+ {
6517
+ row,
6518
+ rowId,
6519
+ rowIndex,
6520
+ column,
6521
+ classNames,
6522
+ renderCard
6523
+ },
6524
+ rowId
6525
+ )) : emptyColumn ? /* @__PURE__ */ jsx("div", { className: cn("flex min-h-24 items-center justify-center rounded-lg border border-dashed border-border/60 px-3 py-4 text-xs text-muted-foreground", classNames?.emptyColumn), children: emptyColumn }) : null
6526
+ }
6527
+ )
6528
+ ]
6529
+ }
6530
+ );
6531
+ }
6532
+ function WorkbenchLaneView({
6533
+ rows = [],
6534
+ columns = [],
6535
+ getRowId = defaultGetRowId,
6536
+ getColumnId = defaultGetColumnId,
6537
+ renderCard = defaultRenderCard,
6538
+ renderOverlayCard,
6539
+ onMoveRow,
6540
+ emptyColumn,
6541
+ activationDistance = 5,
6542
+ columnWidth = 280,
6543
+ columnMinHeight,
6544
+ className,
6545
+ classNames,
6546
+ style
6547
+ }) {
6548
+ const [activeRowId, setActiveRowId] = useState(null);
6549
+ const sensors = useSensors(useSensor(PointerSensor, { activationConstraint: { distance: activationDistance } }));
6550
+ const columnMap = useMemo(() => new Map(columns.map((column) => [column.id, column])), [columns]);
6551
+ const rowEntries = useMemo(() => rows.map((row, rowIndex) => ({
6552
+ row,
6553
+ rowIndex,
6554
+ rowId: getRowId(row, rowIndex),
6555
+ columnId: getColumnId(row, rowIndex)
6556
+ })), [getColumnId, getRowId, rows]);
6557
+ const activeEntry = activeRowId ? rowEntries.find((entry) => entry.rowId === activeRowId) : void 0;
6558
+ const rowsByColumn = useMemo(() => {
6559
+ const next = /* @__PURE__ */ new Map();
6560
+ columns.forEach((column) => next.set(column.id, []));
6561
+ rowEntries.forEach(({ row, rowIndex, rowId, columnId }) => {
6562
+ next.get(columnId)?.push({ row, rowIndex, rowId });
6563
+ });
6564
+ return next;
6565
+ }, [columns, rowEntries]);
6566
+ const activeColumn = activeEntry ? columnMap.get(activeEntry.columnId) : void 0;
6567
+ const handleDragStart = useCallback((event) => {
6568
+ setActiveRowId(String(event.active.id));
6569
+ }, []);
6570
+ const handleDragEnd = useCallback((event) => {
6571
+ setActiveRowId(null);
6572
+ const rowId = String(event.active.id);
6573
+ const nextColumnId = String(event.over?.id ?? "");
6574
+ const activeRow = rowEntries.find((entry) => entry.rowId === rowId);
6575
+ if (!activeRow || !columnMap.has(nextColumnId) || activeRow.columnId === nextColumnId) return;
6576
+ onMoveRow?.(rowId, nextColumnId, activeRow.row);
6577
+ }, [columnMap, onMoveRow, rowEntries]);
6578
+ const handleDragCancel = useCallback(() => {
6579
+ setActiveRowId(null);
6580
+ }, []);
6581
+ return /* @__PURE__ */ jsxs(DndContext, { sensors, onDragStart: handleDragStart, onDragEnd: handleDragEnd, onDragCancel: handleDragCancel, children: [
6582
+ /* @__PURE__ */ jsx(
6583
+ "div",
6584
+ {
6585
+ className: cn("flex min-h-0 flex-1 gap-4 overflow-x-auto p-4 [scrollbar-width:thin]", classNames?.root, className),
6586
+ style,
6587
+ children: columns.map((column) => /* @__PURE__ */ jsx(
6588
+ WorkbenchLaneColumnView,
6589
+ {
6590
+ column,
6591
+ columnRows: rowsByColumn.get(column.id) || [],
6592
+ columnWidth,
6593
+ columnMinHeight,
6594
+ emptyColumn,
6595
+ classNames,
6596
+ renderCard
6597
+ },
6598
+ column.id
6599
+ ))
6600
+ }
6601
+ ),
6602
+ /* @__PURE__ */ jsx(DragOverlay, { children: activeEntry && activeColumn ? /* @__PURE__ */ jsx("div", { className: cn(classNames?.overlayWrapper), children: (renderOverlayCard || renderCard)(activeEntry.row, {
6603
+ row: activeEntry.row,
6604
+ rowIndex: activeEntry.rowIndex,
6605
+ column: activeColumn,
6606
+ isDragging: false,
6607
+ isOverlay: true
6608
+ }) }) : null })
6609
+ ] });
6610
+ }
5499
6611
 
5500
- export { WorkbenchContentPane, WorkbenchContentToolbar, WorkbenchDetailSidebar, WorkbenchGalleryCard, WorkbenchGallerySettingsButton, WorkbenchGallerySettingsPanel, WorkbenchGalleryView, WorkbenchMasonryLayout, WorkbenchResizableSidebar, WorkbenchTableView };
6612
+ export { InteractiveTable, InteractiveTableEditableTextCell, InteractiveTableReadonlyCell, InteractiveTableSelectCell, WorkbenchContentPane, WorkbenchContentToolbar, WorkbenchDetailSidebar, WorkbenchGalleryCard, WorkbenchGallerySettingsButton, WorkbenchGallerySettingsPanel, WorkbenchGalleryView, WorkbenchLaneView, WorkbenchMasonryLayout, WorkbenchResizableSidebar, WorkbenchTableView };
5501
6613
  //# sourceMappingURL=index.mjs.map
5502
6614
  //# sourceMappingURL=index.mjs.map