react-glide-table 2.0.2 → 2.2.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 +35 -0
- package/dist/compound.cjs +590 -126
- package/dist/compound.d.cts +3 -3
- package/dist/compound.d.ts +3 -3
- package/dist/compound.js +571 -102
- package/dist/core.cjs +444 -11
- package/dist/core.d.cts +53 -14
- package/dist/core.d.ts +53 -14
- package/dist/core.js +443 -11
- package/dist/index.cjs +509 -33
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +492 -17
- package/dist/{types-bgEceyRV.d.cts → types-Iot4g4sq.d.cts} +38 -2
- package/dist/{types-bgEceyRV.d.ts → types-Iot4g4sq.d.ts} +38 -2
- package/package.json +1 -1
package/dist/core.js
CHANGED
|
@@ -6,6 +6,7 @@ var DEFAULT_DATA_TABLE_LABELS = {
|
|
|
6
6
|
expandRow: "Expand row",
|
|
7
7
|
collapseRow: "Collapse row",
|
|
8
8
|
resizeColumn: "Resize column",
|
|
9
|
+
reorderColumn: "Reorder column",
|
|
9
10
|
searchPlaceholder: "Search\u2026",
|
|
10
11
|
searchResultHint: "Type to search",
|
|
11
12
|
searchPrevious: "Previous result",
|
|
@@ -47,6 +48,7 @@ var DATA_TABLE_VIRTUAL_OVERSCAN = 8;
|
|
|
47
48
|
var DATA_TABLE_COLUMN_SIZE = 150;
|
|
48
49
|
var DATA_TABLE_COLUMN_MIN_SIZE = 40;
|
|
49
50
|
var DATA_TABLE_COLUMN_MAX_SIZE = 800;
|
|
51
|
+
var DATA_TABLE_COLUMN_REORDER_THRESHOLD = 4;
|
|
50
52
|
|
|
51
53
|
// src/components/ui/table/features/cell-edit/useCellEdit.ts
|
|
52
54
|
import { useCallback, useEffect, useRef, useState } from "react";
|
|
@@ -1312,6 +1314,129 @@ function useCellSelection({
|
|
|
1312
1314
|
};
|
|
1313
1315
|
}
|
|
1314
1316
|
|
|
1317
|
+
// src/components/ui/table/features/column-reorder/columnReorder.ts
|
|
1318
|
+
function getColumnDefId(column) {
|
|
1319
|
+
if (column.id != null && column.id !== "") return column.id;
|
|
1320
|
+
if ("accessorKey" in column && column.accessorKey != null) {
|
|
1321
|
+
return String(column.accessorKey);
|
|
1322
|
+
}
|
|
1323
|
+
return void 0;
|
|
1324
|
+
}
|
|
1325
|
+
function getColumnDefChildren(column) {
|
|
1326
|
+
if (!("columns" in column) || !Array.isArray(column.columns)) return void 0;
|
|
1327
|
+
if (column.columns.length === 0) return void 0;
|
|
1328
|
+
return column.columns;
|
|
1329
|
+
}
|
|
1330
|
+
function collectLeafColumnIds(columns) {
|
|
1331
|
+
const ids = [];
|
|
1332
|
+
for (const column of columns) {
|
|
1333
|
+
const children = getColumnDefChildren(column);
|
|
1334
|
+
if (children) {
|
|
1335
|
+
ids.push(...collectLeafColumnIds(children));
|
|
1336
|
+
continue;
|
|
1337
|
+
}
|
|
1338
|
+
const id = getColumnDefId(column);
|
|
1339
|
+
if (id) ids.push(id);
|
|
1340
|
+
}
|
|
1341
|
+
return ids;
|
|
1342
|
+
}
|
|
1343
|
+
function areColumnOrdersEqual(left, right) {
|
|
1344
|
+
if (left.length !== right.length) return false;
|
|
1345
|
+
return left.every((id, index) => id === right[index]);
|
|
1346
|
+
}
|
|
1347
|
+
function resolveLeafColumnOrder(columns, order) {
|
|
1348
|
+
const leafIds = collectLeafColumnIds(columns);
|
|
1349
|
+
if (!order?.length) return leafIds;
|
|
1350
|
+
const leafSet = new Set(leafIds);
|
|
1351
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1352
|
+
const next = order.filter((id) => {
|
|
1353
|
+
if (!leafSet.has(id) || seen.has(id)) return false;
|
|
1354
|
+
seen.add(id);
|
|
1355
|
+
return true;
|
|
1356
|
+
});
|
|
1357
|
+
for (const id of leafIds) {
|
|
1358
|
+
if (!seen.has(id)) next.push(id);
|
|
1359
|
+
}
|
|
1360
|
+
return next;
|
|
1361
|
+
}
|
|
1362
|
+
function flattenColumnSlots(columns, group) {
|
|
1363
|
+
const slots = [];
|
|
1364
|
+
for (const column of columns) {
|
|
1365
|
+
const id = getColumnDefId(column);
|
|
1366
|
+
const children = getColumnDefChildren(column);
|
|
1367
|
+
if (children) {
|
|
1368
|
+
const nestedGroup = id ? { id, def: column } : group;
|
|
1369
|
+
slots.push(...flattenColumnSlots(children, nestedGroup));
|
|
1370
|
+
continue;
|
|
1371
|
+
}
|
|
1372
|
+
if (!id) continue;
|
|
1373
|
+
slots.push({ id, def: column, group });
|
|
1374
|
+
}
|
|
1375
|
+
return slots;
|
|
1376
|
+
}
|
|
1377
|
+
function rebuildColumnTree(slots) {
|
|
1378
|
+
const result = [];
|
|
1379
|
+
let index = 0;
|
|
1380
|
+
while (index < slots.length) {
|
|
1381
|
+
const slot = slots[index];
|
|
1382
|
+
if (!slot.group) {
|
|
1383
|
+
result.push(slot.def);
|
|
1384
|
+
index += 1;
|
|
1385
|
+
continue;
|
|
1386
|
+
}
|
|
1387
|
+
const groupId = slot.group.id;
|
|
1388
|
+
const children = [];
|
|
1389
|
+
while (index < slots.length && slots[index]?.group?.id === groupId) {
|
|
1390
|
+
children.push(slots[index].def);
|
|
1391
|
+
index += 1;
|
|
1392
|
+
}
|
|
1393
|
+
const firstChildId = children[0] ? getColumnDefId(children[0]) : groupId;
|
|
1394
|
+
result.push({
|
|
1395
|
+
...slot.group.def,
|
|
1396
|
+
id: `${groupId}::${firstChildId}`,
|
|
1397
|
+
columns: children
|
|
1398
|
+
});
|
|
1399
|
+
}
|
|
1400
|
+
return result;
|
|
1401
|
+
}
|
|
1402
|
+
function applyLeafColumnOrder(columns, order) {
|
|
1403
|
+
const resolved = resolveLeafColumnOrder(columns, order);
|
|
1404
|
+
const defaultOrder = collectLeafColumnIds(columns);
|
|
1405
|
+
if (areColumnOrdersEqual(resolved, defaultOrder)) {
|
|
1406
|
+
return columns;
|
|
1407
|
+
}
|
|
1408
|
+
const byId = new Map(
|
|
1409
|
+
flattenColumnSlots(columns).map((slot) => [
|
|
1410
|
+
slot.id,
|
|
1411
|
+
slot
|
|
1412
|
+
])
|
|
1413
|
+
);
|
|
1414
|
+
const ordered = [];
|
|
1415
|
+
for (const id of resolved) {
|
|
1416
|
+
const slot = byId.get(id);
|
|
1417
|
+
if (slot) ordered.push(slot);
|
|
1418
|
+
}
|
|
1419
|
+
return rebuildColumnTree(ordered);
|
|
1420
|
+
}
|
|
1421
|
+
function moveColumnIds(order, fromIds, targetIds, edge) {
|
|
1422
|
+
if (fromIds.length === 0 || targetIds.length === 0) return [...order];
|
|
1423
|
+
const fromSet = new Set(fromIds);
|
|
1424
|
+
if (targetIds.some((id) => fromSet.has(id))) return [...order];
|
|
1425
|
+
const rest = order.filter((id) => !fromSet.has(id));
|
|
1426
|
+
const anchorId = edge === "before" ? targetIds[0] : targetIds[targetIds.length - 1];
|
|
1427
|
+
const anchorIndex = rest.indexOf(anchorId);
|
|
1428
|
+
if (anchorIndex < 0) return [...order];
|
|
1429
|
+
const insertAt = edge === "before" ? anchorIndex : anchorIndex + 1;
|
|
1430
|
+
return [...rest.slice(0, insertAt), ...fromIds, ...rest.slice(insertAt)];
|
|
1431
|
+
}
|
|
1432
|
+
function resolveDropEdge(clientX, rect) {
|
|
1433
|
+
return clientX < rect.left + rect.width / 2 ? "before" : "after";
|
|
1434
|
+
}
|
|
1435
|
+
function parseReorderIds(value) {
|
|
1436
|
+
if (!value) return [];
|
|
1437
|
+
return value.split(",").filter(Boolean);
|
|
1438
|
+
}
|
|
1439
|
+
|
|
1315
1440
|
// src/components/ui/table/features/column-freeze/columnFreeze.ts
|
|
1316
1441
|
var HEADER_Z_BASE = 30;
|
|
1317
1442
|
var BODY_Z_BASE = 5;
|
|
@@ -2085,23 +2210,49 @@ function applySelectionUpdater(mode, updater, previous) {
|
|
|
2085
2210
|
function getRowFieldValue(row, key) {
|
|
2086
2211
|
return row[key];
|
|
2087
2212
|
}
|
|
2088
|
-
function
|
|
2213
|
+
function normalizeRowSpanParent(value) {
|
|
2214
|
+
if (!value) return [];
|
|
2215
|
+
return typeof value === "string" ? [value] : [...value];
|
|
2216
|
+
}
|
|
2217
|
+
function toParentSpanList(parentSpans) {
|
|
2218
|
+
if (!parentSpans?.length) return [];
|
|
2219
|
+
const first = parentSpans[0];
|
|
2220
|
+
if (!Array.isArray(first)) {
|
|
2221
|
+
return [parentSpans];
|
|
2222
|
+
}
|
|
2223
|
+
return parentSpans;
|
|
2224
|
+
}
|
|
2225
|
+
function buildStartRowLookup(spans) {
|
|
2226
|
+
const startRows = new Array(spans.length);
|
|
2227
|
+
let origin = 0;
|
|
2228
|
+
for (let i = 0; i < spans.length; i++) {
|
|
2229
|
+
if ((spans[i]?.rowSpan ?? 1) > 0) origin = i;
|
|
2230
|
+
startRows[i] = origin;
|
|
2231
|
+
}
|
|
2232
|
+
return startRows;
|
|
2233
|
+
}
|
|
2234
|
+
function sharesParentGroup(parentStartRows, rowIndex) {
|
|
2235
|
+
if (parentStartRows.length === 0 || rowIndex <= 0) return true;
|
|
2236
|
+
return parentStartRows.every(
|
|
2237
|
+
(startRows) => startRows[rowIndex - 1] === startRows[rowIndex]
|
|
2238
|
+
);
|
|
2239
|
+
}
|
|
2240
|
+
function computeRowSpans(data, rowSpanKey, parentSpans) {
|
|
2089
2241
|
if (data.length === 0) return [];
|
|
2242
|
+
const parentStartRows = toParentSpanList(parentSpans).map(buildStartRowLookup);
|
|
2090
2243
|
const result = [];
|
|
2091
2244
|
for (let index = 0; index < data.length; index++) {
|
|
2092
2245
|
const currentValue = getRowFieldValue(data[index], rowSpanKey);
|
|
2093
2246
|
const previousValue = index > 0 ? getRowFieldValue(data[index - 1], rowSpanKey) : void 0;
|
|
2094
|
-
if (index > 0 && currentValue === previousValue) {
|
|
2247
|
+
if (index > 0 && currentValue === previousValue && sharesParentGroup(parentStartRows, index)) {
|
|
2095
2248
|
result.push({ rowSpan: 0, isFirstInGroup: false });
|
|
2096
2249
|
continue;
|
|
2097
2250
|
}
|
|
2098
2251
|
let span = 1;
|
|
2099
2252
|
for (let nextIndex = index + 1; nextIndex < data.length; nextIndex++) {
|
|
2100
|
-
if (getRowFieldValue(data[nextIndex], rowSpanKey)
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
break;
|
|
2104
|
-
}
|
|
2253
|
+
if (getRowFieldValue(data[nextIndex], rowSpanKey) !== currentValue) break;
|
|
2254
|
+
if (!sharesParentGroup(parentStartRows, nextIndex)) break;
|
|
2255
|
+
span++;
|
|
2105
2256
|
}
|
|
2106
2257
|
result.push({ rowSpan: span, isFirstInGroup: true });
|
|
2107
2258
|
}
|
|
@@ -2123,10 +2274,50 @@ function resolveRowSpanAt(rowSpans, rowIndex) {
|
|
|
2123
2274
|
}
|
|
2124
2275
|
return { startRow: rowIndex, rowSpan: 1 };
|
|
2125
2276
|
}
|
|
2277
|
+
function findRowSpanColumn(spec, ref) {
|
|
2278
|
+
return spec.find((column) => column.columnId === ref) ?? spec.find((column) => column.rowSpanKey === ref);
|
|
2279
|
+
}
|
|
2126
2280
|
function buildColumnRowSpanMap(data, columnKeys) {
|
|
2127
2281
|
const map = /* @__PURE__ */ new Map();
|
|
2128
|
-
|
|
2129
|
-
|
|
2282
|
+
const visiting = /* @__PURE__ */ new Set();
|
|
2283
|
+
const warnedCycles = /* @__PURE__ */ new Set();
|
|
2284
|
+
const virtualParents = /* @__PURE__ */ new Map();
|
|
2285
|
+
const spansForColumn = (columnId) => {
|
|
2286
|
+
const cached = map.get(columnId);
|
|
2287
|
+
if (cached !== void 0) return cached;
|
|
2288
|
+
const column = columnKeys.find((item) => item.columnId === columnId);
|
|
2289
|
+
if (!column) return void 0;
|
|
2290
|
+
if (visiting.has(columnId)) {
|
|
2291
|
+
if (!warnedCycles.has(columnId)) {
|
|
2292
|
+
warnedCycles.add(columnId);
|
|
2293
|
+
console.warn(
|
|
2294
|
+
`[rowSpan] rowSpanParent cycle detected at column "${columnId}"; dropping the cyclic parent reference.`
|
|
2295
|
+
);
|
|
2296
|
+
}
|
|
2297
|
+
return void 0;
|
|
2298
|
+
}
|
|
2299
|
+
visiting.add(columnId);
|
|
2300
|
+
const parentSpans = (column.rowSpanParent ?? []).map((ref) => spansForParentRef(ref)).filter((spans2) => Boolean(spans2));
|
|
2301
|
+
visiting.delete(columnId);
|
|
2302
|
+
const spans = computeRowSpans(
|
|
2303
|
+
data,
|
|
2304
|
+
column.rowSpanKey,
|
|
2305
|
+
parentSpans.length > 0 ? parentSpans : void 0
|
|
2306
|
+
);
|
|
2307
|
+
map.set(columnId, spans);
|
|
2308
|
+
return spans;
|
|
2309
|
+
};
|
|
2310
|
+
const spansForParentRef = (ref) => {
|
|
2311
|
+
const parentColumn = findRowSpanColumn(columnKeys, ref);
|
|
2312
|
+
if (parentColumn) return spansForColumn(parentColumn.columnId);
|
|
2313
|
+
const cached = virtualParents.get(ref);
|
|
2314
|
+
if (cached !== void 0) return cached;
|
|
2315
|
+
const spans = computeRowSpans(data, ref);
|
|
2316
|
+
virtualParents.set(ref, spans);
|
|
2317
|
+
return spans;
|
|
2318
|
+
};
|
|
2319
|
+
for (const column of columnKeys) {
|
|
2320
|
+
spansForColumn(column.columnId);
|
|
2130
2321
|
}
|
|
2131
2322
|
return map;
|
|
2132
2323
|
}
|
|
@@ -2142,7 +2333,8 @@ function collectRowSpanColumns(columns) {
|
|
|
2142
2333
|
if (!columnId || !columnDef.meta?.rowSpan) continue;
|
|
2143
2334
|
result.push({
|
|
2144
2335
|
columnId,
|
|
2145
|
-
rowSpanKey: columnDef.meta.rowSpanKey ?? columnId
|
|
2336
|
+
rowSpanKey: columnDef.meta.rowSpanKey ?? columnId,
|
|
2337
|
+
rowSpanParent: normalizeRowSpanParent(columnDef.meta.rowSpanParent)
|
|
2146
2338
|
});
|
|
2147
2339
|
}
|
|
2148
2340
|
};
|
|
@@ -2194,6 +2386,9 @@ function useGlideTable(options) {
|
|
|
2194
2386
|
columnSizing: controlledColumnSizing,
|
|
2195
2387
|
onColumnSizingChange,
|
|
2196
2388
|
columnResizeMode = "onChange",
|
|
2389
|
+
enableColumnReorder = false,
|
|
2390
|
+
columnOrder: controlledColumnOrder,
|
|
2391
|
+
onColumnOrderChange,
|
|
2197
2392
|
enableColumnFreeze = false,
|
|
2198
2393
|
enableInlineSearch = false,
|
|
2199
2394
|
showSearch,
|
|
@@ -2216,6 +2411,7 @@ function useGlideTable(options) {
|
|
|
2216
2411
|
const resolvedEnableSubtreeCopy = enableSubtreeCopy ?? enableExpand;
|
|
2217
2412
|
const [internalRowSelection, setInternalRowSelection] = useState4({});
|
|
2218
2413
|
const [internalColumnSizing, setInternalColumnSizing] = useState4({});
|
|
2414
|
+
const [internalColumnOrder, setInternalColumnOrder] = useState4([]);
|
|
2219
2415
|
const [internalExpandedRows, setInternalExpandedRows] = useState4(
|
|
2220
2416
|
() => /* @__PURE__ */ new Set()
|
|
2221
2417
|
);
|
|
@@ -2236,6 +2432,21 @@ function useGlideTable(options) {
|
|
|
2236
2432
|
internalRowSelection
|
|
2237
2433
|
);
|
|
2238
2434
|
const columnSizing = controlledColumnSizing ?? internalColumnSizing;
|
|
2435
|
+
const columnOrder = controlledColumnOrder ?? internalColumnOrder;
|
|
2436
|
+
const tableColumns = useMemo3(() => {
|
|
2437
|
+
if (!enableColumnReorder) return columns;
|
|
2438
|
+
return applyLeafColumnOrder(columns, columnOrder);
|
|
2439
|
+
}, [columnOrder, columns, enableColumnReorder]);
|
|
2440
|
+
const setColumnOrder = useCallback4(
|
|
2441
|
+
(next) => {
|
|
2442
|
+
if (onColumnOrderChange) {
|
|
2443
|
+
onColumnOrderChange(next);
|
|
2444
|
+
return;
|
|
2445
|
+
}
|
|
2446
|
+
setInternalColumnOrder(next);
|
|
2447
|
+
},
|
|
2448
|
+
[onColumnOrderChange]
|
|
2449
|
+
);
|
|
2239
2450
|
const expandedRows = controlledExpandedRows ?? internalExpandedRows;
|
|
2240
2451
|
const handleExpandedRowsChange = useCallback4(
|
|
2241
2452
|
(next) => {
|
|
@@ -2260,7 +2471,7 @@ function useGlideTable(options) {
|
|
|
2260
2471
|
});
|
|
2261
2472
|
const table = useReactTable({
|
|
2262
2473
|
data: tableData,
|
|
2263
|
-
columns,
|
|
2474
|
+
columns: tableColumns,
|
|
2264
2475
|
...enableColumnResize ? {
|
|
2265
2476
|
defaultColumn: {
|
|
2266
2477
|
minSize: DATA_TABLE_COLUMN_MIN_SIZE,
|
|
@@ -2742,6 +2953,7 @@ function useGlideTable(options) {
|
|
|
2742
2953
|
selectionLabel: labels.selection,
|
|
2743
2954
|
enableCellSelection,
|
|
2744
2955
|
enableColumnResize,
|
|
2956
|
+
enableColumnReorder,
|
|
2745
2957
|
enableColumnFreeze,
|
|
2746
2958
|
enableInlineSearch,
|
|
2747
2959
|
shouldVirtualize,
|
|
@@ -2755,6 +2967,7 @@ function useGlideTable(options) {
|
|
|
2755
2967
|
getCellContext,
|
|
2756
2968
|
handleToggleSelect,
|
|
2757
2969
|
clearHover,
|
|
2970
|
+
setColumnOrder,
|
|
2758
2971
|
copySelection: stableCopySelection,
|
|
2759
2972
|
inlineSearch: {
|
|
2760
2973
|
showSearch: inlineSearch.showSearch,
|
|
@@ -2833,6 +3046,219 @@ function getColumnSizeStyle(size, options) {
|
|
|
2833
3046
|
...lockMax ? { maxWidth: size } : {}
|
|
2834
3047
|
};
|
|
2835
3048
|
}
|
|
3049
|
+
|
|
3050
|
+
// src/components/ui/table/features/column-reorder/useColumnReorder.ts
|
|
3051
|
+
import {
|
|
3052
|
+
useCallback as useCallback6,
|
|
3053
|
+
useEffect as useEffect6,
|
|
3054
|
+
useRef as useRef6,
|
|
3055
|
+
useState as useState5
|
|
3056
|
+
} from "react";
|
|
3057
|
+
function hitTestReorderHeader(table, clientX, clientY) {
|
|
3058
|
+
const headers = Array.from(
|
|
3059
|
+
table.querySelectorAll(
|
|
3060
|
+
"thead th[data-column-id][data-reorder-ids]"
|
|
3061
|
+
)
|
|
3062
|
+
);
|
|
3063
|
+
const containing = headers.find((element) => {
|
|
3064
|
+
const rect = element.getBoundingClientRect();
|
|
3065
|
+
return clientX >= rect.left && clientX <= rect.right && clientY >= rect.top && clientY <= rect.bottom;
|
|
3066
|
+
});
|
|
3067
|
+
if (containing) {
|
|
3068
|
+
return {
|
|
3069
|
+
columnId: containing.dataset.columnId ?? "",
|
|
3070
|
+
edge: resolveDropEdge(clientX, containing.getBoundingClientRect())
|
|
3071
|
+
};
|
|
3072
|
+
}
|
|
3073
|
+
const leaves = headers.filter(
|
|
3074
|
+
(element) => element.hasAttribute("data-reorder-leaf")
|
|
3075
|
+
);
|
|
3076
|
+
let match;
|
|
3077
|
+
for (const element of leaves) {
|
|
3078
|
+
const rect = element.getBoundingClientRect();
|
|
3079
|
+
if (clientX >= rect.left && clientX <= rect.right) {
|
|
3080
|
+
match = element;
|
|
3081
|
+
break;
|
|
3082
|
+
}
|
|
3083
|
+
}
|
|
3084
|
+
if (!match && leaves.length > 0) {
|
|
3085
|
+
const first = leaves[0].getBoundingClientRect();
|
|
3086
|
+
const last = leaves[leaves.length - 1].getBoundingClientRect();
|
|
3087
|
+
if (clientX < first.left) match = leaves[0];
|
|
3088
|
+
else if (clientX > last.right) match = leaves[leaves.length - 1];
|
|
3089
|
+
}
|
|
3090
|
+
if (!match) return null;
|
|
3091
|
+
return {
|
|
3092
|
+
columnId: match.dataset.columnId ?? "",
|
|
3093
|
+
edge: resolveDropEdge(clientX, match.getBoundingClientRect())
|
|
3094
|
+
};
|
|
3095
|
+
}
|
|
3096
|
+
function readTargetIds(table, columnId) {
|
|
3097
|
+
const element = table.querySelector(
|
|
3098
|
+
`thead th[data-column-id="${CSS.escape(columnId)}"]`
|
|
3099
|
+
);
|
|
3100
|
+
return parseReorderIds(element?.getAttribute("data-reorder-ids"));
|
|
3101
|
+
}
|
|
3102
|
+
function useColumnReorder(options) {
|
|
3103
|
+
const { enabled, columnOrder, onColumnOrderChange } = options;
|
|
3104
|
+
const sessionRef = useRef6(null);
|
|
3105
|
+
const columnOrderRef = useRef6(columnOrder);
|
|
3106
|
+
const onColumnOrderChangeRef = useRef6(onColumnOrderChange);
|
|
3107
|
+
const [draggingColumnId, setDraggingColumnId] = useState5(null);
|
|
3108
|
+
const [dropTarget, setDropTarget] = useState5(
|
|
3109
|
+
null
|
|
3110
|
+
);
|
|
3111
|
+
const dropTargetRef = useRef6(dropTarget);
|
|
3112
|
+
const previousUserSelectRef = useRef6(null);
|
|
3113
|
+
columnOrderRef.current = columnOrder;
|
|
3114
|
+
onColumnOrderChangeRef.current = onColumnOrderChange;
|
|
3115
|
+
dropTargetRef.current = dropTarget;
|
|
3116
|
+
const resetDrag = useCallback6(() => {
|
|
3117
|
+
sessionRef.current = null;
|
|
3118
|
+
setDraggingColumnId(null);
|
|
3119
|
+
setDropTarget(null);
|
|
3120
|
+
const backup = previousUserSelectRef.current;
|
|
3121
|
+
previousUserSelectRef.current = null;
|
|
3122
|
+
if (backup) {
|
|
3123
|
+
if (backup.value) {
|
|
3124
|
+
document.body.style.setProperty("user-select", backup.value, backup.priority);
|
|
3125
|
+
} else {
|
|
3126
|
+
document.body.style.removeProperty("user-select");
|
|
3127
|
+
}
|
|
3128
|
+
return;
|
|
3129
|
+
}
|
|
3130
|
+
document.body.style.removeProperty("user-select");
|
|
3131
|
+
}, []);
|
|
3132
|
+
useEffect6(() => {
|
|
3133
|
+
if (!enabled) resetDrag();
|
|
3134
|
+
}, [enabled, resetDrag]);
|
|
3135
|
+
useEffect6(() => {
|
|
3136
|
+
return () => {
|
|
3137
|
+
resetDrag();
|
|
3138
|
+
};
|
|
3139
|
+
}, [resetDrag]);
|
|
3140
|
+
const onHeaderPointerDown = useCallback6(
|
|
3141
|
+
(event, meta) => {
|
|
3142
|
+
if (!enabled || !meta.canDrag) return;
|
|
3143
|
+
if (event.button !== 0) return;
|
|
3144
|
+
if (event.pointerType === "mouse" && event.ctrlKey) return;
|
|
3145
|
+
const target = event.target;
|
|
3146
|
+
if (target instanceof Element && target.closest("[data-table-disable-cell-selection]")) {
|
|
3147
|
+
return;
|
|
3148
|
+
}
|
|
3149
|
+
const table = event.currentTarget.closest("table");
|
|
3150
|
+
if (!(table instanceof HTMLTableElement)) return;
|
|
3151
|
+
sessionRef.current = {
|
|
3152
|
+
pointerId: event.pointerId,
|
|
3153
|
+
startX: event.clientX,
|
|
3154
|
+
startY: event.clientY,
|
|
3155
|
+
columnId: meta.columnId,
|
|
3156
|
+
fromIds: meta.leafIds,
|
|
3157
|
+
table,
|
|
3158
|
+
active: false
|
|
3159
|
+
};
|
|
3160
|
+
},
|
|
3161
|
+
[enabled]
|
|
3162
|
+
);
|
|
3163
|
+
useEffect6(() => {
|
|
3164
|
+
if (!enabled) return;
|
|
3165
|
+
const onPointerMove = (event) => {
|
|
3166
|
+
const session = sessionRef.current;
|
|
3167
|
+
if (!session || event.pointerId !== session.pointerId) return;
|
|
3168
|
+
const deltaX = event.clientX - session.startX;
|
|
3169
|
+
const deltaY = event.clientY - session.startY;
|
|
3170
|
+
const distance = Math.hypot(deltaX, deltaY);
|
|
3171
|
+
if (!session.active) {
|
|
3172
|
+
if (distance < DATA_TABLE_COLUMN_REORDER_THRESHOLD) return;
|
|
3173
|
+
session.active = true;
|
|
3174
|
+
if (!previousUserSelectRef.current) {
|
|
3175
|
+
previousUserSelectRef.current = {
|
|
3176
|
+
value: document.body.style.getPropertyValue("user-select"),
|
|
3177
|
+
priority: document.body.style.getPropertyPriority("user-select")
|
|
3178
|
+
};
|
|
3179
|
+
}
|
|
3180
|
+
document.body.style.setProperty("user-select", "none");
|
|
3181
|
+
setDraggingColumnId(session.columnId);
|
|
3182
|
+
}
|
|
3183
|
+
event.preventDefault();
|
|
3184
|
+
const nextTarget = hitTestReorderHeader(
|
|
3185
|
+
session.table,
|
|
3186
|
+
event.clientX,
|
|
3187
|
+
event.clientY
|
|
3188
|
+
);
|
|
3189
|
+
if (!nextTarget || !nextTarget.columnId) {
|
|
3190
|
+
setDropTarget(null);
|
|
3191
|
+
return;
|
|
3192
|
+
}
|
|
3193
|
+
const targetIds = readTargetIds(session.table, nextTarget.columnId);
|
|
3194
|
+
const fromSet = new Set(session.fromIds);
|
|
3195
|
+
if (targetIds.some((id) => fromSet.has(id))) {
|
|
3196
|
+
setDropTarget(null);
|
|
3197
|
+
return;
|
|
3198
|
+
}
|
|
3199
|
+
setDropTarget((previous) => {
|
|
3200
|
+
if (previous?.columnId === nextTarget.columnId && previous.edge === nextTarget.edge) {
|
|
3201
|
+
return previous;
|
|
3202
|
+
}
|
|
3203
|
+
return nextTarget;
|
|
3204
|
+
});
|
|
3205
|
+
};
|
|
3206
|
+
const onPointerUp = (event) => {
|
|
3207
|
+
const session = sessionRef.current;
|
|
3208
|
+
if (!session || event.pointerId !== session.pointerId) {
|
|
3209
|
+
return;
|
|
3210
|
+
}
|
|
3211
|
+
if (session.active) {
|
|
3212
|
+
event.preventDefault();
|
|
3213
|
+
const target = dropTargetRef.current;
|
|
3214
|
+
if (target) {
|
|
3215
|
+
const targetIds = readTargetIds(session.table, target.columnId);
|
|
3216
|
+
const next = moveColumnIds(
|
|
3217
|
+
columnOrderRef.current,
|
|
3218
|
+
session.fromIds,
|
|
3219
|
+
targetIds,
|
|
3220
|
+
target.edge
|
|
3221
|
+
);
|
|
3222
|
+
onColumnOrderChangeRef.current(next);
|
|
3223
|
+
}
|
|
3224
|
+
const suppressClick = (clickEvent) => {
|
|
3225
|
+
clickEvent.preventDefault();
|
|
3226
|
+
clickEvent.stopPropagation();
|
|
3227
|
+
document.removeEventListener("click", suppressClick, true);
|
|
3228
|
+
};
|
|
3229
|
+
document.addEventListener("click", suppressClick, true);
|
|
3230
|
+
window.setTimeout(() => {
|
|
3231
|
+
document.removeEventListener("click", suppressClick, true);
|
|
3232
|
+
}, 0);
|
|
3233
|
+
}
|
|
3234
|
+
resetDrag();
|
|
3235
|
+
};
|
|
3236
|
+
const onPointerCancel = (event) => {
|
|
3237
|
+
const session = sessionRef.current;
|
|
3238
|
+
if (!session || event.pointerId !== session.pointerId) {
|
|
3239
|
+
return;
|
|
3240
|
+
}
|
|
3241
|
+
if (session.active) {
|
|
3242
|
+
event.preventDefault();
|
|
3243
|
+
}
|
|
3244
|
+
resetDrag();
|
|
3245
|
+
};
|
|
3246
|
+
document.addEventListener("pointermove", onPointerMove);
|
|
3247
|
+
document.addEventListener("pointerup", onPointerUp);
|
|
3248
|
+
document.addEventListener("pointercancel", onPointerCancel);
|
|
3249
|
+
return () => {
|
|
3250
|
+
document.removeEventListener("pointermove", onPointerMove);
|
|
3251
|
+
document.removeEventListener("pointerup", onPointerUp);
|
|
3252
|
+
document.removeEventListener("pointercancel", onPointerCancel);
|
|
3253
|
+
};
|
|
3254
|
+
}, [enabled, resetDrag]);
|
|
3255
|
+
return {
|
|
3256
|
+
isReordering: draggingColumnId != null,
|
|
3257
|
+
draggingColumnId,
|
|
3258
|
+
dropTarget,
|
|
3259
|
+
onHeaderPointerDown
|
|
3260
|
+
};
|
|
3261
|
+
}
|
|
2836
3262
|
export {
|
|
2837
3263
|
BUILTIN_CELL_RENDERERS,
|
|
2838
3264
|
CELL_SELECTION_EDGES_CLASS,
|
|
@@ -2845,6 +3271,7 @@ export {
|
|
|
2845
3271
|
ResolvedTableCell,
|
|
2846
3272
|
applyCellEdit,
|
|
2847
3273
|
applyFillData,
|
|
3274
|
+
applyLeafColumnOrder,
|
|
2848
3275
|
applySelectionUpdater,
|
|
2849
3276
|
buildColumnFreezeOffsets,
|
|
2850
3277
|
buildColumnRowSpanMap,
|
|
@@ -2859,6 +3286,7 @@ export {
|
|
|
2859
3286
|
collectCopyRowEntries,
|
|
2860
3287
|
collectCopyRows,
|
|
2861
3288
|
collectFillChanges,
|
|
3289
|
+
collectLeafColumnIds,
|
|
2862
3290
|
collectRowSpanColumns,
|
|
2863
3291
|
collectSearchMatchesInRange,
|
|
2864
3292
|
commitCellValue,
|
|
@@ -2883,6 +3311,7 @@ export {
|
|
|
2883
3311
|
mapSearchResultToVisibleItem,
|
|
2884
3312
|
mapSearchResultsToVisibleKeys,
|
|
2885
3313
|
measureMergedSpanRowHeights,
|
|
3314
|
+
moveColumnIds,
|
|
2886
3315
|
nextSearchIndex,
|
|
2887
3316
|
nextSearchStride,
|
|
2888
3317
|
parseCellEditValue,
|
|
@@ -2892,7 +3321,9 @@ export {
|
|
|
2892
3321
|
resolveCellRenderer,
|
|
2893
3322
|
resolveColumnFreezeSide,
|
|
2894
3323
|
resolveDataTableLabels,
|
|
3324
|
+
resolveDropEdge,
|
|
2895
3325
|
resolveHeaderFreezeOffset,
|
|
3326
|
+
resolveLeafColumnOrder,
|
|
2896
3327
|
resolvePasteColumnIds,
|
|
2897
3328
|
resolveRowSelection,
|
|
2898
3329
|
resolveRowSpanAt,
|
|
@@ -2902,6 +3333,7 @@ export {
|
|
|
2902
3333
|
toggleExpandedRowId,
|
|
2903
3334
|
useCellEdit,
|
|
2904
3335
|
useCellSelection,
|
|
3336
|
+
useColumnReorder,
|
|
2905
3337
|
useConvertTreeData,
|
|
2906
3338
|
useGlideTable,
|
|
2907
3339
|
useInlineSearch,
|