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/index.cjs CHANGED
@@ -33,6 +33,7 @@ __export(src_exports, {
33
33
  Table: () => Table,
34
34
  applyCellEdit: () => applyCellEdit,
35
35
  applyFillData: () => applyFillData,
36
+ applyLeafColumnOrder: () => applyLeafColumnOrder,
36
37
  applySelectionUpdater: () => applySelectionUpdater,
37
38
  buildColumnFreezeOffsets: () => buildColumnFreezeOffsets,
38
39
  buildColumnRowSpanMap: () => buildColumnRowSpanMap,
@@ -47,6 +48,7 @@ __export(src_exports, {
47
48
  collectCopyRowEntries: () => collectCopyRowEntries,
48
49
  collectCopyRows: () => collectCopyRows,
49
50
  collectFillChanges: () => collectFillChanges,
51
+ collectLeafColumnIds: () => collectLeafColumnIds,
50
52
  collectRowSpanColumns: () => collectRowSpanColumns,
51
53
  collectSearchMatchesInRange: () => collectSearchMatchesInRange,
52
54
  commitCellValue: () => commitCellValue,
@@ -72,6 +74,7 @@ __export(src_exports, {
72
74
  mapSearchResultToVisibleItem: () => mapSearchResultToVisibleItem,
73
75
  mapSearchResultsToVisibleKeys: () => mapSearchResultsToVisibleKeys,
74
76
  measureMergedSpanRowHeights: () => measureMergedSpanRowHeights,
77
+ moveColumnIds: () => moveColumnIds,
75
78
  nextSearchIndex: () => nextSearchIndex,
76
79
  nextSearchStride: () => nextSearchStride,
77
80
  parseCellEditValue: () => parseCellEditValue,
@@ -81,7 +84,9 @@ __export(src_exports, {
81
84
  resolveCellRenderer: () => resolveCellRenderer,
82
85
  resolveColumnFreezeSide: () => resolveColumnFreezeSide,
83
86
  resolveDataTableLabels: () => resolveDataTableLabels,
87
+ resolveDropEdge: () => resolveDropEdge,
84
88
  resolveHeaderFreezeOffset: () => resolveHeaderFreezeOffset,
89
+ resolveLeafColumnOrder: () => resolveLeafColumnOrder,
85
90
  resolvePasteColumnIds: () => resolvePasteColumnIds,
86
91
  resolveRowSelection: () => resolveRowSelection,
87
92
  resolveRowSpanAt: () => resolveRowSpanAt,
@@ -91,9 +96,11 @@ __export(src_exports, {
91
96
  toggleExpandedRowId: () => toggleExpandedRowId,
92
97
  useCellEdit: () => useCellEdit,
93
98
  useCellSelection: () => useCellSelection,
99
+ useColumnReorder: () => useColumnReorder,
94
100
  useConvertTreeData: () => useConvertTreeData,
95
101
  useGlideTable: () => useGlideTable,
96
102
  useInlineSearch: () => useInlineSearch,
103
+ withCellUpdate: () => withCellUpdate,
97
104
  writeSelectionToClipboard: () => writeSelectionToClipboard
98
105
  });
99
106
  module.exports = __toCommonJS(src_exports);
@@ -106,6 +113,7 @@ var DEFAULT_DATA_TABLE_LABELS = {
106
113
  expandRow: "Expand row",
107
114
  collapseRow: "Collapse row",
108
115
  resizeColumn: "Resize column",
116
+ reorderColumn: "Reorder column",
109
117
  searchPlaceholder: "Search\u2026",
110
118
  searchResultHint: "Type to search",
111
119
  searchPrevious: "Previous result",
@@ -145,6 +153,7 @@ var DATA_TABLE_VIRTUAL_OVERSCAN = 8;
145
153
  var DATA_TABLE_COLUMN_SIZE = 150;
146
154
  var DATA_TABLE_COLUMN_MIN_SIZE = 40;
147
155
  var DATA_TABLE_COLUMN_MAX_SIZE = 800;
156
+ var DATA_TABLE_COLUMN_REORDER_THRESHOLD = 4;
148
157
 
149
158
  // src/components/ui/table/features/cell-edit/useCellEdit.ts
150
159
  var import_react = require("react");
@@ -518,6 +527,16 @@ function formatDefaultCellValue(value) {
518
527
  return String(value);
519
528
  }
520
529
 
530
+ // src/components/ui/table/features/cell-render/withCellUpdate.ts
531
+ function withCellUpdate(context, commitValue) {
532
+ return {
533
+ ...context,
534
+ update: (next) => {
535
+ commitValue(context.row.id, context.column.id, next);
536
+ }
537
+ };
538
+ }
539
+
521
540
  // src/components/ui/table/features/cell-selection/useCellSelection.ts
522
541
  var import_react2 = require("react");
523
542
 
@@ -1400,6 +1419,135 @@ function useCellSelection({
1400
1419
  };
1401
1420
  }
1402
1421
 
1422
+ // src/components/ui/table/features/column-reorder/columnReorder.ts
1423
+ function getColumnDefId(column) {
1424
+ if (column.id != null && column.id !== "") return column.id;
1425
+ if ("accessorKey" in column && column.accessorKey != null) {
1426
+ return String(column.accessorKey);
1427
+ }
1428
+ return void 0;
1429
+ }
1430
+ function getColumnDefChildren(column) {
1431
+ if (!("columns" in column) || !Array.isArray(column.columns)) return void 0;
1432
+ if (column.columns.length === 0) return void 0;
1433
+ return column.columns;
1434
+ }
1435
+ function collectLeafColumnIds(columns) {
1436
+ const ids = [];
1437
+ for (const column of columns) {
1438
+ const children = getColumnDefChildren(column);
1439
+ if (children) {
1440
+ ids.push(...collectLeafColumnIds(children));
1441
+ continue;
1442
+ }
1443
+ const id = getColumnDefId(column);
1444
+ if (id) ids.push(id);
1445
+ }
1446
+ return ids;
1447
+ }
1448
+ function areColumnOrdersEqual(left, right) {
1449
+ if (left.length !== right.length) return false;
1450
+ return left.every((id, index) => id === right[index]);
1451
+ }
1452
+ function resolveLeafColumnOrder(columns, order) {
1453
+ const leafIds = collectLeafColumnIds(columns);
1454
+ if (!order?.length) return leafIds;
1455
+ const leafSet = new Set(leafIds);
1456
+ const seen = /* @__PURE__ */ new Set();
1457
+ const next = order.filter((id) => {
1458
+ if (!leafSet.has(id) || seen.has(id)) return false;
1459
+ seen.add(id);
1460
+ return true;
1461
+ });
1462
+ for (const id of leafIds) {
1463
+ if (!seen.has(id)) next.push(id);
1464
+ }
1465
+ return next;
1466
+ }
1467
+ function flattenColumnSlots(columns, group) {
1468
+ const slots = [];
1469
+ for (const column of columns) {
1470
+ const id = getColumnDefId(column);
1471
+ const children = getColumnDefChildren(column);
1472
+ if (children) {
1473
+ const nestedGroup = id ? { id, def: column } : group;
1474
+ slots.push(...flattenColumnSlots(children, nestedGroup));
1475
+ continue;
1476
+ }
1477
+ if (!id) continue;
1478
+ slots.push({ id, def: column, group });
1479
+ }
1480
+ return slots;
1481
+ }
1482
+ function rebuildColumnTree(slots) {
1483
+ const result = [];
1484
+ let index = 0;
1485
+ while (index < slots.length) {
1486
+ const slot = slots[index];
1487
+ if (!slot.group) {
1488
+ result.push(slot.def);
1489
+ index += 1;
1490
+ continue;
1491
+ }
1492
+ const groupId = slot.group.id;
1493
+ const children = [];
1494
+ while (index < slots.length && slots[index]?.group?.id === groupId) {
1495
+ children.push(slots[index].def);
1496
+ index += 1;
1497
+ }
1498
+ const firstChildId = children[0] ? getColumnDefId(children[0]) : groupId;
1499
+ result.push({
1500
+ ...slot.group.def,
1501
+ id: `${groupId}::${firstChildId}`,
1502
+ columns: children
1503
+ });
1504
+ }
1505
+ return result;
1506
+ }
1507
+ function applyLeafColumnOrder(columns, order) {
1508
+ const resolved = resolveLeafColumnOrder(columns, order);
1509
+ const defaultOrder = collectLeafColumnIds(columns);
1510
+ if (areColumnOrdersEqual(resolved, defaultOrder)) {
1511
+ return columns;
1512
+ }
1513
+ const byId = new Map(
1514
+ flattenColumnSlots(columns).map((slot) => [
1515
+ slot.id,
1516
+ slot
1517
+ ])
1518
+ );
1519
+ const ordered = [];
1520
+ for (const id of resolved) {
1521
+ const slot = byId.get(id);
1522
+ if (slot) ordered.push(slot);
1523
+ }
1524
+ return rebuildColumnTree(ordered);
1525
+ }
1526
+ function moveColumnIds(order, fromIds, targetIds, edge) {
1527
+ if (fromIds.length === 0 || targetIds.length === 0) return [...order];
1528
+ const fromSet = new Set(fromIds);
1529
+ if (targetIds.some((id) => fromSet.has(id))) return [...order];
1530
+ const rest = order.filter((id) => !fromSet.has(id));
1531
+ const anchorId = edge === "before" ? targetIds[0] : targetIds[targetIds.length - 1];
1532
+ const anchorIndex = rest.indexOf(anchorId);
1533
+ if (anchorIndex < 0) return [...order];
1534
+ const insertAt = edge === "before" ? anchorIndex : anchorIndex + 1;
1535
+ return [...rest.slice(0, insertAt), ...fromIds, ...rest.slice(insertAt)];
1536
+ }
1537
+ function resolveDropEdge(clientX, rect) {
1538
+ return clientX < rect.left + rect.width / 2 ? "before" : "after";
1539
+ }
1540
+ function parseReorderIds(value) {
1541
+ if (!value) return [];
1542
+ return value.split(",").filter(Boolean);
1543
+ }
1544
+ function serializeReorderIds(ids) {
1545
+ return ids.join(",");
1546
+ }
1547
+ function isColumnReorderable(meta) {
1548
+ return meta?.reorderable !== false;
1549
+ }
1550
+
1403
1551
  // src/components/ui/table/features/column-freeze/columnFreeze.ts
1404
1552
  var HEADER_Z_BASE = 30;
1405
1553
  var BODY_Z_BASE = 5;
@@ -2275,6 +2423,9 @@ function useGlideTable(options) {
2275
2423
  columnSizing: controlledColumnSizing,
2276
2424
  onColumnSizingChange,
2277
2425
  columnResizeMode = "onChange",
2426
+ enableColumnReorder = false,
2427
+ columnOrder: controlledColumnOrder,
2428
+ onColumnOrderChange,
2278
2429
  enableColumnFreeze = false,
2279
2430
  enableInlineSearch = false,
2280
2431
  showSearch,
@@ -2297,6 +2448,7 @@ function useGlideTable(options) {
2297
2448
  const resolvedEnableSubtreeCopy = enableSubtreeCopy ?? enableExpand;
2298
2449
  const [internalRowSelection, setInternalRowSelection] = (0, import_react5.useState)({});
2299
2450
  const [internalColumnSizing, setInternalColumnSizing] = (0, import_react5.useState)({});
2451
+ const [internalColumnOrder, setInternalColumnOrder] = (0, import_react5.useState)([]);
2300
2452
  const [internalExpandedRows, setInternalExpandedRows] = (0, import_react5.useState)(
2301
2453
  () => /* @__PURE__ */ new Set()
2302
2454
  );
@@ -2317,6 +2469,21 @@ function useGlideTable(options) {
2317
2469
  internalRowSelection
2318
2470
  );
2319
2471
  const columnSizing = controlledColumnSizing ?? internalColumnSizing;
2472
+ const columnOrder = controlledColumnOrder ?? internalColumnOrder;
2473
+ const tableColumns = (0, import_react5.useMemo)(() => {
2474
+ if (!enableColumnReorder) return columns;
2475
+ return applyLeafColumnOrder(columns, columnOrder);
2476
+ }, [columnOrder, columns, enableColumnReorder]);
2477
+ const setColumnOrder = (0, import_react5.useCallback)(
2478
+ (next) => {
2479
+ if (onColumnOrderChange) {
2480
+ onColumnOrderChange(next);
2481
+ return;
2482
+ }
2483
+ setInternalColumnOrder(next);
2484
+ },
2485
+ [onColumnOrderChange]
2486
+ );
2320
2487
  const expandedRows = controlledExpandedRows ?? internalExpandedRows;
2321
2488
  const handleExpandedRowsChange = (0, import_react5.useCallback)(
2322
2489
  (next) => {
@@ -2341,7 +2508,7 @@ function useGlideTable(options) {
2341
2508
  });
2342
2509
  const table = (0, import_react_table.useReactTable)({
2343
2510
  data: tableData,
2344
- columns,
2511
+ columns: tableColumns,
2345
2512
  ...enableColumnResize ? {
2346
2513
  defaultColumn: {
2347
2514
  minSize: DATA_TABLE_COLUMN_MIN_SIZE,
@@ -2497,6 +2664,10 @@ function useGlideTable(options) {
2497
2664
  }),
2498
2665
  [onCellChange, onDataChange, rows, tableData]
2499
2666
  );
2667
+ const getCellContext = (0, import_react5.useCallback)(
2668
+ (cell) => withCellUpdate(cell.getContext(), commitRenderedCellValue),
2669
+ [commitRenderedCellValue]
2670
+ );
2500
2671
  const handleCellMouseDownWithCommit = (0, import_react5.useCallback)(
2501
2672
  (rowIndex, colIndex, options2) => {
2502
2673
  const isSameEditingCell = editingCell?.rowIndex === rowIndex && editingCell?.colIndex === colIndex;
@@ -2819,6 +2990,7 @@ function useGlideTable(options) {
2819
2990
  selectionLabel: labels.selection,
2820
2991
  enableCellSelection,
2821
2992
  enableColumnResize,
2993
+ enableColumnReorder,
2822
2994
  enableColumnFreeze,
2823
2995
  enableInlineSearch,
2824
2996
  shouldVirtualize,
@@ -2829,8 +3001,10 @@ function useGlideTable(options) {
2829
3001
  paddingTop,
2830
3002
  paddingBottom,
2831
3003
  rowContextValue,
3004
+ getCellContext,
2832
3005
  handleToggleSelect,
2833
3006
  clearHover,
3007
+ setColumnOrder,
2834
3008
  copySelection: stableCopySelection,
2835
3009
  inlineSearch: {
2836
3010
  showSearch: inlineSearch.showSearch,
@@ -2916,13 +3090,221 @@ function getColumnSizeStyle(size, options) {
2916
3090
  };
2917
3091
  }
2918
3092
 
3093
+ // src/components/ui/table/features/column-reorder/useColumnReorder.ts
3094
+ var import_react8 = require("react");
3095
+ function hitTestReorderHeader(table, clientX, clientY) {
3096
+ const headers = Array.from(
3097
+ table.querySelectorAll(
3098
+ "thead th[data-column-id][data-reorder-ids]"
3099
+ )
3100
+ );
3101
+ const containing = headers.find((element) => {
3102
+ const rect = element.getBoundingClientRect();
3103
+ return clientX >= rect.left && clientX <= rect.right && clientY >= rect.top && clientY <= rect.bottom;
3104
+ });
3105
+ if (containing) {
3106
+ return {
3107
+ columnId: containing.dataset.columnId ?? "",
3108
+ edge: resolveDropEdge(clientX, containing.getBoundingClientRect())
3109
+ };
3110
+ }
3111
+ const leaves = headers.filter(
3112
+ (element) => element.hasAttribute("data-reorder-leaf")
3113
+ );
3114
+ let match;
3115
+ for (const element of leaves) {
3116
+ const rect = element.getBoundingClientRect();
3117
+ if (clientX >= rect.left && clientX <= rect.right) {
3118
+ match = element;
3119
+ break;
3120
+ }
3121
+ }
3122
+ if (!match && leaves.length > 0) {
3123
+ const first = leaves[0].getBoundingClientRect();
3124
+ const last = leaves[leaves.length - 1].getBoundingClientRect();
3125
+ if (clientX < first.left) match = leaves[0];
3126
+ else if (clientX > last.right) match = leaves[leaves.length - 1];
3127
+ }
3128
+ if (!match) return null;
3129
+ return {
3130
+ columnId: match.dataset.columnId ?? "",
3131
+ edge: resolveDropEdge(clientX, match.getBoundingClientRect())
3132
+ };
3133
+ }
3134
+ function readTargetIds(table, columnId) {
3135
+ const element = table.querySelector(
3136
+ `thead th[data-column-id="${CSS.escape(columnId)}"]`
3137
+ );
3138
+ return parseReorderIds(element?.getAttribute("data-reorder-ids"));
3139
+ }
3140
+ function useColumnReorder(options) {
3141
+ const { enabled, columnOrder, onColumnOrderChange } = options;
3142
+ const sessionRef = (0, import_react8.useRef)(null);
3143
+ const columnOrderRef = (0, import_react8.useRef)(columnOrder);
3144
+ const onColumnOrderChangeRef = (0, import_react8.useRef)(onColumnOrderChange);
3145
+ const [draggingColumnId, setDraggingColumnId] = (0, import_react8.useState)(null);
3146
+ const [dropTarget, setDropTarget] = (0, import_react8.useState)(
3147
+ null
3148
+ );
3149
+ const dropTargetRef = (0, import_react8.useRef)(dropTarget);
3150
+ const previousUserSelectRef = (0, import_react8.useRef)(null);
3151
+ columnOrderRef.current = columnOrder;
3152
+ onColumnOrderChangeRef.current = onColumnOrderChange;
3153
+ dropTargetRef.current = dropTarget;
3154
+ const resetDrag = (0, import_react8.useCallback)(() => {
3155
+ sessionRef.current = null;
3156
+ setDraggingColumnId(null);
3157
+ setDropTarget(null);
3158
+ const backup = previousUserSelectRef.current;
3159
+ previousUserSelectRef.current = null;
3160
+ if (backup) {
3161
+ if (backup.value) {
3162
+ document.body.style.setProperty("user-select", backup.value, backup.priority);
3163
+ } else {
3164
+ document.body.style.removeProperty("user-select");
3165
+ }
3166
+ return;
3167
+ }
3168
+ document.body.style.removeProperty("user-select");
3169
+ }, []);
3170
+ (0, import_react8.useEffect)(() => {
3171
+ if (!enabled) resetDrag();
3172
+ }, [enabled, resetDrag]);
3173
+ (0, import_react8.useEffect)(() => {
3174
+ return () => {
3175
+ resetDrag();
3176
+ };
3177
+ }, [resetDrag]);
3178
+ const onHeaderPointerDown = (0, import_react8.useCallback)(
3179
+ (event, meta) => {
3180
+ if (!enabled || !meta.canDrag) return;
3181
+ if (event.button !== 0) return;
3182
+ if (event.pointerType === "mouse" && event.ctrlKey) return;
3183
+ const target = event.target;
3184
+ if (target instanceof Element && target.closest("[data-table-disable-cell-selection]")) {
3185
+ return;
3186
+ }
3187
+ const table = event.currentTarget.closest("table");
3188
+ if (!(table instanceof HTMLTableElement)) return;
3189
+ sessionRef.current = {
3190
+ pointerId: event.pointerId,
3191
+ startX: event.clientX,
3192
+ startY: event.clientY,
3193
+ columnId: meta.columnId,
3194
+ fromIds: meta.leafIds,
3195
+ table,
3196
+ active: false
3197
+ };
3198
+ },
3199
+ [enabled]
3200
+ );
3201
+ (0, import_react8.useEffect)(() => {
3202
+ if (!enabled) return;
3203
+ const onPointerMove = (event) => {
3204
+ const session = sessionRef.current;
3205
+ if (!session || event.pointerId !== session.pointerId) return;
3206
+ const deltaX = event.clientX - session.startX;
3207
+ const deltaY = event.clientY - session.startY;
3208
+ const distance = Math.hypot(deltaX, deltaY);
3209
+ if (!session.active) {
3210
+ if (distance < DATA_TABLE_COLUMN_REORDER_THRESHOLD) return;
3211
+ session.active = true;
3212
+ if (!previousUserSelectRef.current) {
3213
+ previousUserSelectRef.current = {
3214
+ value: document.body.style.getPropertyValue("user-select"),
3215
+ priority: document.body.style.getPropertyPriority("user-select")
3216
+ };
3217
+ }
3218
+ document.body.style.setProperty("user-select", "none");
3219
+ setDraggingColumnId(session.columnId);
3220
+ }
3221
+ event.preventDefault();
3222
+ const nextTarget = hitTestReorderHeader(
3223
+ session.table,
3224
+ event.clientX,
3225
+ event.clientY
3226
+ );
3227
+ if (!nextTarget || !nextTarget.columnId) {
3228
+ setDropTarget(null);
3229
+ return;
3230
+ }
3231
+ const targetIds = readTargetIds(session.table, nextTarget.columnId);
3232
+ const fromSet = new Set(session.fromIds);
3233
+ if (targetIds.some((id) => fromSet.has(id))) {
3234
+ setDropTarget(null);
3235
+ return;
3236
+ }
3237
+ setDropTarget((previous) => {
3238
+ if (previous?.columnId === nextTarget.columnId && previous.edge === nextTarget.edge) {
3239
+ return previous;
3240
+ }
3241
+ return nextTarget;
3242
+ });
3243
+ };
3244
+ const onPointerUp = (event) => {
3245
+ const session = sessionRef.current;
3246
+ if (!session || event.pointerId !== session.pointerId) {
3247
+ return;
3248
+ }
3249
+ if (session.active) {
3250
+ event.preventDefault();
3251
+ const target = dropTargetRef.current;
3252
+ if (target) {
3253
+ const targetIds = readTargetIds(session.table, target.columnId);
3254
+ const next = moveColumnIds(
3255
+ columnOrderRef.current,
3256
+ session.fromIds,
3257
+ targetIds,
3258
+ target.edge
3259
+ );
3260
+ onColumnOrderChangeRef.current(next);
3261
+ }
3262
+ const suppressClick = (clickEvent) => {
3263
+ clickEvent.preventDefault();
3264
+ clickEvent.stopPropagation();
3265
+ document.removeEventListener("click", suppressClick, true);
3266
+ };
3267
+ document.addEventListener("click", suppressClick, true);
3268
+ window.setTimeout(() => {
3269
+ document.removeEventListener("click", suppressClick, true);
3270
+ }, 0);
3271
+ }
3272
+ resetDrag();
3273
+ };
3274
+ const onPointerCancel = (event) => {
3275
+ const session = sessionRef.current;
3276
+ if (!session || event.pointerId !== session.pointerId) {
3277
+ return;
3278
+ }
3279
+ if (session.active) {
3280
+ event.preventDefault();
3281
+ }
3282
+ resetDrag();
3283
+ };
3284
+ document.addEventListener("pointermove", onPointerMove);
3285
+ document.addEventListener("pointerup", onPointerUp);
3286
+ document.addEventListener("pointercancel", onPointerCancel);
3287
+ return () => {
3288
+ document.removeEventListener("pointermove", onPointerMove);
3289
+ document.removeEventListener("pointerup", onPointerUp);
3290
+ document.removeEventListener("pointercancel", onPointerCancel);
3291
+ };
3292
+ }, [enabled, resetDrag]);
3293
+ return {
3294
+ isReordering: draggingColumnId != null,
3295
+ draggingColumnId,
3296
+ dropTarget,
3297
+ onHeaderPointerDown
3298
+ };
3299
+ }
3300
+
2919
3301
  // src/components/ui/table/components/DataTable/DataTable.tsx
2920
3302
  var import_react_table3 = require("@tanstack/react-table");
2921
- var import_react9 = require("react");
3303
+ var import_react10 = require("react");
2922
3304
 
2923
3305
  // src/components/ui/table/components/DataTable/DataTableRow.tsx
2924
3306
  var import_react_table2 = require("@tanstack/react-table");
2925
- var import_react8 = require("react");
3307
+ var import_react9 = require("react");
2926
3308
 
2927
3309
  // src/components/ui/table/components/icons.tsx
2928
3310
  var import_jsx_runtime3 = require("react/jsx-runtime");
@@ -3110,6 +3492,7 @@ function DataTableRow({
3110
3492
  selection,
3111
3493
  cellSelection,
3112
3494
  cellEdit,
3495
+ cellRender,
3113
3496
  expand,
3114
3497
  columnResize,
3115
3498
  columnFreeze,
@@ -3147,6 +3530,10 @@ function DataTableRow({
3147
3530
  onCommitEdit,
3148
3531
  onCancelEdit
3149
3532
  } = cellEdit;
3533
+ const renderCell = (tableCell) => (0, import_react_table2.flexRender)(
3534
+ tableCell.column.columnDef.cell,
3535
+ withCellUpdate(tableCell.getContext(), cellRender.commitValue)
3536
+ );
3150
3537
  const {
3151
3538
  enableExpand,
3152
3539
  toggleField,
@@ -3215,9 +3602,9 @@ function DataTableRow({
3215
3602
  const expandKey = toggleField && rowData[toggleField] !== null && rowData[toggleField] !== void 0 ? String(rowData[toggleField]) : null;
3216
3603
  const isExpanded = expandKey !== null && Boolean(expandedRows?.has(expandKey));
3217
3604
  const rowLevel = typeof rowData.level === "number" ? rowData.level : 0;
3218
- const editInputRef = (0, import_react8.useRef)(null);
3605
+ const editInputRef = (0, import_react9.useRef)(null);
3219
3606
  const isRowEditing = editingCell?.rowIndex === rowIndex;
3220
- (0, import_react8.useEffect)(() => {
3607
+ (0, import_react9.useEffect)(() => {
3221
3608
  if (!isRowEditing) return;
3222
3609
  editInputRef.current?.focus();
3223
3610
  editInputRef.current?.select();
@@ -3459,7 +3846,7 @@ function DataTableRow({
3459
3846
  "expand-cell-value",
3460
3847
  classNames?.expandCellValue
3461
3848
  ),
3462
- children: (0, import_react_table2.flexRender)(cell.column.columnDef.cell, cell.getContext())
3849
+ children: renderCell(cell)
3463
3850
  }
3464
3851
  )
3465
3852
  ]
@@ -3498,7 +3885,7 @@ function DataTableRow({
3498
3885
  )
3499
3886
  }
3500
3887
  )
3501
- ] }) : (0, import_react_table2.flexRender)(cell.column.columnDef.cell, cell.getContext()),
3888
+ ] }) : renderCell(cell),
3502
3889
  isBottomRightCell && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
3503
3890
  "div",
3504
3891
  {
@@ -3815,6 +4202,7 @@ function DataTable({
3815
4202
  selectionLabel,
3816
4203
  enableCellSelection,
3817
4204
  enableColumnResize,
4205
+ enableColumnReorder,
3818
4206
  enableColumnFreeze,
3819
4207
  enableInlineSearch,
3820
4208
  shouldVirtualize,
@@ -3827,6 +4215,7 @@ function DataTable({
3827
4215
  rowContextValue,
3828
4216
  handleToggleSelect,
3829
4217
  clearHover,
4218
+ setColumnOrder,
3830
4219
  inlineSearch
3831
4220
  } = useGlideTable(glideOptions);
3832
4221
  const ToolbarSlot = slots?.Toolbar ?? DataTableToolbar;
@@ -3836,7 +4225,13 @@ function DataTable({
3836
4225
  const EmptySlot = slots?.Empty ?? DefaultEmpty;
3837
4226
  const freezeOffsets = rowContextValue.columnFreeze.offsets;
3838
4227
  const headerGroups = getMergedHeaderGroups(table.getHeaderGroups());
3839
- const contextValue = (0, import_react9.useMemo)(
4228
+ const leafColumnIds = table.getVisibleLeafColumns().map((column) => column.id);
4229
+ const { isReordering, draggingColumnId, dropTarget, onHeaderPointerDown } = useColumnReorder({
4230
+ enabled: enableColumnReorder,
4231
+ columnOrder: leafColumnIds,
4232
+ onColumnOrderChange: setColumnOrder
4233
+ });
4234
+ const contextValue = (0, import_react10.useMemo)(
3840
4235
  () => ({ ...rowContextValue, classNames }),
3841
4236
  [rowContextValue, classNames]
3842
4237
  );
@@ -3858,6 +4253,8 @@ function DataTable({
3858
4253
  "DataTableJSX",
3859
4254
  !enableCellSelection && "DataTableJSX--no-cell-selection",
3860
4255
  enableColumnResize && "DataTableJSX--column-resize",
4256
+ enableColumnReorder && "DataTableJSX--column-reorder",
4257
+ isReordering && "DataTableJSX--column-reordering",
3861
4258
  enableColumnFreeze && "DataTableJSX--column-freeze",
3862
4259
  enableInlineSearch && "DataTableJSX--inline-search",
3863
4260
  classNames?.root,
@@ -3926,20 +4323,43 @@ function DataTable({
3926
4323
  ...sizeStyle,
3927
4324
  ...freezeStyle
3928
4325
  };
4326
+ const isPlaceholder = header.isPlaceholder;
4327
+ const leafColumns = header.column.getLeafColumns();
4328
+ const leafIds = leafColumns.map((leafColumn) => leafColumn.id);
4329
+ const isLeafHeader = !isPlaceholder && header.subHeaders.length === 0;
4330
+ const canDrag = enableColumnReorder && !isPlaceholder && leafIds.length > 0 && leafColumns.every(
4331
+ (leafColumn) => isColumnReorderable(leafColumn.columnDef.meta)
4332
+ );
4333
+ const isDragging = draggingColumnId === header.column.id;
4334
+ const dropEdge = !isPlaceholder && dropTarget?.columnId === header.column.id ? dropTarget.edge : void 0;
3929
4335
  return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
3930
4336
  "th",
3931
4337
  {
3932
4338
  colSpan: header.colSpan,
3933
4339
  rowSpan: header.mergedRowSpan,
4340
+ "data-column-id": enableColumnReorder && !isPlaceholder ? header.column.id : void 0,
4341
+ "data-reorder-ids": enableColumnReorder && !isPlaceholder ? serializeReorderIds(leafIds) : void 0,
4342
+ "data-reorder-leaf": enableColumnReorder && isLeafHeader ? "" : void 0,
4343
+ "data-reorderable": canDrag ? "" : void 0,
4344
+ "data-reordering": isDragging ? "" : void 0,
4345
+ "data-drop-edge": dropEdge,
3934
4346
  "data-resizing": header.column.getIsResizing() ? "" : void 0,
3935
4347
  "data-frozen": freezeOffset?.side,
3936
4348
  "data-freeze-edge": getColumnFreezeEdgeAttr(freezeOffset),
4349
+ "aria-grabbed": isDragging ? true : void 0,
4350
+ title: canDrag ? labels.reorderColumn : void 0,
4351
+ onPointerDown: enableColumnReorder ? (event) => onHeaderPointerDown(event, {
4352
+ columnId: header.column.id,
4353
+ leafIds,
4354
+ canDrag
4355
+ }) : void 0,
3937
4356
  style: Object.keys(headerStyle).length > 0 ? headerStyle : void 0,
3938
4357
  className: cn(
3939
4358
  "data-table-head-cell",
3940
4359
  freezeOffset && `data-table-head-cell--frozen-${freezeOffset.side}`,
3941
4360
  CELL_ALIGN_CLASS[align],
3942
4361
  classNames?.headCell,
4362
+ dropEdge && classNames?.dropEdge,
3943
4363
  headerClassName
3944
4364
  ),
3945
4365
  children: [
@@ -4061,7 +4481,7 @@ function DataTable({
4061
4481
  }
4062
4482
 
4063
4483
  // src/components/ui/table/components/Table/Table.tsx
4064
- var import_react12 = require("react");
4484
+ var import_react13 = require("react");
4065
4485
 
4066
4486
  // src/components/ui/table/components/Table/buildColumnDef.tsx
4067
4487
  var import_jsx_runtime8 = require("react/jsx-runtime");
@@ -4099,6 +4519,7 @@ function buildColumnDef(props, sort, onSort) {
4099
4519
  minWidth,
4100
4520
  maxWidth,
4101
4521
  resizable,
4522
+ reorderable,
4102
4523
  frozen,
4103
4524
  align,
4104
4525
  rowSpan,
@@ -4144,6 +4565,7 @@ function buildColumnDef(props, sort, onSort) {
4144
4565
  cellProps,
4145
4566
  cellRender: render,
4146
4567
  frozen,
4568
+ reorderable,
4147
4569
  className,
4148
4570
  headerClassName
4149
4571
  }
@@ -4189,10 +4611,10 @@ function countLeafColumns(nodes) {
4189
4611
  }
4190
4612
 
4191
4613
  // src/components/ui/table/components/Table/parseTableChildren.ts
4192
- var import_react11 = require("react");
4614
+ var import_react12 = require("react");
4193
4615
 
4194
4616
  // src/components/ui/table/components/Table/tableChildTypes.ts
4195
- var import_react10 = require("react");
4617
+ var import_react11 = require("react");
4196
4618
  var TABLE_HEADER_DISPLAY_NAME = "Table.Header";
4197
4619
  var TABLE_BODY_DISPLAY_NAME = "Table.Body";
4198
4620
  var TABLE_COLUMN_DISPLAY_NAME = "Table.Column";
@@ -4205,19 +4627,19 @@ function getComponentDisplayName(type) {
4205
4627
  return void 0;
4206
4628
  }
4207
4629
  function isTableHeaderElement(child) {
4208
- return (0, import_react10.isValidElement)(child) && getComponentDisplayName(child.type) === TABLE_HEADER_DISPLAY_NAME;
4630
+ return (0, import_react11.isValidElement)(child) && getComponentDisplayName(child.type) === TABLE_HEADER_DISPLAY_NAME;
4209
4631
  }
4210
4632
  function isTableBodyElement(child) {
4211
- return (0, import_react10.isValidElement)(child) && getComponentDisplayName(child.type) === TABLE_BODY_DISPLAY_NAME;
4633
+ return (0, import_react11.isValidElement)(child) && getComponentDisplayName(child.type) === TABLE_BODY_DISPLAY_NAME;
4212
4634
  }
4213
4635
  function isTableColumnElement(child) {
4214
- return (0, import_react10.isValidElement)(child) && getComponentDisplayName(child.type) === TABLE_COLUMN_DISPLAY_NAME;
4636
+ return (0, import_react11.isValidElement)(child) && getComponentDisplayName(child.type) === TABLE_COLUMN_DISPLAY_NAME;
4215
4637
  }
4216
4638
  function isTableColumnGroupElement(child) {
4217
- return (0, import_react10.isValidElement)(child) && getComponentDisplayName(child.type) === TABLE_COLUMN_GROUP_DISPLAY_NAME;
4639
+ return (0, import_react11.isValidElement)(child) && getComponentDisplayName(child.type) === TABLE_COLUMN_GROUP_DISPLAY_NAME;
4218
4640
  }
4219
4641
  function isTablePaginationElement(child) {
4220
- return (0, import_react10.isValidElement)(child) && getComponentDisplayName(child.type) === TABLE_PAGINATION_DISPLAY_NAME;
4642
+ return (0, import_react11.isValidElement)(child) && getComponentDisplayName(child.type) === TABLE_PAGINATION_DISPLAY_NAME;
4221
4643
  }
4222
4644
 
4223
4645
  // src/components/ui/table/components/Table/parseTableChildren.ts
@@ -4227,7 +4649,7 @@ function parseTableChildren(children) {
4227
4649
  body: null,
4228
4650
  pagination: null
4229
4651
  };
4230
- for (const child of import_react11.Children.toArray(children)) {
4652
+ for (const child of import_react12.Children.toArray(children)) {
4231
4653
  if (isTableHeaderElement(child)) {
4232
4654
  slots.header = child;
4233
4655
  continue;
@@ -4244,7 +4666,7 @@ function parseTableChildren(children) {
4244
4666
  }
4245
4667
  function walkColumnTreeNodes(children) {
4246
4668
  const result = [];
4247
- for (const child of import_react11.Children.toArray(children)) {
4669
+ for (const child of import_react12.Children.toArray(children)) {
4248
4670
  if (isTableColumnElement(child)) {
4249
4671
  result.push({
4250
4672
  type: "leaf",
@@ -4261,7 +4683,7 @@ function walkColumnTreeNodes(children) {
4261
4683
  });
4262
4684
  continue;
4263
4685
  }
4264
- if ((0, import_react11.isValidElement)(child)) {
4686
+ if ((0, import_react12.isValidElement)(child)) {
4265
4687
  const nested = child.props.children;
4266
4688
  if (nested != null) {
4267
4689
  result.push(...walkColumnTreeNodes(nested));
@@ -4387,12 +4809,12 @@ function TableRoot({
4387
4809
  filteredCount,
4388
4810
  ...dataTableProps
4389
4811
  }) {
4390
- const { header, pagination: paginationElement } = (0, import_react12.useMemo)(
4812
+ const { header, pagination: paginationElement } = (0, import_react13.useMemo)(
4391
4813
  () => parseTableChildren(children),
4392
4814
  [children]
4393
4815
  );
4394
- const [sort, setSort] = (0, import_react12.useState)(null);
4395
- const handleSort = (0, import_react12.useCallback)((field) => {
4816
+ const [sort, setSort] = (0, import_react13.useState)(null);
4817
+ const handleSort = (0, import_react13.useCallback)((field) => {
4396
4818
  setSort((previous) => {
4397
4819
  if (previous?.field !== field) {
4398
4820
  return { field, direction: "asc" };
@@ -4403,8 +4825,8 @@ function TableRoot({
4403
4825
  return null;
4404
4826
  });
4405
4827
  }, []);
4406
- const columnTree = (0, import_react12.useMemo)(() => extractColumnTree(header), [header]);
4407
- const columns = (0, import_react12.useMemo)(
4828
+ const columnTree = (0, import_react13.useMemo)(() => extractColumnTree(header), [header]);
4829
+ const columns = (0, import_react13.useMemo)(
4408
4830
  () => buildColumnDefsFromTree(columnTree, sort, handleSort),
4409
4831
  [columnTree, sort, handleSort]
4410
4832
  );
@@ -4412,7 +4834,7 @@ function TableRoot({
4412
4834
  const pageSize = paginationProps?.pageSize ?? 10;
4413
4835
  const page = paginationProps?.page ?? 1;
4414
4836
  const resolvedTotalCount = paginationProps?.totalCount ?? totalCount ?? data.length;
4415
- const tableData = (0, import_react12.useMemo)(() => {
4837
+ const tableData = (0, import_react13.useMemo)(() => {
4416
4838
  const sortedData = sortTableData(data, sort);
4417
4839
  if (!paginationProps) return sortedData;
4418
4840
  return paginateTableData(sortedData, page, pageSize);
@@ -4490,6 +4912,7 @@ var Table = Object.assign(TableRoot, {
4490
4912
  Table,
4491
4913
  applyCellEdit,
4492
4914
  applyFillData,
4915
+ applyLeafColumnOrder,
4493
4916
  applySelectionUpdater,
4494
4917
  buildColumnFreezeOffsets,
4495
4918
  buildColumnRowSpanMap,
@@ -4504,6 +4927,7 @@ var Table = Object.assign(TableRoot, {
4504
4927
  collectCopyRowEntries,
4505
4928
  collectCopyRows,
4506
4929
  collectFillChanges,
4930
+ collectLeafColumnIds,
4507
4931
  collectRowSpanColumns,
4508
4932
  collectSearchMatchesInRange,
4509
4933
  commitCellValue,
@@ -4529,6 +4953,7 @@ var Table = Object.assign(TableRoot, {
4529
4953
  mapSearchResultToVisibleItem,
4530
4954
  mapSearchResultsToVisibleKeys,
4531
4955
  measureMergedSpanRowHeights,
4956
+ moveColumnIds,
4532
4957
  nextSearchIndex,
4533
4958
  nextSearchStride,
4534
4959
  parseCellEditValue,
@@ -4538,7 +4963,9 @@ var Table = Object.assign(TableRoot, {
4538
4963
  resolveCellRenderer,
4539
4964
  resolveColumnFreezeSide,
4540
4965
  resolveDataTableLabels,
4966
+ resolveDropEdge,
4541
4967
  resolveHeaderFreezeOffset,
4968
+ resolveLeafColumnOrder,
4542
4969
  resolvePasteColumnIds,
4543
4970
  resolveRowSelection,
4544
4971
  resolveRowSpanAt,
@@ -4548,8 +4975,10 @@ var Table = Object.assign(TableRoot, {
4548
4975
  toggleExpandedRowId,
4549
4976
  useCellEdit,
4550
4977
  useCellSelection,
4978
+ useColumnReorder,
4551
4979
  useConvertTreeData,
4552
4980
  useGlideTable,
4553
4981
  useInlineSearch,
4982
+ withCellUpdate,
4554
4983
  writeSelectionToClipboard
4555
4984
  });