@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.
@@ -2,7 +2,28 @@
2
2
 
3
3
  var react = require('react');
4
4
  var jsxRuntime = require('react/jsx-runtime');
5
- require('@radix-ui/react-context-menu');
5
+ var ContextMenu = require('@radix-ui/react-context-menu');
6
+ var core = require('@dnd-kit/core');
7
+
8
+ function _interopNamespace(e) {
9
+ if (e && e.__esModule) return e;
10
+ var n = Object.create(null);
11
+ if (e) {
12
+ Object.keys(e).forEach(function (k) {
13
+ if (k !== 'default') {
14
+ var d = Object.getOwnPropertyDescriptor(e, k);
15
+ Object.defineProperty(n, k, d.get ? d : {
16
+ enumerable: true,
17
+ get: function () { return e[k]; }
18
+ });
19
+ }
20
+ });
21
+ }
22
+ n.default = e;
23
+ return Object.freeze(n);
24
+ }
25
+
26
+ var ContextMenu__namespace = /*#__PURE__*/_interopNamespace(ContextMenu);
6
27
 
7
28
  // src/components/workbench/WorkbenchResizableSidebar.tsx
8
29
 
@@ -709,7 +730,41 @@ var baseSlots = {
709
730
  tableEmptyActions: "mt-4 flex flex-wrap items-center justify-center gap-2",
710
731
  tableLoadingRow: "border-b border-border/60",
711
732
  tableLoadingCell: "px-3 py-2",
712
- tableLoadingSkeleton: "h-4 w-full rounded-md bg-muted/70"
733
+ tableLoadingSkeleton: "h-4 w-full rounded-md bg-muted/70",
734
+ layoutRoot: cn(
735
+ "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",
736
+ motionBase
737
+ ),
738
+ layoutRootFull: "h-full min-h-0",
739
+ layoutHeader: "min-w-0",
740
+ layoutBody: "grid min-h-0 min-w-0 overflow-hidden gap-3",
741
+ layoutSidebar: "min-h-0 min-w-0 overflow-hidden",
742
+ layoutMain: "min-h-0 min-w-0 overflow-hidden",
743
+ layoutAside: "min-h-0 min-w-0 overflow-hidden",
744
+ layoutFooter: "min-w-0",
745
+ layoutPane: cn(
746
+ "h-full max-h-full min-h-0 min-w-0 overflow-hidden rounded-lg bg-background text-foreground",
747
+ motionBase
748
+ ),
749
+ layoutPaneScrollable: "overflow-auto",
750
+ layoutPaneBordered: "border border-border/70",
751
+ layoutPaneMuted: "bg-muted/25",
752
+ layoutPaneSoft: "bg-background/95 shadow-sm",
753
+ layoutPaneTransparent: "bg-transparent shadow-none",
754
+ layoutSplitRoot: "grid min-h-0 min-w-0 overflow-hidden",
755
+ layoutSplitHorizontal: "grid-flow-col",
756
+ layoutSplitVertical: "grid-flow-row",
757
+ layoutSplitPane: "min-h-0 min-w-0 overflow-hidden",
758
+ layoutSplitPrimary: "",
759
+ layoutSplitSecondary: "",
760
+ layoutResizeHandle: cn(
761
+ "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",
762
+ motionInteractive
763
+ ),
764
+ layoutResizeHandleHorizontal: "w-2 cursor-col-resize",
765
+ layoutResizeHandleVertical: "h-2 cursor-row-resize",
766
+ layoutResizeHandleDisabled: "cursor-default opacity-60",
767
+ layoutResizeHandleIndicator: "rounded-full bg-muted-foreground/45 group-hover/resize:bg-primary/70"
713
768
  };
