react-glide-table 2.0.1 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/compound.cjs CHANGED
@@ -28,7 +28,7 @@ module.exports = __toCommonJS(compound_exports);
28
28
 
29
29
  // src/components/ui/table/components/DataTable/DataTable.tsx
30
30
  var import_react_table3 = require("@tanstack/react-table");
31
- var import_react8 = require("react");
31
+ var import_react9 = require("react");
32
32
 
33
33
  // src/components/ui/table/components/DataTable/DataTableRow.tsx
34
34
  var import_react_table = require("@tanstack/react-table");
@@ -49,6 +49,7 @@ var DATA_TABLE_VIRTUAL_OVERSCAN = 8;
49
49
  var DATA_TABLE_COLUMN_SIZE = 150;
50
50
  var DATA_TABLE_COLUMN_MIN_SIZE = 40;
51
51
  var DATA_TABLE_COLUMN_MAX_SIZE = 800;
52
+ var DATA_TABLE_COLUMN_REORDER_THRESHOLD = 4;
52
53
 
53
54
  // src/components/ui/table/DataTableContext.tsx
54
55
  var import_react = require("react");
@@ -100,6 +101,16 @@ function getCellEditDraftValue(value) {
100
101
  return String(value);
101
102
  }
102
103
 
104
+ // src/components/ui/table/features/cell-render/withCellUpdate.ts
105
+ function withCellUpdate(context, commitValue) {
106
+ return {
107
+ ...context,
108
+ update: (next) => {
109
+ commitValue(context.row.id, context.column.id, next);
110
+ }
111
+ };
112
+ }
113
+
103
114
  // src/components/ui/table/features/cell-selection/cellSelection.ts
104
115
  var INITIAL_DRAG_STATE = {
105
116
  isSelecting: false,
@@ -1130,6 +1141,7 @@ function DataTableRow({
1130
1141
  selection,
1131
1142
  cellSelection,
1132
1143
  cellEdit,
1144
+ cellRender,
1133
1145
  expand,
1134
1146
  columnResize,
1135
1147
  columnFreeze,
@@ -1167,6 +1179,10 @@ function DataTableRow({
1167
1179
  onCommitEdit,
1168
1180
  onCancelEdit
1169
1181
  } = cellEdit;
1182
+ const renderCell = (tableCell) => (0, import_react_table.flexRender)(
1183
+ tableCell.column.columnDef.cell,
1184
+ withCellUpdate(tableCell.getContext(), cellRender.commitValue)
1185
+ );
1170
1186
  const {
1171
1187
  enableExpand,
1172
1188
  toggleField,
@@ -1479,7 +1495,7 @@ function DataTableRow({
1479
1495
  "expand-cell-value",
1480
1496
  classNames?.expandCellValue
1481
1497
  ),
1482
- children: (0, import_react_table.flexRender)(cell.column.columnDef.cell, cell.getContext())
1498
+ children: renderCell(cell)
1483
1499
  }
1484
1500
  )
1485
1501
  ]
@@ -1518,7 +1534,7 @@ function DataTableRow({
1518
1534
  )
1519
1535
  }
1520
1536
  )
1521
- ] }) : (0, import_react_table.flexRender)(cell.column.columnDef.cell, cell.getContext()),
1537
+ ] }) : renderCell(cell),
1522
1538
  isBottomRightCell && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1523
1539
  "div",
1524
1540
  {
@@ -1770,13 +1786,350 @@ function getMergedHeaderGroups(headerGroups) {
1770
1786
  }));
1771
1787
  }
1772
1788
 
