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.js CHANGED
@@ -21,6 +21,7 @@ var DATA_TABLE_VIRTUAL_OVERSCAN = 8;
21
21
  var DATA_TABLE_COLUMN_SIZE = 150;
22
22
  var DATA_TABLE_COLUMN_MIN_SIZE = 40;
23
23
  var DATA_TABLE_COLUMN_MAX_SIZE = 800;
24
+ var DATA_TABLE_COLUMN_REORDER_THRESHOLD = 4;
24
25
 
25
26
  // src/components/ui/table/DataTableContext.tsx
26
27
  import { createContext, use } from "react";
@@ -72,6 +73,16 @@ function getCellEditDraftValue(value) {
72
73
  return String(value);
73
74
  }
74
75
 
76
+ // src/components/ui/table/features/cell-render/withCellUpdate.ts
77
+ function withCellUpdate(context, commitValue) {
78
+ return {
79
+ ...context,
80
+ update: (next) => {
81
+ commitValue(context.row.id, context.column.id, next);
82
+ }
83
+ };
84
+ }
85
+
75
86
  // src/components/ui/table/features/cell-selection/cellSelection.ts
76
87
  var INITIAL_DRAG_STATE = {
77
88
  isSelecting: false,
@@ -1102,6 +1113,7 @@ function DataTableRow({
1102
1113
  selection,
1103
1114
  cellSelection,
1104
1115
  cellEdit,
1116
+ cellRender,
1105
1117
  expand,
1106
1118
  columnResize,
1107
1119
  columnFreeze,
@@ -1139,6 +1151,10 @@ function DataTableRow({
1139
1151
  onCommitEdit,
1140
1152
  onCancelEdit
1141
1153
  } = cellEdit;
1154
+ const renderCell = (tableCell) => flexRender(
1155
+ tableCell.column.columnDef.cell,
1156
+ withCellUpdate(tableCell.getContext(), cellRender.commitValue)
1157
+ );
1142
1158
  const {
1143
1159
  enableExpand,
1144
1160
  toggleField,
@@ -1451,7 +1467,7 @@ function DataTableRow({
1451
1467
  "expand-cell-value",
1452
1468
  classNames?.expandCellValue
1453
1469
  ),
1454
- children: flexRender(cell.column.columnDef.cell, cell.getContext())
1470
+ children: renderCell(cell)
1455
1471
  }
1456
1472
  )
1457
1473
  ]
@@ -1490,7 +1506,7 @@ function DataTableRow({
1490
1506
  )
1491
1507
  }
1492
1508
  )
1493
- ] }) : flexRender(cell.column.columnDef.cell, cell.getContext()),
1509
+ ] }) : renderCell(cell),
1494
1510
  isBottomRightCell && /* @__PURE__ */ jsx3(
1495
1511
  "div",
1496
1512
  {
@@ -1742,6 +1758,348 @@ function getMergedHeaderGroups(headerGroups) {
1742
1758
  }));
1743
1759
  }
1744
1760
 
