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/README.md +70 -6
- package/dist/compound.cjs +532 -117
- package/dist/compound.d.cts +3 -3
- package/dist/compound.d.ts +3 -3
- package/dist/compound.js +513 -93
- package/dist/core.cjs +384 -1
- package/dist/core.d.cts +58 -6
- package/dist/core.d.ts +58 -6
- package/dist/core.js +382 -1
- package/dist/index.cjs +454 -25
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +436 -9
- package/dist/{types-DJOlsDL8.d.cts → types-CMUGtH-c.d.cts} +33 -1
- package/dist/{types-DJOlsDL8.d.ts → types-CMUGtH-c.d.ts} +33 -1
- package/package.json +1 -1
package/dist/core.cjs
CHANGED
|
@@ -31,6 +31,7 @@ __export(core_exports, {
|
|
|
31
31
|
ResolvedTableCell: () => ResolvedTableCell,
|
|
32
32
|
applyCellEdit: () => applyCellEdit,
|
|
33
33
|
applyFillData: () => applyFillData,
|
|
34
|
+
applyLeafColumnOrder: () => applyLeafColumnOrder,
|
|
34
35
|
applySelectionUpdater: () => applySelectionUpdater,
|
|
35
36
|
buildColumnFreezeOffsets: () => buildColumnFreezeOffsets,
|
|
36
37
|
buildColumnRowSpanMap: () => buildColumnRowSpanMap,
|
|
@@ -45,6 +46,7 @@ __export(core_exports, {
|
|
|
45
46
|
collectCopyRowEntries: () => collectCopyRowEntries,
|
|
46
47
|
collectCopyRows: () => collectCopyRows,
|
|
47
48
|
collectFillChanges: () => collectFillChanges,
|
|
49
|
+
collectLeafColumnIds: () => collectLeafColumnIds,
|
|
48
50
|
collectRowSpanColumns: () => collectRowSpanColumns,
|
|
49
51
|
collectSearchMatchesInRange: () => collectSearchMatchesInRange,
|
|
50
52
|
commitCellValue: () => commitCellValue,
|
|
@@ -69,6 +71,7 @@ __export(core_exports, {
|
|
|
69
71
|
mapSearchResultToVisibleItem: () => mapSearchResultToVisibleItem,
|
|
70
72
|
mapSearchResultsToVisibleKeys: () => mapSearchResultsToVisibleKeys,
|
|
71
73
|
measureMergedSpanRowHeights: () => measureMergedSpanRowHeights,
|
|
74
|
+
moveColumnIds: () => moveColumnIds,
|
|
72
75
|
nextSearchIndex: () => nextSearchIndex,
|
|
73
76
|
nextSearchStride: () => nextSearchStride,
|
|
74
77
|
parseCellEditValue: () => parseCellEditValue,
|
|
@@ -78,7 +81,9 @@ __export(core_exports, {
|
|
|
78
81
|
resolveCellRenderer: () => resolveCellRenderer,
|
|
79
82
|
resolveColumnFreezeSide: () => resolveColumnFreezeSide,
|
|
80
83
|
resolveDataTableLabels: () => resolveDataTableLabels,
|
|
84
|
+
resolveDropEdge: () => resolveDropEdge,
|
|
81
85
|
resolveHeaderFreezeOffset: () => resolveHeaderFreezeOffset,
|
|
86
|
+
resolveLeafColumnOrder: () => resolveLeafColumnOrder,
|
|
82
87
|
resolvePasteColumnIds: () => resolvePasteColumnIds,
|
|
83
88
|
resolveRowSelection: () => resolveRowSelection,
|
|
84
89
|
resolveRowSpanAt: () => resolveRowSpanAt,
|
|
@@ -88,9 +93,11 @@ __export(core_exports, {
|
|
|
88
93
|
toggleExpandedRowId: () => toggleExpandedRowId,
|
|
89
94
|
useCellEdit: () => useCellEdit,
|
|
90
95
|
useCellSelection: () => useCellSelection,
|
|
96
|
+
useColumnReorder: () => useColumnReorder,
|
|
91
97
|
useConvertTreeData: () => useConvertTreeData,
|
|
92
98
|
useGlideTable: () => useGlideTable,
|
|
93
99
|
useInlineSearch: () => useInlineSearch,
|
|
100
|
+
withCellUpdate: () => withCellUpdate,
|
|
94
101
|
writeSelectionToClipboard: () => writeSelectionToClipboard
|
|
95
102
|
});
|
|
96
103
|
module.exports = __toCommonJS(core_exports);
|
|
@@ -103,6 +110,7 @@ var DEFAULT_DATA_TABLE_LABELS = {
|
|
|
103
110
|
expandRow: "Expand row",
|
|
104
111
|
collapseRow: "Collapse row",
|
|
105
112
|
resizeColumn: "Resize column",
|
|
113
|
+
reorderColumn: "Reorder column",
|
|
106
114
|
searchPlaceholder: "Search\u2026",
|
|
107
115
|
searchResultHint: "Type to search",
|
|
108
116
|
searchPrevious: "Previous result",
|
|
@@ -133,6 +141,7 @@ var DATA_TABLE_VIRTUAL_OVERSCAN = 8;
|
|
|
133
141
|
var DATA_TABLE_COLUMN_SIZE = 150;
|
|
134
142
|
var DATA_TABLE_COLUMN_MIN_SIZE = 40;
|
|
135
143
|
var DATA_TABLE_COLUMN_MAX_SIZE = 800;
|
|
144
|
+
var DATA_TABLE_COLUMN_REORDER_THRESHOLD = 4;
|
|
136
145
|
|
|
137
146
|
// src/components/ui/table/features/cell-edit/useCellEdit.ts
|
|
138
147
|
var import_react = require("react");
|
|
@@ -506,6 +515,16 @@ function formatDefaultCellValue(value) {
|
|
|
506
515
|
return String(value);
|
|
507
516
|
}
|
|
508
517
|
|
|
518
|
+
// src/components/ui/table/features/cell-render/withCellUpdate.ts
|
|
519
|
+
function withCellUpdate(context, commitValue) {
|
|
520
|
+
return {
|
|
521
|
+
...context,
|
|
522
|
+
update: (next) => {
|
|
523
|
+
commitValue(context.row.id, context.column.id, next);
|
|
524
|
+
}
|
|
525
|
+
};
|
|
526
|
+
}
|
|
527
|
+
|
|
509
528
|
// src/components/ui/table/features/cell-selection/useCellSelection.ts
|
|
510
529
|
var import_react2 = require("react");
|
|
511
530
|
|
|
@@ -1388,6 +1407,129 @@ function useCellSelection({
|
|
|
1388
1407
|
};
|
|
1389
1408
|
}
|
|
1390
1409
|
|
|
1410
|
+
// src/components/ui/table/features/column-reorder/columnReorder.ts
|
|
1411
|
+
function getColumnDefId(column) {
|
|
1412
|
+
if (column.id != null && column.id !== "") return column.id;
|
|
1413
|
+
if ("accessorKey" in column && column.accessorKey != null) {
|
|
1414
|
+
return String(column.accessorKey);
|
|
1415
|
+
}
|
|
1416
|
+
return void 0;
|
|
1417
|
+
}
|
|
1418
|
+
function getColumnDefChildren(column) {
|
|
1419
|
+
if (!("columns" in column) || !Array.isArray(column.columns)) return void 0;
|
|
1420
|
+
if (column.columns.length === 0) return void 0;
|
|
1421
|
+
return column.columns;
|
|
1422
|
+
}
|
|
1423
|
+
function collectLeafColumnIds(columns) {
|
|
1424
|
+
const ids = [];
|
|
1425
|
+
for (const column of columns) {
|
|
1426
|
+
const children = getColumnDefChildren(column);
|
|
1427
|
+
if (children) {
|
|
1428
|
+
ids.push(...collectLeafColumnIds(children));
|
|
1429
|
+
continue;
|
|
1430
|
+
}
|
|
1431
|
+
const id = getColumnDefId(column);
|
|
1432
|
+
if (id) ids.push(id);
|
|
1433
|
+
}
|
|
1434
|
+
return ids;
|
|
1435
|
+
}
|
|
1436
|
+
function areColumnOrdersEqual(left, right) {
|
|
1437
|
+
if (left.length !== right.length) return false;
|
|
1438
|
+
return left.every((id, index) => id === right[index]);
|
|
1439
|
+
}
|
|
1440
|
+
function resolveLeafColumnOrder(columns, order) {
|
|
1441
|
+
const leafIds = collectLeafColumnIds(columns);
|
|
1442
|
+
if (!order?.length) return leafIds;
|
|
1443
|
+
const leafSet = new Set(leafIds);
|
|
1444
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1445
|
+
const next = order.filter((id) => {
|
|
1446
|
+
if (!leafSet.has(id) || seen.has(id)) return false;
|
|
1447
|
+
seen.add(id);
|
|
1448
|
+
return true;
|
|
1449
|
+
});
|
|
1450
|
+
for (const id of leafIds) {
|
|
1451
|
+
if (!seen.has(id)) next.push(id);
|
|
1452
|
+
}
|
|
1453
|
+
return next;
|
|
1454
|
+
}
|
|
1455
|
+
function flattenColumnSlots(columns, group) {
|
|
1456
|
+
const slots = [];
|
|
1457
|
+
for (const column of columns) {
|
|
1458
|
+
const id = getColumnDefId(column);
|
|
1459
|
+
const children = getColumnDefChildren(column);
|
|
1460
|
+
if (children) {
|
|
1461
|
+
const nestedGroup = id ? { id, def: column } : group;
|
|
1462
|
+
slots.push(...flattenColumnSlots(children, nestedGroup));
|
|
1463
|
+
continue;
|
|
1464
|
+
}
|
|
1465
|
+
if (!id) continue;
|
|
1466
|
+
slots.push({ id, def: column, group });
|
|
1467
|
+
}
|
|
1468
|
+
return slots;
|
|
1469
|
+
}
|
|
1470
|
+
function rebuildColumnTree(slots) {
|
|
1471
|
+
const result = [];
|
|
1472
|
+
let index = 0;
|
|
1473
|
+
while (index < slots.length) {
|
|
1474
|
+
const slot = slots[index];
|
|
1475
|
+
if (!slot.group) {
|
|
1476
|
+
result.push(slot.def);
|
|
1477
|
+
index += 1;
|
|
1478
|
+
continue;
|
|
1479
|
+
}
|
|
1480
|
+
const groupId = slot.group.id;
|
|
1481
|
+
const children = [];
|
|
1482
|
+
while (index < slots.length && slots[index]?.group?.id === groupId) {
|
|
1483
|
+
children.push(slots[index].def);
|
|
1484
|
+
index += 1;
|
|
1485
|
+
}
|
|
1486
|
+
const firstChildId = children[0] ? getColumnDefId(children[0]) : groupId;
|
|
1487
|
+
result.push({
|
|
1488
|
+
...slot.group.def,
|
|
1489
|
+
id: `${groupId}::${firstChildId}`,
|
|
1490
|
+
columns: children
|
|
1491
|
+
});
|
|
1492
|
+
}
|
|
1493
|
+
return result;
|
|
1494
|
+
}
|
|
1495
|
+
function applyLeafColumnOrder(columns, order) {
|
|
1496
|
+
const resolved = resolveLeafColumnOrder(columns, order);
|
|
1497
|
+
const defaultOrder = collectLeafColumnIds(columns);
|
|
1498
|
+
if (areColumnOrdersEqual(resolved, defaultOrder)) {
|
|
1499
|
+
return columns;
|
|
1500
|
+
}
|
|
1501
|
+
const byId = new Map(
|
|
1502
|
+
flattenColumnSlots(columns).map((slot) => [
|
|
1503
|
+
slot.id,
|
|
1504
|
+
slot
|
|
1505
|
+
])
|
|
1506
|
+
);
|
|
1507
|
+
const ordered = [];
|
|
1508
|
+
for (const id of resolved) {
|
|
1509
|
+
const slot = byId.get(id);
|
|
1510
|
+
if (slot) ordered.push(slot);
|
|
1511
|
+
}
|
|
1512
|
+
return rebuildColumnTree(ordered);
|
|
1513
|
+
}
|
|
1514
|
+
function moveColumnIds(order, fromIds, targetIds, edge) {
|
|
1515
|
+
if (fromIds.length === 0 || targetIds.length === 0) return [...order];
|
|
1516
|
+
const fromSet = new Set(fromIds);
|
|
1517
|
+
if (targetIds.some((id) => fromSet.has(id))) return [...order];
|
|
1518
|
+
const rest = order.filter((id) => !fromSet.has(id));
|
|
1519
|
+
const anchorId = edge === "before" ? targetIds[0] : targetIds[targetIds.length - 1];
|
|
1520
|
+
const anchorIndex = rest.indexOf(anchorId);
|
|
1521
|
+
if (anchorIndex < 0) return [...order];
|
|
1522
|
+
const insertAt = edge === "before" ? anchorIndex : anchorIndex + 1;
|
|
1523
|
+
return [...rest.slice(0, insertAt), ...fromIds, ...rest.slice(insertAt)];
|
|
1524
|
+
}
|
|
1525
|
+
function resolveDropEdge(clientX, rect) {
|
|
1526
|
+
return clientX < rect.left + rect.width / 2 ? "before" : "after";
|
|
1527
|
+
}
|
|
1528
|
+
function parseReorderIds(value) {
|
|
1529
|
+
if (!value) return [];
|
|
1530
|
+
return value.split(",").filter(Boolean);
|
|
1531
|
+
}
|
|
1532
|
+
|
|
1391
1533
|
// src/components/ui/table/features/column-freeze/columnFreeze.ts
|
|
1392
1534
|
var HEADER_Z_BASE = 30;
|
|
1393
1535
|
var BODY_Z_BASE = 5;
|
|
@@ -2263,6 +2405,9 @@ function useGlideTable(options) {
|
|
|
2263
2405
|
columnSizing: controlledColumnSizing,
|
|
2264
2406
|
onColumnSizingChange,
|
|
2265
2407
|
columnResizeMode = "onChange",
|
|
2408
|
+
enableColumnReorder = false,
|
|
2409
|
+
columnOrder: controlledColumnOrder,
|
|
2410
|
+
onColumnOrderChange,
|
|
2266
2411
|
enableColumnFreeze = false,
|
|
2267
2412
|
enableInlineSearch = false,
|
|
2268
2413
|
showSearch,
|
|
@@ -2285,6 +2430,7 @@ function useGlideTable(options) {
|
|
|
2285
2430
|
const resolvedEnableSubtreeCopy = enableSubtreeCopy ?? enableExpand;
|
|
2286
2431
|
const [internalRowSelection, setInternalRowSelection] = (0, import_react5.useState)({});
|
|
2287
2432
|
const [internalColumnSizing, setInternalColumnSizing] = (0, import_react5.useState)({});
|
|
2433
|
+
const [internalColumnOrder, setInternalColumnOrder] = (0, import_react5.useState)([]);
|
|
2288
2434
|
const [internalExpandedRows, setInternalExpandedRows] = (0, import_react5.useState)(
|
|
2289
2435
|
() => /* @__PURE__ */ new Set()
|
|
2290
2436
|
);
|
|
@@ -2305,6 +2451,21 @@ function useGlideTable(options) {
|
|
|
2305
2451
|
internalRowSelection
|
|
2306
2452
|
);
|
|
2307
2453
|
const columnSizing = controlledColumnSizing ?? internalColumnSizing;
|
|
2454
|
+
const columnOrder = controlledColumnOrder ?? internalColumnOrder;
|
|
2455
|
+
const tableColumns = (0, import_react5.useMemo)(() => {
|
|
2456
|
+
if (!enableColumnReorder) return columns;
|
|
2457
|
+
return applyLeafColumnOrder(columns, columnOrder);
|
|
2458
|
+
}, [columnOrder, columns, enableColumnReorder]);
|
|
2459
|
+
const setColumnOrder = (0, import_react5.useCallback)(
|
|
2460
|
+
(next) => {
|
|
2461
|
+
if (onColumnOrderChange) {
|
|
2462
|
+
onColumnOrderChange(next);
|
|
2463
|
+
return;
|
|
2464
|
+
}
|
|
2465
|
+
setInternalColumnOrder(next);
|
|
2466
|
+
},
|
|
2467
|
+
[onColumnOrderChange]
|
|
2468
|
+
);
|
|
2308
2469
|
const expandedRows = controlledExpandedRows ?? internalExpandedRows;
|
|
2309
2470
|
const handleExpandedRowsChange = (0, import_react5.useCallback)(
|
|
2310
2471
|
(next) => {
|
|
@@ -2329,7 +2490,7 @@ function useGlideTable(options) {
|
|
|
2329
2490
|
});
|
|
2330
2491
|
const table = (0, import_react_table.useReactTable)({
|
|
2331
2492
|
data: tableData,
|
|
2332
|
-
columns,
|
|
2493
|
+
columns: tableColumns,
|
|
2333
2494
|
...enableColumnResize ? {
|
|
2334
2495
|
defaultColumn: {
|
|
2335
2496
|
minSize: DATA_TABLE_COLUMN_MIN_SIZE,
|
|
@@ -2485,6 +2646,10 @@ function useGlideTable(options) {
|
|
|
2485
2646
|
}),
|
|
2486
2647
|
[onCellChange, onDataChange, rows, tableData]
|
|
2487
2648
|
);
|
|
2649
|
+
const getCellContext = (0, import_react5.useCallback)(
|
|
2650
|
+
(cell) => withCellUpdate(cell.getContext(), commitRenderedCellValue),
|
|
2651
|
+
[commitRenderedCellValue]
|
|
2652
|
+
);
|
|
2488
2653
|
const handleCellMouseDownWithCommit = (0, import_react5.useCallback)(
|
|
2489
2654
|
(rowIndex, colIndex, options2) => {
|
|
2490
2655
|
const isSameEditingCell = editingCell?.rowIndex === rowIndex && editingCell?.colIndex === colIndex;
|
|
@@ -2807,6 +2972,7 @@ function useGlideTable(options) {
|
|
|
2807
2972
|
selectionLabel: labels.selection,
|
|
2808
2973
|
enableCellSelection,
|
|
2809
2974
|
enableColumnResize,
|
|
2975
|
+
enableColumnReorder,
|
|
2810
2976
|
enableColumnFreeze,
|
|
2811
2977
|
enableInlineSearch,
|
|
2812
2978
|
shouldVirtualize,
|
|
@@ -2817,8 +2983,10 @@ function useGlideTable(options) {
|
|
|
2817
2983
|
paddingTop,
|
|
2818
2984
|
paddingBottom,
|
|
2819
2985
|
rowContextValue,
|
|
2986
|
+
getCellContext,
|
|
2820
2987
|
handleToggleSelect,
|
|
2821
2988
|
clearHover,
|
|
2989
|
+
setColumnOrder,
|
|
2822
2990
|
copySelection: stableCopySelection,
|
|
2823
2991
|
inlineSearch: {
|
|
2824
2992
|
showSearch: inlineSearch.showSearch,
|
|
@@ -2897,6 +3065,214 @@ function getColumnSizeStyle(size, options) {
|
|
|
2897
3065
|
...lockMax ? { maxWidth: size } : {}
|
|
2898
3066
|
};
|
|
2899
3067
|
}
|
|
3068
|
+
|
|
3069
|
+
// src/components/ui/table/features/column-reorder/useColumnReorder.ts
|
|
3070
|
+
var import_react8 = require("react");
|
|
3071
|
+
function hitTestReorderHeader(table, clientX, clientY) {
|
|
3072
|
+
const headers = Array.from(
|
|
3073
|
+
table.querySelectorAll(
|
|
3074
|
+
"thead th[data-column-id][data-reorder-ids]"
|
|
3075
|
+
)
|
|
3076
|
+
);
|
|
3077
|
+
const containing = headers.find((element) => {
|
|
3078
|
+
const rect = element.getBoundingClientRect();
|
|
3079
|
+
return clientX >= rect.left && clientX <= rect.right && clientY >= rect.top && clientY <= rect.bottom;
|
|
3080
|
+
});
|
|
3081
|
+
if (containing) {
|
|
3082
|
+
return {
|
|
3083
|
+
columnId: containing.dataset.columnId ?? "",
|
|
3084
|
+
edge: resolveDropEdge(clientX, containing.getBoundingClientRect())
|
|
3085
|
+
};
|
|
3086
|
+
}
|
|
3087
|
+
const leaves = headers.filter(
|
|
3088
|
+
(element) => element.hasAttribute("data-reorder-leaf")
|
|
3089
|
+
);
|
|
3090
|
+
let match;
|
|
3091
|
+
for (const element of leaves) {
|
|
3092
|
+
const rect = element.getBoundingClientRect();
|
|
3093
|
+
if (clientX >= rect.left && clientX <= rect.right) {
|
|
3094
|
+
match = element;
|
|
3095
|
+
break;
|
|
3096
|
+
}
|
|
3097
|
+
}
|
|
3098
|
+
if (!match && leaves.length > 0) {
|
|
3099
|
+
const first = leaves[0].getBoundingClientRect();
|
|
3100
|
+
const last = leaves[leaves.length - 1].getBoundingClientRect();
|
|
3101
|
+
if (clientX < first.left) match = leaves[0];
|
|
3102
|
+
else if (clientX > last.right) match = leaves[leaves.length - 1];
|
|
3103
|
+
}
|
|
3104
|
+
if (!match) return null;
|
|
3105
|
+
return {
|
|
3106
|
+
columnId: match.dataset.columnId ?? "",
|
|
3107
|
+
edge: resolveDropEdge(clientX, match.getBoundingClientRect())
|
|
3108
|
+
};
|
|
3109
|
+
}
|
|
3110
|
+
function readTargetIds(table, columnId) {
|
|
3111
|
+
const element = table.querySelector(
|
|
3112
|
+
`thead th[data-column-id="${CSS.escape(columnId)}"]`
|
|
3113
|
+
);
|
|
3114
|
+
return parseReorderIds(element?.getAttribute("data-reorder-ids"));
|
|
3115
|
+
}
|
|
3116
|
+
function useColumnReorder(options) {
|
|
3117
|
+
const { enabled, columnOrder, onColumnOrderChange } = options;
|
|
3118
|
+
const sessionRef = (0, import_react8.useRef)(null);
|
|
3119
|
+
const columnOrderRef = (0, import_react8.useRef)(columnOrder);
|
|
3120
|
+
const onColumnOrderChangeRef = (0, import_react8.useRef)(onColumnOrderChange);
|
|
3121
|
+
const [draggingColumnId, setDraggingColumnId] = (0, import_react8.useState)(null);
|
|
3122
|
+
const [dropTarget, setDropTarget] = (0, import_react8.useState)(
|
|
3123
|
+
null
|
|
3124
|
+
);
|
|
3125
|
+
const dropTargetRef = (0, import_react8.useRef)(dropTarget);
|
|
3126
|
+
const previousUserSelectRef = (0, import_react8.useRef)(null);
|
|
3127
|
+
columnOrderRef.current = columnOrder;
|
|
3128
|
+
onColumnOrderChangeRef.current = onColumnOrderChange;
|
|
3129
|
+
dropTargetRef.current = dropTarget;
|
|
3130
|
+
const resetDrag = (0, import_react8.useCallback)(() => {
|
|
3131
|
+
sessionRef.current = null;
|
|
3132
|
+
setDraggingColumnId(null);
|
|
3133
|
+
setDropTarget(null);
|
|
3134
|
+
const backup = previousUserSelectRef.current;
|
|
3135
|
+
previousUserSelectRef.current = null;
|
|
3136
|
+
if (backup) {
|
|
3137
|
+
if (backup.value) {
|
|
3138
|
+
document.body.style.setProperty("user-select", backup.value, backup.priority);
|
|
3139
|
+
} else {
|
|
3140
|
+
document.body.style.removeProperty("user-select");
|
|
3141
|
+
}
|
|
3142
|
+
return;
|
|
3143
|
+
}
|
|
3144
|
+
document.body.style.removeProperty("user-select");
|
|
3145
|
+
}, []);
|
|
3146
|
+
(0, import_react8.useEffect)(() => {
|
|
3147
|
+
if (!enabled) resetDrag();
|
|
3148
|
+
}, [enabled, resetDrag]);
|
|
3149
|
+
(0, import_react8.useEffect)(() => {
|
|
3150
|
+
return () => {
|
|
3151
|
+
resetDrag();
|
|
3152
|
+
};
|
|
3153
|
+
}, [resetDrag]);
|
|
3154
|
+
const onHeaderPointerDown = (0, import_react8.useCallback)(
|
|
3155
|
+
(event, meta) => {
|
|
3156
|
+
if (!enabled || !meta.canDrag) return;
|
|
3157
|
+
if (event.button !== 0) return;
|
|
3158
|
+
if (event.pointerType === "mouse" && event.ctrlKey) return;
|
|
3159
|
+
const target = event.target;
|
|
3160
|
+
if (target instanceof Element && target.closest("[data-table-disable-cell-selection]")) {
|
|
3161
|
+
return;
|
|
3162
|
+
}
|
|
3163
|
+
const table = event.currentTarget.closest("table");
|
|
3164
|
+
if (!(table instanceof HTMLTableElement)) return;
|
|
3165
|
+
sessionRef.current = {
|
|
3166
|
+
pointerId: event.pointerId,
|
|
3167
|
+
startX: event.clientX,
|
|
3168
|
+
startY: event.clientY,
|
|
3169
|
+
columnId: meta.columnId,
|
|
3170
|
+
fromIds: meta.leafIds,
|
|
3171
|
+
table,
|
|
3172
|
+
active: false
|
|
3173
|
+
};
|
|
3174
|
+
},
|
|
3175
|
+
[enabled]
|
|
3176
|
+
);
|
|
3177
|
+
(0, import_react8.useEffect)(() => {
|
|
3178
|
+
if (!enabled) return;
|
|
3179
|
+
const onPointerMove = (event) => {
|
|
3180
|
+
const session = sessionRef.current;
|
|
3181
|
+
if (!session || event.pointerId !== session.pointerId) return;
|
|
3182
|
+
const deltaX = event.clientX - session.startX;
|
|
3183
|
+
const deltaY = event.clientY - session.startY;
|
|
3184
|
+
const distance = Math.hypot(deltaX, deltaY);
|
|
3185
|
+
if (!session.active) {
|
|
3186
|
+
if (distance < DATA_TABLE_COLUMN_REORDER_THRESHOLD) return;
|
|
3187
|
+
session.active = true;
|
|
3188
|
+
if (!previousUserSelectRef.current) {
|
|
3189
|
+
previousUserSelectRef.current = {
|
|
3190
|
+
value: document.body.style.getPropertyValue("user-select"),
|
|
3191
|
+
priority: document.body.style.getPropertyPriority("user-select")
|
|
3192
|
+
};
|
|
3193
|
+
}
|
|
3194
|
+
document.body.style.setProperty("user-select", "none");
|
|
3195
|
+
setDraggingColumnId(session.columnId);
|
|
3196
|
+
}
|
|
3197
|
+
event.preventDefault();
|
|
3198
|
+
const nextTarget = hitTestReorderHeader(
|
|
3199
|
+
session.table,
|
|
3200
|
+
event.clientX,
|
|
3201
|
+
event.clientY
|
|
3202
|
+
);
|
|
3203
|
+
if (!nextTarget || !nextTarget.columnId) {
|
|
3204
|
+
setDropTarget(null);
|
|
3205
|
+
return;
|
|
3206
|
+
}
|
|
3207
|
+
const targetIds = readTargetIds(session.table, nextTarget.columnId);
|
|
3208
|
+
const fromSet = new Set(session.fromIds);
|
|
3209
|
+
if (targetIds.some((id) => fromSet.has(id))) {
|
|
3210
|
+
setDropTarget(null);
|
|
3211
|
+
return;
|
|
3212
|
+
}
|
|
3213
|
+
setDropTarget((previous) => {
|
|
3214
|
+
if (previous?.columnId === nextTarget.columnId && previous.edge === nextTarget.edge) {
|
|
3215
|
+
return previous;
|
|
3216
|
+
}
|
|
3217
|
+
return nextTarget;
|
|
3218
|
+
});
|
|
3219
|
+
};
|
|
3220
|
+
const onPointerUp = (event) => {
|
|
3221
|
+
const session = sessionRef.current;
|
|
3222
|
+
if (!session || event.pointerId !== session.pointerId) {
|
|
3223
|
+
return;
|
|
3224
|
+
}
|
|
3225
|
+
if (session.active) {
|
|
3226
|
+
event.preventDefault();
|
|
3227
|
+
const target = dropTargetRef.current;
|
|
3228
|
+
if (target) {
|
|
3229
|
+
const targetIds = readTargetIds(session.table, target.columnId);
|
|
3230
|
+
const next = moveColumnIds(
|
|
3231
|
+
columnOrderRef.current,
|
|
3232
|
+
session.fromIds,
|
|
3233
|
+
targetIds,
|
|
3234
|
+
target.edge
|
|
3235
|
+
);
|
|
3236
|
+
onColumnOrderChangeRef.current(next);
|
|
3237
|
+
}
|
|
3238
|
+
const suppressClick = (clickEvent) => {
|
|
3239
|
+
clickEvent.preventDefault();
|
|
3240
|
+
clickEvent.stopPropagation();
|
|
3241
|
+
document.removeEventListener("click", suppressClick, true);
|
|
3242
|
+
};
|
|
3243
|
+
document.addEventListener("click", suppressClick, true);
|
|
3244
|
+
window.setTimeout(() => {
|
|
3245
|
+
document.removeEventListener("click", suppressClick, true);
|
|
3246
|
+
}, 0);
|
|
3247
|
+
}
|
|
3248
|
+
resetDrag();
|
|
3249
|
+
};
|
|
3250
|
+
const onPointerCancel = (event) => {
|
|
3251
|
+
const session = sessionRef.current;
|
|
3252
|
+
if (!session || event.pointerId !== session.pointerId) {
|
|
3253
|
+
return;
|
|
3254
|
+
}
|
|
3255
|
+
if (session.active) {
|
|
3256
|
+
event.preventDefault();
|
|
3257
|
+
}
|
|
3258
|
+
resetDrag();
|
|
3259
|
+
};
|
|
3260
|
+
document.addEventListener("pointermove", onPointerMove);
|
|
3261
|
+
document.addEventListener("pointerup", onPointerUp);
|
|
3262
|
+
document.addEventListener("pointercancel", onPointerCancel);
|
|
3263
|
+
return () => {
|
|
3264
|
+
document.removeEventListener("pointermove", onPointerMove);
|
|
3265
|
+
document.removeEventListener("pointerup", onPointerUp);
|
|
3266
|
+
document.removeEventListener("pointercancel", onPointerCancel);
|
|
3267
|
+
};
|
|
3268
|
+
}, [enabled, resetDrag]);
|
|
3269
|
+
return {
|
|
3270
|
+
isReordering: draggingColumnId != null,
|
|
3271
|
+
draggingColumnId,
|
|
3272
|
+
dropTarget,
|
|
3273
|
+
onHeaderPointerDown
|
|
3274
|
+
};
|
|
3275
|
+
}
|
|
2900
3276
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2901
3277
|
0 && (module.exports = {
|
|
2902
3278
|
BUILTIN_CELL_RENDERERS,
|
|
@@ -2910,6 +3286,7 @@ function getColumnSizeStyle(size, options) {
|
|
|
2910
3286
|
ResolvedTableCell,
|
|
2911
3287
|
applyCellEdit,
|
|
2912
3288
|
applyFillData,
|
|
3289
|
+
applyLeafColumnOrder,
|
|
2913
3290
|
applySelectionUpdater,
|
|
2914
3291
|
buildColumnFreezeOffsets,
|
|
2915
3292
|
buildColumnRowSpanMap,
|
|
@@ -2924,6 +3301,7 @@ function getColumnSizeStyle(size, options) {
|
|
|
2924
3301
|
collectCopyRowEntries,
|
|
2925
3302
|
collectCopyRows,
|
|
2926
3303
|
collectFillChanges,
|
|
3304
|
+
collectLeafColumnIds,
|
|
2927
3305
|
collectRowSpanColumns,
|
|
2928
3306
|
collectSearchMatchesInRange,
|
|
2929
3307
|
commitCellValue,
|
|
@@ -2948,6 +3326,7 @@ function getColumnSizeStyle(size, options) {
|
|
|
2948
3326
|
mapSearchResultToVisibleItem,
|
|
2949
3327
|
mapSearchResultsToVisibleKeys,
|
|
2950
3328
|
measureMergedSpanRowHeights,
|
|
3329
|
+
moveColumnIds,
|
|
2951
3330
|
nextSearchIndex,
|
|
2952
3331
|
nextSearchStride,
|
|
2953
3332
|
parseCellEditValue,
|
|
@@ -2957,7 +3336,9 @@ function getColumnSizeStyle(size, options) {
|
|
|
2957
3336
|
resolveCellRenderer,
|
|
2958
3337
|
resolveColumnFreezeSide,
|
|
2959
3338
|
resolveDataTableLabels,
|
|
3339
|
+
resolveDropEdge,
|
|
2960
3340
|
resolveHeaderFreezeOffset,
|
|
3341
|
+
resolveLeafColumnOrder,
|
|
2961
3342
|
resolvePasteColumnIds,
|
|
2962
3343
|
resolveRowSelection,
|
|
2963
3344
|
resolveRowSpanAt,
|
|
@@ -2967,8 +3348,10 @@ function getColumnSizeStyle(size, options) {
|
|
|
2967
3348
|
toggleExpandedRowId,
|
|
2968
3349
|
useCellEdit,
|
|
2969
3350
|
useCellSelection,
|
|
3351
|
+
useColumnReorder,
|
|
2970
3352
|
useConvertTreeData,
|
|
2971
3353
|
useGlideTable,
|
|
2972
3354
|
useInlineSearch,
|
|
3355
|
+
withCellUpdate,
|
|
2973
3356
|
writeSelectionToClipboard
|
|
2974
3357
|
});
|
package/dist/core.d.cts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { W as CellEditType, c as CellRenderer, C as CellKind, a as CellRenderContext, i as DataTableClassNames, R as RowSelectionMode, g as ColumnFreezeOffset, p as SearchResultItem, q as SearchStatus, l as DataTableProps, k as DataTableLabels, j as DataTableCopyActions, P as PasteMode, o as RowsPastePayload } from './types-
|
|
2
|
-
export { B as BuiltinCellKind, b as CellRenderFn, d as ColumnFreezeColumnInput, e as ColumnFreezeEdgeSide, f as ColumnFreezeMeta, h as ColumnFreezeSide, D as DEFAULT_DATA_TABLE_LABELS, I as INLINE_SEARCH_MAX_RESULTS, S as SearchCorpusRow, t as buildColumnFreezeOffsets, u as buildFlatSearchCorpus, v as buildSearchMatchKey, w as buildSearchMatchKeys, x as buildTreeSearchCorpus, y as cellValueToSearchText, z as collectAncestorKeysToExpand, A as collectSearchMatchesInRange, E as createSearchRegex, F as escapeSearchRegex, G as formatSearchResultLabel, H as getColumnFreezeEdgeAttr, J as getColumnFreezeStyle, K as mapSearchResultToVisibleItem, L as mapSearchResultsToVisibleKeys, M as nextSearchIndex, N as nextSearchStride, O as previousSearchIndex, Q as resolveColumnFreezeSide, U as resolveDataTableLabels, V as resolveHeaderFreezeOffset } from './types-
|
|
3
|
-
import { Row, ColumnDef, Table,
|
|
4
|
-
export { ColumnDef, ColumnResizeMode, ColumnSizingState, RowSelectionState } from '@tanstack/react-table';
|
|
1
|
+
import { W as CellEditType, c as CellRenderer, C as CellKind, a as CellRenderContext, i as DataTableClassNames, R as RowSelectionMode, g as ColumnFreezeOffset, p as SearchResultItem, q as SearchStatus, l as DataTableProps, k as DataTableLabels, j as DataTableCopyActions, P as PasteMode, o as RowsPastePayload } from './types-CMUGtH-c.cjs';
|
|
2
|
+
export { B as BuiltinCellKind, b as CellRenderFn, d as ColumnFreezeColumnInput, e as ColumnFreezeEdgeSide, f as ColumnFreezeMeta, h as ColumnFreezeSide, D as DEFAULT_DATA_TABLE_LABELS, I as INLINE_SEARCH_MAX_RESULTS, S as SearchCorpusRow, t as buildColumnFreezeOffsets, u as buildFlatSearchCorpus, v as buildSearchMatchKey, w as buildSearchMatchKeys, x as buildTreeSearchCorpus, y as cellValueToSearchText, z as collectAncestorKeysToExpand, A as collectSearchMatchesInRange, E as createSearchRegex, F as escapeSearchRegex, G as formatSearchResultLabel, H as getColumnFreezeEdgeAttr, J as getColumnFreezeStyle, K as mapSearchResultToVisibleItem, L as mapSearchResultsToVisibleKeys, M as nextSearchIndex, N as nextSearchStride, O as previousSearchIndex, Q as resolveColumnFreezeSide, U as resolveDataTableLabels, V as resolveHeaderFreezeOffset } from './types-CMUGtH-c.cjs';
|
|
3
|
+
import { Row, ColumnDef, CellContext, Table, Cell, ColumnOrderState, Updater, RowSelectionState } from '@tanstack/react-table';
|
|
4
|
+
export { ColumnDef, ColumnOrderState, ColumnResizeMode, ColumnSizingState, RowSelectionState } from '@tanstack/react-table';
|
|
5
5
|
import { Virtualizer, VirtualItem } from '@tanstack/react-virtual';
|
|
6
6
|
import * as react from 'react';
|
|
7
|
-
import { RefObject, CSSProperties } from 'react';
|
|
7
|
+
import { RefObject, CSSProperties, PointerEvent } from 'react';
|
|
8
8
|
|
|
9
9
|
/** Neutral default field names for tree conversion */
|
|
10
10
|
declare const DEFAULT_TREE_ID_FIELD = "id";
|
|
@@ -197,6 +197,19 @@ type DataTableRowContextValue = {
|
|
|
197
197
|
};
|
|
198
198
|
};
|
|
199
199
|
|
|
200
|
+
/**
|
|
201
|
+
* TanStack `CellContext` with a guaranteed `update` commit helper.
|
|
202
|
+
* Prefer this over bare `cell.getContext()`, which does not include `update` at runtime.
|
|
203
|
+
*/
|
|
204
|
+
type CellContextWithUpdate<TData, TValue> = CellContext<TData, TValue> & {
|
|
205
|
+
update: (next: TValue) => void;
|
|
206
|
+
};
|
|
207
|
+
/**
|
|
208
|
+
* Injects `update` into a TanStack `CellContext` so `ColumnDef.cell` can commit
|
|
209
|
+
* through `onCellChange` / `onDataChange` the same way compound `Column.render` does.
|
|
210
|
+
*/
|
|
211
|
+
declare function withCellUpdate<TData extends Record<string, unknown>, TValue>(context: CellContext<TData, TValue>, commitValue: (rowId: string, columnId: string, value: unknown) => boolean): CellContextWithUpdate<TData, TValue>;
|
|
212
|
+
|
|
200
213
|
type UseInlineSearchOptions = {
|
|
201
214
|
enabled?: boolean;
|
|
202
215
|
rowCount: number;
|
|
@@ -248,6 +261,7 @@ type UseGlideTableResult<T extends Record<string, unknown>> = {
|
|
|
248
261
|
selectionLabel: DataTableLabels["selection"];
|
|
249
262
|
enableCellSelection: boolean;
|
|
250
263
|
enableColumnResize: boolean;
|
|
264
|
+
enableColumnReorder: boolean;
|
|
251
265
|
enableColumnFreeze: boolean;
|
|
252
266
|
enableInlineSearch: boolean;
|
|
253
267
|
shouldVirtualize: boolean;
|
|
@@ -258,8 +272,14 @@ type UseGlideTableResult<T extends Record<string, unknown>> = {
|
|
|
258
272
|
paddingTop: number;
|
|
259
273
|
paddingBottom: number;
|
|
260
274
|
rowContextValue: DataTableRowContextValue;
|
|
275
|
+
/**
|
|
276
|
+
* TanStack `CellContext` with `update` injected for custom `ColumnDef.cell` renders.
|
|
277
|
+
* Prefer this over `cell.getContext()` when calling `flexRender` yourself.
|
|
278
|
+
*/
|
|
279
|
+
getCellContext: <TValue>(cell: Cell<T, TValue>) => CellContextWithUpdate<T, TValue>;
|
|
261
280
|
handleToggleSelect: (row: Row<T>) => void;
|
|
262
281
|
clearHover: () => void;
|
|
282
|
+
setColumnOrder: (next: ColumnOrderState) => void;
|
|
263
283
|
copySelection: DataTableCopyActions["copySelection"];
|
|
264
284
|
inlineSearch: {
|
|
265
285
|
showSearch: boolean;
|
|
@@ -321,6 +341,38 @@ declare function getColumnSizeStyle(size: number, options?: {
|
|
|
321
341
|
lockMax?: boolean;
|
|
322
342
|
}): CSSProperties | undefined;
|
|
323
343
|
|
|
344
|
+
type ColumnDropEdge = "before" | "after";
|
|
345
|
+
declare function collectLeafColumnIds<T>(columns: readonly ColumnDef<T, unknown>[]): string[];
|
|
346
|
+
/** Keep known ids in the given order and append any new leaves at the end. */
|
|
347
|
+
declare function resolveLeafColumnOrder<T>(columns: readonly ColumnDef<T, unknown>[], order: readonly string[] | undefined): string[];
|
|
348
|
+
/**
|
|
349
|
+
* Reorder nested `ColumnDef`s by leaf id list.
|
|
350
|
+
* Consecutive leaves that still share a parent group stay wrapped together;
|
|
351
|
+
* interleaved groups split (Glide-style).
|
|
352
|
+
*/
|
|
353
|
+
declare function applyLeafColumnOrder<T>(columns: readonly ColumnDef<T, unknown>[], order: readonly string[] | undefined): ColumnDef<T, unknown>[];
|
|
354
|
+
declare function moveColumnIds(order: readonly string[], fromIds: readonly string[], targetIds: readonly string[], edge: ColumnDropEdge): string[];
|
|
355
|
+
declare function resolveDropEdge(clientX: number, rect: Pick<DOMRect, "left" | "width">): ColumnDropEdge;
|
|
356
|
+
|
|
357
|
+
type ColumnReorderDropTarget = {
|
|
358
|
+
columnId: string;
|
|
359
|
+
edge: ColumnDropEdge;
|
|
360
|
+
};
|
|
361
|
+
declare function useColumnReorder(options: {
|
|
362
|
+
enabled: boolean;
|
|
363
|
+
columnOrder: readonly string[];
|
|
364
|
+
onColumnOrderChange: (next: string[]) => void;
|
|
365
|
+
}): {
|
|
366
|
+
isReordering: boolean;
|
|
367
|
+
draggingColumnId: string | null;
|
|
368
|
+
dropTarget: ColumnReorderDropTarget | null;
|
|
369
|
+
onHeaderPointerDown: (event: PointerEvent<HTMLTableCellElement>, meta: {
|
|
370
|
+
columnId: string;
|
|
371
|
+
leafIds: string[];
|
|
372
|
+
canDrag: boolean;
|
|
373
|
+
}) => void;
|
|
374
|
+
};
|
|
375
|
+
|
|
324
376
|
type ParsedClipboardTSV = {
|
|
325
377
|
values: string[][];
|
|
326
378
|
/**
|
|
@@ -445,4 +497,4 @@ declare const useConvertTreeData: <T extends Record<string, unknown>>({ data, en
|
|
|
445
497
|
declare function resolveRowSelection(mode: RowSelectionMode, controlledSelection: RowSelectionState | undefined, internalSelection: RowSelectionState): RowSelectionState;
|
|
446
498
|
declare function applySelectionUpdater(mode: RowSelectionMode, updater: Updater<RowSelectionState>, previous: RowSelectionState): RowSelectionState;
|
|
447
499
|
|
|
448
|
-
export { BUILTIN_CELL_RENDERERS, CELL_SELECTION_EDGES_CLASS, CellKind, CellRenderContext, CellRenderer, type CellRendererRegistry, type CellSelectionBounds, ColumnFreezeOffset, type ColumnRowSpanMap, type CopyRowEntry, type CopySelectionMode, DEFAULT_TREE_CHILDREN_FIELD, DEFAULT_TREE_ID_FIELD, DEFAULT_TREE_PARENT_ID_FIELD, DEFAULT_TREE_QTY_FIELD, DataTableCopyActions, DataTableLabels, DataTableProps, type DragState, type EditingCell, PasteMode, ResolvedTableCell, RowSelectionMode, type RowSpanInfo, RowsPastePayload, SearchResultItem, SearchStatus, type TreeRow, type UseConvertTreeDataParams, type UseGlideTableOptions, type UseGlideTableResult, type UseInlineSearchOptions, type UseInlineSearchResult, applyCellEdit, applyFillData, applySelectionUpdater, buildColumnRowSpanMap, buildRowsPastePayload, canExpandRow, collectCopyRowEntries, collectCopyRows, collectFillChanges, collectRowSpanColumns, commitCellValue, createCellRendererRegistry, flattenSubtreeRows, formatCellValue, formatDefaultCellValue, getCellEditDraftValue, getCellSelectionEdgeStyle, getColumnEditType, getColumnSizeStyle, getRowIndexInMergedCell, hasCellSelectionEdges, isCellInSelection, isColumnEditable, isEditablePasteTarget, measureMergedSpanRowHeights, parseCellEditValue, parseClipboardTSV, parseClipboardTSVWithDepths, resolveCellRenderer, resolvePasteColumnIds, resolveRowSelection, resolveRowSpanAt, rowRangeToHeightRatios, serializeCopyRowsToTSV, serializeSelectionToTSV, toggleExpandedRowId, useCellEdit, useCellSelection, useConvertTreeData, useGlideTable, useInlineSearch, writeSelectionToClipboard };
|
|
500
|
+
export { BUILTIN_CELL_RENDERERS, CELL_SELECTION_EDGES_CLASS, type CellContextWithUpdate, CellKind, CellRenderContext, CellRenderer, type CellRendererRegistry, type CellSelectionBounds, type ColumnDropEdge, ColumnFreezeOffset, type ColumnRowSpanMap, type CopyRowEntry, type CopySelectionMode, DEFAULT_TREE_CHILDREN_FIELD, DEFAULT_TREE_ID_FIELD, DEFAULT_TREE_PARENT_ID_FIELD, DEFAULT_TREE_QTY_FIELD, DataTableCopyActions, DataTableLabels, DataTableProps, type DragState, type EditingCell, PasteMode, ResolvedTableCell, RowSelectionMode, type RowSpanInfo, RowsPastePayload, SearchResultItem, SearchStatus, type TreeRow, type UseConvertTreeDataParams, type UseGlideTableOptions, type UseGlideTableResult, type UseInlineSearchOptions, type UseInlineSearchResult, applyCellEdit, applyFillData, applyLeafColumnOrder, applySelectionUpdater, buildColumnRowSpanMap, buildRowsPastePayload, canExpandRow, collectCopyRowEntries, collectCopyRows, collectFillChanges, collectLeafColumnIds, collectRowSpanColumns, commitCellValue, createCellRendererRegistry, flattenSubtreeRows, formatCellValue, formatDefaultCellValue, getCellEditDraftValue, getCellSelectionEdgeStyle, getColumnEditType, getColumnSizeStyle, getRowIndexInMergedCell, hasCellSelectionEdges, isCellInSelection, isColumnEditable, isEditablePasteTarget, measureMergedSpanRowHeights, moveColumnIds, parseCellEditValue, parseClipboardTSV, parseClipboardTSVWithDepths, resolveCellRenderer, resolveDropEdge, resolveLeafColumnOrder, resolvePasteColumnIds, resolveRowSelection, resolveRowSpanAt, rowRangeToHeightRatios, serializeCopyRowsToTSV, serializeSelectionToTSV, toggleExpandedRowId, useCellEdit, useCellSelection, useColumnReorder, useConvertTreeData, useGlideTable, useInlineSearch, withCellUpdate, writeSelectionToClipboard };
|