1789
+ // src/components/ui/table/features/column-reorder/columnReorder.ts
1790
+ function getColumnDefId(column) {
1791
+ if (column.id != null && column.id !== "") return column.id;
1792
+ if ("accessorKey" in column && column.accessorKey != null) {
1793
+ return String(column.accessorKey);
1794
+ }
1795
+ return void 0;
1796
+ }
1797
+ function getColumnDefChildren(column) {
1798
+ if (!("columns" in column) || !Array.isArray(column.columns)) return void 0;
1799
+ if (column.columns.length === 0) return void 0;
1800
+ return column.columns;
1801
+ }
1802
+ function collectLeafColumnIds(columns) {
1803
+ const ids = [];
1804
+ for (const column of columns) {
1805
+ const children = getColumnDefChildren(column);
1806
+ if (children) {
1807
+ ids.push(...collectLeafColumnIds(children));
1808
+ continue;
1809
+ }
1810
+ const id = getColumnDefId(column);
1811
+ if (id) ids.push(id);
1812
+ }
1813
+ return ids;
1814
+ }
1815
+ function areColumnOrdersEqual(left, right) {
1816
+ if (left.length !== right.length) return false;
1817
+ return left.every((id, index) => id === right[index]);
1818
+ }
1819
+ function resolveLeafColumnOrder(columns, order) {
1820
+ const leafIds = collectLeafColumnIds(columns);
1821
+ if (!order?.length) return leafIds;
1822
+ const leafSet = new Set(leafIds);
1823
+ const seen = /* @__PURE__ */ new Set();
1824
+ const next = order.filter((id) => {
1825
+ if (!leafSet.has(id) || seen.has(id)) return false;
1826
+ seen.add(id);
1827
+ return true;
1828
+ });
1829
+ for (const id of leafIds) {
1830
+ if (!seen.has(id)) next.push(id);
1831
+ }
1832
+ return next;
1833
+ }
1834
+ function flattenColumnSlots(columns, group) {
1835
+ const slots = [];
1836
+ for (const column of columns) {
1837
+ const id = getColumnDefId(column);
1838
+ const children = getColumnDefChildren(column);
1839
+ if (children) {
1840
+ const nestedGroup = id ? { id, def: column } : group;
1841
+ slots.push(...flattenColumnSlots(children, nestedGroup));
1842
+ continue;
1843
+ }
1844
+ if (!id) continue;
1845
+ slots.push({ id, def: column, group });
1846
+ }
1847
+ return slots;
1848
+ }
1849
+ function rebuildColumnTree(slots) {
1850
+ const result = [];
1851
+ let index = 0;
1852
+ while (index < slots.length) {
1853
+ const slot = slots[index];
1854
+ if (!slot.group) {
1855
+ result.push(slot.def);
1856
+ index += 1;
1857
+ continue;
1858
+ }
1859
+ const groupId = slot.group.id;
1860
+ const children = [];
1861
+ while (index < slots.length && slots[index]?.group?.id === groupId) {
1862
+ children.push(slots[index].def);
1863
+ index += 1;
1864
+ }
1865
+ const firstChildId = children[0] ? getColumnDefId(children[0]) : groupId;
1866
+ result.push({
1867
+ ...slot.group.def,
1868
+ id: `${groupId}::${firstChildId}`,
1869
+ columns: children
1870
+ });
1871
+ }
1872
+ return result;
1873
+ }
1874
+ function applyLeafColumnOrder(columns, order) {
1875
+ const resolved = resolveLeafColumnOrder(columns, order);
1876
+ const defaultOrder = collectLeafColumnIds(columns);
1877
+ if (areColumnOrdersEqual(resolved, defaultOrder)) {
1878
+ return columns;
1879
+ }
1880
+ const byId = new Map(
1881
+ flattenColumnSlots(columns).map((slot) => [
1882
+ slot.id,
1883
+ slot
1884
+ ])
1885
+ );
1886
+ const ordered = [];
1887
+ for (const id of resolved) {
1888
+ const slot = byId.get(id);
1889
+ if (slot) ordered.push(slot);
1890
+ }
1891
+ return rebuildColumnTree(ordered);
1892
+ }
1893
+ function moveColumnIds(order, fromIds, targetIds, edge) {
1894
+ if (fromIds.length === 0 || targetIds.length === 0) return [...order];
1895
+ const fromSet = new Set(fromIds);
1896
+ if (targetIds.some((id) => fromSet.has(id))) return [...order];
1897
+ const rest = order.filter((id) => !fromSet.has(id));
1898
+ const anchorId = edge === "before" ? targetIds[0] : targetIds[targetIds.length - 1];
1899
+ const anchorIndex = rest.indexOf(anchorId);
1900
+ if (anchorIndex < 0) return [...order];
1901
+ const insertAt = edge === "before" ? anchorIndex : anchorIndex + 1;
1902
+ return [...rest.slice(0, insertAt), ...fromIds, ...rest.slice(insertAt)];
1903
+ }
1904
+ function resolveDropEdge(clientX, rect) {
1905
+ return clientX < rect.left + rect.width / 2 ? "before" : "after";
1906
+ }
1907
+ function parseReorderIds(value) {
1908
+ if (!value) return [];
1909
+ return value.split(",").filter(Boolean);
1910
+ }
1911
+ function serializeReorderIds(ids) {
1912
+ return ids.join(",");
1913
+ }
1914
+ function isColumnReorderable(meta) {
1915
+ return meta?.reorderable !== false;
1916
+ }
1917
+
1918
+ // src/components/ui/table/features/column-reorder/useColumnReorder.ts
1919
+ var import_react4 = require("react");
1920
+ function hitTestReorderHeader(table, clientX, clientY) {
1921
+ const headers = Array.from(
1922
+ table.querySelectorAll(
1923
+ "thead th[data-column-id][data-reorder-ids]"
1924
+ )
1925
+ );
1926
+ const containing = headers.find((element) => {
1927
+ const rect = element.getBoundingClientRect();
1928
+ return clientX >= rect.left && clientX <= rect.right && clientY >= rect.top && clientY <= rect.bottom;
1929
+ });
1930
+ if (containing) {
1931
+ return {
1932
+ columnId: containing.dataset.columnId ?? "",
1933
+ edge: resolveDropEdge(clientX, containing.getBoundingClientRect())
1934
+ };
1935
+ }
1936
+ const leaves = headers.filter(
1937
+ (element) => element.hasAttribute("data-reorder-leaf")
1938
+ );
1939
+ let match;
1940
+ for (const element of leaves) {
1941
+ const rect = element.getBoundingClientRect();
1942
+ if (clientX >= rect.left && clientX <= rect.right) {
1943
+ match = element;
1944
+ break;
1945
+ }
1946
+ }
1947
+ if (!match && leaves.length > 0) {
1948
+ const first = leaves[0].getBoundingClientRect();
1949
+ const last = leaves[leaves.length - 1].getBoundingClientRect();
1950
+ if (clientX < first.left) match = leaves[0];
1951
+ else if (clientX > last.right) match = leaves[leaves.length - 1];
1952
+ }
1953
+ if (!match) return null;
1954
+ return {
1955
+ columnId: match.dataset.columnId ?? "",
1956
+ edge: resolveDropEdge(clientX, match.getBoundingClientRect())
1957
+ };
1958
+ }
1959
+ function readTargetIds(table, columnId) {
1960
+ const element = table.querySelector(
1961
+ `thead th[data-column-id="${CSS.escape(columnId)}"]`
1962
+ );
1963
+ return parseReorderIds(element?.getAttribute("data-reorder-ids"));
1964
+ }
1965
+ function useColumnReorder(options) {
1966
+ const { enabled, columnOrder, onColumnOrderChange } = options;
1967
+ const sessionRef = (0, import_react4.useRef)(null);
1968
+ const columnOrderRef = (0, import_react4.useRef)(columnOrder);
1969
+ const onColumnOrderChangeRef = (0, import_react4.useRef)(onColumnOrderChange);
1970
+ const [draggingColumnId, setDraggingColumnId] = (0, import_react4.useState)(null);
1971
+ const [dropTarget, setDropTarget] = (0, import_react4.useState)(
1972
+ null
1973
+ );
1974
+ const dropTargetRef = (0, import_react4.useRef)(dropTarget);
1975
+ const previousUserSelectRef = (0, import_react4.useRef)(null);
1976
+ columnOrderRef.current = columnOrder;
1977
+ onColumnOrderChangeRef.current = onColumnOrderChange;
1978
+ dropTargetRef.current = dropTarget;
1979
+ const resetDrag = (0, import_react4.useCallback)(() => {
1980
+ sessionRef.current = null;
1981
+ setDraggingColumnId(null);
1982
+ setDropTarget(null);
1983
+ const backup = previousUserSelectRef.current;
1984
+ previousUserSelectRef.current = null;
1985
+ if (backup) {
1986
+ if (backup.value) {
1987
+ document.body.style.setProperty("user-select", backup.value, backup.priority);
1988
+ } else {
1989
+ document.body.style.removeProperty("user-select");
1990
+ }
1991
+ return;
1992
+ }
1993
+ document.body.style.removeProperty("user-select");
1994
+ }, []);
1995
+ (0, import_react4.useEffect)(() => {
1996
+ if (!enabled) resetDrag();
1997
+ }, [enabled, resetDrag]);
1998
+ (0, import_react4.useEffect)(() => {
1999
+ return () => {
2000
+ resetDrag();
2001
+ };
2002
+ }, [resetDrag]);
2003
+ const onHeaderPointerDown = (0, import_react4.useCallback)(
2004
+ (event, meta) => {
2005
+ if (!enabled || !meta.canDrag) return;
2006
+ if (event.button !== 0) return;
2007
+ if (event.pointerType === "mouse" && event.ctrlKey) return;
2008
+ const target = event.target;
2009
+ if (target instanceof Element && target.closest("[data-table-disable-cell-selection]")) {
2010
+ return;
2011
+ }
2012
+ const table = event.currentTarget.closest("table");
2013
+ if (!(table instanceof HTMLTableElement)) return;
2014
+ sessionRef.current = {
2015
+ pointerId: event.pointerId,
2016
+ startX: event.clientX,
2017
+ startY: event.clientY,
2018
+ columnId: meta.columnId,
2019
+ fromIds: meta.leafIds,
2020
+ table,
2021
+ active: false
2022
+ };
2023
+ },
2024
+ [enabled]
2025
+ );
2026
+ (0, import_react4.useEffect)(() => {
2027
+ if (!enabled) return;
2028
+ const onPointerMove = (event) => {
2029
+ const session = sessionRef.current;
2030
+ if (!session || event.pointerId !== session.pointerId) return;
2031
+ const deltaX = event.clientX - session.startX;
2032
+ const deltaY = event.clientY - session.startY;
2033
+ const distance = Math.hypot(deltaX, deltaY);
2034
+ if (!session.active) {
2035
+ if (distance < DATA_TABLE_COLUMN_REORDER_THRESHOLD) return;
2036
+ session.active = true;
2037
+ if (!previousUserSelectRef.current) {
2038
+ previousUserSelectRef.current = {
2039
+ value: document.body.style.getPropertyValue("user-select"),
2040
+ priority: document.body.style.getPropertyPriority("user-select")
2041
+ };
2042
+ }
2043
+ document.body.style.setProperty("user-select", "none");
2044
+ setDraggingColumnId(session.columnId);
2045
+ }
2046
+ event.preventDefault();
2047
+ const nextTarget = hitTestReorderHeader(
2048
+ session.table,
2049
+ event.clientX,
2050
+ event.clientY
2051
+ );
2052
+ if (!nextTarget || !nextTarget.columnId) {
2053
+ setDropTarget(null);
2054
+ return;
2055
+ }
2056
+ const targetIds = readTargetIds(session.table, nextTarget.columnId);
2057
+ const fromSet = new Set(session.fromIds);
2058
+ if (targetIds.some((id) => fromSet.has(id))) {
2059
+ setDropTarget(null);
2060
+ return;
2061
+ }
2062
+ setDropTarget((previous) => {
2063
+ if (previous?.columnId === nextTarget.columnId && previous.edge === nextTarget.edge) {
2064
+ return previous;
2065
+ }
2066
+ return nextTarget;
2067
+ });
2068
+ };
2069
+ const onPointerUp = (event) => {
2070
+ const session = sessionRef.current;
2071
+ if (!session || event.pointerId !== session.pointerId) {
2072
+ return;
2073
+ }
2074
+ if (session.active) {
2075
+ event.preventDefault();
2076
+ const target = dropTargetRef.current;
2077
+ if (target) {
2078
+ const targetIds = readTargetIds(session.table, target.columnId);
2079
+ const next = moveColumnIds(
2080
+ columnOrderRef.current,
2081
+ session.fromIds,
2082
+ targetIds,
2083
+ target.edge
2084
+ );
2085
+ onColumnOrderChangeRef.current(next);
2086
+ }
2087
+ const suppressClick = (clickEvent) => {
2088
+ clickEvent.preventDefault();
2089
+ clickEvent.stopPropagation();
2090
+ document.removeEventListener("click", suppressClick, true);
2091
+ };
2092
+ document.addEventListener("click", suppressClick, true);
2093
+ window.setTimeout(() => {
2094
+ document.removeEventListener("click", suppressClick, true);
2095
+ }, 0);
2096
+ }
2097
+ resetDrag();
2098
+ };
2099
+ const onPointerCancel = (event) => {
2100
+ const session = sessionRef.current;
2101
+ if (!session || event.pointerId !== session.pointerId) {
2102
+ return;
2103
+ }
2104
+ if (session.active) {
2105
+ event.preventDefault();
2106
+ }
2107
+ resetDrag();
2108
+ };
2109
+ document.addEventListener("pointermove", onPointerMove);
2110
+ document.addEventListener("pointerup", onPointerUp);
2111
+ document.addEventListener("pointercancel", onPointerCancel);
2112
+ return () => {
2113
+ document.removeEventListener("pointermove", onPointerMove);
2114
+ document.removeEventListener("pointerup", onPointerUp);
2115
+ document.removeEventListener("pointercancel", onPointerCancel);
2116
+ };
2117
+ }, [enabled, resetDrag]);
2118
+ return {
2119
+ isReordering: draggingColumnId != null,
2120
+ draggingColumnId,
2121
+ dropTarget,
2122
+ onHeaderPointerDown
2123
+ };
2124
+ }
2125
+
1773
2126
  // src/core/useGlideTable.ts