714
769
  var densitySlots = {
715
770
  compact: {
@@ -783,7 +838,12 @@ var densitySlots = {
783
838
  tableCell: "px-2 py-1.5 text-xs",
784
839
  tableHeadLabel: "text-[11px]",
785
840
  tableHeadDescription: "text-[10px] leading-3",
786
- tableLoadingCell: "px-2 py-1.5"
841
+ tableLoadingCell: "px-2 py-1.5",
842
+ layoutRoot: "gap-2 p-2",
843
+ layoutBody: "gap-2",
844
+ layoutPane: "rounded-md text-xs",
845
+ layoutResizeHandleHorizontal: "w-1.5",
846
+ layoutResizeHandleVertical: "h-1.5"
787
847
  },
788
848
  default: {
789
849
  buttonBase: "h-9"
@@ -834,7 +894,12 @@ var densitySlots = {
834
894
  menuSubTrigger: "min-h-9 px-3 py-2",
835
895
  tableHead: "h-12 px-4 py-3",
836
896
  tableCell: "px-4 py-3",
837
- tableLoadingCell: "px-4 py-3"
897
+ tableLoadingCell: "px-4 py-3",
898
+ layoutRoot: "gap-4 p-4",
899
+ layoutBody: "gap-4",
900
+ layoutPane: "rounded-xl",
901
+ layoutResizeHandleHorizontal: "w-2.5",
902
+ layoutResizeHandleVertical: "h-2.5"
838
903
  }
839
904
  };
840
905
  var radiusSlots = {
@@ -878,7 +943,9 @@ var radiusSlots = {
878
943
  menuSubContent: "rounded-none",
879
944
  tableContainer: "rounded-none",
880
945
  tableEmptyIcon: "rounded-none",
881
- tableLoadingSkeleton: "rounded-none"
946
+ tableLoadingSkeleton: "rounded-none",
947
+ layoutRoot: "rounded-none",
948
+ layoutPane: "rounded-none"
882
949
  },
883
950
  sm: {
884
951
  buttonBase: "rounded-sm",
@@ -920,7 +987,9 @@ var radiusSlots = {
920
987
  menuSubContent: "rounded-sm",
921
988
  tableContainer: "rounded-sm",
922
989
  tableEmptyIcon: "rounded-sm",
923
- tableLoadingSkeleton: "rounded-sm"
990
+ tableLoadingSkeleton: "rounded-sm",
991
+ layoutRoot: "rounded-sm",
992
+ layoutPane: "rounded-sm"
924
993
  },
925
994
  md: {},
926
995
  lg: {
@@ -957,7 +1026,9 @@ var radiusSlots = {
957
1026
  menuSubContent: "rounded-lg",
958
1027
  tableContainer: "rounded-xl",
959
1028
  tableEmptyIcon: "rounded-xl",
960
- tableLoadingSkeleton: "rounded-lg"
1029
+ tableLoadingSkeleton: "rounded-lg",
1030
+ layoutRoot: "rounded-xl",
1031
+ layoutPane: "rounded-xl"
961
1032
  },
962
1033
  xl: {
963
1034
  buttonBase: "rounded-xl",
@@ -995,7 +1066,9 @@ var radiusSlots = {
995
1066
  menuSubContent: "rounded-xl",
996
1067
  tableContainer: "rounded-2xl",
997
1068
  tableEmptyIcon: "rounded-2xl",
998
- tableLoadingSkeleton: "rounded-xl"
1069
+ tableLoadingSkeleton: "rounded-xl",
1070
+ layoutRoot: "rounded-2xl",
1071
+ layoutPane: "rounded-2xl"
999
1072
  },
1000
1073
  full: {
1001
1074
  buttonBase: "rounded-full",
@@ -1037,7 +1110,9 @@ var radiusSlots = {
1037
1110
  menuSubContent: "rounded-2xl",
1038
1111
  tableContainer: "rounded-2xl",
1039
1112
  tableEmptyIcon: "rounded-full",
1040
- tableLoadingSkeleton: "rounded-full"
1113
+ tableLoadingSkeleton: "rounded-full",
1114
+ layoutRoot: "rounded-2xl",
1115
+ layoutPane: "rounded-2xl"
1041
1116
  }
1042
1117
  };
1043
1118
  var borderSlots = {
@@ -1079,7 +1154,10 @@ var borderSlots = {
1079
1154
  tableFooterBarAttached: "border-t border-transparent",
1080
1155
  tableRow: "border-transparent",
1081
1156
  tableEmptyRow: "border-transparent",
1082
- tableLoadingRow: "border-transparent"
1157
+ tableLoadingRow: "border-transparent",
1158
+ layoutRoot: "border-transparent",
1159
+ layoutPaneBordered: "border-transparent",
1160
+ layoutResizeHandle: "bg-transparent hover:bg-transparent active:bg-transparent focus-visible:bg-transparent"
1083
1161
  },
1084
1162
  subtle: {
1085
1163
  buttonDefault: "border-border/60",
@@ -1119,7 +1197,9 @@ var borderSlots = {
1119
1197
  tableFooterBarAttached: "border-t border-border/60",
1120
1198
  tableRow: "border-border/50",
1121
1199
  tableEmptyRow: "border-border/50",
1122
- tableLoadingRow: "border-border/50"
1200
+ tableLoadingRow: "border-border/50",
1201
+ layoutRoot: "border-border/60",
1202
+ layoutPaneBordered: "border-border/60"
1123
1203
  },
1124
1204
  solid: {},
1125
1205
  strong: {
@@ -1160,7 +1240,10 @@ var borderSlots = {
1160
1240
  tableFooterBarAttached: "border-t border-foreground/20",
1161
1241
  tableRow: "border-foreground/15",
1162
1242
  tableEmptyRow: "border-foreground/15",
1163
- tableLoadingRow: "border-foreground/15"
1243
+ tableLoadingRow: "border-foreground/15",
1244
+ layoutRoot: "border-foreground/20",
1245
+ layoutPaneBordered: "border-foreground/20",
1246
+ layoutResizeHandle: "hover:bg-foreground/15 active:bg-foreground/20 focus-visible:bg-foreground/15"
1164
1247
  }
1165
1248
  };
1166
1249
  var backgroundSlots = {
@@ -1202,7 +1285,11 @@ var backgroundSlots = {
1202
1285
  tableFooter: "bg-muted/35",
1203
1286
  tableFooterBar: "bg-muted/30 shadow-none",
1204
1287
  tableRowInteractive: "cursor-pointer hover:bg-muted/45",
1205
- tableLoadingSkeleton: "bg-muted"
1288
+ tableLoadingSkeleton: "bg-muted",
1289
+ layoutRoot: "bg-card",
1290
+ layoutPane: "bg-card",
1291
+ layoutPaneMuted: "bg-muted/35",
1292
+ layoutResizeHandle: "hover:bg-border/70 active:bg-border/80 focus-visible:bg-border/70"
1206
1293
  },
1207
1294
  soft: {
1208
1295
  buttonDefault: "bg-muted/30 hover:bg-muted/55",
@@ -1238,7 +1325,10 @@ var backgroundSlots = {
1238
1325
  tableFooter: "bg-muted/25",
1239
1326
  tableFooterBar: "bg-muted/25 shadow-none",
1240
1327
  tableRowInteractive: "cursor-pointer hover:bg-muted/35",
1241
- tableLoadingSkeleton: "bg-muted/65"
1328
+ tableLoadingSkeleton: "bg-muted/65",
1329
+ layoutRoot: "bg-background/95 shadow-sm",
1330
+ layoutPane: "bg-background/95 shadow-sm",
1331
+ layoutPaneSoft: "bg-background/95 shadow-md"
1242
1332
  },
1243
1333
  glass: {
1244
1334
  buttonBase: "backdrop-blur-md",
@@ -1299,7 +1389,13 @@ var backgroundSlots = {
1299
1389
  tableRow: "border-white/10",
1300
1390
  tableRowInteractive: "cursor-pointer hover:bg-white/[0.08]",
1301
1391
  tableHeadLabel: "text-foreground",
1302
- tableLoadingSkeleton: "bg-white/[0.16]"
1392
+ tableLoadingSkeleton: "bg-white/[0.16]",
1393
+ layoutRoot: "border-white/10 bg-white/[0.05] shadow-none backdrop-blur-md",
1394
+ layoutPane: "border-white/10 bg-white/[0.06] shadow-none backdrop-blur-md",
1395
+ layoutPaneMuted: "bg-white/[0.08]",
1396
+ layoutPaneSoft: "bg-white/[0.10] shadow-none backdrop-blur-md",
1397
+ layoutResizeHandle: "text-foreground/65 hover:bg-white/10 active:bg-white/15 focus-visible:bg-white/10",
1398
+ layoutResizeHandleIndicator: "bg-white/45 group-hover/resize:bg-white/75"
1303
1399
  },
1304
1400
  dark: {
1305
1401
  buttonBase: "border-white/15 text-white shadow-lg backdrop-blur",
@@ -1428,7 +1524,13 @@ var backgroundSlots = {
1428
1524
  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]",
1429
1525
  menuSubTriggerIcon: "text-white/55",
1430
1526
  menuSubContent: "border-white/10 bg-slate-950 text-white shadow-2xl",
1431
- tableLoadingSkeleton: "bg-white/[0.14]"
1527
+ tableLoadingSkeleton: "bg-white/[0.14]",
1528
+ layoutRoot: "border-white/10 bg-slate-950 text-white shadow-none",
1529
+ layoutPane: "border-white/10 bg-slate-950 text-white shadow-none",
1530
+ layoutPaneMuted: "bg-white/[0.06]",
1531
+ layoutPaneSoft: "bg-white/[0.08] shadow-none",
1532
+ layoutResizeHandle: "text-white/65 hover:bg-white/10 active:bg-white/15 focus-visible:bg-white/10",
1533
+ layoutResizeHandleIndicator: "bg-white/45 group-hover/resize:bg-white/75"
1432
1534
  }
1433
1535
  };
1434
1536
  var presetDefaults = {
@@ -1581,6 +1683,16 @@ function getBaseButtonToneClassName(theme, tone = "default", active = false) {
1581
1683
  active && theme.slots.buttonActive
1582
1684
  );
1583
1685
  }
1686
+ function getBaseMenuItemToneClassName(theme, tone = "default") {
1687
+ return cn(
1688
+ tone === "default" && theme.slots.menuItemDefault,
1689
+ tone === "primary" && theme.slots.menuItemPrimary,
1690
+ tone === "success" && theme.slots.menuItemSuccess,
1691
+ tone === "warning" && theme.slots.menuItemWarning,
1692
+ tone === "danger" && theme.slots.menuItemDanger,
1693
+ tone === "muted" && theme.slots.menuItemMuted
1694
+ );
1695
+ }
1584
1696
  function LoadingIcon() {
1585
1697
  return /* @__PURE__ */ jsxRuntime.jsxs(
1586
1698
  "svg",
@@ -1801,6 +1913,198 @@ var BaseCheckbox = react.forwardRef(
1801
1913
  );
1802
1914
  }
1803
1915
  );
1916
+ function renderItemContent({
1917
+ label,
1918
+ icon,
1919
+ shortcut,
1920
+ children,
1921
+ classNames,
1922
+ inset,
1923
+ indicator
1924
+ }) {
1925
+ const resolvedLabel = children ?? label;
1926
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1927
+ indicator ? indicator : null,
1928
+ hasRenderableNode(icon) ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn(classNames?.icon), children: icon }) : inset ? /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", className: "h-4 w-4 shrink-0" }) : null,
1929
+ hasRenderableNode(resolvedLabel) ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn(classNames?.label), children: resolvedLabel }) : null,
1930
+ hasRenderableNode(shortcut) ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn(classNames?.shortcut), children: shortcut }) : null
1931
+ ] });
1932
+ }
1933
+ function BaseContextMenu({
1934
+ children,
1935
+ trigger,
1936
+ content,
1937
+ disabled = false,
1938
+ modal = true,
1939
+ dir,
1940
+ appearance,
1941
+ className,
1942
+ classNames,
1943
+ onOpenChange
1944
+ }) {
1945
+ const theme = resolveBaseAppearance(appearance);
1946
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1947
+ ContextMenu__namespace.Root,
1948
+ {
1949
+ onOpenChange,
1950
+ modal,
1951
+ dir,
1952
+ children: [
1953
+ trigger ? /* @__PURE__ */ jsxRuntime.jsx(
1954
+ ContextMenu__namespace.Trigger,
1955
+ {
1956
+ disabled,
1957
+ className: cn(
1958
+ theme.slots.menuTrigger,
1959
+ disabled && theme.slots.menuItemDisabled,
1960
+ classNames?.trigger,
1961
+ className
1962
+ ),
1963
+ children: trigger
1964
+ }
1965
+ ) : null,
1966
+ content ? /* @__PURE__ */ jsxRuntime.jsx(BaseContextMenuContent, { appearance, className: classNames?.content, children: content }) : null,
1967
+ children
1968
+ ]
1969
+ }
1970
+ );
1971
+ }
1972
+ function BaseContextMenuTrigger({
1973
+ children,
1974
+ disabled = false,
1975
+ asChild = false,
1976
+ appearance,
1977
+ className,
1978
+ style,
1979
+ ...triggerProps
1980
+ }) {
1981
+ const theme = resolveBaseAppearance(appearance);
1982
+ return /* @__PURE__ */ jsxRuntime.jsx(
1983
+ ContextMenu__namespace.Trigger,
1984
+ {
1985
+ ...triggerProps,
1986
+ asChild,
1987
+ disabled,
1988
+ className: cn(
1989
+ !asChild && theme.slots.menuTrigger,
1990
+ disabled && !asChild && theme.slots.menuItemDisabled,
1991
+ className
1992
+ ),
1993
+ style,
1994
+ children
1995
+ }
1996
+ );
1997
+ }
1998
+ function BaseContextMenuContent({
1999
+ children,
2000
+ appearance,
2001
+ className,
2002
+ classNames,
2003
+ style,
2004
+ ...contentProps
2005
+ }) {
2006
+ const theme = resolveBaseAppearance(appearance);
2007
+ return /* @__PURE__ */ jsxRuntime.jsx(ContextMenu__namespace.Portal, { children: /* @__PURE__ */ jsxRuntime.jsx(
2008
+ ContextMenu__namespace.Content,
2009
+ {
2010
+ ...contentProps,
2011
+ className: cn(theme.slots.menuContent, classNames?.root, className),
2012
+ style: {
2013
+ ...theme.styles.menuContent,
2014
+ ...style
2015
+ },
2016
+ children
2017
+ }
2018
+ ) });
2019
+ }
2020
+ function BaseContextMenuLabel({
2021
+ children,
2022
+ appearance,
2023
+ className,
2024
+ style,
2025
+ ...labelProps
2026
+ }) {
2027
+ const theme = resolveBaseAppearance(appearance);
2028
+ return /* @__PURE__ */ jsxRuntime.jsx(
2029
+ ContextMenu__namespace.Label,
2030
+ {
2031
+ ...labelProps,
2032
+ className: cn(theme.slots.menuLabel, className),
2033
+ style,
2034
+ children
2035
+ }
2036
+ );
2037
+ }
2038
+ function BaseContextMenuSeparator({
2039
+ appearance,
2040
+ className,
2041
+ style,
2042
+ ...separatorProps
2043
+ }) {
2044
+ const theme = resolveBaseAppearance(appearance);
2045
+ return /* @__PURE__ */ jsxRuntime.jsx(
2046
+ ContextMenu__namespace.Separator,
2047
+ {
2048
+ ...separatorProps,
2049
+ className: cn(theme.slots.menuSeparator, className),
2050
+ style
2051
+ }
2052
+ );
2053
+ }
2054
+ function BaseContextMenuItem({
2055
+ children,
2056
+ label,
2057
+ icon,
2058
+ shortcut,
2059
+ tone,
2060
+ disabled = false,
2061
+ inset = false,
2062
+ appearance,
2063
+ className,
2064
+ classNames,
2065
+ style,
2066
+ onSelect,
2067
+ ...itemProps
2068
+ }) {
2069
+ const theme = resolveBaseAppearance(appearance);
2070
+ return /* @__PURE__ */ jsxRuntime.jsx(
2071
+ ContextMenu__namespace.Item,
2072
+ {
2073
+ ...itemProps,
2074
+ disabled,
2075
+ className: cn(
2076
+ theme.slots.menuItem,
2077
+ getBaseMenuItemToneClassName(theme, tone),
2078
+ disabled && theme.slots.menuItemDisabled,
2079
+ classNames?.root,
2080
+ className
2081
+ ),
2082
+ style: {
2083
+ ...theme.styles.menuItem,
2084
+ ...style
2085
+ },
2086
+ onSelect: (event) => {
2087
+ if (disabled) {
2088
+ event.preventDefault();
2089
+ return;
2090
+ }
2091
+ onSelect?.(event);
2092
+ },
2093
+ children: renderItemContent({
2094
+ children,
2095
+ label,
2096
+ icon,
2097
+ shortcut,
2098
+ inset,
2099
+ classNames: {
2100
+ icon: cn(theme.slots.menuItemIcon, classNames?.icon),
2101
+ label: cn(theme.slots.menuItemLabel, classNames?.label),
2102
+ shortcut: cn(theme.slots.menuItemShortcut, classNames?.shortcut)
2103
+ }
2104
+ })
2105
+ }
2106
+ );
2107
+ }
1804
2108
  var columnClassNames = {
1805
2109
  1: "grid-cols-1",
1806
2110
  2: "md:grid-cols-2",
@@ -2699,7 +3003,7 @@ function BaseTableRow({
2699
3003
  }
2700
3004
  );
2701
3005
  }