1761
+ // src/components/ui/table/features/column-reorder/columnReorder.ts
1762
+ function getColumnDefId(column) {
1763
+ if (column.id != null && column.id !== "") return column.id;
1764
+ if ("accessorKey" in column && column.accessorKey != null) {
1765
+ return String(column.accessorKey);
1766
+ }
1767
+ return void 0;
1768
+ }
1769
+ function getColumnDefChildren(column) {
1770
+ if (!("columns" in column) || !Array.isArray(column.columns)) return void 0;
1771
+ if (column.columns.length === 0) return void 0;
1772
+ return column.columns;
1773
+ }
1774
+ function collectLeafColumnIds(columns) {
1775
+ const ids = [];
1776
+ for (const column of columns) {
1777
+ const children = getColumnDefChildren(column);
1778
+ if (children) {
1779
+ ids.push(...collectLeafColumnIds(children));
1780
+ continue;
1781
+ }
1782
+ const id = getColumnDefId(column);
1783
+ if (id) ids.push(id);
1784
+ }
1785
+ return ids;
1786
+ }
1787
+ function areColumnOrdersEqual(left, right) {
1788
+ if (left.length !== right.length) return false;
1789
+ return left.every((id, index) => id === right[index]);
1790
+ }
1791
+ function resolveLeafColumnOrder(columns, order) {
1792
+ const leafIds = collectLeafColumnIds(columns);
1793
+ if (!order?.length) return leafIds;
1794
+ const leafSet = new Set(leafIds);
1795
+ const seen = /* @__PURE__ */ new Set();
1796
+ const next = order.filter((id) => {
1797
+ if (!leafSet.has(id) || seen.has(id)) return false;
1798
+ seen.add(id);
1799
+ return true;
1800
+ });
1801
+ for (const id of leafIds) {
1802
+ if (!seen.has(id)) next.push(id);
1803
+ }
1804
+ return next;
1805
+ }
1806
+ function flattenColumnSlots(columns, group) {
1807
+ const slots = [];
1808
+ for (const column of columns) {
1809
+ const id = getColumnDefId(column);
1810
+ const children = getColumnDefChildren(column);
1811
+ if (children) {
1812
+ const nestedGroup = id ? { id, def: column } : group;
1813
+ slots.push(...flattenColumnSlots(children, nestedGroup));
1814
+ continue;
1815
+ }
1816
+ if (!id) continue;
1817
+ slots.push({ id, def: column, group });
1818
+ }
1819
+ return slots;
1820
+ }
1821
+ function rebuildColumnTree(slots) {
1822
+ const result = [];
1823
+ let index = 0;
1824
+ while (index < slots.length) {
1825
+ const slot = slots[index];
1826
+ if (!slot.group) {
1827
+ result.push(slot.def);
1828
+ index += 1;
1829
+ continue;
1830
+ }
1831
+ const groupId = slot.group.id;
1832
+ const children = [];
1833
+ while (index < slots.length && slots[index]?.group?.id === groupId) {
1834
+ children.push(slots[index].def);
1835
+ index += 1;
1836
+ }
1837
+ const firstChildId = children[0] ? getColumnDefId(children[0]) : groupId;
1838
+ result.push({
1839
+ ...slot.group.def,
1840
+ id: `${groupId}::${firstChildId}`,
1841
+ columns: children
1842
+ });
1843
+ }
1844
+ return result;
1845
+ }
1846
+ function applyLeafColumnOrder(columns, order) {
1847
+ const resolved = resolveLeafColumnOrder(columns, order);
1848
+ const defaultOrder = collectLeafColumnIds(columns);
1849
+ if (areColumnOrdersEqual(resolved, defaultOrder)) {
1850
+ return columns;
1851
+ }
1852
+ const byId = new Map(
1853
+ flattenColumnSlots(columns).map((slot) => [
1854
+ slot.id,
1855
+ slot
1856
+ ])
1857
+ );
1858
+ const ordered = [];
1859
+ for (const id of resolved) {
1860
+ const slot = byId.get(id);
1861
+ if (slot) ordered.push(slot);
1862
+ }
1863
+ return rebuildColumnTree(ordered);
1864
+ }
1865
+ function moveColumnIds(order, fromIds, targetIds, edge) {
1866
+ if (fromIds.length === 0 || targetIds.length === 0) return [...order];
1867
+ const fromSet = new Set(fromIds);
1868
+ if (targetIds.some((id) => fromSet.has(id))) return [...order];
1869
+ const rest = order.filter((id) => !fromSet.has(id));
1870
+ const anchorId = edge === "before" ? targetIds[0] : targetIds[targetIds.length - 1];
1871
+ const anchorIndex = rest.indexOf(anchorId);
1872
+ if (anchorIndex < 0) return [...order];
1873
+ const insertAt = edge === "before" ? anchorIndex : anchorIndex + 1;
1874
+ return [...rest.slice(0, insertAt), ...fromIds, ...rest.slice(insertAt)];
1875
+ }
1876
+ function resolveDropEdge(clientX, rect) {
1877
+ return clientX < rect.left + rect.width / 2 ? "before" : "after";
1878
+ }
1879
+ function parseReorderIds(value) {
1880
+ if (!value) return [];
1881
+ return value.split(",").filter(Boolean);
1882
+ }
1883
+ function serializeReorderIds(ids) {
1884
+ return ids.join(",");
1885
+ }
1886
+ function isColumnReorderable(meta) {
1887
+ return meta?.reorderable !== false;
1888
+ }
1889
+
1890
+ // src/components/ui/table/features/column-reorder/useColumnReorder.ts
1891
+ import {
1892
+ useCallback,
1893
+ useEffect as useEffect3,
1894
+ useRef as useRef3,
1895
+ useState
1896
+ } from "react";
1897
+ function hitTestReorderHeader(table, clientX, clientY) {
1898
+ const headers = Array.from(
1899
+ table.querySelectorAll(
1900
+ "thead th[data-column-id][data-reorder-ids]"
1901
+ )
1902
+ );
1903
+ const containing = headers.find((element) => {
1904
+ const rect = element.getBoundingClientRect();
1905
+ return clientX >= rect.left && clientX <= rect.right && clientY >= rect.top && clientY <= rect.bottom;
1906
+ });
1907
+ if (containing) {
1908
+ return {
1909
+ columnId: containing.dataset.columnId ?? "",
1910
+ edge: resolveDropEdge(clientX, containing.getBoundingClientRect())
1911
+ };
1912
+ }
1913
+ const leaves = headers.filter(
1914
+ (element) => element.hasAttribute("data-reorder-leaf")
1915
+ );
1916
+ let match;
1917
+ for (const element of leaves) {
1918
+ const rect = element.getBoundingClientRect();
1919
+ if (clientX >= rect.left && clientX <= rect.right) {
1920
+ match = element;
1921
+ break;
1922
+ }
1923
+ }
1924
+ if (!match && leaves.length > 0) {
1925
+ const first = leaves[0].getBoundingClientRect();
1926
+ const last = leaves[leaves.length - 1].getBoundingClientRect();
1927
+ if (clientX < first.left) match = leaves[0];
1928
+ else if (clientX > last.right) match = leaves[leaves.length - 1];
1929
+ }
1930
+ if (!match) return null;
1931
+ return {
1932
+ columnId: match.dataset.columnId ?? "",
1933
+ edge: resolveDropEdge(clientX, match.getBoundingClientRect())
1934
+ };
1935
+ }
1936
+ function readTargetIds(table, columnId) {
1937
+ const element = table.querySelector(
1938
+ `thead th[data-column-id="${CSS.escape(columnId)}"]`
1939
+ );
1940
+ return parseReorderIds(element?.getAttribute("data-reorder-ids"));
1941
+ }
1942
+ function useColumnReorder(options) {
1943
+ const { enabled, columnOrder, onColumnOrderChange } = options;
1944
+ const sessionRef = useRef3(null);
1945
+ const columnOrderRef = useRef3(columnOrder);
1946
+ const onColumnOrderChangeRef = useRef3(onColumnOrderChange);
1947
+ const [draggingColumnId, setDraggingColumnId] = useState(null);
1948
+ const [dropTarget, setDropTarget] = useState(
1949
+ null
1950
+ );
1951
+ const dropTargetRef = useRef3(dropTarget);
1952
+ const previousUserSelectRef = useRef3(null);
1953
+ columnOrderRef.current = columnOrder;
1954
+ onColumnOrderChangeRef.current = onColumnOrderChange;
1955
+ dropTargetRef.current = dropTarget;
1956
+ const resetDrag = useCallback(() => {
1957
+ sessionRef.current = null;
1958
+ setDraggingColumnId(null);
1959
+ setDropTarget(null);
1960
+ const backup = previousUserSelectRef.current;
1961
+ previousUserSelectRef.current = null;
1962
+ if (backup) {
1963
+ if (backup.value) {
1964
+ document.body.style.setProperty("user-select", backup.value, backup.priority);
1965
+ } else {
1966
+ document.body.style.removeProperty("user-select");
1967
+ }
1968
+ return;
1969
+ }
1970
+ document.body.style.removeProperty("user-select");
1971
+ }, []);
1972
+ useEffect3(() => {
1973
+ if (!enabled) resetDrag();
1974
+ }, [enabled, resetDrag]);
1975
+ useEffect3(() => {
1976
+ return () => {
1977
+ resetDrag();
1978
+ };
1979
+ }, [resetDrag]);
1980
+ const onHeaderPointerDown = useCallback(
1981
+ (event, meta) => {
1982
+ if (!enabled || !meta.canDrag) return;
1983
+ if (event.button !== 0) return;
1984
+ if (event.pointerType === "mouse" && event.ctrlKey) return;
1985
+ const target = event.target;
1986
+ if (target instanceof Element && target.closest("[data-table-disable-cell-selection]")) {
1987
+ return;
1988
+ }
1989
+ const table = event.currentTarget.closest("table");
1990
+ if (!(table instanceof HTMLTableElement)) return;
1991
+ sessionRef.current = {
1992
+ pointerId: event.pointerId,
1993
+ startX: event.clientX,
1994
+ startY: event.clientY,
1995
+ columnId: meta.columnId,
1996
+ fromIds: meta.leafIds,
1997
+ table,
1998
+ active: false
1999
+ };
2000
+ },
2001
+ [enabled]
2002
+ );
2003
+ useEffect3(() => {
2004
+ if (!enabled) return;
2005
+ const onPointerMove = (event) => {
2006
+ const session = sessionRef.current;
2007
+ if (!session || event.pointerId !== session.pointerId) return;
2008
+ const deltaX = event.clientX - session.startX;
2009
+ const deltaY = event.clientY - session.startY;
2010
+ const distance = Math.hypot(deltaX, deltaY);
2011
+ if (!session.active) {
2012
+ if (distance < DATA_TABLE_COLUMN_REORDER_THRESHOLD) return;
2013
+ session.active = true;
2014
+ if (!previousUserSelectRef.current) {
2015
+ previousUserSelectRef.current = {
2016
+ value: document.body.style.getPropertyValue("user-select"),
2017
+ priority: document.body.style.getPropertyPriority("user-select")
2018
+ };
2019
+ }
2020
+ document.body.style.setProperty("user-select", "none");
2021
+ setDraggingColumnId(session.columnId);
2022
+ }
2023
+ event.preventDefault();
2024
+ const nextTarget = hitTestReorderHeader(
2025
+ session.table,
2026
+ event.clientX,
2027
+ event.clientY
2028
+ );
2029
+ if (!nextTarget || !nextTarget.columnId) {
2030
+ setDropTarget(null);
2031
+ return;
2032
+ }
2033
+ const targetIds = readTargetIds(session.table, nextTarget.columnId);
2034
+ const fromSet = new Set(session.fromIds);
2035
+ if (targetIds.some((id) => fromSet.has(id))) {
2036
+ setDropTarget(null);
2037
+ return;
2038
+ }
2039
+ setDropTarget((previous) => {
2040
+ if (previous?.columnId === nextTarget.columnId && previous.edge === nextTarget.edge) {
2041
+ return previous;
2042
+ }
2043
+ return nextTarget;
2044
+ });
2045
+ };
2046
+ const onPointerUp = (event) => {
2047
+ const session = sessionRef.current;
2048
+ if (!session || event.pointerId !== session.pointerId) {
2049
+ return;
2050
+ }
2051
+ if (session.active) {
2052
+ event.preventDefault();
2053
+ const target = dropTargetRef.current;
2054
+ if (target) {
2055
+ const targetIds = readTargetIds(session.table, target.columnId);
2056
+ const next = moveColumnIds(
2057
+ columnOrderRef.current,
2058
+ session.fromIds,
2059
+ targetIds,
2060
+ target.edge
2061
+ );
2062
+ onColumnOrderChangeRef.current(next);
2063
+ }
2064
+ const suppressClick = (clickEvent) => {
2065
+ clickEvent.preventDefault();
2066
+ clickEvent.stopPropagation();
2067
+ document.removeEventListener("click", suppressClick, true);
2068
+ };
2069
+ document.addEventListener("click", suppressClick, true);
2070
+ window.setTimeout(() => {
2071
+ document.removeEventListener("click", suppressClick, true);
2072
+ }, 0);
2073
+ }
2074
+ resetDrag();
2075
+ };
2076
+ const onPointerCancel = (event) => {
2077
+ const session = sessionRef.current;
2078
+ if (!session || event.pointerId !== session.pointerId) {
2079
+ return;
2080
+ }
2081
+ if (session.active) {
2082
+ event.preventDefault();
2083
+ }
2084
+ resetDrag();
2085
+ };
2086
+ document.addEventListener("pointermove", onPointerMove);
2087
+ document.addEventListener("pointerup", onPointerUp);
2088
+ document.addEventListener("pointercancel", onPointerCancel);
2089
+ return () => {
2090
+ document.removeEventListener("pointermove", onPointerMove);
2091
+ document.removeEventListener("pointerup", onPointerUp);
2092
+ document.removeEventListener("pointercancel", onPointerCancel);
2093
+ };
2094
+ }, [enabled, resetDrag]);
2095
+ return {
2096
+ isReordering: draggingColumnId != null,
2097
+ draggingColumnId,
2098
+ dropTarget,
2099
+ onHeaderPointerDown
2100
+ };
2101
+ }
2102
+
1745
2103
  // src/core/useGlideTable.ts
