react-glide-table 2.0.2 → 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");
@@ -1785,13 +1786,350 @@ function getMergedHeaderGroups(headerGroups) {
1785
1786
  }));
1786
1787
  }
1787
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
+
1788
2126
  // src/core/useGlideTable.ts
1789
2127
  var import_react_table2 = require("@tanstack/react-table");
1790
2128
  var import_react_virtual = require("@tanstack/react-virtual");
1791
- var import_react7 = require("react");
2129
+ var import_react8 = require("react");
1792
2130
 
1793
2131
  // src/components/ui/table/features/cell-edit/useCellEdit.ts
1794
- var import_react4 = require("react");
2132
+ var import_react5 = require("react");
1795
2133
 
1796
2134
  // src/components/ui/table/features/cell-render/commitCellValue.ts
1797
2135
  function commitCellValue({
@@ -1831,21 +2169,21 @@ function useCellEdit({
1831
2169
  onDataChange,
1832
2170
  onCellChange
1833
2171
  }) {
1834
- const [editingCell, setEditingCell] = (0, import_react4.useState)(null);
1835
- const [draftValue, setDraftValue] = (0, import_react4.useState)("");
1836
- const draftValueRef = (0, import_react4.useRef)(draftValue);
1837
- const editingCellRef = (0, import_react4.useRef)(editingCell);
1838
- (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)(() => {
1839
2177
  draftValueRef.current = draftValue;
1840
2178
  }, [draftValue]);
1841
- (0, import_react4.useEffect)(() => {
2179
+ (0, import_react5.useEffect)(() => {
1842
2180
  editingCellRef.current = editingCell;
1843
2181
  }, [editingCell]);
1844
- const cancelEdit = (0, import_react4.useCallback)(() => {
2182
+ const cancelEdit = (0, import_react5.useCallback)(() => {
1845
2183
  setEditingCell(null);
1846
2184
  setDraftValue("");
1847
2185
  }, []);
1848
- const commitEdit = (0, import_react4.useCallback)(
2186
+ const commitEdit = (0, import_react5.useCallback)(
1849
2187
  (raw) => {
1850
2188
  const current = editingCellRef.current;
1851
2189
  if (!current) return true;
@@ -1881,7 +2219,7 @@ function useCellEdit({
1881
2219
  },
1882
2220
  [cancelEdit, data, onCellChange, onDataChange, rows]
1883
2221
  );
1884
- const startEdit = (0, import_react4.useCallback)(
2222
+ const startEdit = (0, import_react5.useCallback)(
1885
2223
  (rowIndex, colIndex) => {
1886
2224
  const cell = rows[rowIndex]?.getVisibleCells()[colIndex];
1887
2225
  if (!cell || !isColumnEditable(cell.column.columnDef)) return;
@@ -2117,7 +2455,7 @@ function formatDefaultCellValue(value) {
2117
2455
  }
2118
2456
 
2119
2457
  // src/components/ui/table/features/cell-selection/useCellSelection.ts
2120
- var import_react5 = require("react");
2458
+ var import_react6 = require("react");
2121
2459
 
2122
2460
  // src/components/ui/table/features/cell-selection/copyData.ts
2123
2461
  function formatPrimitive(value) {
@@ -2396,15 +2734,15 @@ function useCellSelection({
2396
2734
  onRowsPaste,
2397
2735
  onCellNavigate
2398
2736
  }) {
2399
- const [dragState, setDragState] = (0, import_react5.useState)(INITIAL_DRAG_STATE);
2400
- const pendingPasteModeRef = (0, import_react5.useRef)(null);
2401
- const dragStateRef = (0, import_react5.useRef)(dragState);
2402
- 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);
2403
2741
  dragStateRef.current = dragState;
2404
2742
  onCellNavigateRef.current = onCellNavigate;
2405
2743
  const cellSelectionBounds = getCellSelectionBounds(dragState.start, dragState.end);
2406
2744
  const activeSelectionBounds = enabled ? getActiveSelectionBounds(dragState, cellSelectionBounds) : null;
2407
- const handleCellMouseDown = (0, import_react5.useCallback)(
2745
+ const handleCellMouseDown = (0, import_react6.useCallback)(
2408
2746
  (rowIndex, colIndex, options) => {
2409
2747
  if (!enabled) return;
2410
2748
  setDragState((prev) => {
@@ -2430,7 +2768,7 @@ function useCellSelection({
2430
2768
  },
2431
2769
  [enabled]
2432
2770
  );
2433
- const handleCellMouseEnter = (0, import_react5.useCallback)(
2771
+ const handleCellMouseEnter = (0, import_react6.useCallback)(
2434
2772
  (rowIndex, colIndex) => {
2435
2773
  if (!enabled) return;
2436
2774
  setDragState((prev) => {
@@ -2445,7 +2783,7 @@ function useCellSelection({
2445
2783
  },
2446
2784
  [enabled]
2447
2785
  );
2448
- const handleFillHandleMouseDown = (0, import_react5.useCallback)(
2786
+ const handleFillHandleMouseDown = (0, import_react6.useCallback)(
2449
2787
  (rowIndex, colIndex) => {
2450
2788
  if (!enabled) return;
2451
2789
  setDragState((prev) => {
@@ -2462,12 +2800,12 @@ function useCellSelection({
2462
2800
  },
2463
2801
  [enabled]
2464
2802
  );
2465
- (0, import_react5.useEffect)(() => {
2803
+ (0, import_react6.useEffect)(() => {
2466
2804
  if (!enabled) {
2467
2805
  setDragState(INITIAL_DRAG_STATE);
2468
2806
  }
2469
2807
  }, [enabled]);
2470
- (0, import_react5.useEffect)(() => {
2808
+ (0, import_react6.useEffect)(() => {
2471
2809
  if (!enabled) return;
2472
2810
  const handleKeyDown = (e) => {
2473
2811
  if (e.ctrlKey || e.metaKey || e.altKey) return;
@@ -2514,7 +2852,7 @@ function useCellSelection({
2514
2852
  window.addEventListener("keydown", handleKeyDown);
2515
2853
  return () => window.removeEventListener("keydown", handleKeyDown);
2516
2854
  }, [columnCount, enabled, rows]);
2517
- const copySelection = (0, import_react5.useCallback)(
2855
+ const copySelection = (0, import_react6.useCallback)(
2518
2856
  async (options) => {
2519
2857
  if (!enabled || !activeSelectionBounds) return false;
2520
2858
  const mode = options?.includeDescendants && enableSubtreeCopy ? "subtree" : "visible";
@@ -2522,7 +2860,7 @@ function useCellSelection({
2522
2860
  },
2523
2861
  [activeSelectionBounds, enableSubtreeCopy, enabled, rows]
2524
2862
  );
2525
- (0, import_react5.useEffect)(() => {
2863
+ (0, import_react6.useEffect)(() => {
2526
2864
  if (!enabled) return;
2527
2865
  const handleKeyDown = (e) => {
2528
2866
  if (!activeSelectionBounds) return;
@@ -2536,7 +2874,7 @@ function useCellSelection({
2536
2874
  window.addEventListener("keydown", handleKeyDown);
2537
2875
  return () => window.removeEventListener("keydown", handleKeyDown);
2538
2876
  }, [activeSelectionBounds, copySelection, enableSubtreeCopy, enabled]);
2539
- const emitRowsPaste = (0, import_react5.useCallback)(
2877
+ const emitRowsPaste = (0, import_react6.useCallback)(
2540
2878
  (text, mode) => {
2541
2879
  if (!onRowsPaste || !activeSelectionBounds) return false;
2542
2880
  const payload = buildRowsPastePayload(
@@ -2553,7 +2891,7 @@ function useCellSelection({
2553
2891
  },
2554
2892
  [activeSelectionBounds, onRowsPaste, rows]
2555
2893
  );
2556
- (0, import_react5.useEffect)(() => {
2894
+ (0, import_react6.useEffect)(() => {
2557
2895
  if (!enabled || !onRowsPaste) return;
2558
2896
  const pasteHandledRef = { current: false };
2559
2897
  const ignoreNextPasteRef = { current: false };
@@ -2621,7 +2959,7 @@ function useCellSelection({
2621
2959
  enabled,
2622
2960
  onRowsPaste
2623
2961
  ]);
2624
- (0, import_react5.useEffect)(() => {
2962
+ (0, import_react6.useEffect)(() => {
2625
2963
  if (!enabled) return;
2626
2964
  const handleMouseUp = () => {
2627
2965
  setDragState((prev) => {
@@ -2672,7 +3010,7 @@ function useCellSelection({
2672
3010
  }
2673
3011
 
2674
3012
  // src/components/ui/table/features/inline-search/useInlineSearch.ts
2675
- var import_react6 = require("react");
3013
+ var import_react7 = require("react");
2676
3014
  var EMPTY_MATCH_KEYS = /* @__PURE__ */ new Set();
2677
3015
  function useInlineSearch({
2678
3016
  enabled = false,
@@ -2689,46 +3027,46 @@ function useInlineSearch({
2689
3027
  onNavigateToResult,
2690
3028
  rootRef
2691
3029
  }) {
2692
- const searchInputId = (0, import_react6.useId)();
2693
- const searchInputRef = (0, import_react6.useRef)(null);
2694
- const [internalShowSearch, setInternalShowSearch] = (0, import_react6.useState)(false);
2695
- const [internalSearchValue, setInternalSearchValue] = (0, import_react6.useState)("");
2696
- 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)(
2697
3035
  []
2698
3036
  );
2699
- const [searchStatus, setSearchStatus] = (0, import_react6.useState)();
2700
- const searchStatusRef = (0, import_react6.useRef)(searchStatus);
3037
+ const [searchStatus, setSearchStatus] = (0, import_react7.useState)();
3038
+ const searchStatusRef = (0, import_react7.useRef)(searchStatus);
2701
3039
  searchStatusRef.current = searchStatus;
2702
- const abortControllerRef = (0, import_react6.useRef)(null);
2703
- const searchHandleRef = (0, import_react6.useRef)(void 0);
2704
- 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);
2705
3043
  initialStartRowRef.current = initialStartRow;
2706
- const getCellValueRef = (0, import_react6.useRef)(getCellValue);
3044
+ const getCellValueRef = (0, import_react7.useRef)(getCellValue);
2707
3045
  getCellValueRef.current = getCellValue;
2708
3046
  const showSearch = controlledShowSearch ?? internalShowSearch;
2709
3047
  const searchValue = controlledSearchValue ?? internalSearchValue;
2710
3048
  const searchResults = controlledSearchResults ?? internalResults;
2711
- const setSearchValue = (0, import_react6.useCallback)(
3049
+ const setSearchValue = (0, import_react7.useCallback)(
2712
3050
  (value) => {
2713
3051
  setInternalSearchValue(value);
2714
3052
  onSearchValueChange?.(value);
2715
3053
  },
2716
3054
  [onSearchValueChange]
2717
3055
  );
2718
- const cancelSearch = (0, import_react6.useCallback)(() => {
3056
+ const cancelSearch = (0, import_react7.useCallback)(() => {
2719
3057
  if (searchHandleRef.current !== void 0) {
2720
3058
  window.cancelAnimationFrame(searchHandleRef.current);
2721
3059
  searchHandleRef.current = void 0;
2722
3060
  }
2723
3061
  abortControllerRef.current?.abort();
2724
3062
  }, []);
2725
- const emitResultsChanged = (0, import_react6.useCallback)(
3063
+ const emitResultsChanged = (0, import_react7.useCallback)(
2726
3064
  (results, navIndex) => {
2727
3065
  onSearchResultsChanged?.(results, navIndex);
2728
3066
  },
2729
3067
  [onSearchResultsChanged]
2730
3068
  );
2731
- const navigateToIndex = (0, import_react6.useCallback)(
3069
+ const navigateToIndex = (0, import_react7.useCallback)(
2732
3070
  (results, navIndex) => {
2733
3071
  if (onSearchResultsChanged) return;
2734
3072
  if (navIndex < 0 || navIndex >= results.length) return;
@@ -2738,7 +3076,7 @@ function useInlineSearch({
2738
3076
  },
2739
3077
  [onNavigateToResult, onSearchResultsChanged]
2740
3078
  );
2741
- const beginSearch = (0, import_react6.useCallback)(
3079
+ const beginSearch = (0, import_react7.useCallback)(
2742
3080
  (query) => {
2743
3081
  if (controlledSearchResults !== void 0) return;
2744
3082
  const totalRows = rowCount;
@@ -2810,12 +3148,12 @@ function useInlineSearch({
2810
3148
  rowCount
2811
3149
  ]
2812
3150
  );
2813
- const openSearch = (0, import_react6.useCallback)(() => {
3151
+ const openSearch = (0, import_react7.useCallback)(() => {
2814
3152
  if (controlledShowSearch === void 0) {
2815
3153
  setInternalShowSearch(true);
2816
3154
  }
2817
3155
  }, [controlledShowSearch]);
2818
- const closeSearch = (0, import_react6.useCallback)(() => {
3156
+ const closeSearch = (0, import_react7.useCallback)(() => {
2819
3157
  if (controlledShowSearch === void 0) {
2820
3158
  setInternalShowSearch(false);
2821
3159
  }
@@ -2830,7 +3168,7 @@ function useInlineSearch({
2830
3168
  emitResultsChanged,
2831
3169
  onSearchClose
2832
3170
  ]);
2833
- const goToNext = (0, import_react6.useCallback)(() => {
3171
+ const goToNext = (0, import_react7.useCallback)(() => {
2834
3172
  if (!searchStatus || searchStatus.results === 0) return;
2835
3173
  const newIndex = nextSearchIndex(
2836
3174
  searchStatus.selectedIndex,
@@ -2840,7 +3178,7 @@ function useInlineSearch({
2840
3178
  emitResultsChanged(searchResults, newIndex);
2841
3179
  navigateToIndex(searchResults, newIndex);
2842
3180
  }, [emitResultsChanged, navigateToIndex, searchResults, searchStatus]);
2843
- const goToPrevious = (0, import_react6.useCallback)(() => {
3181
+ const goToPrevious = (0, import_react7.useCallback)(() => {
2844
3182
  if (!searchStatus || searchStatus.results === 0) return;
2845
3183
  const newIndex = previousSearchIndex(
2846
3184
  searchStatus.selectedIndex,
@@ -2850,7 +3188,7 @@ function useInlineSearch({
2850
3188
  emitResultsChanged(searchResults, newIndex);
2851
3189
  navigateToIndex(searchResults, newIndex);
2852
3190
  }, [emitResultsChanged, navigateToIndex, searchResults, searchStatus]);
2853
- (0, import_react6.useEffect)(() => {
3191
+ (0, import_react7.useEffect)(() => {
2854
3192
  if (controlledSearchResults === void 0) return;
2855
3193
  if (controlledSearchResults.length > 0) {
2856
3194
  setSearchStatus((current) => ({
@@ -2862,7 +3200,7 @@ function useInlineSearch({
2862
3200
  setSearchStatus(void 0);
2863
3201
  }
2864
3202
  }, [controlledSearchResults, rowCount]);
2865
- (0, import_react6.useEffect)(() => {
3203
+ (0, import_react7.useEffect)(() => {
2866
3204
  if (!enabled) return;
2867
3205
  setSearchStatus(void 0);
2868
3206
  setInternalResults([]);
@@ -2875,7 +3213,7 @@ function useInlineSearch({
2875
3213
  cancelSearch();
2876
3214
  }
2877
3215
  }, [enabled, showSearch]);
2878
- (0, import_react6.useEffect)(() => {
3216
+ (0, import_react7.useEffect)(() => {
2879
3217
  if (!enabled || !showSearch) return;
2880
3218
  if (controlledSearchResults !== void 0) return;
2881
3219
  if (searchValue.trim() === "") {
@@ -2895,7 +3233,7 @@ function useInlineSearch({
2895
3233
  searchValue,
2896
3234
  showSearch
2897
3235
  ]);
2898
- (0, import_react6.useEffect)(() => {
3236
+ (0, import_react7.useEffect)(() => {
2899
3237
  if (!enabled) return;
2900
3238
  const handleKeyDown = (event) => {
2901
3239
  if (!(event.ctrlKey || event.metaKey)) return;
@@ -2922,12 +3260,12 @@ function useInlineSearch({
2922
3260
  window.addEventListener("keydown", handleKeyDown, true);
2923
3261
  return () => window.removeEventListener("keydown", handleKeyDown, true);
2924
3262
  }, [controlledShowSearch, enabled, rootRef, showSearch]);
2925
- (0, import_react6.useEffect)(() => () => cancelSearch(), [cancelSearch]);
2926
- const searchMatchKeys = (0, import_react6.useMemo)(
3263
+ (0, import_react7.useEffect)(() => () => cancelSearch(), [cancelSearch]);
3264
+ const searchMatchKeys = (0, import_react7.useMemo)(
2927
3265
  () => buildSearchMatchKeys(searchResults),
2928
3266
  [searchResults]
2929
3267
  );
2930
- const activeMatch = (0, import_react6.useMemo)(() => {
3268
+ const activeMatch = (0, import_react7.useMemo)(() => {
2931
3269
  if (!searchStatus || searchStatus.selectedIndex < 0) return null;
2932
3270
  return searchResults[searchStatus.selectedIndex] ?? null;
2933
3271
  }, [searchResults, searchStatus]);
@@ -2992,6 +3330,7 @@ var DEFAULT_DATA_TABLE_LABELS = {
2992
3330
  expandRow: "Expand row",
2993
3331
  collapseRow: "Collapse row",
2994
3332
  resizeColumn: "Resize column",
3333
+ reorderColumn: "Reorder column",
2995
3334
  searchPlaceholder: "Search\u2026",
2996
3335
  searchResultHint: "Type to search",
2997
3336
  searchPrevious: "Previous result",
@@ -3049,6 +3388,9 @@ function useGlideTable(options) {
3049
3388
  columnSizing: controlledColumnSizing,
3050
3389
  onColumnSizingChange,
3051
3390
  columnResizeMode = "onChange",
3391
+ enableColumnReorder = false,
3392
+ columnOrder: controlledColumnOrder,
3393
+ onColumnOrderChange,
3052
3394
  enableColumnFreeze = false,
3053
3395
  enableInlineSearch = false,
3054
3396
  showSearch,
@@ -3058,7 +3400,7 @@ function useGlideTable(options) {
3058
3400
  searchResults,
3059
3401
  onSearchResultsChanged
3060
3402
  } = options;
3061
- const labels = (0, import_react7.useMemo)(() => {
3403
+ const labels = (0, import_react8.useMemo)(() => {
3062
3404
  const resolved = resolveDataTableLabels(labelsProp);
3063
3405
  return {
3064
3406
  ...resolved,
@@ -3069,16 +3411,17 @@ function useGlideTable(options) {
3069
3411
  }, [labelsProp, emptyText, loadingText, selectionLabel]);
3070
3412
  const enableExpand = Boolean(toggleField);
3071
3413
  const resolvedEnableSubtreeCopy = enableSubtreeCopy ?? enableExpand;
3072
- const [internalRowSelection, setInternalRowSelection] = (0, import_react7.useState)({});
3073
- const [internalColumnSizing, setInternalColumnSizing] = (0, import_react7.useState)({});
3074
- 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)(
3075
3418
  () => /* @__PURE__ */ new Set()
3076
3419
  );
3077
- const [hoveredRowIndex, setHoveredRowIndex] = (0, import_react7.useState)(null);
3078
- const scrollRef = (0, import_react7.useRef)(null);
3079
- 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);
3080
3423
  const shouldVirtualize = enableVirtualization && !enableRowSpan;
3081
- (0, import_react7.useEffect)(() => {
3424
+ (0, import_react8.useEffect)(() => {
3082
3425
  if (enableVirtualization && enableRowSpan) {
3083
3426
  console.warn(
3084
3427
  "[useGlideTable] enableRowSpan is on; virtualization is disabled to preserve cell merges."
@@ -3091,8 +3434,23 @@ function useGlideTable(options) {
3091
3434
  internalRowSelection
3092
3435
  );
3093
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
+ );
3094
3452
  const expandedRows = controlledExpandedRows ?? internalExpandedRows;
3095
- const handleExpandedRowsChange = (0, import_react7.useCallback)(
3453
+ const handleExpandedRowsChange = (0, import_react8.useCallback)(
3096
3454
  (next) => {
3097
3455
  if (onExpandedRowsChange) {
3098
3456
  onExpandedRowsChange(next);
@@ -3115,7 +3473,7 @@ function useGlideTable(options) {
3115
3473
  });
3116
3474
  const table = (0, import_react_table2.useReactTable)({
3117
3475
  data: tableData,
3118
- columns,
3476
+ columns: tableColumns,
3119
3477
  ...enableColumnResize ? {
3120
3478
  defaultColumn: {
3121
3479
  minSize: DATA_TABLE_COLUMN_MIN_SIZE,
@@ -3153,13 +3511,13 @@ function useGlideTable(options) {
3153
3511
  getCoreRowModel: (0, import_react_table2.getCoreRowModel)(),
3154
3512
  getRowId: getRowId ? (originalRow, index) => getRowId(originalRow, index) : (_originalRow, index) => String(index)
3155
3513
  });
3156
- const rowSpanColumnKeys = (0, import_react7.useMemo)(() => {
3514
+ const rowSpanColumnKeys = (0, import_react8.useMemo)(() => {
3157
3515
  if (!enableRowSpan) return [];
3158
3516
  return collectRowSpanColumns(columns);
3159
3517
  }, [enableRowSpan, columns]);
3160
3518
  const primaryRowSpanKey = rowSpanColumnKeys[0]?.rowSpanKey;
3161
3519
  const primaryRowSpanColumnId = rowSpanColumnKeys[0]?.columnId;
3162
- const columnRowSpanMap = (0, import_react7.useMemo)(
3520
+ const columnRowSpanMap = (0, import_react8.useMemo)(
3163
3521
  () => buildColumnRowSpanMap(tableData, rowSpanColumnKeys),
3164
3522
  [tableData, rowSpanColumnKeys]
3165
3523
  );
@@ -3168,7 +3526,7 @@ function useGlideTable(options) {
3168
3526
  const rows = table.getRowModel().rows;
3169
3527
  const columnCount = table.getAllLeafColumns().length || 1;
3170
3528
  const visibleLeafColumns = table.getVisibleLeafColumns();
3171
- const columnFreezeOffsets = (0, import_react7.useMemo)(() => {
3529
+ const columnFreezeOffsets = (0, import_react8.useMemo)(() => {
3172
3530
  if (!enableColumnFreeze) return EMPTY_COLUMN_FREEZE_OFFSETS;
3173
3531
  return buildColumnFreezeOffsets(
3174
3532
  visibleLeafColumns.map((column) => ({
@@ -3188,14 +3546,14 @@ function useGlideTable(options) {
3188
3546
  const totalSize = rowVirtualizer.getTotalSize();
3189
3547
  const paddingTop = virtualRows.length > 0 ? virtualRows[0]?.start ?? 0 : 0;
3190
3548
  const paddingBottom = virtualRows.length > 0 ? totalSize - (virtualRows[virtualRows.length - 1]?.end ?? 0) : 0;
3191
- const selectedRowIndices = (0, import_react7.useMemo)(() => {
3549
+ const selectedRowIndices = (0, import_react8.useMemo)(() => {
3192
3550
  const indices = /* @__PURE__ */ new Set();
3193
3551
  for (const selectedRow of selectedRows) {
3194
3552
  indices.add(selectedRow.index);
3195
3553
  }
3196
3554
  return indices;
3197
3555
  }, [selectedRows]);
3198
- const scrollCellIntoView = (0, import_react7.useCallback)(
3556
+ const scrollCellIntoView = (0, import_react8.useCallback)(
3199
3557
  (rowIndex, colIndex, options2) => {
3200
3558
  const align = options2?.align ?? "nearest";
3201
3559
  const blockAlign = align === "center" ? "center" : "nearest";
@@ -3222,7 +3580,7 @@ function useGlideTable(options) {
3222
3580
  },
3223
3581
  [rowVirtualizer, shouldVirtualize]
3224
3582
  );
3225
- const handleCellNavigate = (0, import_react7.useCallback)(
3583
+ const handleCellNavigate = (0, import_react8.useCallback)(
3226
3584
  (position) => {
3227
3585
  scrollCellIntoView(position.row, position.col, { align: "nearest" });
3228
3586
  },
@@ -3255,11 +3613,11 @@ function useGlideTable(options) {
3255
3613
  commitEdit,
3256
3614
  cancelEdit
3257
3615
  } = useCellEdit({ data: tableData, rows, onDataChange, onCellChange });
3258
- const cellRendererRegistry = (0, import_react7.useMemo)(
3616
+ const cellRendererRegistry = (0, import_react8.useMemo)(
3259
3617
  () => createCellRendererRegistry(cellRenderers),
3260
3618
  [cellRenderers]
3261
3619
  );
3262
- const commitRenderedCellValue = (0, import_react7.useCallback)(
3620
+ const commitRenderedCellValue = (0, import_react8.useCallback)(
3263
3621
  (rowId, columnId, value) => commitCellValue({
3264
3622
  data: tableData,
3265
3623
  rows,
@@ -3271,11 +3629,11 @@ function useGlideTable(options) {
3271
3629
  }),
3272
3630
  [onCellChange, onDataChange, rows, tableData]
3273
3631
  );
3274
- const getCellContext = (0, import_react7.useCallback)(
3632
+ const getCellContext = (0, import_react8.useCallback)(
3275
3633
  (cell) => withCellUpdate(cell.getContext(), commitRenderedCellValue),
3276
3634
  [commitRenderedCellValue]
3277
3635
  );
3278
- const handleCellMouseDownWithCommit = (0, import_react7.useCallback)(
3636
+ const handleCellMouseDownWithCommit = (0, import_react8.useCallback)(
3279
3637
  (rowIndex, colIndex, options2) => {
3280
3638
  const isSameEditingCell = editingCell?.rowIndex === rowIndex && editingCell?.colIndex === colIndex;
3281
3639
  if (editingCell && !isSameEditingCell && !commitEdit()) {
@@ -3285,7 +3643,7 @@ function useGlideTable(options) {
3285
3643
  },
3286
3644
  [commitEdit, editingCell, handleCellMouseDown]
3287
3645
  );
3288
- const navigateToSearchResult = (0, import_react7.useCallback)(
3646
+ const navigateToSearchResult = (0, import_react8.useCallback)(
3289
3647
  (item) => {
3290
3648
  const [colIndex, rowIndex] = item;
3291
3649
  handleCellMouseDownWithCommit(rowIndex, colIndex);
@@ -3293,7 +3651,7 @@ function useGlideTable(options) {
3293
3651
  },
3294
3652
  [handleCellMouseDownWithCommit, scrollCellIntoView]
3295
3653
  );
3296
- const resolveSearchRowId = (0, import_react7.useCallback)(
3654
+ const resolveSearchRowId = (0, import_react8.useCallback)(
3297
3655
  (row, index) => {
3298
3656
  if (getRowId) return getRowId(row, index);
3299
3657
  if (enableExpand) {
@@ -3317,7 +3675,7 @@ function useGlideTable(options) {
3317
3675
  },
3318
3676
  [enableExpand, getRowId, toggleField]
3319
3677
  );
3320
- const searchCorpus = (0, import_react7.useMemo)(() => {
3678
+ const searchCorpus = (0, import_react8.useMemo)(() => {
3321
3679
  if (!enableInlineSearch) return [];
3322
3680
  if (enableExpand && toggleField) {
3323
3681
  return buildTreeSearchCorpus(tableData, {
@@ -3333,16 +3691,16 @@ function useGlideTable(options) {
3333
3691
  tableData,
3334
3692
  toggleField
3335
3693
  ]);
3336
- const searchCorpusRef = (0, import_react7.useRef)(searchCorpus);
3694
+ const searchCorpusRef = (0, import_react8.useRef)(searchCorpus);
3337
3695
  searchCorpusRef.current = searchCorpus;
3338
- const visibleRowIndexById = (0, import_react7.useMemo)(() => {
3696
+ const visibleRowIndexById = (0, import_react8.useMemo)(() => {
3339
3697
  const map = /* @__PURE__ */ new Map();
3340
3698
  for (const row of rows) {
3341
3699
  map.set(resolveSearchRowId(row.original, row.index), row.index);
3342
3700
  }
3343
3701
  return map;
3344
3702
  }, [resolveSearchRowId, rows]);
3345
- const getSearchCellValue = (0, import_react7.useCallback)(
3703
+ const getSearchCellValue = (0, import_react8.useCallback)(
3346
3704
  (rowIndex, colIndex) => {
3347
3705
  const corpusRow = searchCorpusRef.current[rowIndex];
3348
3706
  const column = visibleLeafColumns[colIndex];
@@ -3365,14 +3723,14 @@ function useGlideTable(options) {
3365
3723
  },
3366
3724
  [rows, visibleLeafColumns, visibleRowIndexById]
3367
3725
  );
3368
- const pendingSearchNavRef = (0, import_react7.useRef)(null);
3369
- const focusSearchResult = (0, import_react7.useCallback)(
3726
+ const pendingSearchNavRef = (0, import_react8.useRef)(null);
3727
+ const focusSearchResult = (0, import_react8.useCallback)(
3370
3728
  (colIndex, visibleRowIndex) => {
3371
3729
  navigateToSearchResult([colIndex, visibleRowIndex]);
3372
3730
  },
3373
3731
  [navigateToSearchResult]
3374
3732
  );
3375
- const navigateToCorpusSearchResult = (0, import_react7.useCallback)(
3733
+ const navigateToCorpusSearchResult = (0, import_react8.useCallback)(
3376
3734
  (item) => {
3377
3735
  const [colIndex, corpusRowIndex] = item;
3378
3736
  const corpusRow = searchCorpusRef.current[corpusRowIndex];
@@ -3405,7 +3763,7 @@ function useGlideTable(options) {
3405
3763
  visibleRowIndexById
3406
3764
  ]
3407
3765
  );
3408
- (0, import_react7.useEffect)(() => {
3766
+ (0, import_react8.useEffect)(() => {
3409
3767
  const pending = pendingSearchNavRef.current;
3410
3768
  if (!pending) return;
3411
3769
  const visibleRowIndex = visibleRowIndexById.get(pending.rowId);
@@ -3429,7 +3787,7 @@ function useGlideTable(options) {
3429
3787
  onNavigateToResult: navigateToCorpusSearchResult,
3430
3788
  rootRef
3431
3789
  });
3432
- const visibleSearchMatchKeys = (0, import_react7.useMemo)(() => {
3790
+ const visibleSearchMatchKeys = (0, import_react8.useMemo)(() => {
3433
3791
  if (!enableInlineSearch) return EMPTY_SEARCH_MATCH_KEYS;
3434
3792
  return mapSearchResultsToVisibleKeys(
3435
3793
  inlineSearch.searchResults,
@@ -3442,7 +3800,7 @@ function useGlideTable(options) {
3442
3800
  searchCorpus,
3443
3801
  visibleRowIndexById
3444
3802
  ]);
3445
- const visibleActiveMatch = (0, import_react7.useMemo)(() => {
3803
+ const visibleActiveMatch = (0, import_react8.useMemo)(() => {
3446
3804
  if (!enableInlineSearch || !inlineSearch.activeMatch) return null;
3447
3805
  return mapSearchResultToVisibleItem(
3448
3806
  inlineSearch.activeMatch,
@@ -3455,13 +3813,13 @@ function useGlideTable(options) {
3455
3813
  searchCorpus,
3456
3814
  visibleRowIndexById
3457
3815
  ]);
3458
- const clearHover = (0, import_react7.useCallback)(() => {
3816
+ const clearHover = (0, import_react8.useCallback)(() => {
3459
3817
  setHoveredRowIndex(null);
3460
3818
  }, []);
3461
- const handleRowHover = (0, import_react7.useCallback)((rowIndex, _rowData) => {
3819
+ const handleRowHover = (0, import_react8.useCallback)((rowIndex, _rowData) => {
3462
3820
  setHoveredRowIndex(rowIndex);
3463
3821
  }, []);
3464
- const handleToggleSelect = (0, import_react7.useCallback)(
3822
+ const handleToggleSelect = (0, import_react8.useCallback)(
3465
3823
  (row) => {
3466
3824
  if (!row.getCanSelect()) return;
3467
3825
  if (preserveRowSelection && row.getIsSelected()) {
@@ -3471,14 +3829,14 @@ function useGlideTable(options) {
3471
3829
  },
3472
3830
  [preserveRowSelection]
3473
3831
  );
3474
- const handleToggleExpand = (0, import_react7.useCallback)(
3832
+ const handleToggleExpand = (0, import_react8.useCallback)(
3475
3833
  (rowKey) => {
3476
3834
  if (preventExpand) return;
3477
3835
  handleExpandedRowsChange(toggleExpandedRowId(rowKey, expandedRows));
3478
3836
  },
3479
3837
  [preventExpand, handleExpandedRowsChange, expandedRows]
3480
3838
  );
3481
- const rowContextValue = (0, import_react7.useMemo)(() => {
3839
+ const rowContextValue = (0, import_react8.useMemo)(() => {
3482
3840
  return {
3483
3841
  rowSpan: {
3484
3842
  enableRowSpan,
@@ -3577,12 +3935,12 @@ function useGlideTable(options) {
3577
3935
  visibleSearchMatchKeys,
3578
3936
  visibleActiveMatch
3579
3937
  ]);
3580
- const copySelectionRef = (0, import_react7.useRef)(copySelection);
3581
- (0, import_react7.useEffect)(() => {
3938
+ const copySelectionRef = (0, import_react8.useRef)(copySelection);
3939
+ (0, import_react8.useEffect)(() => {
3582
3940
  copySelectionRef.current = copySelection;
3583
3941
  }, [copySelection]);
3584
- const stableCopySelection = (0, import_react7.useCallback)((options2) => copySelectionRef.current(options2), []);
3585
- (0, import_react7.useEffect)(() => {
3942
+ const stableCopySelection = (0, import_react8.useCallback)((options2) => copySelectionRef.current(options2), []);
3943
+ (0, import_react8.useEffect)(() => {
3586
3944
  onCopyActionsReady?.({ copySelection: stableCopySelection });
3587
3945
  }, [onCopyActionsReady, stableCopySelection]);
3588
3946
  return {
@@ -3597,6 +3955,7 @@ function useGlideTable(options) {
3597
3955
  selectionLabel: labels.selection,
3598
3956
  enableCellSelection,
3599
3957
  enableColumnResize,
3958
+ enableColumnReorder,
3600
3959
  enableColumnFreeze,
3601
3960
  enableInlineSearch,
3602
3961
  shouldVirtualize,
@@ -3610,6 +3969,7 @@ function useGlideTable(options) {
3610
3969
  getCellContext,
3611
3970
  handleToggleSelect,
3612
3971
  clearHover,
3972
+ setColumnOrder,
3613
3973
  copySelection: stableCopySelection,
3614
3974
  inlineSearch: {
3615
3975
  showSearch: inlineSearch.showSearch,
@@ -3693,6 +4053,7 @@ function DataTable({
3693
4053
  selectionLabel,
3694
4054
  enableCellSelection,
3695
4055
  enableColumnResize,
4056
+ enableColumnReorder,
3696
4057
  enableColumnFreeze,
3697
4058
  enableInlineSearch,
3698
4059
  shouldVirtualize,
@@ -3705,6 +4066,7 @@ function DataTable({
3705
4066
  rowContextValue,
3706
4067
  handleToggleSelect,
3707
4068
  clearHover,
4069
+ setColumnOrder,
3708
4070
  inlineSearch
3709
4071
  } = useGlideTable(glideOptions);
3710
4072
  const ToolbarSlot = slots?.Toolbar ?? DataTableToolbar;
@@ -3714,7 +4076,13 @@ function DataTable({
3714
4076
  const EmptySlot = slots?.Empty ?? DefaultEmpty;
3715
4077
  const freezeOffsets = rowContextValue.columnFreeze.offsets;
3716
4078
  const headerGroups = getMergedHeaderGroups(table.getHeaderGroups());
3717
- 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)(
3718
4086
  () => ({ ...rowContextValue, classNames }),
3719
4087
  [rowContextValue, classNames]
3720
4088
  );
@@ -3736,6 +4104,8 @@ function DataTable({
3736
4104
  "DataTableJSX",
3737
4105
  !enableCellSelection && "DataTableJSX--no-cell-selection",
3738
4106
  enableColumnResize && "DataTableJSX--column-resize",
4107
+ enableColumnReorder && "DataTableJSX--column-reorder",
4108
+ isReordering && "DataTableJSX--column-reordering",
3739
4109
  enableColumnFreeze && "DataTableJSX--column-freeze",
3740
4110
  enableInlineSearch && "DataTableJSX--inline-search",
3741
4111
  classNames?.root,
@@ -3804,20 +4174,43 @@ function DataTable({
3804
4174
  ...sizeStyle,
3805
4175
  ...freezeStyle
3806
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;
3807
4186
  return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
3808
4187
  "th",
3809
4188
  {
3810
4189
  colSpan: header.colSpan,
3811
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,
3812
4197
  "data-resizing": header.column.getIsResizing() ? "" : void 0,
3813
4198
  "data-frozen": freezeOffset?.side,
3814
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,
3815
4207
  style: Object.keys(headerStyle).length > 0 ? headerStyle : void 0,
3816
4208
  className: cn(
3817
4209
  "data-table-head-cell",
3818
4210
  freezeOffset && `data-table-head-cell--frozen-${freezeOffset.side}`,
3819
4211
  CELL_ALIGN_CLASS[align],
3820
4212
  classNames?.headCell,
4213
+ dropEdge && classNames?.dropEdge,
3821
4214
  headerClassName
3822
4215
  ),
3823
4216
  children: [
@@ -3939,10 +4332,10 @@ function DataTable({
3939
4332
  }
3940
4333
 
3941
4334
  // src/components/ui/table/components/Table/Table.tsx
3942
- var import_react12 = require("react");
4335
+ var import_react13 = require("react");
3943
4336
 
3944
4337
  // src/components/ui/table/features/cell-render/ResolvedTableCell.tsx
3945
- var import_react9 = require("react");
4338
+ var import_react10 = require("react");
3946
4339
  function ResolvedTableCell({
3947
4340
  info
3948
4341
  }) {
@@ -3951,7 +4344,7 @@ function ResolvedTableCell({
3951
4344
  const meta = column.columnDef.meta;
3952
4345
  const value = getValue();
3953
4346
  const columnId = column.id;
3954
- const update = (0, import_react9.useCallback)(
4347
+ const update = (0, import_react10.useCallback)(
3955
4348
  (next) => {
3956
4349
  cellRender.commitValue(row.id, columnId, next);
3957
4350
  },
@@ -4011,6 +4404,7 @@ function buildColumnDef(props, sort, onSort) {
4011
4404
  minWidth,
4012
4405
  maxWidth,
4013
4406
  resizable,
4407
+ reorderable,
4014
4408
  frozen,
4015
4409
  align,
4016
4410
  rowSpan,
@@ -4056,6 +4450,7 @@ function buildColumnDef(props, sort, onSort) {
4056
4450
  cellProps,
4057
4451
  cellRender: render,
4058
4452
  frozen,
4453
+ reorderable,
4059
4454
  className,
4060
4455
  headerClassName
4061
4456
  }
@@ -4101,10 +4496,10 @@ function countLeafColumns(nodes) {
4101
4496
  }
4102
4497
 
4103
4498
  // src/components/ui/table/components/Table/parseTableChildren.ts
4104
- var import_react11 = require("react");
4499
+ var import_react12 = require("react");
4105
4500
 
4106
4501
  // src/components/ui/table/components/Table/tableChildTypes.ts
4107
- var import_react10 = require("react");
4502
+ var import_react11 = require("react");
4108
4503
  var TABLE_HEADER_DISPLAY_NAME = "Table.Header";
4109
4504
  var TABLE_BODY_DISPLAY_NAME = "Table.Body";
4110
4505
  var TABLE_COLUMN_DISPLAY_NAME = "Table.Column";
@@ -4117,19 +4512,19 @@ function getComponentDisplayName(type) {
4117
4512
  return void 0;
4118
4513
  }
4119
4514
  function isTableHeaderElement(child) {
4120
- 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;
4121
4516
  }
4122
4517
  function isTableBodyElement(child) {
4123
- 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;
4124
4519
  }
4125
4520
  function isTableColumnElement(child) {
4126
- 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;
4127
4522
  }
4128
4523
  function isTableColumnGroupElement(child) {
4129
- 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;
4130
4525
  }
4131
4526
  function isTablePaginationElement(child) {
4132
- 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;
4133
4528
  }
4134
4529
 
4135
4530
  // src/components/ui/table/components/Table/parseTableChildren.ts
@@ -4139,7 +4534,7 @@ function parseTableChildren(children) {
4139
4534
  body: null,
4140
4535
  pagination: null
4141
4536
  };
4142
- for (const child of import_react11.Children.toArray(children)) {
4537
+ for (const child of import_react12.Children.toArray(children)) {
4143
4538
  if (isTableHeaderElement(child)) {
4144
4539
  slots.header = child;
4145
4540
  continue;
@@ -4156,7 +4551,7 @@ function parseTableChildren(children) {
4156
4551
  }
4157
4552
  function walkColumnTreeNodes(children) {
4158
4553
  const result = [];
4159
- for (const child of import_react11.Children.toArray(children)) {
4554
+ for (const child of import_react12.Children.toArray(children)) {
4160
4555
  if (isTableColumnElement(child)) {
4161
4556
  result.push({
4162
4557
  type: "leaf",
@@ -4173,7 +4568,7 @@ function walkColumnTreeNodes(children) {
4173
4568
  });
4174
4569
  continue;
4175
4570
  }
4176
- if ((0, import_react11.isValidElement)(child)) {
4571
+ if ((0, import_react12.isValidElement)(child)) {
4177
4572
  const nested = child.props.children;
4178
4573
  if (nested != null) {
4179
4574
  result.push(...walkColumnTreeNodes(nested));
@@ -4299,12 +4694,12 @@ function TableRoot({
4299
4694
  filteredCount,
4300
4695
  ...dataTableProps
4301
4696
  }) {
4302
- const { header, pagination: paginationElement } = (0, import_react12.useMemo)(
4697
+ const { header, pagination: paginationElement } = (0, import_react13.useMemo)(
4303
4698
  () => parseTableChildren(children),
4304
4699
  [children]
4305
4700
  );
4306
- const [sort, setSort] = (0, import_react12.useState)(null);
4307
- const handleSort = (0, import_react12.useCallback)((field) => {
4701
+ const [sort, setSort] = (0, import_react13.useState)(null);
4702
+ const handleSort = (0, import_react13.useCallback)((field) => {
4308
4703
  setSort((previous) => {
4309
4704
  if (previous?.field !== field) {
4310
4705
  return { field, direction: "asc" };
@@ -4315,8 +4710,8 @@ function TableRoot({
4315
4710
  return null;
4316
4711
  });
4317
4712
  }, []);
4318
- const columnTree = (0, import_react12.useMemo)(() => extractColumnTree(header), [header]);
4319
- const columns = (0, import_react12.useMemo)(
4713
+ const columnTree = (0, import_react13.useMemo)(() => extractColumnTree(header), [header]);
4714
+ const columns = (0, import_react13.useMemo)(
4320
4715
  () => buildColumnDefsFromTree(columnTree, sort, handleSort),
4321
4716
  [columnTree, sort, handleSort]
4322
4717
  );
@@ -4324,7 +4719,7 @@ function TableRoot({
4324
4719
  const pageSize = paginationProps?.pageSize ?? 10;
4325
4720
  const page = paginationProps?.page ?? 1;
4326
4721
  const resolvedTotalCount = paginationProps?.totalCount ?? totalCount ?? data.length;
4327
- const tableData = (0, import_react12.useMemo)(() => {
4722
+ const tableData = (0, import_react13.useMemo)(() => {
4328
4723
  const sortedData = sortTableData(data, sort);
4329
4724
  if (!paginationProps) return sortedData;
4330
4725
  return paginateTableData(sortedData, page, pageSize);