2702
- function BaseTableHead({
3006
+ var BaseTableHead = react.forwardRef(function BaseTableHead2({
2703
3007
  columnId,
2704
3008
  align = "left",
2705
3009
  icon,
@@ -2727,10 +3031,18 @@ function BaseTableHead({
2727
3031
  onDragOver,
2728
3032
  onDrop,
2729
3033
  ...headProps
2730
- }) {
3034
+ }, forwardedRef) {
2731
3035
  const tableContext = useBaseTableContext(appearance);
2732
3036
  const { theme } = tableContext;
2733
3037
  const headRef = react.useRef(null);
3038
+ const setHeadRef = (node) => {
3039
+ headRef.current = node;
3040
+ if (typeof forwardedRef === "function") {
3041
+ forwardedRef(node);
3042
+ } else if (forwardedRef) {
3043
+ forwardedRef.current = node;
3044
+ }
3045
+ };
2734
3046
  const controlledWidth = columnId && tableContext.columnSizes?.[columnId] !== void 0 ? tableContext.columnSizes[columnId] : width;
2735
3047
  const canDrag = Boolean(
2736
3048
  columnId && draggable !== false && (draggable || tableContext.columnDragEnabled) && tableContext.columnOrder && tableContext.onColumnOrderChange
@@ -2885,7 +3197,7 @@ function BaseTableHead({
2885
3197
  "th",
2886
3198
  {
2887
3199
  ...headProps,
2888
- ref: headRef,
3200
+ ref: setHeadRef,
2889
3201
  scope: headProps.scope ?? "col",
2890
3202
  "aria-sort": ariaSort,
2891
3203
  className: cn(
@@ -2920,7 +3232,7 @@ function BaseTableHead({
2920
3232
  ]
2921
3233
  }
2922
3234
  );
2923
- }
3235
+ });
2924
3236
  function BaseTableCell({
2925
3237
  align = "left",
2926
3238
  appearance,
@@ -4312,6 +4624,659 @@ function WorkbenchTableView({
4312
4624
  }
4313
4625
  );
4314
4626
  }
4627
+ function toCssSize3(value) {
4628
+ if (value === void 0) return void 0;
4629
+ return typeof value === "number" ? `${value}px` : value;
4630
+ }
4631
+ function isBrowser() {
4632
+ return typeof window !== "undefined";
4633
+ }
4634
+ function defaultGetRowKey2(row, rowIndex) {
4635
+ return row?.id ?? row?.key ?? rowIndex;
4636
+ }
4637
+ function getColumnDefaultSize(column) {
4638
+ if (typeof column.width === "number") return column.width;
4639
+ if (typeof column.minWidth === "number") return column.minWidth;
4640
+ return 160;
4641
+ }
4642
+ function buildDefaultColumnSizes(columns, explicit) {
4643
+ return columns.reduce((acc, column) => {
4644
+ acc[column.key] = explicit?.[column.key] ?? getColumnDefaultSize(column);
4645
+ return acc;
4646
+ }, {});
4647
+ }
4648
+ function loadStoredColumnSizes(storageKey, defaults) {
4649
+ if (!storageKey || !isBrowser()) return defaults;
4650
+ try {
4651
+ const parsed = JSON.parse(window.localStorage.getItem(storageKey) || "{}");
4652
+ return Object.keys(defaults).reduce((acc, key) => {
4653
+ const value = Number(parsed?.[key]);
4654
+ acc[key] = Number.isFinite(value) ? value : defaults[key];
4655
+ return acc;
4656
+ }, {});
4657
+ } catch {
4658
+ return defaults;
4659
+ }
4660
+ }
4661
+ function persistColumnSizes(storageKey, sizes) {
4662
+ if (!storageKey || !isBrowser()) return;
4663
+ window.localStorage.setItem(storageKey, JSON.stringify(sizes));
4664
+ }
4665
+ function getFrozenColumnStorageKey(storageKey) {
4666
+ return storageKey ? `${storageKey}.frozenColumnCount` : void 0;
4667
+ }
4668
+ function getFrozenEndColumnStorageKey(storageKey) {
4669
+ return storageKey ? `${storageKey}.frozenEndColumnCount` : void 0;
4670
+ }
4671
+ function clampFrozenColumnCount(count, columnCount) {
4672
+ if (!Number.isFinite(count)) return 0;
4673
+ return Math.max(0, Math.min(Math.round(count), columnCount));
4674
+ }
4675
+ function normalizeFrozenColumnCounts(startCount, endCount, columnCount) {
4676
+ const normalizedStartCount = clampFrozenColumnCount(startCount, columnCount);
4677
+ const normalizedEndCount = clampFrozenColumnCount(endCount, Math.max(0, columnCount - normalizedStartCount));
4678
+ return {
4679
+ startCount: normalizedStartCount,
4680
+ endCount: normalizedEndCount
4681
+ };
4682
+ }
4683
+ function loadStoredFrozenColumnCount(storageKey, defaultCount, columnCount) {
4684
+ const fallback = clampFrozenColumnCount(defaultCount, columnCount);
4685
+ const frozenStorageKey = getFrozenColumnStorageKey(storageKey);
4686
+ if (!frozenStorageKey || !isBrowser()) return fallback;
4687
+ try {
4688
+ const storedValue = window.localStorage.getItem(frozenStorageKey);
4689
+ if (storedValue === null) return fallback;
4690
+ const value = Number(storedValue);
4691
+ return Number.isFinite(value) ? clampFrozenColumnCount(value, columnCount) : fallback;
4692
+ } catch {
4693
+ return fallback;
4694
+ }
4695
+ }
4696
+ function persistFrozenColumnCount(storageKey, count) {
4697
+ const frozenStorageKey = getFrozenColumnStorageKey(storageKey);
4698
+ if (!frozenStorageKey || !isBrowser()) return;
4699
+ window.localStorage.setItem(frozenStorageKey, String(count));
4700
+ }
4701
+ function loadStoredFrozenEndColumnCount(storageKey, defaultCount, columnCount) {
4702
+ const fallback = clampFrozenColumnCount(defaultCount, columnCount);
4703
+ const frozenStorageKey = getFrozenEndColumnStorageKey(storageKey);
4704
+ if (!frozenStorageKey || !isBrowser()) return fallback;
4705
+ try {
4706
+ const storedValue = window.localStorage.getItem(frozenStorageKey);
4707
+ if (storedValue === null) return fallback;
4708
+ const value = Number(storedValue);
4709
+ return Number.isFinite(value) ? clampFrozenColumnCount(value, columnCount) : fallback;
4710
+ } catch {
4711
+ return fallback;
4712
+ }
4713
+ }
4714
+ function persistFrozenEndColumnCount(storageKey, count) {
4715
+ const frozenStorageKey = getFrozenEndColumnStorageKey(storageKey);
4716
+ if (!frozenStorageKey || !isBrowser()) return;
4717
+ window.localStorage.setItem(frozenStorageKey, String(count));
4718
+ }
4719
+ function normalizeColumnOrder2(columnKeys, columnOrder) {
4720
+ const validColumnKeys = new Set(columnKeys);
4721
+ const orderedKeys = (columnOrder || []).filter((columnKey) => validColumnKeys.has(columnKey));
4722
+ const orderedKeySet = new Set(orderedKeys);
4723
+ const remainingKeys = columnKeys.filter((columnKey) => !orderedKeySet.has(columnKey));
4724
+ return [...orderedKeys, ...remainingKeys];
4725
+ }
4726
+ function getOrderedColumns2(columns, columnOrder) {
4727
+ const normalizedOrder = normalizeColumnOrder2(columns.map((column) => column.key), columnOrder);
4728
+ const columnMap = new Map(columns.map((column) => [column.key, column]));
4729
+ return normalizedOrder.map((columnKey) => columnMap.get(columnKey)).filter(Boolean);
4730
+ }
4731
+ function getColumnNumericWidth(column, columnSizes) {
4732
+ const controlledWidth = columnSizes[column.key];
4733
+ if (typeof controlledWidth === "number") return controlledWidth;
4734
+ return getColumnDefaultSize(column);
4735
+ }
4736
+ function buildFrozenOffsets(columns, columnSizes, frozenColumnCount) {
4737
+ const offsets = /* @__PURE__ */ new Map();
4738
+ let left = 0;
4739
+ columns.slice(0, Math.max(0, frozenColumnCount)).forEach((column) => {
4740
+ offsets.set(column.key, left);
4741
+ left += getColumnNumericWidth(column, columnSizes);
4742
+ });
4743
+ return offsets;
4744
+ }
4745
+ function buildFrozenEndOffsets(columns, columnSizes, frozenEndColumnCount) {
4746
+ const offsets = /* @__PURE__ */ new Map();
4747
+ let right = 0;
4748
+ columns.slice(Math.max(0, columns.length - frozenEndColumnCount)).reverse().forEach((column) => {
4749
+ offsets.set(column.key, right);
4750
+ right += getColumnNumericWidth(column, columnSizes);
4751
+ });
4752
+ return offsets;
4753
+ }
4754
+ function resolveRowClassName(rowClassName, row, rowIndex) {
4755
+ return typeof rowClassName === "function" ? rowClassName(row, rowIndex) : rowClassName;
4756
+ }
4757
+ function renderDefaultCell(column, row) {
4758
+ const value = row?.[column.key];
4759
+ if (value === void 0 || value === null || value === "") return "\u2014";
4760
+ return String(value);
4761
+ }
4762
+ function InteractiveTableCellContent({
4763
+ children,
4764
+ wrap
4765
+ }) {
4766
+ return /* @__PURE__ */ jsxRuntime.jsx(
4767
+ "div",
4768
+ {
4769
+ className: cn(
4770
+ "min-w-0 max-w-full overflow-auto overscroll-contain [scrollbar-width:thin]",
4771
+ wrap ? "max-h-20 whitespace-pre-wrap break-words leading-5" : "whitespace-nowrap"
4772
+ ),
4773
+ children
4774
+ }
4775
+ );
4776
+ }
4777
+ function PinIcon({ className }) {
4778
+ return /* @__PURE__ */ jsxRuntime.jsxs(
4779
+ "svg",
4780
+ {
4781
+ "aria-hidden": "true",
4782
+ viewBox: "0 0 16 16",
4783
+ className,
4784
+ fill: "none",
4785
+ stroke: "currentColor",
4786
+ strokeLinecap: "round",
4787
+ strokeLinejoin: "round",
4788
+ strokeWidth: "1.75",
4789
+ children: [
4790
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M5.25 2.75h5.5" }),
4791
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M6.25 2.75v4L4.5 9.25h7L9.75 6.75v-4" }),
4792
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M8 9.25v4" })
4793
+ ]
4794
+ }
4795
+ );
4796
+ }
4797
+ function InteractiveTable({
4798
+ rows = [],
4799
+ columns = [],
4800
+ pinnedTopRows = [],
4801
+ getRowKey = defaultGetRowKey2,
4802
+ getPinnedTopRowKey = defaultGetRowKey2,
4803
+ renderCell,
4804
+ renderPinnedTopCell,
4805
+ renderColumnHeader,
4806
+ onRowClick,
4807
+ getRowState,
4808
+ rowClassName,
4809
+ pinnedTopRowClassName,
4810
+ emptyState = "\u2014",
4811
+ columnMenuLabels,
4812
+ columnStorageKey,
4813
+ columnOrder,
4814
+ columnSizes,
4815
+ defaultColumnSizes,
4816
+ columnDragEnabled = false,
4817
+ columnResizeEnabled = true,
4818
+ frozenColumnCount = 0,
4819
+ frozenEndColumnCount = 0,
4820
+ tableMinWidth,
4821
+ bodyMaxHeight = "min(60vh, 42rem)",
4822
+ appearance,
4823
+ className,
4824
+ tableClassName,
4825
+ classNames,
4826
+ style,
4827
+ onColumnOrderChange,
4828
+ onColumnSizeChange,
4829
+ onResetColumnSizes,
4830
+ onFrozenColumnCountChange,
4831
+ onFrozenEndColumnCountChange,
4832
+ onSort
4833
+ }) {
4834
+ const columnKeySignature = columns.map((column) => column.key).join("");
4835
+ const defaultOrder = react.useMemo(
4836
+ () => columnKeySignature ? columnKeySignature.split("") : [],
4837
+ [columnKeySignature]
4838
+ );
4839
+ const defaultSizes = react.useMemo(
4840
+ () => buildDefaultColumnSizes(columns, defaultColumnSizes),
4841
+ [columns, defaultColumnSizes]
4842
+ );
4843
+ const [internalColumnOrder, setInternalColumnOrder] = react.useState(defaultOrder);
4844
+ const [internalColumnSizes, setInternalColumnSizes] = react.useState(() => loadStoredColumnSizes(columnStorageKey, defaultSizes));
4845
+ const [internalFrozenColumnCount, setInternalFrozenColumnCount] = react.useState(() => loadStoredFrozenColumnCount(columnStorageKey, frozenColumnCount, columns.length));
4846
+ const [internalFrozenEndColumnCount, setInternalFrozenEndColumnCount] = react.useState(() => loadStoredFrozenEndColumnCount(columnStorageKey, frozenEndColumnCount, columns.length));
4847
+ react.useEffect(() => {
4848
+ setInternalColumnOrder((current) => normalizeColumnOrder2(defaultOrder, current));
4849
+ }, [defaultOrder]);
4850
+ react.useEffect(() => {
4851
+ if (columnSizes) return;
4852
+ setInternalColumnSizes(loadStoredColumnSizes(columnStorageKey, defaultSizes));
4853
+ }, [columnSizes, columnStorageKey, defaultSizes]);
4854
+ react.useEffect(() => {
4855
+ setInternalFrozenColumnCount(loadStoredFrozenColumnCount(columnStorageKey, frozenColumnCount, columns.length));
4856
+ }, [columnStorageKey, columns.length, frozenColumnCount]);
4857
+ react.useEffect(() => {
4858
+ setInternalFrozenEndColumnCount(loadStoredFrozenEndColumnCount(columnStorageKey, frozenEndColumnCount, columns.length));
4859
+ }, [columnStorageKey, columns.length, frozenEndColumnCount]);
4860
+ const resolvedColumnOrder = columnOrder ? normalizeColumnOrder2(defaultOrder, columnOrder) : internalColumnOrder;
4861
+ const resolvedColumnSizes = columnSizes ?? internalColumnSizes;
4862
+ const orderedColumns = getOrderedColumns2(columns, resolvedColumnOrder);
4863
+ const {
4864
+ startCount: resolvedFrozenColumnCount,
4865
+ endCount: resolvedFrozenEndColumnCount
4866
+ } = normalizeFrozenColumnCounts(internalFrozenColumnCount, internalFrozenEndColumnCount, orderedColumns.length);
4867
+ const frozenOffsets = buildFrozenOffsets(orderedColumns, resolvedColumnSizes, resolvedFrozenColumnCount);
4868
+ const frozenEndOffsets = buildFrozenEndOffsets(orderedColumns, resolvedColumnSizes, resolvedFrozenEndColumnCount);
4869
+ const resolvedMinWidth = tableMinWidth ?? Math.max(760, orderedColumns.reduce((total, column) => total + getColumnNumericWidth(column, resolvedColumnSizes), 0));
4870
+ const labels = {
4871
+ columnActions: columnMenuLabels?.columnActions ?? "Column actions",
4872
+ freezeColumn: columnMenuLabels?.freezeColumn ?? "Freeze to left",
4873
+ freezeEndColumn: columnMenuLabels?.freezeEndColumn ?? "Freeze to right",
4874
+ unfreezeColumn: columnMenuLabels?.unfreezeColumn ?? "Unfreeze from left",
4875
+ unfreezeEndColumn: columnMenuLabels?.unfreezeEndColumn ?? "Unfreeze from right",
4876
+ unfreezeAllColumns: columnMenuLabels?.unfreezeAllColumns ?? "Unfreeze all columns",
4877
+ resetColumnWidth: columnMenuLabels?.resetColumnWidth ?? "Reset column width",
4878
+ frozenColumnTitle: columnMenuLabels?.frozenColumnTitle ?? "Frozen column"
4879
+ };
4880
+ const handleColumnOrderChange = react.useCallback((nextOrder, detail) => {
4881
+ const normalizedOrder = normalizeColumnOrder2(defaultOrder, nextOrder);
4882
+ if (!columnOrder) {
4883
+ setInternalColumnOrder(normalizedOrder);
4884
+ }
4885
+ onColumnOrderChange?.(normalizedOrder, detail);
4886
+ }, [columnOrder, defaultOrder, onColumnOrderChange]);
4887
+ const handleColumnSizeChange = react.useCallback((columnId, width, detail) => {
4888
+ const column = columns.find((item) => item.key === columnId);
4889
+ const minWidth = column?.minWidth;
4890
+ const maxWidth = column?.maxWidth;
4891
+ const nextWidth = Math.max(
4892
+ typeof minWidth === "number" ? minWidth : 0,
4893
+ Math.min(width, typeof maxWidth === "number" ? maxWidth : Number.POSITIVE_INFINITY)
4894
+ );
4895
+ const nextSizes = {
4896
+ ...resolvedColumnSizes,
4897
+ [columnId]: nextWidth
4898
+ };
4899
+ if (!columnSizes) {
4900
+ setInternalColumnSizes(nextSizes);
4901
+ }
4902
+ persistColumnSizes(columnStorageKey, nextSizes);
4903
+ onColumnSizeChange?.(columnId, nextWidth, detail);
4904
+ }, [columnSizes, columnStorageKey, columns, onColumnSizeChange, resolvedColumnSizes]);
4905
+ const handleResetColumnSize = react.useCallback((column) => {
4906
+ const nextWidth = defaultSizes[column.key] ?? getColumnDefaultSize(column);
4907
+ const previousWidth = getColumnNumericWidth(column, resolvedColumnSizes);
4908
+ const nextSizes = {
4909
+ ...resolvedColumnSizes,
4910
+ [column.key]: nextWidth
4911
+ };
4912
+ if (!columnSizes) {
4913
+ setInternalColumnSizes(nextSizes);
4914
+ }
4915
+ persistColumnSizes(columnStorageKey, nextSizes);
4916
+ onColumnSizeChange?.(column.key, nextWidth, {
4917
+ columnId: column.key,
4918
+ previousWidth,
4919
+ minWidth: column.minWidth,
4920
+ maxWidth: column.maxWidth
4921
+ });
4922
+ onResetColumnSizes?.(nextSizes);
4923
+ }, [columnSizes, columnStorageKey, defaultSizes, onColumnSizeChange, onResetColumnSizes, resolvedColumnSizes]);
4924
+ const setFrozenColumnCount = react.useCallback((nextCount) => {
4925
+ const normalizedCount = clampFrozenColumnCount(nextCount, Math.max(0, orderedColumns.length - resolvedFrozenEndColumnCount));
4926
+ setInternalFrozenColumnCount(normalizedCount);
4927
+ persistFrozenColumnCount(columnStorageKey, normalizedCount);
4928
+ onFrozenColumnCountChange?.(normalizedCount);
4929
+ }, [columnStorageKey, onFrozenColumnCountChange, orderedColumns.length, resolvedFrozenEndColumnCount]);
4930
+ const setFrozenEndColumnCount = react.useCallback((nextCount) => {
4931
+ const normalizedCount = clampFrozenColumnCount(nextCount, Math.max(0, orderedColumns.length - resolvedFrozenColumnCount));
4932
+ setInternalFrozenEndColumnCount(normalizedCount);
4933
+ persistFrozenEndColumnCount(columnStorageKey, normalizedCount);
4934
+ onFrozenEndColumnCountChange?.(normalizedCount);
4935
+ }, [columnStorageKey, onFrozenEndColumnCountChange, orderedColumns.length, resolvedFrozenColumnCount]);
4936
+ const getFrozenPosition = (columnIndex) => {
4937
+ if (columnIndex < resolvedFrozenColumnCount) return "start";
4938
+ if (columnIndex >= orderedColumns.length - resolvedFrozenEndColumnCount) return "end";
4939
+ return void 0;
4940
+ };
4941
+ const getFrozenClassName = (column, columnIndex, isHeader = false) => {
4942
+ const position = getFrozenPosition(columnIndex);
4943
+ if (!position) return void 0;
4944
+ return cn(
4945
+ "sticky",
4946
+ position === "start" ? "shadow-[1px_0_0_0_hsl(var(--border)/0.45)]" : "shadow-[-1px_0_0_0_hsl(var(--border)/0.45)]",
4947
+ isHeader ? "bg-muted/60" : "bg-inherit",
4948
+ isHeader ? "z-40" : "z-20",
4949
+ (columnIndex === 0 || columnIndex === orderedColumns.length - 1) && (isHeader ? "z-50" : "z-30")
4950
+ );
4951
+ };
4952
+ const getFrozenStyle = (column, columnIndex) => {
4953
+ const position = getFrozenPosition(columnIndex);
4954
+ if (position === "start") return { left: frozenOffsets.get(column.key) ?? 0 };
4955
+ if (position === "end") return { right: frozenEndOffsets.get(column.key) ?? 0 };
4956
+ return void 0;
4957
+ };
4958
+ return /* @__PURE__ */ jsxRuntime.jsx(
4959
+ BaseTableContainer,
4960
+ {
4961
+ appearance,
4962
+ className: cn("flex h-full min-h-0 flex-col overflow-hidden rounded-lg border border-border/60 bg-card", classNames?.root, className),
4963
+ style,
4964
+ children: /* @__PURE__ */ jsxRuntime.jsx(
4965
+ "div",
4966
+ {
4967
+ className: cn("min-h-0 flex-1 overflow-auto", classNames?.scrollArea),
4968
+ style: { maxHeight: toCssSize3(bodyMaxHeight) },
4969
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
4970
+ BaseTable,
4971
+ {
4972
+ appearance,
4973
+ columnOrder: resolvedColumnOrder,
4974
+ columnSizes: resolvedColumnSizes,
4975
+ columnDragEnabled,
4976
+ columnResizeEnabled,
4977
+ onColumnOrderChange: handleColumnOrderChange,
4978
+ onColumnSizeChange: handleColumnSizeChange,
4979
+ className: cn("w-full table-fixed text-left text-xs", classNames?.table, tableClassName),
4980
+ style: { minWidth: resolvedMinWidth },
4981
+ children: [
4982
+ /* @__PURE__ */ jsxRuntime.jsx("colgroup", { children: orderedColumns.map((column) => /* @__PURE__ */ jsxRuntime.jsx(
4983
+ "col",
4984
+ {
4985
+ style: {
4986
+ width: toCssSize3(resolvedColumnSizes[column.key] ?? column.width),
4987
+ minWidth: toCssSize3(column.minWidth)
4988
+ }
4989
+ },
4990
+ column.key
4991
+ )) }),
4992
+ /* @__PURE__ */ jsxRuntime.jsx(BaseTableHeader, { appearance, className: cn("border-b border-border/60 bg-muted/60 text-[11px] font-medium text-muted-foreground", classNames?.tableHeader), children: /* @__PURE__ */ jsxRuntime.jsx(BaseTableRow, { appearance, className: cn("hover:bg-transparent", classNames?.headerRow), children: orderedColumns.map((column, columnIndex) => {
4993
+ const headerContent = renderColumnHeader ? renderColumnHeader(column, { column, columnIndex, columns: orderedColumns, rows }) : column.label;
4994
+ const sortable = Boolean(column.sortable);
4995
+ const handleSort = sortable && onSort ? () => onSort(column.key, column) : void 0;
4996
+ const isFrozenStart = columnIndex < resolvedFrozenColumnCount;
4997
+ const isFrozenEnd = columnIndex >= orderedColumns.length - resolvedFrozenEndColumnCount;
4998
+ const isFrozen = isFrozenStart || isFrozenEnd;
4999
+ const isColumnAtDefaultWidth = getColumnNumericWidth(column, resolvedColumnSizes) === (defaultSizes[column.key] ?? getColumnDefaultSize(column));
5000
+ return /* @__PURE__ */ jsxRuntime.jsxs(BaseContextMenu, { modal: false, children: [
5001
+ /* @__PURE__ */ jsxRuntime.jsx(BaseContextMenuTrigger, { asChild: true, appearance, children: /* @__PURE__ */ jsxRuntime.jsx(
5002
+ BaseTableHead,
5003
+ {
5004
+ appearance,
5005
+ columnId: column.key,
5006
+ align: column.align,
5007
+ label: headerContent,
5008
+ description: column.description,
5009
+ trailing: isFrozen ? /* @__PURE__ */ jsxRuntime.jsx("span", { title: labels.frozenColumnTitle, className: "inline-flex h-5 w-5 items-center justify-center rounded text-primary", children: /* @__PURE__ */ jsxRuntime.jsx(PinIcon, { className: "h-3.5 w-3.5" }) }) : null,
5010
+ sortable,
5011
+ sortDirection: column.sortDirection,
5012
+ sortLabel: column.sortLabel,
5013
+ onSort: handleSort,
5014
+ draggable: column.draggable,
5015
+ resizable: column.resizable,
5016
+ width: column.width,
5017
+ minWidth: column.minWidth,
5018
+ maxWidth: column.maxWidth,
5019
+ className: cn(
5020
+ "sticky top-0 h-9 whitespace-nowrap border-r border-border/50 bg-muted/60 px-2.5 py-2 backdrop-blur",
5021
+ getFrozenClassName(column, columnIndex, true),
5022
+ column.headerClassName,
5023
+ column.className,
5024
+ classNames?.headerCell
5025
+ ),
5026
+ style: getFrozenStyle(column, columnIndex)
5027
+ }
5028
+ ) }),
5029
+ /* @__PURE__ */ jsxRuntime.jsxs(BaseContextMenuContent, { appearance, alignOffset: -4, className: "min-w-44", children: [
5030
+ /* @__PURE__ */ jsxRuntime.jsx(BaseContextMenuLabel, { appearance, children: labels.columnActions }),
5031
+ isFrozen ? /* @__PURE__ */ jsxRuntime.jsx(
5032
+ BaseContextMenuItem,
5033
+ {
5034
+ appearance,
5035
+ onSelect: () => {
5036
+ if (isFrozenEnd) setFrozenEndColumnCount(orderedColumns.length - columnIndex - 1);
5037
+ else setFrozenColumnCount(columnIndex);
5038
+ },
5039
+ children: isFrozenEnd ? labels.unfreezeEndColumn : labels.unfreezeColumn
5040
+ }
5041
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
5042
+ BaseContextMenuItem,
5043
+ {
5044
+ appearance,
5045
+ onSelect: () => setFrozenColumnCount(columnIndex + 1),
5046
+ children: labels.freezeColumn
5047
+ }
5048
+ ),
5049
+ !isFrozen ? /* @__PURE__ */ jsxRuntime.jsx(
5050
+ BaseContextMenuItem,
5051
+ {
5052
+ appearance,
5053
+ onSelect: () => setFrozenEndColumnCount(orderedColumns.length - columnIndex),
5054
+ children: labels.freezeEndColumn
5055
+ }
5056
+ ) : null,
5057
+ /* @__PURE__ */ jsxRuntime.jsx(
5058
+ BaseContextMenuItem,
5059
+ {
5060
+ appearance,
5061
+ disabled: resolvedFrozenColumnCount === 0 && resolvedFrozenEndColumnCount === 0,
5062
+ onSelect: () => {
5063
+ setFrozenColumnCount(0);
5064
+ setFrozenEndColumnCount(0);
5065
+ },
5066
+ children: labels.unfreezeAllColumns
5067
+ }
5068
+ ),
5069
+ /* @__PURE__ */ jsxRuntime.jsx(BaseContextMenuSeparator, { appearance }),
5070
+ /* @__PURE__ */ jsxRuntime.jsx(
5071
+ BaseContextMenuItem,
5072
+ {
5073
+ appearance,
5074
+ disabled: isColumnAtDefaultWidth,
5075
+ onSelect: () => handleResetColumnSize(column),
5076
+ children: labels.resetColumnWidth
5077
+ }
5078
+ )
5079
+ ] })
5080
+ ] }, column.key);
5081
+ }) }) }),
5082
+ /* @__PURE__ */ jsxRuntime.jsxs(BaseTableBody, { appearance, className: cn("divide-y divide-border/50", classNames?.body), children: [
5083
+ pinnedTopRows.map((row, rowIndex) => {
5084
+ const key = getPinnedTopRowKey(row, rowIndex);
5085
+ const resolvedRowClassName = resolveRowClassName(pinnedTopRowClassName, row, rowIndex);
5086
+ return /* @__PURE__ */ jsxRuntime.jsx(
5087
+ BaseTableRow,
5088
+ {
5089
+ appearance,
5090
+ className: cn("bg-card/95", classNames?.pinnedTopRow, resolvedRowClassName),
5091
+ children: orderedColumns.map((column, columnIndex) => /* @__PURE__ */ jsxRuntime.jsx(
5092
+ BaseTableCell,
5093
+ {
5094
+ appearance,
5095
+ align: column.align,
5096
+ className: cn(
5097
+ "h-[52px] border-r border-border/50 px-2.5 py-1.5 align-middle",
5098
+ column.wrap ? "whitespace-normal" : "whitespace-nowrap",
5099
+ getFrozenClassName(column, columnIndex),
5100
+ column.cellClassName,
5101
+ classNames?.cell
5102
+ ),
5103
+ style: getFrozenStyle(column, columnIndex),
5104
+ children: /* @__PURE__ */ jsxRuntime.jsx(InteractiveTableCellContent, { wrap: column.wrap, children: renderPinnedTopCell ? renderPinnedTopCell(column, row, { row, rowIndex, column, columnIndex, isPinnedTopRow: true }) : renderDefaultCell(column, row) })
5105
+ },
5106
+ `pinned-${key}-${column.key}`
5107
+ ))
5108
+ },
5109
+ `pinned-${key}`
5110
+ );
5111
+ }),
5112
+ rows.length ? rows.map((row, rowIndex) => {
5113
+ const key = getRowKey(row, rowIndex);
5114
+ const state = getRowState?.(row, rowIndex) || {};
5115
+ const resolvedRowClassName = resolveRowClassName(rowClassName, row, rowIndex);
5116
+ return /* @__PURE__ */ jsxRuntime.jsx(
5117
+ BaseTableRow,
5118
+ {
5119
+ appearance,
5120
+ interactive: Boolean(onRowClick) && !state.disabled,
5121
+ selected: state.selected,
5122
+ disabled: state.disabled,
5123
+ onClick: () => {
5124
+ if (!state.disabled) onRowClick?.(row, rowIndex);
5125
+ },
5126
+ className: cn(
5127
+ "min-h-[52px] bg-card transition-colors",
5128
+ state.saving && "bg-primary/5",
5129
+ state.pending && "opacity-80",
5130
+ onRowClick && !state.disabled ? "cursor-pointer hover:bg-muted/30" : "hover:bg-muted/30",
5131
+ classNames?.row,
5132
+ resolvedRowClassName
5133
+ ),
5134
+ children: orderedColumns.map((column, columnIndex) => /* @__PURE__ */ jsxRuntime.jsx(
5135
+ BaseTableCell,
5136
+ {
5137
+ appearance,
5138
+ align: column.align,
5139
+ className: cn(
5140
+ "h-[52px] border-r border-border/50 px-2.5 py-1.5 align-middle",
5141
+ column.wrap ? "whitespace-normal" : "whitespace-nowrap",
5142
+ getFrozenClassName(column, columnIndex),
5143
+ column.cellClassName,
5144
+ classNames?.cell
5145
+ ),
5146
+ style: getFrozenStyle(column, columnIndex),
5147
+ children: /* @__PURE__ */ jsxRuntime.jsx(InteractiveTableCellContent, { wrap: column.wrap, children: renderCell ? renderCell(column, row, { row, rowIndex, column, columnIndex, isPinnedTopRow: false }) : renderDefaultCell(column, row) })
5148
+ },
5149
+ `${key}-${column.key}`
5150
+ ))
5151
+ },
5152
+ key
5153
+ );
5154
+ }) : pinnedTopRows.length ? null : /* @__PURE__ */ jsxRuntime.jsx(
5155
+ BaseTableEmpty,
5156
+ {
5157
+ appearance,
5158
+ colSpan: Math.max(orderedColumns.length, 1),
5159
+ className: classNames?.empty,
5160
+ children: emptyState
5161
+ }
5162
+ )
5163
+ ] })
5164
+ ]
5165
+ }
5166
+ )
5167
+ }
5168
+ )
5169
+ }
5170
+ );
5171
+ }
5172
+ function InteractiveTableEditableTextCell({
5173
+ value,
5174
+ placeholder,
5175
+ disabled,
5176
+ multiline = false,
5177
+ commitOnBlur = true,
5178
+ className,
5179
+ inputClassName,
5180
+ onCommit
5181
+ }) {
5182
+ const initialValue = String(value || "");
5183
+ const [draft, setDraft] = react.useState(initialValue);
5184
+ react.useEffect(() => {
5185
+ setDraft(initialValue);
5186
+ }, [initialValue]);
5187
+ const commit = react.useCallback(async () => {
5188
+ const nextValue = String(draft || "").trim();
5189
+ const previousValue = String(initialValue || "").trim();
5190
+ if (nextValue === previousValue) return;
5191
+ try {
5192
+ await onCommit?.(nextValue);
5193
+ } catch {
5194
+ setDraft(initialValue);
5195
+ }
5196
+ }, [draft, initialValue, onCommit]);
5197
+ const controlClassName = cn(
5198
+ "w-full resize-none rounded-sm border border-transparent bg-transparent px-1.5 py-1 text-xs text-foreground outline-none transition-colors",
5199
+ "placeholder:text-muted-foreground/70 hover:border-border/60 hover:bg-background focus:border-primary/45 focus:bg-background",
5200
+ multiline ? "min-h-[42px] leading-5" : "h-8",
5201
+ disabled && "cursor-not-allowed text-muted-foreground hover:border-transparent hover:bg-transparent",
5202
+ inputClassName
5203
+ );
5204
+ if (multiline) {
5205
+ return /* @__PURE__ */ jsxRuntime.jsx(
5206
+ "textarea",
5207
+ {
5208
+ className: cn(controlClassName, className),
5209
+ disabled,
5210
+ value: draft,
5211
+ placeholder,
5212
+ onChange: (event) => setDraft(event.target.value),
5213
+ onBlur: () => {
5214
+ if (commitOnBlur) void commit();
5215
+ },
5216
+ onKeyDown: (event) => {
5217
+ if ((event.metaKey || event.ctrlKey) && event.key === "Enter") {
5218
+ event.currentTarget.blur();
5219
+ }
5220
+ if (event.key === "Escape") {
5221
+ setDraft(initialValue);
5222
+ event.currentTarget.blur();
5223
+ }
5224
+ }
5225
+ }
5226
+ );
5227
+ }
5228
+ return /* @__PURE__ */ jsxRuntime.jsx(
5229
+ "input",
5230
+ {
5231
+ className: cn(controlClassName, className),
5232
+ disabled,
5233
+ value: draft,
5234
+ placeholder,
5235
+ onChange: (event) => setDraft(event.target.value),
5236
+ onBlur: () => {
5237
+ if (commitOnBlur) void commit();
5238
+ },
5239
+ onKeyDown: (event) => {
5240
+ if (event.key === "Enter") event.currentTarget.blur();
5241
+ if (event.key === "Escape") {
5242
+ setDraft(initialValue);
5243
+ event.currentTarget.blur();
5244
+ }
5245
+ }
5246
+ }
5247
+ );
5248
+ }
5249
+ function InteractiveTableReadonlyCell({
5250
+ children,
5251
+ mono = false,
5252
+ className
5253
+ }) {
5254
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("min-w-0 text-xs text-muted-foreground", mono && "font-mono", className), children: hasRenderableNode(children) ? children : "\u2014" });
5255
+ }
5256
+ function InteractiveTableSelectCell({
5257
+ value,
5258
+ options,
5259
+ disabled,
5260
+ ariaLabel,
5261
+ children,
5262
+ className,
5263
+ onChange
5264
+ }) {
5265
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("relative flex w-full items-center", className), children: [
5266
+ children,
5267
+ /* @__PURE__ */ jsxRuntime.jsx(
5268
+ "select",
5269
+ {
5270
+ "aria-label": ariaLabel,
5271
+ disabled,
5272
+ value,
5273
+ onChange: (event) => onChange?.(event.target.value),
5274
+ className: "absolute inset-0 h-full w-full cursor-pointer opacity-0 disabled:cursor-not-allowed",
5275
+ children: options.map((option) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: option.value, children: option.label }, option.value))
5276
+ }
5277
+ )
5278
+ ] });
5279
+ }
4315
5280
  var imageExtPattern = /\.(png|jpe?g|webp|gif|svg|bmp|avif)$/i;