1746
2104
  import {
1747
2105
  getCoreRowModel,
@@ -1751,15 +2109,15 @@ import {
1751
2109
  useVirtualizer
1752
2110
  } from "@tanstack/react-virtual";
1753
2111
  import {
1754
- useCallback as useCallback4,
1755
- useEffect as useEffect6,
2112
+ useCallback as useCallback5,
2113
+ useEffect as useEffect7,
1756
2114
  useMemo as useMemo3,
1757
- useRef as useRef6,
1758
- useState as useState4
2115
+ useRef as useRef7,
2116
+ useState as useState5
1759
2117
  } from "react";
1760
2118
 
1761
2119
  // src/components/ui/table/features/cell-edit/useCellEdit.ts
1762
- import { useCallback, useEffect as useEffect3, useRef as useRef3, useState } from "react";
2120
+ import { useCallback as useCallback2, useEffect as useEffect4, useRef as useRef4, useState as useState2 } from "react";
1763
2121
 
1764
2122
  // src/components/ui/table/features/cell-render/commitCellValue.ts
1765
2123
  function commitCellValue({
@@ -1799,21 +2157,21 @@ function useCellEdit({
1799
2157
  onDataChange,
1800
2158
  onCellChange
1801
2159
  }) {
1802
- const [editingCell, setEditingCell] = useState(null);
1803
- const [draftValue, setDraftValue] = useState("");
1804
- const draftValueRef = useRef3(draftValue);
1805
- const editingCellRef = useRef3(editingCell);
1806
- useEffect3(() => {
2160
+ const [editingCell, setEditingCell] = useState2(null);
2161
+ const [draftValue, setDraftValue] = useState2("");
2162
+ const draftValueRef = useRef4(draftValue);
2163
+ const editingCellRef = useRef4(editingCell);
2164
+ useEffect4(() => {
1807
2165
  draftValueRef.current = draftValue;
1808
2166
  }, [draftValue]);
1809
- useEffect3(() => {
2167
+ useEffect4(() => {
1810
2168
  editingCellRef.current = editingCell;
1811
2169
  }, [editingCell]);
1812
- const cancelEdit = useCallback(() => {
2170
+ const cancelEdit = useCallback2(() => {
1813
2171
  setEditingCell(null);
1814
2172
  setDraftValue("");
1815
2173
  }, []);
1816
- const commitEdit = useCallback(
2174
+ const commitEdit = useCallback2(
1817
2175
  (raw) => {
1818
2176
  const current = editingCellRef.current;
1819
2177
  if (!current) return true;
@@ -1849,7 +2207,7 @@ function useCellEdit({
1849
2207
  },
1850
2208
  [cancelEdit, data, onCellChange, onDataChange, rows]
1851
2209
  );
1852
- const startEdit = useCallback(
2210
+ const startEdit = useCallback2(
1853
2211
  (rowIndex, colIndex) => {
1854
2212
  const cell = rows[rowIndex]?.getVisibleCells()[colIndex];
1855
2213
  if (!cell || !isColumnEditable(cell.column.columnDef)) return;
@@ -2085,7 +2443,7 @@ function formatDefaultCellValue(value) {
2085
2443
  }
2086
2444
 
2087
2445
  // src/components/ui/table/features/cell-selection/useCellSelection.ts
2088
- import { useCallback as useCallback2, useEffect as useEffect4, useRef as useRef4, useState as useState2 } from "react";
2446
+ import { useCallback as useCallback3, useEffect as useEffect5, useRef as useRef5, useState as useState3 } from "react";
2089
2447
 
2090
2448
  // src/components/ui/table/features/cell-selection/copyData.ts
2091
2449
  function formatPrimitive(value) {
@@ -2364,15 +2722,15 @@ function useCellSelection({
2364
2722
  onRowsPaste,
2365
2723
  onCellNavigate
2366
2724
  }) {
2367
- const [dragState, setDragState] = useState2(INITIAL_DRAG_STATE);
2368
- const pendingPasteModeRef = useRef4(null);
2369
- const dragStateRef = useRef4(dragState);
2370
- const onCellNavigateRef = useRef4(onCellNavigate);
2725
+ const [dragState, setDragState] = useState3(INITIAL_DRAG_STATE);
2726
+ const pendingPasteModeRef = useRef5(null);
2727
+ const dragStateRef = useRef5(dragState);
2728
+ const onCellNavigateRef = useRef5(onCellNavigate);
2371
2729
  dragStateRef.current = dragState;
2372
2730
  onCellNavigateRef.current = onCellNavigate;
2373
2731
  const cellSelectionBounds = getCellSelectionBounds(dragState.start, dragState.end);
2374
2732
  const activeSelectionBounds = enabled ? getActiveSelectionBounds(dragState, cellSelectionBounds) : null;
2375
- const handleCellMouseDown = useCallback2(
2733
+ const handleCellMouseDown = useCallback3(
2376
2734
  (rowIndex, colIndex, options) => {
2377
2735
  if (!enabled) return;
2378
2736
  setDragState((prev) => {
@@ -2398,7 +2756,7 @@ function useCellSelection({
2398
2756
  },
2399
2757
  [enabled]
2400
2758
  );
2401
- const handleCellMouseEnter = useCallback2(
2759
+ const handleCellMouseEnter = useCallback3(
2402
2760
  (rowIndex, colIndex) => {
2403
2761
  if (!enabled) return;
2404
2762
  setDragState((prev) => {
@@ -2413,7 +2771,7 @@ function useCellSelection({
2413
2771
  },
2414
2772
  [enabled]
2415
2773
  );
2416
- const handleFillHandleMouseDown = useCallback2(
2774
+ const handleFillHandleMouseDown = useCallback3(
2417
2775
  (rowIndex, colIndex) => {
2418
2776
  if (!enabled) return;
2419
2777
  setDragState((prev) => {
@@ -2430,12 +2788,12 @@ function useCellSelection({
2430
2788
  },
2431
2789
  [enabled]
2432
2790
  );
2433
- useEffect4(() => {
2791
+ useEffect5(() => {
2434
2792
  if (!enabled) {
2435
2793
  setDragState(INITIAL_DRAG_STATE);
2436
2794
  }
2437
2795
  }, [enabled]);
2438
- useEffect4(() => {
2796
+ useEffect5(() => {
2439
2797
  if (!enabled) return;
2440
2798
  const handleKeyDown = (e) => {
2441
2799
  if (e.ctrlKey || e.metaKey || e.altKey) return;
@@ -2482,7 +2840,7 @@ function useCellSelection({
2482
2840
  window.addEventListener("keydown", handleKeyDown);
2483
2841
  return () => window.removeEventListener("keydown", handleKeyDown);
2484
2842
  }, [columnCount, enabled, rows]);
2485
- const copySelection = useCallback2(
2843
+ const copySelection = useCallback3(
2486
2844
  async (options) => {
2487
2845
  if (!enabled || !activeSelectionBounds) return false;
2488
2846
  const mode = options?.includeDescendants && enableSubtreeCopy ? "subtree" : "visible";
@@ -2490,7 +2848,7 @@ function useCellSelection({
2490
2848
  },
2491
2849
  [activeSelectionBounds, enableSubtreeCopy, enabled, rows]
2492
2850
  );
2493
- useEffect4(() => {
2851
+ useEffect5(() => {
2494
2852
  if (!enabled) return;
2495
2853
  const handleKeyDown = (e) => {
2496
2854
  if (!activeSelectionBounds) return;
@@ -2504,7 +2862,7 @@ function useCellSelection({
2504
2862
  window.addEventListener("keydown", handleKeyDown);
2505
2863
  return () => window.removeEventListener("keydown", handleKeyDown);
2506
2864
  }, [activeSelectionBounds, copySelection, enableSubtreeCopy, enabled]);
2507
- const emitRowsPaste = useCallback2(
2865
+ const emitRowsPaste = useCallback3(
2508
2866
  (text, mode) => {
2509
2867
  if (!onRowsPaste || !activeSelectionBounds) return false;
2510
2868
  const payload = buildRowsPastePayload(
@@ -2521,7 +2879,7 @@ function useCellSelection({
2521
2879
  },
2522
2880
  [activeSelectionBounds, onRowsPaste, rows]
2523
2881
  );
2524
- useEffect4(() => {
2882
+ useEffect5(() => {
2525
2883
  if (!enabled || !onRowsPaste) return;
2526
2884
  const pasteHandledRef = { current: false };
2527
2885
  const ignoreNextPasteRef = { current: false };
@@ -2589,7 +2947,7 @@ function useCellSelection({
2589
2947
  enabled,
2590
2948
  onRowsPaste
2591
2949
  ]);
2592
- useEffect4(() => {
2950
+ useEffect5(() => {
2593
2951
  if (!enabled) return;
2594
2952
  const handleMouseUp = () => {
2595
2953
  setDragState((prev) => {
@@ -2641,12 +2999,12 @@ function useCellSelection({
2641
2999
 
2642
3000
  // src/components/ui/table/features/inline-search/useInlineSearch.ts
2643
3001
  import {
2644
- useCallback as useCallback3,
2645
- useEffect as useEffect5,
3002
+ useCallback as useCallback4,
3003
+ useEffect as useEffect6,
2646
3004
  useId,
2647
3005
  useMemo as useMemo2,
2648
- useRef as useRef5,
2649
- useState as useState3
3006
+ useRef as useRef6,
3007
+ useState as useState4
2650
3008
  } from "react";
2651
3009
  var EMPTY_MATCH_KEYS = /* @__PURE__ */ new Set();
2652
3010
  function useInlineSearch({
@@ -2665,45 +3023,45 @@ function useInlineSearch({
2665
3023
  rootRef
2666
3024
  }) {
2667
3025
  const searchInputId = useId();
2668
- const searchInputRef = useRef5(null);
2669
- const [internalShowSearch, setInternalShowSearch] = useState3(false);
2670
- const [internalSearchValue, setInternalSearchValue] = useState3("");
2671
- const [internalResults, setInternalResults] = useState3(
3026
+ const searchInputRef = useRef6(null);
3027
+ const [internalShowSearch, setInternalShowSearch] = useState4(false);
3028
+ const [internalSearchValue, setInternalSearchValue] = useState4("");
3029
+ const [internalResults, setInternalResults] = useState4(
2672
3030
  []
2673
3031
  );
2674
- const [searchStatus, setSearchStatus] = useState3();
2675
- const searchStatusRef = useRef5(searchStatus);
3032
+ const [searchStatus, setSearchStatus] = useState4();
3033
+ const searchStatusRef = useRef6(searchStatus);
2676
3034
  searchStatusRef.current = searchStatus;
2677
- const abortControllerRef = useRef5(null);
2678
- const searchHandleRef = useRef5(void 0);
2679
- const initialStartRowRef = useRef5(initialStartRow);
3035
+ const abortControllerRef = useRef6(null);
3036
+ const searchHandleRef = useRef6(void 0);
3037
+ const initialStartRowRef = useRef6(initialStartRow);
2680
3038
  initialStartRowRef.current = initialStartRow;
2681
- const getCellValueRef = useRef5(getCellValue);
3039
+ const getCellValueRef = useRef6(getCellValue);
2682
3040
  getCellValueRef.current = getCellValue;
2683
3041
  const showSearch = controlledShowSearch ?? internalShowSearch;
2684
3042
  const searchValue = controlledSearchValue ?? internalSearchValue;
2685
3043
  const searchResults = controlledSearchResults ?? internalResults;
2686
- const setSearchValue = useCallback3(
3044
+ const setSearchValue = useCallback4(
2687
3045
  (value) => {
2688
3046
  setInternalSearchValue(value);
2689
3047
  onSearchValueChange?.(value);
2690
3048
  },
2691
3049
  [onSearchValueChange]
2692
3050
  );
2693
- const cancelSearch = useCallback3(() => {
3051
+ const cancelSearch = useCallback4(() => {
2694
3052
  if (searchHandleRef.current !== void 0) {
2695
3053
  window.cancelAnimationFrame(searchHandleRef.current);
2696
3054
  searchHandleRef.current = void 0;
2697
3055
  }
2698
3056
  abortControllerRef.current?.abort();
2699
3057
  }, []);
2700
- const emitResultsChanged = useCallback3(
3058
+ const emitResultsChanged = useCallback4(
2701
3059
  (results, navIndex) => {
2702
3060
  onSearchResultsChanged?.(results, navIndex);
2703
3061
  },
2704
3062
  [onSearchResultsChanged]
2705
3063
  );
2706
- const navigateToIndex = useCallback3(
3064
+ const navigateToIndex = useCallback4(
2707
3065
  (results, navIndex) => {
2708
3066
  if (onSearchResultsChanged) return;
2709
3067
  if (navIndex < 0 || navIndex >= results.length) return;
@@ -2713,7 +3071,7 @@ function useInlineSearch({
2713
3071
  },
2714
3072
  [onNavigateToResult, onSearchResultsChanged]
2715
3073
  );
2716
- const beginSearch = useCallback3(
3074
+ const beginSearch = useCallback4(
2717
3075
  (query) => {
2718
3076
  if (controlledSearchResults !== void 0) return;
2719
3077
  const totalRows = rowCount;
@@ -2785,12 +3143,12 @@ function useInlineSearch({
2785
3143
  rowCount
2786
3144
  ]
2787
3145
  );
2788
- const openSearch = useCallback3(() => {
3146
+ const openSearch = useCallback4(() => {
2789
3147
  if (controlledShowSearch === void 0) {
2790
3148
  setInternalShowSearch(true);
2791
3149
  }
2792
3150
  }, [controlledShowSearch]);
2793
- const closeSearch = useCallback3(() => {
3151
+ const closeSearch = useCallback4(() => {
2794
3152
  if (controlledShowSearch === void 0) {
2795
3153
  setInternalShowSearch(false);
2796
3154
  }
@@ -2805,7 +3163,7 @@ function useInlineSearch({
2805
3163
  emitResultsChanged,
2806
3164
  onSearchClose
2807
3165
  ]);
2808
- const goToNext = useCallback3(() => {
3166
+ const goToNext = useCallback4(() => {
2809
3167
  if (!searchStatus || searchStatus.results === 0) return;
2810
3168
  const newIndex = nextSearchIndex(
2811
3169
  searchStatus.selectedIndex,
@@ -2815,7 +3173,7 @@ function useInlineSearch({
2815
3173
  emitResultsChanged(searchResults, newIndex);
2816
3174
  navigateToIndex(searchResults, newIndex);
2817
3175
  }, [emitResultsChanged, navigateToIndex, searchResults, searchStatus]);
2818
- const goToPrevious = useCallback3(() => {
3176
+ const goToPrevious = useCallback4(() => {
2819
3177
  if (!searchStatus || searchStatus.results === 0) return;
2820
3178
  const newIndex = previousSearchIndex(
2821
3179
  searchStatus.selectedIndex,
@@ -2825,7 +3183,7 @@ function useInlineSearch({
2825
3183
  emitResultsChanged(searchResults, newIndex);
2826
3184
  navigateToIndex(searchResults, newIndex);
2827
3185
  }, [emitResultsChanged, navigateToIndex, searchResults, searchStatus]);
2828
- useEffect5(() => {
3186
+ useEffect6(() => {
2829
3187
  if (controlledSearchResults === void 0) return;
2830
3188
  if (controlledSearchResults.length > 0) {
2831
3189
  setSearchStatus((current) => ({
@@ -2837,7 +3195,7 @@ function useInlineSearch({
2837
3195
  setSearchStatus(void 0);
2838
3196
  }
2839
3197
  }, [controlledSearchResults, rowCount]);
2840
- useEffect5(() => {
3198
+ useEffect6(() => {
2841
3199
  if (!enabled) return;
2842
3200
  setSearchStatus(void 0);
2843
3201
  setInternalResults([]);
@@ -2850,7 +3208,7 @@ function useInlineSearch({
2850
3208
  cancelSearch();
2851
3209
  }
2852
3210
  }, [enabled, showSearch]);
2853
- useEffect5(() => {
3211
+ useEffect6(() => {
2854
3212
  if (!enabled || !showSearch) return;
2855
3213
  if (controlledSearchResults !== void 0) return;
2856
3214
  if (searchValue.trim() === "") {
@@ -2870,7 +3228,7 @@ function useInlineSearch({
2870
3228
  searchValue,
2871
3229
  showSearch
2872
3230
  ]);
2873
- useEffect5(() => {
3231
+ useEffect6(() => {
2874
3232
  if (!enabled) return;
2875
3233
  const handleKeyDown = (event) => {
2876
3234
  if (!(event.ctrlKey || event.metaKey)) return;
@@ -2897,7 +3255,7 @@ function useInlineSearch({
2897
3255
  window.addEventListener("keydown", handleKeyDown, true);
2898
3256
  return () => window.removeEventListener("keydown", handleKeyDown, true);
2899
3257
  }, [controlledShowSearch, enabled, rootRef, showSearch]);
2900
- useEffect5(() => () => cancelSearch(), [cancelSearch]);
3258
+ useEffect6(() => () => cancelSearch(), [cancelSearch]);
2901
3259
  const searchMatchKeys = useMemo2(
2902
3260
  () => buildSearchMatchKeys(searchResults),
2903
3261
  [searchResults]
@@ -2967,6 +3325,7 @@ var DEFAULT_DATA_TABLE_LABELS = {
2967
3325
  expandRow: "Expand row",
2968
3326
  collapseRow: "Collapse row",
2969
3327
  resizeColumn: "Resize column",
3328
+ reorderColumn: "Reorder column",
2970
3329
  searchPlaceholder: "Search\u2026",
2971
3330
  searchResultHint: "Type to search",
2972
3331
  searchPrevious: "Previous result",
@@ -3024,6 +3383,9 @@ function useGlideTable(options) {
3024
3383
  columnSizing: controlledColumnSizing,
3025
3384
  onColumnSizingChange,
3026
3385
  columnResizeMode = "onChange",
3386
+ enableColumnReorder = false,
3387
+ columnOrder: controlledColumnOrder,
3388
+ onColumnOrderChange,
3027
3389
  enableColumnFreeze = false,
3028
3390
  enableInlineSearch = false,
3029
3391
  showSearch,
@@ -3044,16 +3406,17 @@ function useGlideTable(options) {
3044
3406
  }, [labelsProp, emptyText, loadingText, selectionLabel]);
3045
3407
  const enableExpand = Boolean(toggleField);
3046
3408
  const resolvedEnableSubtreeCopy = enableSubtreeCopy ?? enableExpand;
3047
- const [internalRowSelection, setInternalRowSelection] = useState4({});
3048
- const [internalColumnSizing, setInternalColumnSizing] = useState4({});
3049
- const [internalExpandedRows, setInternalExpandedRows] = useState4(
3409
+ const [internalRowSelection, setInternalRowSelection] = useState5({});
3410
+ const [internalColumnSizing, setInternalColumnSizing] = useState5({});
3411
+ const [internalColumnOrder, setInternalColumnOrder] = useState5([]);
3412
+ const [internalExpandedRows, setInternalExpandedRows] = useState5(
3050
3413
  () => /* @__PURE__ */ new Set()
3051
3414
  );
3052
- const [hoveredRowIndex, setHoveredRowIndex] = useState4(null);
3053
- const scrollRef = useRef6(null);
3054
- const rootRef = useRef6(null);
3415
+ const [hoveredRowIndex, setHoveredRowIndex] = useState5(null);
3416
+ const scrollRef = useRef7(null);
3417
+ const rootRef = useRef7(null);
3055
3418
  const shouldVirtualize = enableVirtualization && !enableRowSpan;
3056
- useEffect6(() => {
3419
+ useEffect7(() => {
3057
3420
  if (enableVirtualization && enableRowSpan) {
3058
3421
  console.warn(
3059
3422
  "[useGlideTable] enableRowSpan is on; virtualization is disabled to preserve cell merges."
@@ -3066,8 +3429,23 @@ function useGlideTable(options) {
3066
3429
  internalRowSelection
3067
3430
  );
3068
3431
  const columnSizing = controlledColumnSizing ?? internalColumnSizing;
3432
+ const columnOrder = controlledColumnOrder ?? internalColumnOrder;
3433
+ const tableColumns = useMemo3(() => {
3434
+ if (!enableColumnReorder) return columns;
3435
+ return applyLeafColumnOrder(columns, columnOrder);
3436
+ }, [columnOrder, columns, enableColumnReorder]);
3437
+ const setColumnOrder = useCallback5(
3438
+ (next) => {
3439
+ if (onColumnOrderChange) {
3440
+ onColumnOrderChange(next);
3441
+ return;
3442
+ }
3443
+ setInternalColumnOrder(next);
3444
+ },
3445
+ [onColumnOrderChange]
3446
+ );
3069
3447
  const expandedRows = controlledExpandedRows ?? internalExpandedRows;
3070
- const handleExpandedRowsChange = useCallback4(
3448
+ const handleExpandedRowsChange = useCallback5(
3071
3449
  (next) => {
3072
3450
  if (onExpandedRowsChange) {
3073
3451
  onExpandedRowsChange(next);
@@ -3090,7 +3468,7 @@ function useGlideTable(options) {
3090
3468
  });
3091
3469
  const table = useReactTable({
3092
3470
  data: tableData,
3093
- columns,
3471
+ columns: tableColumns,
3094
3472
  ...enableColumnResize ? {
3095
3473
  defaultColumn: {
3096
3474
  minSize: DATA_TABLE_COLUMN_MIN_SIZE,
@@ -3170,7 +3548,7 @@ function useGlideTable(options) {
3170
3548
  }
3171
3549
  return indices;
3172
3550
  }, [selectedRows]);
3173
- const scrollCellIntoView = useCallback4(
3551
+ const scrollCellIntoView = useCallback5(
3174
3552
  (rowIndex, colIndex, options2) => {
3175
3553
  const align = options2?.align ?? "nearest";
3176
3554
  const blockAlign = align === "center" ? "center" : "nearest";
@@ -3197,7 +3575,7 @@ function useGlideTable(options) {
3197
3575
  },
3198
3576
  [rowVirtualizer, shouldVirtualize]
3199
3577
  );
3200
- const handleCellNavigate = useCallback4(
3578
+ const handleCellNavigate = useCallback5(
3201
3579
  (position) => {
3202
3580
  scrollCellIntoView(position.row, position.col, { align: "nearest" });
3203
3581
  },
@@ -3234,7 +3612,7 @@ function useGlideTable(options) {
3234
3612
  () => createCellRendererRegistry(cellRenderers),
3235
3613
  [cellRenderers]
3236
3614
  );
3237
- const commitRenderedCellValue = useCallback4(
3615
+ const commitRenderedCellValue = useCallback5(
3238
3616
  (rowId, columnId, value) => commitCellValue({
3239
3617
  data: tableData,
3240
3618
  rows,
@@ -3246,7 +3624,11 @@ function useGlideTable(options) {
3246
3624
  }),
3247
3625
  [onCellChange, onDataChange, rows, tableData]
3248
3626
  );
3249
- const handleCellMouseDownWithCommit = useCallback4(
3627
+ const getCellContext = useCallback5(
3628
+ (cell) => withCellUpdate(cell.getContext(), commitRenderedCellValue),
3629
+ [commitRenderedCellValue]
3630
+ );
3631
+ const handleCellMouseDownWithCommit = useCallback5(
3250
3632
  (rowIndex, colIndex, options2) => {
3251
3633
  const isSameEditingCell = editingCell?.rowIndex === rowIndex && editingCell?.colIndex === colIndex;
3252
3634
  if (editingCell && !isSameEditingCell && !commitEdit()) {
@@ -3256,7 +3638,7 @@ function useGlideTable(options) {
3256
3638
  },
3257
3639
  [commitEdit, editingCell, handleCellMouseDown]
3258
3640
  );
3259
- const navigateToSearchResult = useCallback4(
3641
+ const navigateToSearchResult = useCallback5(
3260
3642
  (item) => {
3261
3643
  const [colIndex, rowIndex] = item;
3262
3644
  handleCellMouseDownWithCommit(rowIndex, colIndex);
@@ -3264,7 +3646,7 @@ function useGlideTable(options) {
3264
3646
  },
3265
3647
  [handleCellMouseDownWithCommit, scrollCellIntoView]
3266
3648
  );
3267
- const resolveSearchRowId = useCallback4(
3649
+ const resolveSearchRowId = useCallback5(
3268
3650
  (row, index) => {
3269
3651
  if (getRowId) return getRowId(row, index);
3270
3652
  if (enableExpand) {
@@ -3304,7 +3686,7 @@ function useGlideTable(options) {
3304
3686
  tableData,
3305
3687
  toggleField
3306
3688
  ]);
3307
- const searchCorpusRef = useRef6(searchCorpus);
3689
+ const searchCorpusRef = useRef7(searchCorpus);
3308
3690
  searchCorpusRef.current = searchCorpus;
3309
3691
  const visibleRowIndexById = useMemo3(() => {
3310
3692
  const map = /* @__PURE__ */ new Map();
@@ -3313,7 +3695,7 @@ function useGlideTable(options) {
3313
3695
  }
3314
3696
  return map;
3315
3697
  }, [resolveSearchRowId, rows]);
3316
- const getSearchCellValue = useCallback4(
3698
+ const getSearchCellValue = useCallback5(
3317
3699
  (rowIndex, colIndex) => {
3318
3700
  const corpusRow = searchCorpusRef.current[rowIndex];
3319
3701
  const column = visibleLeafColumns[colIndex];
@@ -3336,14 +3718,14 @@ function useGlideTable(options) {
3336
3718
  },
3337
3719
  [rows, visibleLeafColumns, visibleRowIndexById]
3338
3720
  );
3339
- const pendingSearchNavRef = useRef6(null);
3340
- const focusSearchResult = useCallback4(
3721
+ const pendingSearchNavRef = useRef7(null);
3722
+ const focusSearchResult = useCallback5(
3341
3723
  (colIndex, visibleRowIndex) => {
3342
3724
  navigateToSearchResult([colIndex, visibleRowIndex]);
3343
3725
  },
3344
3726
  [navigateToSearchResult]
3345
3727
  );
3346
- const navigateToCorpusSearchResult = useCallback4(
3728
+ const navigateToCorpusSearchResult = useCallback5(
3347
3729
  (item) => {
3348
3730
  const [colIndex, corpusRowIndex] = item;
3349
3731
  const corpusRow = searchCorpusRef.current[corpusRowIndex];
@@ -3376,7 +3758,7 @@ function useGlideTable(options) {
3376
3758
  visibleRowIndexById
3377
3759
  ]
3378
3760
  );
3379
- useEffect6(() => {
3761
+ useEffect7(() => {
3380
3762
  const pending = pendingSearchNavRef.current;
3381
3763
  if (!pending) return;
3382
3764
  const visibleRowIndex = visibleRowIndexById.get(pending.rowId);
@@ -3426,13 +3808,13 @@ function useGlideTable(options) {
3426
3808
  searchCorpus,
3427
3809
  visibleRowIndexById
3428
3810
  ]);
3429
- const clearHover = useCallback4(() => {
3811
+ const clearHover = useCallback5(() => {
3430
3812
  setHoveredRowIndex(null);
3431
3813
  }, []);
3432
- const handleRowHover = useCallback4((rowIndex, _rowData) => {
3814
+ const handleRowHover = useCallback5((rowIndex, _rowData) => {
3433
3815
  setHoveredRowIndex(rowIndex);
3434
3816
  }, []);
3435
- const handleToggleSelect = useCallback4(
3817
+ const handleToggleSelect = useCallback5(
3436
3818
  (row) => {
3437
3819
  if (!row.getCanSelect()) return;
3438
3820
  if (preserveRowSelection && row.getIsSelected()) {
@@ -3442,7 +3824,7 @@ function useGlideTable(options) {
3442
3824
  },
3443
3825
  [preserveRowSelection]
3444
3826
  );
3445
- const handleToggleExpand = useCallback4(
3827
+ const handleToggleExpand = useCallback5(
3446
3828
  (rowKey) => {
3447
3829
  if (preventExpand) return;
3448
3830
  handleExpandedRowsChange(toggleExpandedRowId(rowKey, expandedRows));
@@ -3548,12 +3930,12 @@ function useGlideTable(options) {
3548
3930
  visibleSearchMatchKeys,
3549
3931
  visibleActiveMatch
3550
3932
  ]);
3551
- const copySelectionRef = useRef6(copySelection);
3552
- useEffect6(() => {
3933
+ const copySelectionRef = useRef7(copySelection);
3934
+ useEffect7(() => {
3553
3935
  copySelectionRef.current = copySelection;
3554
3936
  }, [copySelection]);
3555
- const stableCopySelection = useCallback4((options2) => copySelectionRef.current(options2), []);
3556
- useEffect6(() => {
3937
+ const stableCopySelection = useCallback5((options2) => copySelectionRef.current(options2), []);
3938
+ useEffect7(() => {
3557
3939
  onCopyActionsReady?.({ copySelection: stableCopySelection });
3558
3940
  }, [onCopyActionsReady, stableCopySelection]);
3559
3941
  return {
@@ -3568,6 +3950,7 @@ function useGlideTable(options) {
3568
3950
  selectionLabel: labels.selection,
3569
3951
  enableCellSelection,
3570
3952
  enableColumnResize,
3953
+ enableColumnReorder,
3571
3954
  enableColumnFreeze,
3572
3955
  enableInlineSearch,
3573
3956
  shouldVirtualize,
@@ -3578,8 +3961,10 @@ function useGlideTable(options) {
3578
3961
  paddingTop,
3579
3962
  paddingBottom,
3580
3963
  rowContextValue,
3964
+ getCellContext,
3581
3965
  handleToggleSelect,
3582
3966
  clearHover,
3967
+ setColumnOrder,
3583
3968
  copySelection: stableCopySelection,
3584
3969
  inlineSearch: {
3585
3970
  showSearch: inlineSearch.showSearch,
@@ -3663,6 +4048,7 @@ function DataTable({
3663
4048
  selectionLabel,
3664
4049
  enableCellSelection,
3665
4050
  enableColumnResize,
4051
+ enableColumnReorder,
3666
4052
  enableColumnFreeze,
3667
4053
  enableInlineSearch,
3668
4054
  shouldVirtualize,
@@ -3675,6 +4061,7 @@ function DataTable({
3675
4061
  rowContextValue,
3676
4062
  handleToggleSelect,
3677
4063
  clearHover,
4064
+ setColumnOrder,
3678
4065
  inlineSearch
3679
4066
  } = useGlideTable(glideOptions);
3680
4067
  const ToolbarSlot = slots?.Toolbar ?? DataTableToolbar;
@@ -3684,6 +4071,12 @@ function DataTable({
3684
4071
  const EmptySlot = slots?.Empty ?? DefaultEmpty;
3685
4072
  const freezeOffsets = rowContextValue.columnFreeze.offsets;
3686
4073
  const headerGroups = getMergedHeaderGroups(table.getHeaderGroups());
4074
+ const leafColumnIds = table.getVisibleLeafColumns().map((column) => column.id);
4075
+ const { isReordering, draggingColumnId, dropTarget, onHeaderPointerDown } = useColumnReorder({
4076
+ enabled: enableColumnReorder,
4077
+ columnOrder: leafColumnIds,
4078
+ onColumnOrderChange: setColumnOrder
4079
+ });
3687
4080
  const contextValue = useMemo4(
3688
4081
  () => ({ ...rowContextValue, classNames }),
3689
4082
  [rowContextValue, classNames]
@@ -3706,6 +4099,8 @@ function DataTable({
3706
4099
  "DataTableJSX",
3707
4100
  !enableCellSelection && "DataTableJSX--no-cell-selection",
3708
4101
  enableColumnResize && "DataTableJSX--column-resize",
4102
+ enableColumnReorder && "DataTableJSX--column-reorder",
4103
+ isReordering && "DataTableJSX--column-reordering",
3709
4104
  enableColumnFreeze && "DataTableJSX--column-freeze",
3710
4105
  enableInlineSearch && "DataTableJSX--inline-search",
3711
4106
  classNames?.root,
@@ -3774,20 +4169,43 @@ function DataTable({
3774
4169
  ...sizeStyle,
3775
4170
  ...freezeStyle
3776
4171
  };
4172
+ const isPlaceholder = header.isPlaceholder;
4173
+ const leafColumns = header.column.getLeafColumns();
4174
+ const leafIds = leafColumns.map((leafColumn) => leafColumn.id);
4175
+ const isLeafHeader = !isPlaceholder && header.subHeaders.length === 0;
4176
+ const canDrag = enableColumnReorder && !isPlaceholder && leafIds.length > 0 && leafColumns.every(
4177
+ (leafColumn) => isColumnReorderable(leafColumn.columnDef.meta)
4178
+ );
4179
+ const isDragging = draggingColumnId === header.column.id;
4180
+ const dropEdge = !isPlaceholder && dropTarget?.columnId === header.column.id ? dropTarget.edge : void 0;
3777
4181
  return /* @__PURE__ */ jsxs6(
3778
4182
  "th",
3779
4183
  {
3780
4184
  colSpan: header.colSpan,
3781
4185
  rowSpan: header.mergedRowSpan,
4186
+ "data-column-id": enableColumnReorder && !isPlaceholder ? header.column.id : void 0,
4187
+ "data-reorder-ids": enableColumnReorder && !isPlaceholder ? serializeReorderIds(leafIds) : void 0,
4188
+ "data-reorder-leaf": enableColumnReorder && isLeafHeader ? "" : void 0,
4189
+ "data-reorderable": canDrag ? "" : void 0,
4190
+ "data-reordering": isDragging ? "" : void 0,
4191
+ "data-drop-edge": dropEdge,
3782
4192
  "data-resizing": header.column.getIsResizing() ? "" : void 0,
3783
4193
  "data-frozen": freezeOffset?.side,
3784
4194
  "data-freeze-edge": getColumnFreezeEdgeAttr(freezeOffset),
4195
+ "aria-grabbed": isDragging ? true : void 0,
4196
+ title: canDrag ? labels.reorderColumn : void 0,
4197
+ onPointerDown: enableColumnReorder ? (event) => onHeaderPointerDown(event, {
4198
+ columnId: header.column.id,
4199
+ leafIds,
4200
+ canDrag
4201
+ }) : void 0,
3785
4202
  style: Object.keys(headerStyle).length > 0 ? headerStyle : void 0,
3786
4203
  className: cn(
3787
4204
  "data-table-head-cell",
3788
4205
  freezeOffset && `data-table-head-cell--frozen-${freezeOffset.side}`,
3789
4206
  CELL_ALIGN_CLASS[align],
3790
4207
  classNames?.headCell,
4208
+ dropEdge && classNames?.dropEdge,
3791
4209
  headerClassName
3792
4210
  ),
3793
4211
  children: [
@@ -3909,10 +4327,10 @@ function DataTable({
3909
4327
  }
3910
4328
 
3911
4329
  // src/components/ui/table/components/Table/Table.tsx
3912
- import { useCallback as useCallback6, useMemo as useMemo5, useState as useState5 } from "react";
4330
+ import { useCallback as useCallback7, useMemo as useMemo5, useState as useState6 } from "react";
3913
4331
 
3914
4332
  // src/components/ui/table/features/cell-render/ResolvedTableCell.tsx
3915
- import { useCallback as useCallback5 } from "react";
4333
+ import { useCallback as useCallback6 } from "react";
3916
4334
  function ResolvedTableCell({
3917
4335
  info
3918
4336
  }) {
@@ -3921,7 +4339,7 @@ function ResolvedTableCell({
3921
4339
  const meta = column.columnDef.meta;
3922
4340
  const value = getValue();
3923
4341
  const columnId = column.id;
3924
- const update = useCallback5(
4342
+ const update = useCallback6(
3925
4343
  (next) => {
3926
4344
  cellRender.commitValue(row.id, columnId, next);
3927
4345
  },
@@ -3981,6 +4399,7 @@ function buildColumnDef(props, sort, onSort) {
3981
4399
  minWidth,
3982
4400
  maxWidth,
3983
4401
  resizable,
4402
+ reorderable,
3984
4403
  frozen,
3985
4404
  align,
3986
4405
  rowSpan,
@@ -4026,6 +4445,7 @@ function buildColumnDef(props, sort, onSort) {
4026
4445
  cellProps,
4027
4446
  cellRender: render,
4028
4447
  frozen,
4448
+ reorderable,
4029
4449
  className,
4030
4450
  headerClassName
4031
4451
  }
@@ -4273,8 +4693,8 @@ function TableRoot({
4273
4693
  () => parseTableChildren(children),
4274
4694
  [children]
4275
4695
  );
4276
- const [sort, setSort] = useState5(null);
4277
- const handleSort = useCallback6((field) => {
4696
+ const [sort, setSort] = useState6(null);
4697
+ const handleSort = useCallback7((field) => {
4278
4698
  setSort((previous) => {
4279
4699
  if (previous?.field !== field) {
4280
4700
  return { field, direction: "asc" };