1774
2127
  var import_react_table2 = require("@tanstack/react-table");
1775
2128
  var import_react_virtual = require("@tanstack/react-virtual");
1776
- var import_react7 = require("react");
2129
+ var import_react8 = require("react");
1777
2130
 
1778
2131
  // src/components/ui/table/features/cell-edit/useCellEdit.ts
1779
- var import_react4 = require("react");
2132
+ var import_react5 = require("react");
1780
2133
 
1781
2134
  // src/components/ui/table/features/cell-render/commitCellValue.ts
1782
2135
  function commitCellValue({
@@ -1816,21 +2169,21 @@ function useCellEdit({
1816
2169
  onDataChange,
1817
2170
  onCellChange
1818
2171
  }) {
1819
- const [editingCell, setEditingCell] = (0, import_react4.useState)(null);
1820
- const [draftValue, setDraftValue] = (0, import_react4.useState)("");
1821
- const draftValueRef = (0, import_react4.useRef)(draftValue);
1822
- const editingCellRef = (0, import_react4.useRef)(editingCell);
1823
- (0, import_react4.useEffect)(() => {
2172
+ const [editingCell, setEditingCell] = (0, import_react5.useState)(null);
2173
+ const [draftValue, setDraftValue] = (0, import_react5.useState)("");
2174
+ const draftValueRef = (0, import_react5.useRef)(draftValue);
2175
+ const editingCellRef = (0, import_react5.useRef)(editingCell);
2176
+ (0, import_react5.useEffect)(() => {
1824
2177
  draftValueRef.current = draftValue;
1825
2178
  }, [draftValue]);
1826
- (0, import_react4.useEffect)(() => {
2179
+ (0, import_react5.useEffect)(() => {
1827
2180
  editingCellRef.current = editingCell;
1828
2181
  }, [editingCell]);
1829
- const cancelEdit = (0, import_react4.useCallback)(() => {
2182
+ const cancelEdit = (0, import_react5.useCallback)(() => {
1830
2183
  setEditingCell(null);
1831
2184
  setDraftValue("");
1832
2185
  }, []);
1833
- const commitEdit = (0, import_react4.useCallback)(
2186
+ const commitEdit = (0, import_react5.useCallback)(
1834
2187
  (raw) => {
1835
2188
  const current = editingCellRef.current;
1836
2189
  if (!current) return true;
@@ -1866,7 +2219,7 @@ function useCellEdit({
1866
2219
  },
1867
2220
  [cancelEdit, data, onCellChange, onDataChange, rows]
1868
2221
  );
1869
- const startEdit = (0, import_react4.useCallback)(
2222
+ const startEdit = (0, import_react5.useCallback)(
1870
2223
  (rowIndex, colIndex) => {
1871
2224
  const cell = rows[rowIndex]?.getVisibleCells()[colIndex];
1872
2225
  if (!cell || !isColumnEditable(cell.column.columnDef)) return;
@@ -2102,7 +2455,7 @@ function formatDefaultCellValue(value) {
2102
2455
  }
2103
2456
 
2104
2457
  // src/components/ui/table/features/cell-selection/useCellSelection.ts
2105
- var import_react5 = require("react");
2458
+ var import_react6 = require("react");
2106
2459
 
2107
2460
  // src/components/ui/table/features/cell-selection/copyData.ts
2108
2461
  function formatPrimitive(value) {
@@ -2381,15 +2734,15 @@ function useCellSelection({
2381
2734
  onRowsPaste,
2382
2735
  onCellNavigate
2383
2736
  }) {
2384
- const [dragState, setDragState] = (0, import_react5.useState)(INITIAL_DRAG_STATE);
2385
- const pendingPasteModeRef = (0, import_react5.useRef)(null);
2386
- const dragStateRef = (0, import_react5.useRef)(dragState);
2387
- const onCellNavigateRef = (0, import_react5.useRef)(onCellNavigate);
2737
+ const [dragState, setDragState] = (0, import_react6.useState)(INITIAL_DRAG_STATE);
2738
+ const pendingPasteModeRef = (0, import_react6.useRef)(null);
2739
+ const dragStateRef = (0, import_react6.useRef)(dragState);
2740
+ const onCellNavigateRef = (0, import_react6.useRef)(onCellNavigate);
2388
2741
  dragStateRef.current = dragState;
2389
2742
  onCellNavigateRef.current = onCellNavigate;
2390
2743
  const cellSelectionBounds = getCellSelectionBounds(dragState.start, dragState.end);
2391
2744
  const activeSelectionBounds = enabled ? getActiveSelectionBounds(dragState, cellSelectionBounds) : null;
2392
- const handleCellMouseDown = (0, import_react5.useCallback)(
2745
+ const handleCellMouseDown = (0, import_react6.useCallback)(
2393
2746
  (rowIndex, colIndex, options) => {
2394
2747
  if (!enabled) return;
2395
2748
  setDragState((prev) => {
@@ -2415,7 +2768,7 @@ function useCellSelection({
2415
2768
  },
2416
2769
  [enabled]
2417
2770
  );
2418
- const handleCellMouseEnter = (0, import_react5.useCallback)(
2771
+ const handleCellMouseEnter = (0, import_react6.useCallback)(
2419
2772
  (rowIndex, colIndex) => {
2420
2773
  if (!enabled) return;
2421
2774
  setDragState((prev) => {
@@ -2430,7 +2783,7 @@ function useCellSelection({
2430
2783
  },
2431
2784
  [enabled]
2432
2785
  );
2433
- const handleFillHandleMouseDown = (0, import_react5.useCallback)(
2786
+ const handleFillHandleMouseDown = (0, import_react6.useCallback)(
2434
2787
  (rowIndex, colIndex) => {
2435
2788
  if (!enabled) return;
2436
2789
  setDragState((prev) => {
@@ -2447,12 +2800,12 @@ function useCellSelection({
2447
2800
  },
2448
2801
  [enabled]
2449
2802
  );
2450
- (0, import_react5.useEffect)(() => {
2803
+ (0, import_react6.useEffect)(() => {
2451
2804
  if (!enabled) {
2452
2805
  setDragState(INITIAL_DRAG_STATE);
2453
2806
  }
2454
2807
  }, [enabled]);
2455
- (0, import_react5.useEffect)(() => {
2808
+ (0, import_react6.useEffect)(() => {
2456
2809
  if (!enabled) return;
2457
2810
  const handleKeyDown = (e) => {
2458
2811
  if (e.ctrlKey || e.metaKey || e.altKey) return;
@@ -2499,7 +2852,7 @@ function useCellSelection({
2499
2852
  window.addEventListener("keydown", handleKeyDown);
2500
2853
  return () => window.removeEventListener("keydown", handleKeyDown);
2501
2854
  }, [columnCount, enabled, rows]);
2502
- const copySelection = (0, import_react5.useCallback)(
2855
+ const copySelection = (0, import_react6.useCallback)(
2503
2856
  async (options) => {
2504
2857
  if (!enabled || !activeSelectionBounds) return false;
2505
2858
  const mode = options?.includeDescendants && enableSubtreeCopy ? "subtree" : "visible";
@@ -2507,7 +2860,7 @@ function useCellSelection({
2507
2860
  },
2508
2861
  [activeSelectionBounds, enableSubtreeCopy, enabled, rows]
2509
2862
  );
2510
- (0, import_react5.useEffect)(() => {
2863
+ (0, import_react6.useEffect)(() => {
2511
2864
  if (!enabled) return;
2512
2865
  const handleKeyDown = (e) => {
2513
2866
  if (!activeSelectionBounds) return;
@@ -2521,7 +2874,7 @@ function useCellSelection({
2521
2874
  window.addEventListener("keydown", handleKeyDown);
2522
2875
  return () => window.removeEventListener("keydown", handleKeyDown);
2523
2876
  }, [activeSelectionBounds, copySelection, enableSubtreeCopy, enabled]);
2524
- const emitRowsPaste = (0, import_react5.useCallback)(
2877
+ const emitRowsPaste = (0, import_react6.useCallback)(
2525
2878
  (text, mode) => {
2526
2879
  if (!onRowsPaste || !activeSelectionBounds) return false;
2527
2880
  const payload = buildRowsPastePayload(
@@ -2538,7 +2891,7 @@ function useCellSelection({
2538
2891
  },
2539
2892
  [activeSelectionBounds, onRowsPaste, rows]
2540
2893
  );
2541
- (0, import_react5.useEffect)(() => {
2894
+ (0, import_react6.useEffect)(() => {
2542
2895
  if (!enabled || !onRowsPaste) return;
2543
2896
  const pasteHandledRef = { current: false };
2544
2897
  const ignoreNextPasteRef = { current: false };
@@ -2606,7 +2959,7 @@ function useCellSelection({
2606
2959
  enabled,
2607
2960
  onRowsPaste
2608
2961
  ]);
2609
- (0, import_react5.useEffect)(() => {
2962
+ (0, import_react6.useEffect)(() => {
2610
2963
  if (!enabled) return;
2611
2964
  const handleMouseUp = () => {
2612
2965
  setDragState((prev) => {
@@ -2657,7 +3010,7 @@ function useCellSelection({
2657
3010
  }
2658
3011
 
2659
3012
  // src/components/ui/table/features/inline-search/useInlineSearch.ts
2660
- var import_react6 = require("react");
3013
+ var import_react7 = require("react");
2661
3014
  var EMPTY_MATCH_KEYS = /* @__PURE__ */ new Set();
2662
3015
  function useInlineSearch({
2663
3016
  enabled = false,
@@ -2674,46 +3027,46 @@ function useInlineSearch({
2674
3027
  onNavigateToResult,
2675
3028
  rootRef
2676
3029
  }) {
2677
- const searchInputId = (0, import_react6.useId)();
2678
- const searchInputRef = (0, import_react6.useRef)(null);
2679
- const [internalShowSearch, setInternalShowSearch] = (0, import_react6.useState)(false);
2680
- const [internalSearchValue, setInternalSearchValue] = (0, import_react6.useState)("");
2681
- const [internalResults, setInternalResults] = (0, import_react6.useState)(
3030
+ const searchInputId = (0, import_react7.useId)();
3031
+ const searchInputRef = (0, import_react7.useRef)(null);
3032
+ const [internalShowSearch, setInternalShowSearch] = (0, import_react7.useState)(false);
3033
+ const [internalSearchValue, setInternalSearchValue] = (0, import_react7.useState)("");
3034
+ const [internalResults, setInternalResults] = (0, import_react7.useState)(
2682
3035
  []
2683
3036
  );
2684
- const [searchStatus, setSearchStatus] = (0, import_react6.useState)();
2685
- const searchStatusRef = (0, import_react6.useRef)(searchStatus);
3037
+ const [searchStatus, setSearchStatus] = (0, import_react7.useState)();
3038
+ const searchStatusRef = (0, import_react7.useRef)(searchStatus);
2686
3039
  searchStatusRef.current = searchStatus;
2687
- const abortControllerRef = (0, import_react6.useRef)(null);
2688
- const searchHandleRef = (0, import_react6.useRef)(void 0);
2689
- const initialStartRowRef = (0, import_react6.useRef)(initialStartRow);
3040
+ const abortControllerRef = (0, import_react7.useRef)(null);
3041
+ const searchHandleRef = (0, import_react7.useRef)(void 0);
3042
+ const initialStartRowRef = (0, import_react7.useRef)(initialStartRow);
2690
3043
  initialStartRowRef.current = initialStartRow;
2691
- const getCellValueRef = (0, import_react6.useRef)(getCellValue);
3044
+ const getCellValueRef = (0, import_react7.useRef)(getCellValue);
2692
3045
  getCellValueRef.current = getCellValue;
2693
3046
  const showSearch = controlledShowSearch ?? internalShowSearch;
2694
3047
  const searchValue = controlledSearchValue ?? internalSearchValue;
2695
3048
  const searchResults = controlledSearchResults ?? internalResults;
2696
- const setSearchValue = (0, import_react6.useCallback)(
3049
+ const setSearchValue = (0, import_react7.useCallback)(
2697
3050
  (value) => {
2698
3051
  setInternalSearchValue(value);
2699
3052
  onSearchValueChange?.(value);
2700
3053
  },
2701
3054
  [onSearchValueChange]
2702
3055
  );
2703
- const cancelSearch = (0, import_react6.useCallback)(() => {
3056
+ const cancelSearch = (0, import_react7.useCallback)(() => {
2704
3057
  if (searchHandleRef.current !== void 0) {
2705
3058
  window.cancelAnimationFrame(searchHandleRef.current);
2706
3059
  searchHandleRef.current = void 0;
2707
3060
  }
2708
3061
  abortControllerRef.current?.abort();
2709
3062
  }, []);
2710
- const emitResultsChanged = (0, import_react6.useCallback)(
3063
+ const emitResultsChanged = (0, import_react7.useCallback)(
2711
3064
  (results, navIndex) => {
2712
3065
  onSearchResultsChanged?.(results, navIndex);
2713
3066
  },
2714
3067
  [onSearchResultsChanged]
2715
3068
  );
2716
- const navigateToIndex = (0, import_react6.useCallback)(
3069
+ const navigateToIndex = (0, import_react7.useCallback)(
2717
3070
  (results, navIndex) => {
2718
3071
  if (onSearchResultsChanged) return;
2719
3072
  if (navIndex < 0 || navIndex >= results.length) return;
@@ -2723,7 +3076,7 @@ function useInlineSearch({
2723
3076
  },
2724
3077
  [onNavigateToResult, onSearchResultsChanged]
2725
3078
  );
2726
- const beginSearch = (0, import_react6.useCallback)(
3079
+ const beginSearch = (0, import_react7.useCallback)(
2727
3080
  (query) => {
2728
3081
  if (controlledSearchResults !== void 0) return;
2729
3082
  const totalRows = rowCount;
@@ -2795,12 +3148,12 @@ function useInlineSearch({
2795
3148
  rowCount
2796
3149
  ]
2797
3150
  );
2798
- const openSearch = (0, import_react6.useCallback)(() => {
3151
+ const openSearch = (0, import_react7.useCallback)(() => {
2799
3152
  if (controlledShowSearch === void 0) {
2800
3153
  setInternalShowSearch(true);
2801
3154
  }
2802
3155
  }, [controlledShowSearch]);
2803
- const closeSearch = (0, import_react6.useCallback)(() => {
3156
+ const closeSearch = (0, import_react7.useCallback)(() => {
2804
3157
  if (controlledShowSearch === void 0) {
2805
3158
  setInternalShowSearch(false);
2806
3159
  }
@@ -2815,7 +3168,7 @@ function useInlineSearch({
2815
3168
  emitResultsChanged,
2816
3169
  onSearchClose
2817
3170
  ]);
2818
- const goToNext = (0, import_react6.useCallback)(() => {
3171
+ const goToNext = (0, import_react7.useCallback)(() => {
2819
3172
  if (!searchStatus || searchStatus.results === 0) return;
2820
3173
  const newIndex = nextSearchIndex(
2821
3174
  searchStatus.selectedIndex,
@@ -2825,7 +3178,7 @@ function useInlineSearch({
2825
3178
  emitResultsChanged(searchResults, newIndex);
2826
3179
  navigateToIndex(searchResults, newIndex);
2827
3180
  }, [emitResultsChanged, navigateToIndex, searchResults, searchStatus]);
2828
- const goToPrevious = (0, import_react6.useCallback)(() => {
3181
+ const goToPrevious = (0, import_react7.useCallback)(() => {
2829
3182
  if (!searchStatus || searchStatus.results === 0) return;
2830
3183
  const newIndex = previousSearchIndex(
2831
3184
  searchStatus.selectedIndex,
@@ -2835,7 +3188,7 @@ function useInlineSearch({
2835
3188
  emitResultsChanged(searchResults, newIndex);
2836
3189
  navigateToIndex(searchResults, newIndex);
2837
3190
  }, [emitResultsChanged, navigateToIndex, searchResults, searchStatus]);
2838
- (0, import_react6.useEffect)(() => {
3191
+ (0, import_react7.useEffect)(() => {
2839
3192
  if (controlledSearchResults === void 0) return;
2840
3193
  if (controlledSearchResults.length > 0) {
2841
3194
  setSearchStatus((current) => ({
@@ -2847,7 +3200,7 @@ function useInlineSearch({
2847
3200
  setSearchStatus(void 0);
2848
3201
  }
2849
3202
  }, [controlledSearchResults, rowCount]);
2850
- (0, import_react6.useEffect)(() => {
3203
+ (0, import_react7.useEffect)(() => {
2851
3204
  if (!enabled) return;
2852
3205
  setSearchStatus(void 0);
2853
3206
  setInternalResults([]);
@@ -2860,7 +3213,7 @@ function useInlineSearch({
2860
3213
  cancelSearch();
2861
3214
  }
2862
3215
  }, [enabled, showSearch]);
2863
- (0, import_react6.useEffect)(() => {
3216
+ (0, import_react7.useEffect)(() => {
2864
3217
  if (!enabled || !showSearch) return;
2865
3218
  if (controlledSearchResults !== void 0) return;
2866
3219
  if (searchValue.trim() === "") {
@@ -2880,7 +3233,7 @@ function useInlineSearch({
2880
3233
  searchValue,
2881
3234
  showSearch
2882
3235
  ]);
2883
- (0, import_react6.useEffect)(() => {
3236
+ (0, import_react7.useEffect)(() => {
2884
3237
  if (!enabled) return;
2885
3238
  const handleKeyDown = (event) => {
2886
3239
  if (!(event.ctrlKey || event.metaKey)) return;
@@ -2907,12 +3260,12 @@ function useInlineSearch({
2907
3260
  window.addEventListener("keydown", handleKeyDown, true);
2908
3261
  return () => window.removeEventListener("keydown", handleKeyDown, true);
2909
3262
  }, [controlledShowSearch, enabled, rootRef, showSearch]);
2910
- (0, import_react6.useEffect)(() => () => cancelSearch(), [cancelSearch]);
2911
- const searchMatchKeys = (0, import_react6.useMemo)(
3263
+ (0, import_react7.useEffect)(() => () => cancelSearch(), [cancelSearch]);
3264
+ const searchMatchKeys = (0, import_react7.useMemo)(
2912
3265
  () => buildSearchMatchKeys(searchResults),
2913
3266
  [searchResults]
2914
3267
  );
2915
- const activeMatch = (0, import_react6.useMemo)(() => {
3268
+ const activeMatch = (0, import_react7.useMemo)(() => {
2916
3269
  if (!searchStatus || searchStatus.selectedIndex < 0) return null;
2917
3270
  return searchResults[searchStatus.selectedIndex] ?? null;
2918
3271
  }, [searchResults, searchStatus]);
@@ -2977,6 +3330,7 @@ var DEFAULT_DATA_TABLE_LABELS = {
2977
3330
  expandRow: "Expand row",
2978
3331
  collapseRow: "Collapse row",
2979
3332
  resizeColumn: "Resize column",
3333
+ reorderColumn: "Reorder column",
2980
3334
  searchPlaceholder: "Search\u2026",
2981
3335
  searchResultHint: "Type to search",
2982
3336
  searchPrevious: "Previous result",
@@ -3034,6 +3388,9 @@ function useGlideTable(options) {
3034
3388
  columnSizing: controlledColumnSizing,
3035
3389
  onColumnSizingChange,
3036
3390
  columnResizeMode = "onChange",
3391
+ enableColumnReorder = false,
3392
+ columnOrder: controlledColumnOrder,
3393
+ onColumnOrderChange,
3037
3394
  enableColumnFreeze = false,
3038
3395
  enableInlineSearch = false,
3039
3396
  showSearch,
@@ -3043,7 +3400,7 @@ function useGlideTable(options) {
3043
3400
  searchResults,
3044
3401
  onSearchResultsChanged
3045
3402
  } = options;
3046
- const labels = (0, import_react7.useMemo)(() => {
3403
+ const labels = (0, import_react8.useMemo)(() => {
3047
3404
  const resolved = resolveDataTableLabels(labelsProp);
3048
3405
  return {
3049
3406
  ...resolved,
@@ -3054,16 +3411,17 @@ function useGlideTable(options) {
3054
3411
  }, [labelsProp, emptyText, loadingText, selectionLabel]);
3055
3412
  const enableExpand = Boolean(toggleField);
3056
3413
  const resolvedEnableSubtreeCopy = enableSubtreeCopy ?? enableExpand;
3057
- const [internalRowSelection, setInternalRowSelection] = (0, import_react7.useState)({});
3058
- const [internalColumnSizing, setInternalColumnSizing] = (0, import_react7.useState)({});
3059
- const [internalExpandedRows, setInternalExpandedRows] = (0, import_react7.useState)(
3414
+ const [internalRowSelection, setInternalRowSelection] = (0, import_react8.useState)({});
3415
+ const [internalColumnSizing, setInternalColumnSizing] = (0, import_react8.useState)({});
3416
+ const [internalColumnOrder, setInternalColumnOrder] = (0, import_react8.useState)([]);
3417
+ const [internalExpandedRows, setInternalExpandedRows] = (0, import_react8.useState)(
3060
3418
  () => /* @__PURE__ */ new Set()
3061
3419
  );
3062
- const [hoveredRowIndex, setHoveredRowIndex] = (0, import_react7.useState)(null);
3063
- const scrollRef = (0, import_react7.useRef)(null);
3064
- const rootRef = (0, import_react7.useRef)(null);
3420
+ const [hoveredRowIndex, setHoveredRowIndex] = (0, import_react8.useState)(null);
3421
+ const scrollRef = (0, import_react8.useRef)(null);
3422
+ const rootRef = (0, import_react8.useRef)(null);
3065
3423
  const shouldVirtualize = enableVirtualization && !enableRowSpan;
3066
- (0, import_react7.useEffect)(() => {
3424
+ (0, import_react8.useEffect)(() => {
3067
3425
  if (enableVirtualization && enableRowSpan) {
3068
3426
  console.warn(
3069
3427
  "[useGlideTable] enableRowSpan is on; virtualization is disabled to preserve cell merges."
@@ -3076,8 +3434,23 @@ function useGlideTable(options) {
3076
3434
  internalRowSelection
3077
3435
  );
3078
3436
  const columnSizing = controlledColumnSizing ?? internalColumnSizing;
3437
+ const columnOrder = controlledColumnOrder ?? internalColumnOrder;
3438
+ const tableColumns = (0, import_react8.useMemo)(() => {
3439
+ if (!enableColumnReorder) return columns;
3440
+ return applyLeafColumnOrder(columns, columnOrder);
3441
+ }, [columnOrder, columns, enableColumnReorder]);
3442
+ const setColumnOrder = (0, import_react8.useCallback)(
3443
+ (next) => {
3444
+ if (onColumnOrderChange) {
3445
+ onColumnOrderChange(next);
3446
+ return;
3447
+ }
3448
+ setInternalColumnOrder(next);
3449
+ },
3450
+ [onColumnOrderChange]
3451
+ );
3079
3452
  const expandedRows = controlledExpandedRows ?? internalExpandedRows;
3080
- const handleExpandedRowsChange = (0, import_react7.useCallback)(
3453
+ const handleExpandedRowsChange = (0, import_react8.useCallback)(
3081
3454
  (next) => {
3082
3455
  if (onExpandedRowsChange) {
3083
3456
  onExpandedRowsChange(next);
@@ -3100,7 +3473,7 @@ function useGlideTable(options) {
3100
3473
  });
3101
3474
  const table = (0, import_react_table2.useReactTable)({
3102
3475
  data: tableData,
3103
- columns,
3476
+ columns: tableColumns,
3104
3477
  ...enableColumnResize ? {
3105
3478
  defaultColumn: {
3106
3479
  minSize: DATA_TABLE_COLUMN_MIN_SIZE,
@@ -3138,13 +3511,13 @@ function useGlideTable(options) {
3138
3511
  getCoreRowModel: (0, import_react_table2.getCoreRowModel)(),
3139
3512
  getRowId: getRowId ? (originalRow, index) => getRowId(originalRow, index) : (_originalRow, index) => String(index)
3140
3513
  });
3141
- const rowSpanColumnKeys = (0, import_react7.useMemo)(() => {
3514
+ const rowSpanColumnKeys = (0, import_react8.useMemo)(() => {
3142
3515
  if (!enableRowSpan) return [];
3143
3516
  return collectRowSpanColumns(columns);
3144
3517
  }, [enableRowSpan, columns]);
3145
3518
  const primaryRowSpanKey = rowSpanColumnKeys[0]?.rowSpanKey;
3146
3519
  const primaryRowSpanColumnId = rowSpanColumnKeys[0]?.columnId;
3147
- const columnRowSpanMap = (0, import_react7.useMemo)(
3520
+ const columnRowSpanMap = (0, import_react8.useMemo)(
3148
3521
  () => buildColumnRowSpanMap(tableData, rowSpanColumnKeys),
3149
3522
  [tableData, rowSpanColumnKeys]
3150
3523
  );
@@ -3153,7 +3526,7 @@ function useGlideTable(options) {
3153
3526
  const rows = table.getRowModel().rows;
3154
3527
  const columnCount = table.getAllLeafColumns().length || 1;
3155
3528
  const visibleLeafColumns = table.getVisibleLeafColumns();
3156
- const columnFreezeOffsets = (0, import_react7.useMemo)(() => {
3529
+ const columnFreezeOffsets = (0, import_react8.useMemo)(() => {
3157
3530
  if (!enableColumnFreeze) return EMPTY_COLUMN_FREEZE_OFFSETS;
3158
3531
  return buildColumnFreezeOffsets(
3159
3532
  visibleLeafColumns.map((column) => ({
@@ -3173,14 +3546,14 @@ function useGlideTable(options) {
3173
3546
  const totalSize = rowVirtualizer.getTotalSize();
3174
3547
  const paddingTop = virtualRows.length > 0 ? virtualRows[0]?.start ?? 0 : 0;
3175
3548
  const paddingBottom = virtualRows.length > 0 ? totalSize - (virtualRows[virtualRows.length - 1]?.end ?? 0) : 0;
3176
- const selectedRowIndices = (0, import_react7.useMemo)(() => {
3549
+ const selectedRowIndices = (0, import_react8.useMemo)(() => {
3177
3550
  const indices = /* @__PURE__ */ new Set();
3178
3551
  for (const selectedRow of selectedRows) {
3179
3552
  indices.add(selectedRow.index);
3180
3553
  }
3181
3554
  return indices;
3182
3555
  }, [selectedRows]);
3183
- const scrollCellIntoView = (0, import_react7.useCallback)(
3556
+ const scrollCellIntoView = (0, import_react8.useCallback)(
3184
3557
  (rowIndex, colIndex, options2) => {
3185
3558
  const align = options2?.align ?? "nearest";
3186
3559
  const blockAlign = align === "center" ? "center" : "nearest";
@@ -3207,7 +3580,7 @@ function useGlideTable(options) {
3207
3580
  },
3208
3581
  [rowVirtualizer, shouldVirtualize]
3209
3582
  );
3210
- const handleCellNavigate = (0, import_react7.useCallback)(
3583
+ const handleCellNavigate = (0, import_react8.useCallback)(
3211
3584
  (position) => {
3212
3585
  scrollCellIntoView(position.row, position.col, { align: "nearest" });
3213
3586
  },
@@ -3240,11 +3613,11 @@ function useGlideTable(options) {
3240
3613
  commitEdit,
3241
3614
  cancelEdit
3242
3615
  } = useCellEdit({ data: tableData, rows, onDataChange, onCellChange });
3243
- const cellRendererRegistry = (0, import_react7.useMemo)(
3616
+ const cellRendererRegistry = (0, import_react8.useMemo)(
3244
3617
  () => createCellRendererRegistry(cellRenderers),
3245
3618
  [cellRenderers]
3246
3619
  );
3247
- const commitRenderedCellValue = (0, import_react7.useCallback)(
3620
+ const commitRenderedCellValue = (0, import_react8.useCallback)(
3248
3621
  (rowId, columnId, value) => commitCellValue({
3249
3622
  data: tableData,
3250
3623
  rows,
@@ -3256,7 +3629,11 @@ function useGlideTable(options) {
3256
3629
  }),
3257
3630
  [onCellChange, onDataChange, rows, tableData]
3258
3631
  );
3259
- const handleCellMouseDownWithCommit = (0, import_react7.useCallback)(
3632
+ const getCellContext = (0, import_react8.useCallback)(
3633
+ (cell) => withCellUpdate(cell.getContext(), commitRenderedCellValue),
3634
+ [commitRenderedCellValue]
3635
+ );
3636
+ const handleCellMouseDownWithCommit = (0, import_react8.useCallback)(
3260
3637
  (rowIndex, colIndex, options2) => {
3261
3638
  const isSameEditingCell = editingCell?.rowIndex === rowIndex && editingCell?.colIndex === colIndex;
3262
3639
  if (editingCell && !isSameEditingCell && !commitEdit()) {
@@ -3266,7 +3643,7 @@ function useGlideTable(options) {
3266
3643
  },
3267
3644
  [commitEdit, editingCell, handleCellMouseDown]
3268
3645
  );
3269
- const navigateToSearchResult = (0, import_react7.useCallback)(
3646
+ const navigateToSearchResult = (0, import_react8.useCallback)(
3270
3647
  (item) => {
3271
3648
  const [colIndex, rowIndex] = item;
3272
3649
  handleCellMouseDownWithCommit(rowIndex, colIndex);
@@ -3274,7 +3651,7 @@ function useGlideTable(options) {
3274
3651
  },
3275
3652
  [handleCellMouseDownWithCommit, scrollCellIntoView]
3276
3653
  );
3277
- const resolveSearchRowId = (0, import_react7.useCallback)(
3654
+ const resolveSearchRowId = (0, import_react8.useCallback)(
3278
3655
  (row, index) => {
3279
3656
  if (getRowId) return getRowId(row, index);
3280
3657
  if (enableExpand) {
@@ -3298,7 +3675,7 @@ function useGlideTable(options) {
3298
3675
  },
3299
3676
  [enableExpand, getRowId, toggleField]
3300
3677
  );
3301
- const searchCorpus = (0, import_react7.useMemo)(() => {
3678
+ const searchCorpus = (0, import_react8.useMemo)(() => {
3302
3679
  if (!enableInlineSearch) return [];
3303
3680
  if (enableExpand && toggleField) {
3304
3681
  return buildTreeSearchCorpus(tableData, {
@@ -3314,16 +3691,16 @@ function useGlideTable(options) {
3314
3691
  tableData,
3315
3692
  toggleField
3316
3693
  ]);
3317
- const searchCorpusRef = (0, import_react7.useRef)(searchCorpus);
3694
+ const searchCorpusRef = (0, import_react8.useRef)(searchCorpus);
3318
3695
  searchCorpusRef.current = searchCorpus;
3319
- const visibleRowIndexById = (0, import_react7.useMemo)(() => {
3696
+ const visibleRowIndexById = (0, import_react8.useMemo)(() => {
3320
3697
  const map = /* @__PURE__ */ new Map();
3321
3698
  for (const row of rows) {
3322
3699
  map.set(resolveSearchRowId(row.original, row.index), row.index);
3323
3700
  }
3324
3701
  return map;
3325
3702
  }, [resolveSearchRowId, rows]);
3326
- const getSearchCellValue = (0, import_react7.useCallback)(
3703
+ const getSearchCellValue = (0, import_react8.useCallback)(
3327
3704
  (rowIndex, colIndex) => {
3328
3705
  const corpusRow = searchCorpusRef.current[rowIndex];
3329
3706
  const column = visibleLeafColumns[colIndex];
@@ -3346,14 +3723,14 @@ function useGlideTable(options) {
3346
3723
  },
3347
3724
  [rows, visibleLeafColumns, visibleRowIndexById]
3348
3725
  );
3349
- const pendingSearchNavRef = (0, import_react7.useRef)(null);
3350
- const focusSearchResult = (0, import_react7.useCallback)(
3726
+ const pendingSearchNavRef = (0, import_react8.useRef)(null);
3727
+ const focusSearchResult = (0, import_react8.useCallback)(
3351
3728
  (colIndex, visibleRowIndex) => {
3352
3729
  navigateToSearchResult([colIndex, visibleRowIndex]);
3353
3730
  },
3354
3731
  [navigateToSearchResult]
3355
3732
  );
3356
- const navigateToCorpusSearchResult = (0, import_react7.useCallback)(
3733
+ const navigateToCorpusSearchResult = (0, import_react8.useCallback)(
3357
3734
  (item) => {
3358
3735
  const [colIndex, corpusRowIndex] = item;
3359
3736
  const corpusRow = searchCorpusRef.current[corpusRowIndex];
@@ -3386,7 +3763,7 @@ function useGlideTable(options) {
3386
3763
  visibleRowIndexById
3387
3764
  ]
3388
3765
  );
3389
- (0, import_react7.useEffect)(() => {
3766
+ (0, import_react8.useEffect)(() => {
3390
3767
  const pending = pendingSearchNavRef.current;
3391
3768
  if (!pending) return;
3392
3769
  const visibleRowIndex = visibleRowIndexById.get(pending.rowId);
@@ -3410,7 +3787,7 @@ function useGlideTable(options) {
3410
3787
  onNavigateToResult: navigateToCorpusSearchResult,
3411
3788
  rootRef
3412
3789
  });
3413
- const visibleSearchMatchKeys = (0, import_react7.useMemo)(() => {
3790
+ const visibleSearchMatchKeys = (0, import_react8.useMemo)(() => {
3414
3791
  if (!enableInlineSearch) return EMPTY_SEARCH_MATCH_KEYS;
3415
3792
  return mapSearchResultsToVisibleKeys(
3416
3793
  inlineSearch.searchResults,
@@ -3423,7 +3800,7 @@ function useGlideTable(options) {
3423
3800
  searchCorpus,
3424
3801
  visibleRowIndexById
3425
3802
  ]);
3426
- const visibleActiveMatch = (0, import_react7.useMemo)(() => {
3803
+ const visibleActiveMatch = (0, import_react8.useMemo)(() => {
3427
3804
  if (!enableInlineSearch || !inlineSearch.activeMatch) return null;
3428
3805
  return mapSearchResultToVisibleItem(
3429
3806
  inlineSearch.activeMatch,
@@ -3436,13 +3813,13 @@ function useGlideTable(options) {
3436
3813
  searchCorpus,
3437
3814
  visibleRowIndexById
3438
3815
  ]);
3439
- const clearHover = (0, import_react7.useCallback)(() => {
3816
+ const clearHover = (0, import_react8.useCallback)(() => {
3440
3817
  setHoveredRowIndex(null);
3441
3818
  }, []);
3442
- const handleRowHover = (0, import_react7.useCallback)((rowIndex, _rowData) => {
3819
+ const handleRowHover = (0, import_react8.useCallback)((rowIndex, _rowData) => {
3443
3820
  setHoveredRowIndex(rowIndex);
3444
3821
  }, []);
3445
- const handleToggleSelect = (0, import_react7.useCallback)(
3822
+ const handleToggleSelect = (0, import_react8.useCallback)(
3446
3823
  (row) => {
3447
3824
  if (!row.getCanSelect()) return;
3448
3825
  if (preserveRowSelection && row.getIsSelected()) {
@@ -3452,14 +3829,14 @@ function useGlideTable(options) {
3452
3829
  },
3453
3830
  [preserveRowSelection]
3454
3831
  );
3455
- const handleToggleExpand = (0, import_react7.useCallback)(
3832
+ const handleToggleExpand = (0, import_react8.useCallback)(
3456
3833
  (rowKey) => {
3457
3834
  if (preventExpand) return;
3458
3835
  handleExpandedRowsChange(toggleExpandedRowId(rowKey, expandedRows));
3459
3836
  },
3460
3837
  [preventExpand, handleExpandedRowsChange, expandedRows]
3461
3838
  );
3462
- const rowContextValue = (0, import_react7.useMemo)(() => {
3839
+ const rowContextValue = (0, import_react8.useMemo)(() => {
3463
3840
  return {
3464
3841
  rowSpan: {
3465
3842
  enableRowSpan,
@@ -3558,12 +3935,12 @@ function useGlideTable(options) {
3558
3935
  visibleSearchMatchKeys,
3559
3936
  visibleActiveMatch
3560
3937
  ]);
3561
- const copySelectionRef = (0, import_react7.useRef)(copySelection);
3562
- (0, import_react7.useEffect)(() => {
3938
+ const copySelectionRef = (0, import_react8.useRef)(copySelection);
3939
+ (0, import_react8.useEffect)(() => {
3563
3940
  copySelectionRef.current = copySelection;
3564
3941
  }, [copySelection]);
3565
- const stableCopySelection = (0, import_react7.useCallback)((options2) => copySelectionRef.current(options2), []);
3566
- (0, import_react7.useEffect)(() => {
3942
+ const stableCopySelection = (0, import_react8.useCallback)((options2) => copySelectionRef.current(options2), []);
3943
+ (0, import_react8.useEffect)(() => {
3567
3944
  onCopyActionsReady?.({ copySelection: stableCopySelection });
3568
3945
  }, [onCopyActionsReady, stableCopySelection]);
3569
3946
  return {
@@ -3578,6 +3955,7 @@ function useGlideTable(options) {
3578
3955
  selectionLabel: labels.selection,
3579
3956
  enableCellSelection,
3580
3957
  enableColumnResize,
3958
+ enableColumnReorder,
3581
3959
  enableColumnFreeze,
3582
3960
  enableInlineSearch,
3583
3961
  shouldVirtualize,
@@ -3588,8 +3966,10 @@ function useGlideTable(options) {
3588
3966
  paddingTop,
3589
3967
  paddingBottom,
3590
3968
  rowContextValue,
3969
+ getCellContext,
3591
3970
  handleToggleSelect,
3592
3971
  clearHover,
3972
+ setColumnOrder,
3593
3973
  copySelection: stableCopySelection,
3594
3974
  inlineSearch: {
3595
3975
  showSearch: inlineSearch.showSearch,
@@ -3673,6 +4053,7 @@ function DataTable({
3673
4053
  selectionLabel,
3674
4054
  enableCellSelection,
3675
4055
  enableColumnResize,
4056
+ enableColumnReorder,
3676
4057
  enableColumnFreeze,
3677
4058
  enableInlineSearch,
3678
4059
  shouldVirtualize,
@@ -3685,6 +4066,7 @@ function DataTable({
3685
4066
  rowContextValue,
3686
4067
  handleToggleSelect,
3687
4068
  clearHover,
4069
+ setColumnOrder,
3688
4070
  inlineSearch
3689
4071
  } = useGlideTable(glideOptions);
3690
4072
  const ToolbarSlot = slots?.Toolbar ?? DataTableToolbar;
@@ -3694,7 +4076,13 @@ function DataTable({
3694
4076
  const EmptySlot = slots?.Empty ?? DefaultEmpty;
3695
4077
  const freezeOffsets = rowContextValue.columnFreeze.offsets;
3696
4078
  const headerGroups = getMergedHeaderGroups(table.getHeaderGroups());
3697
- const contextValue = (0, import_react8.useMemo)(
4079
+ const leafColumnIds = table.getVisibleLeafColumns().map((column) => column.id);
4080
+ const { isReordering, draggingColumnId, dropTarget, onHeaderPointerDown } = useColumnReorder({
4081
+ enabled: enableColumnReorder,
4082
+ columnOrder: leafColumnIds,
4083
+ onColumnOrderChange: setColumnOrder
4084
+ });
4085
+ const contextValue = (0, import_react9.useMemo)(
3698
4086
  () => ({ ...rowContextValue, classNames }),
3699
4087
  [rowContextValue, classNames]
3700
4088
  );
@@ -3716,6 +4104,8 @@ function DataTable({
3716
4104
  "DataTableJSX",
3717
4105
  !enableCellSelection && "DataTableJSX--no-cell-selection",
3718
4106
  enableColumnResize && "DataTableJSX--column-resize",
4107
+ enableColumnReorder && "DataTableJSX--column-reorder",
4108
+ isReordering && "DataTableJSX--column-reordering",
3719
4109
  enableColumnFreeze && "DataTableJSX--column-freeze",
3720
4110
  enableInlineSearch && "DataTableJSX--inline-search",
3721
4111
  classNames?.root,
@@ -3784,20 +4174,43 @@ function DataTable({
3784
4174
  ...sizeStyle,
3785
4175
  ...freezeStyle
3786
4176
  };
4177
+ const isPlaceholder = header.isPlaceholder;
4178
+ const leafColumns = header.column.getLeafColumns();
4179
+ const leafIds = leafColumns.map((leafColumn) => leafColumn.id);
4180
+ const isLeafHeader = !isPlaceholder && header.subHeaders.length === 0;
4181
+ const canDrag = enableColumnReorder && !isPlaceholder && leafIds.length > 0 && leafColumns.every(
4182
+ (leafColumn) => isColumnReorderable(leafColumn.columnDef.meta)
4183
+ );
4184
+ const isDragging = draggingColumnId === header.column.id;
4185
+ const dropEdge = !isPlaceholder && dropTarget?.columnId === header.column.id ? dropTarget.edge : void 0;
3787
4186
  return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
3788
4187
  "th",
3789
4188
  {
3790
4189
  colSpan: header.colSpan,
3791
4190
  rowSpan: header.mergedRowSpan,
4191
+ "data-column-id": enableColumnReorder && !isPlaceholder ? header.column.id : void 0,
4192
+ "data-reorder-ids": enableColumnReorder && !isPlaceholder ? serializeReorderIds(leafIds) : void 0,
4193
+ "data-reorder-leaf": enableColumnReorder && isLeafHeader ? "" : void 0,
4194
+ "data-reorderable": canDrag ? "" : void 0,
4195
+ "data-reordering": isDragging ? "" : void 0,
4196
+ "data-drop-edge": dropEdge,
3792
4197
  "data-resizing": header.column.getIsResizing() ? "" : void 0,
3793
4198
  "data-frozen": freezeOffset?.side,
3794
4199
  "data-freeze-edge": getColumnFreezeEdgeAttr(freezeOffset),
4200
+ "aria-grabbed": isDragging ? true : void 0,
4201
+ title: canDrag ? labels.reorderColumn : void 0,
4202
+ onPointerDown: enableColumnReorder ? (event) => onHeaderPointerDown(event, {
4203
+ columnId: header.column.id,
4204
+ leafIds,
4205
+ canDrag
4206
+ }) : void 0,
3795
4207
  style: Object.keys(headerStyle).length > 0 ? headerStyle : void 0,
3796
4208
  className: cn(
3797
4209
  "data-table-head-cell",
3798
4210
  freezeOffset && `data-table-head-cell--frozen-${freezeOffset.side}`,
3799
4211
  CELL_ALIGN_CLASS[align],
3800
4212
  classNames?.headCell,
4213
+ dropEdge && classNames?.dropEdge,
3801
4214
  headerClassName
3802
4215
  ),
3803
4216
  children: [
@@ -3919,10 +4332,10 @@ function DataTable({
3919
4332
  }
3920
4333
 
3921
4334
  // src/components/ui/table/components/Table/Table.tsx
3922
- var import_react12 = require("react");
4335
+ var import_react13 = require("react");
3923
4336
 
3924
4337
  // src/components/ui/table/features/cell-render/ResolvedTableCell.tsx
3925
- var import_react9 = require("react");
4338
+ var import_react10 = require("react");
3926
4339
  function ResolvedTableCell({
3927
4340
  info
3928
4341
  }) {
@@ -3931,7 +4344,7 @@ function ResolvedTableCell({
3931
4344
  const meta = column.columnDef.meta;
3932
4345
  const value = getValue();
3933
4346
  const columnId = column.id;
3934
- const update = (0, import_react9.useCallback)(
4347
+ const update = (0, import_react10.useCallback)(
3935
4348
  (next) => {
3936
4349
  cellRender.commitValue(row.id, columnId, next);
3937
4350
  },
@@ -3991,6 +4404,7 @@ function buildColumnDef(props, sort, onSort) {
3991
4404
  minWidth,
3992
4405
  maxWidth,
3993
4406
  resizable,
4407
+ reorderable,
3994
4408
  frozen,
3995
4409
  align,
3996
4410
  rowSpan,
@@ -4036,6 +4450,7 @@ function buildColumnDef(props, sort, onSort) {
4036
4450
  cellProps,
4037
4451
  cellRender: render,
4038
4452
  frozen,
4453
+ reorderable,
4039
4454
  className,
4040
4455
  headerClassName
4041
4456
  }
@@ -4081,10 +4496,10 @@ function countLeafColumns(nodes) {
4081
4496
  }
4082
4497
 
4083
4498
  // src/components/ui/table/components/Table/parseTableChildren.ts
4084
- var import_react11 = require("react");
4499
+ var import_react12 = require("react");
4085
4500
 
4086
4501
  // src/components/ui/table/components/Table/tableChildTypes.ts
4087
- var import_react10 = require("react");
4502
+ var import_react11 = require("react");
4088
4503
  var TABLE_HEADER_DISPLAY_NAME = "Table.Header";
4089
4504
  var TABLE_BODY_DISPLAY_NAME = "Table.Body";
4090
4505
  var TABLE_COLUMN_DISPLAY_NAME = "Table.Column";
@@ -4097,19 +4512,19 @@ function getComponentDisplayName(type) {
4097
4512
  return void 0;
4098
4513
  }
4099
4514
  function isTableHeaderElement(child) {
4100
- return (0, import_react10.isValidElement)(child) && getComponentDisplayName(child.type) === TABLE_HEADER_DISPLAY_NAME;
4515
+ return (0, import_react11.isValidElement)(child) && getComponentDisplayName(child.type) === TABLE_HEADER_DISPLAY_NAME;
4101
4516
  }
4102
4517
  function isTableBodyElement(child) {
4103
- return (0, import_react10.isValidElement)(child) && getComponentDisplayName(child.type) === TABLE_BODY_DISPLAY_NAME;
4518
+ return (0, import_react11.isValidElement)(child) && getComponentDisplayName(child.type) === TABLE_BODY_DISPLAY_NAME;
4104
4519
  }
4105
4520
  function isTableColumnElement(child) {
4106
- return (0, import_react10.isValidElement)(child) && getComponentDisplayName(child.type) === TABLE_COLUMN_DISPLAY_NAME;
4521
+ return (0, import_react11.isValidElement)(child) && getComponentDisplayName(child.type) === TABLE_COLUMN_DISPLAY_NAME;
4107
4522
  }
4108
4523
  function isTableColumnGroupElement(child) {
4109
- return (0, import_react10.isValidElement)(child) && getComponentDisplayName(child.type) === TABLE_COLUMN_GROUP_DISPLAY_NAME;
4524
+ return (0, import_react11.isValidElement)(child) && getComponentDisplayName(child.type) === TABLE_COLUMN_GROUP_DISPLAY_NAME;
4110
4525
  }
4111
4526
  function isTablePaginationElement(child) {
4112
- return (0, import_react10.isValidElement)(child) && getComponentDisplayName(child.type) === TABLE_PAGINATION_DISPLAY_NAME;
4527
+ return (0, import_react11.isValidElement)(child) && getComponentDisplayName(child.type) === TABLE_PAGINATION_DISPLAY_NAME;
4113
4528
  }
4114
4529
 
4115
4530
  // src/components/ui/table/components/Table/parseTableChildren.ts
@@ -4119,7 +4534,7 @@ function parseTableChildren(children) {
4119
4534
  body: null,
4120
4535
  pagination: null
4121
4536
  };
4122
- for (const child of import_react11.Children.toArray(children)) {
4537
+ for (const child of import_react12.Children.toArray(children)) {
4123
4538
  if (isTableHeaderElement(child)) {
4124
4539
  slots.header = child;
4125
4540
  continue;
@@ -4136,7 +4551,7 @@ function parseTableChildren(children) {
4136
4551
  }
4137
4552
  function walkColumnTreeNodes(children) {
4138
4553
  const result = [];
4139
- for (const child of import_react11.Children.toArray(children)) {
4554
+ for (const child of import_react12.Children.toArray(children)) {
4140
4555
  if (isTableColumnElement(child)) {
4141
4556
  result.push({
4142
4557
  type: "leaf",
@@ -4153,7 +4568,7 @@ function walkColumnTreeNodes(children) {
4153
4568
  });
4154
4569
  continue;
4155
4570
  }
4156
- if ((0, import_react11.isValidElement)(child)) {
4571
+ if ((0, import_react12.isValidElement)(child)) {
4157
4572
  const nested = child.props.children;
4158
4573
  if (nested != null) {
4159
4574
  result.push(...walkColumnTreeNodes(nested));
@@ -4279,12 +4694,12 @@ function TableRoot({
4279
4694
  filteredCount,
4280
4695
  ...dataTableProps
4281
4696
  }) {
4282
- const { header, pagination: paginationElement } = (0, import_react12.useMemo)(
4697
+ const { header, pagination: paginationElement } = (0, import_react13.useMemo)(
4283
4698
  () => parseTableChildren(children),
4284
4699
  [children]
4285
4700
  );
4286
- const [sort, setSort] = (0, import_react12.useState)(null);
4287
- const handleSort = (0, import_react12.useCallback)((field) => {
4701
+ const [sort, setSort] = (0, import_react13.useState)(null);
4702
+ const handleSort = (0, import_react13.useCallback)((field) => {
4288
4703
  setSort((previous) => {
4289
4704
  if (previous?.field !== field) {
4290
4705
  return { field, direction: "asc" };
@@ -4295,8 +4710,8 @@ function TableRoot({
4295
4710
  return null;
4296
4711
  });
4297
4712
  }, []);
4298
- const columnTree = (0, import_react12.useMemo)(() => extractColumnTree(header), [header]);
4299
- const columns = (0, import_react12.useMemo)(
4713
+ const columnTree = (0, import_react13.useMemo)(() => extractColumnTree(header), [header]);
4714
+ const columns = (0, import_react13.useMemo)(
4300
4715
  () => buildColumnDefsFromTree(columnTree, sort, handleSort),
4301
4716
  [columnTree, sort, handleSort]
4302
4717
  );
@@ -4304,7 +4719,7 @@ function TableRoot({
4304
4719
  const pageSize = paginationProps?.pageSize ?? 10;
4305
4720
  const page = paginationProps?.page ?? 1;
4306
4721
  const resolvedTotalCount = paginationProps?.totalCount ?? totalCount ?? data.length;
4307
- const tableData = (0, import_react12.useMemo)(() => {
4722
+ const tableData = (0, import_react13.useMemo)(() => {
4308
4723
  const sortedData = sortTableData(data, sort);
4309
4724
  if (!paginationProps) return sortedData;
4310
4725
  return paginateTableData(sortedData, page, pageSize);