4316
5281
  var audioExtPattern = /\.(wav|mp3|ogg|m4a|flac|aac)$/i;
4317
5282
  var isLikelyUrl = (value) => /^https?:\/\//i.test(String(value || ""));
@@ -5498,7 +6463,178 @@ function WorkbenchGalleryView({
5498
6463
  }
5499
6464
  );
5500
6465
  }
6466
+ function toCssSize4(value) {
6467
+ if (value === void 0) return void 0;
6468
+ return typeof value === "number" ? `${value}px` : value;
6469
+ }
6470
+ function defaultGetRowId(row, rowIndex) {
6471
+ return String(row?.id ?? row?.key ?? rowIndex);
6472
+ }
6473
+ function defaultGetColumnId(row) {
6474
+ return String(row?.columnId ?? row?.status ?? "");
6475
+ }
6476
+ function defaultRenderCard(row) {
6477
+ const value = row?.title ?? row?.name ?? row?.id ?? "Untitled";
6478
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-lg border border-border/70 bg-card px-3 py-2 text-sm text-foreground shadow-sm", children: String(value) });
6479
+ }
6480
+ function WorkbenchLaneDraggableCard({
6481
+ row,
6482
+ rowId,
6483
+ rowIndex,
6484
+ column,
6485
+ classNames,
6486
+ renderCard
6487
+ }) {
6488
+ const { attributes, listeners, setNodeRef, isDragging } = core.useDraggable({ id: rowId });
6489
+ return /* @__PURE__ */ jsxRuntime.jsx(
6490
+ "div",
6491
+ {
6492
+ ref: setNodeRef,
6493
+ ...listeners,
6494
+ ...attributes,
6495
+ className: cn("touch-none", classNames?.cardWrapper),
6496
+ children: renderCard(row, { row, rowIndex, column, isDragging, isOverlay: false })
6497
+ }
6498
+ );
6499
+ }
6500
+ function WorkbenchLaneColumnView({
6501
+ column,
6502
+ columnRows,
6503
+ columnWidth,
6504
+ columnMinHeight,
6505
+ emptyColumn,
6506
+ classNames,
6507
+ renderCard
6508
+ }) {
6509
+ const { setNodeRef, isOver } = core.useDroppable({ id: column.id });
6510
+ return /* @__PURE__ */ jsxRuntime.jsxs(
6511
+ "section",
6512
+ {
6513
+ className: cn(
6514
+ "flex shrink-0 flex-col rounded-xl border border-border/60 bg-card p-2 shadow-sm",
6515
+ classNames?.column,
6516
+ column.className
6517
+ ),
6518
+ style: { width: toCssSize4(columnWidth) ?? "280px" },
6519
+ children: [
6520
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex h-10 items-center gap-2 px-1", classNames?.columnHeader, column.headerClassName), children: [
6521
+ column.icon ? /* @__PURE__ */ jsxRuntime.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,
6522
+ /* @__PURE__ */ jsxRuntime.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 }),
6523
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("text-xs text-muted-foreground", classNames?.columnCount), children: columnRows.length })
6524
+ ] }),
6525
+ /* @__PURE__ */ jsxRuntime.jsx(
6526
+ "div",
6527
+ {
6528
+ ref: setNodeRef,
6529
+ className: cn(
6530
+ "mt-1 flex min-h-[200px] flex-1 flex-col gap-2 overflow-y-auto rounded-lg p-1 transition-colors [scrollbar-width:thin]",
6531
+ isOver && "bg-accent/60",
6532
+ classNames?.columnBody,
6533
+ column.bodyClassName
6534
+ ),
6535
+ style: { minHeight: toCssSize4(columnMinHeight) },
6536
+ children: columnRows.length ? columnRows.map(({ row, rowIndex, rowId }) => /* @__PURE__ */ jsxRuntime.jsx(
6537
+ WorkbenchLaneDraggableCard,
6538
+ {
6539
+ row,
6540
+ rowId,
6541
+ rowIndex,
6542
+ column,
6543
+ classNames,
6544
+ renderCard
6545
+ },
6546
+ rowId
6547
+ )) : emptyColumn ? /* @__PURE__ */ jsxRuntime.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
6548
+ }
6549
+ )
6550
+ ]
6551
+ }
6552
+ );
6553
+ }
6554
+ function WorkbenchLaneView({
6555
+ rows = [],
6556
+ columns = [],
6557
+ getRowId = defaultGetRowId,
6558
+ getColumnId = defaultGetColumnId,
6559
+ renderCard = defaultRenderCard,
6560
+ renderOverlayCard,
6561
+ onMoveRow,
6562
+ emptyColumn,
6563
+ activationDistance = 5,
6564
+ columnWidth = 280,
6565
+ columnMinHeight,
6566
+ className,
6567
+ classNames,
6568
+ style
6569
+ }) {
6570
+ const [activeRowId, setActiveRowId] = react.useState(null);
6571
+ const sensors = core.useSensors(core.useSensor(core.PointerSensor, { activationConstraint: { distance: activationDistance } }));
6572
+ const columnMap = react.useMemo(() => new Map(columns.map((column) => [column.id, column])), [columns]);
6573
+ const rowEntries = react.useMemo(() => rows.map((row, rowIndex) => ({
6574
+ row,
6575
+ rowIndex,
6576
+ rowId: getRowId(row, rowIndex),
6577
+ columnId: getColumnId(row, rowIndex)
6578
+ })), [getColumnId, getRowId, rows]);
6579
+ const activeEntry = activeRowId ? rowEntries.find((entry) => entry.rowId === activeRowId) : void 0;
6580
+ const rowsByColumn = react.useMemo(() => {
6581
+ const next = /* @__PURE__ */ new Map();
6582
+ columns.forEach((column) => next.set(column.id, []));
6583
+ rowEntries.forEach(({ row, rowIndex, rowId, columnId }) => {
6584
+ next.get(columnId)?.push({ row, rowIndex, rowId });
6585
+ });
6586
+ return next;
6587
+ }, [columns, rowEntries]);
6588
+ const activeColumn = activeEntry ? columnMap.get(activeEntry.columnId) : void 0;
6589
+ const handleDragStart = react.useCallback((event) => {
6590
+ setActiveRowId(String(event.active.id));
6591
+ }, []);
6592
+ const handleDragEnd = react.useCallback((event) => {
6593
+ setActiveRowId(null);
6594
+ const rowId = String(event.active.id);
6595
+ const nextColumnId = String(event.over?.id ?? "");
6596
+ const activeRow = rowEntries.find((entry) => entry.rowId === rowId);
6597
+ if (!activeRow || !columnMap.has(nextColumnId) || activeRow.columnId === nextColumnId) return;
6598
+ onMoveRow?.(rowId, nextColumnId, activeRow.row);
6599
+ }, [columnMap, onMoveRow, rowEntries]);
6600
+ const handleDragCancel = react.useCallback(() => {
6601
+ setActiveRowId(null);
6602
+ }, []);
6603
+ return /* @__PURE__ */ jsxRuntime.jsxs(core.DndContext, { sensors, onDragStart: handleDragStart, onDragEnd: handleDragEnd, onDragCancel: handleDragCancel, children: [
6604
+ /* @__PURE__ */ jsxRuntime.jsx(
6605
+ "div",
6606
+ {
6607
+ className: cn("flex min-h-0 flex-1 gap-4 overflow-x-auto p-4 [scrollbar-width:thin]", classNames?.root, className),
6608
+ style,
6609
+ children: columns.map((column) => /* @__PURE__ */ jsxRuntime.jsx(
6610
+ WorkbenchLaneColumnView,
6611
+ {
6612
+ column,
6613
+ columnRows: rowsByColumn.get(column.id) || [],
6614
+ columnWidth,
6615
+ columnMinHeight,
6616
+ emptyColumn,
6617
+ classNames,
6618
+ renderCard
6619
+ },
6620
+ column.id
6621
+ ))
6622
+ }
6623
+ ),
6624
+ /* @__PURE__ */ jsxRuntime.jsx(core.DragOverlay, { children: activeEntry && activeColumn ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn(classNames?.overlayWrapper), children: (renderOverlayCard || renderCard)(activeEntry.row, {
6625
+ row: activeEntry.row,
6626
+ rowIndex: activeEntry.rowIndex,
6627
+ column: activeColumn,
6628
+ isDragging: false,
6629
+ isOverlay: true
6630
+ }) }) : null })
6631
+ ] });
6632
+ }
5501
6633
 
6634
+ exports.InteractiveTable = InteractiveTable;
6635
+ exports.InteractiveTableEditableTextCell = InteractiveTableEditableTextCell;
6636
+ exports.InteractiveTableReadonlyCell = InteractiveTableReadonlyCell;
6637
+ exports.InteractiveTableSelectCell = InteractiveTableSelectCell;
5502
6638
  exports.WorkbenchContentPane = WorkbenchContentPane;
5503
6639
  exports.WorkbenchContentToolbar = WorkbenchContentToolbar;
5504
6640
  exports.WorkbenchDetailSidebar = WorkbenchDetailSidebar;
@@ -5506,6 +6642,7 @@ exports.WorkbenchGalleryCard = WorkbenchGalleryCard;
5506
6642
  exports.WorkbenchGallerySettingsButton = WorkbenchGallerySettingsButton;
5507
6643
  exports.WorkbenchGallerySettingsPanel = WorkbenchGallerySettingsPanel;
5508
6644
  exports.WorkbenchGalleryView = WorkbenchGalleryView;
6645
+ exports.WorkbenchLaneView = WorkbenchLaneView;
5509
6646
  exports.WorkbenchMasonryLayout = WorkbenchMasonryLayout;
5510
6647
  exports.WorkbenchResizableSidebar = WorkbenchResizableSidebar;
5511
6648
  exports.WorkbenchTableView = WorkbenchTableView;