react-glide-table 2.3.0 → 2.3.2
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 +27 -0
- package/dist/compound.cjs +219 -105
- package/dist/compound.d.cts +2 -2
- package/dist/compound.d.ts +2 -2
- package/dist/compound.js +219 -105
- package/dist/core.cjs +219 -107
- package/dist/core.d.cts +3 -2
- package/dist/core.d.ts +3 -2
- package/dist/core.js +219 -107
- package/dist/index.cjs +222 -108
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +222 -108
- package/dist/{types-DdeVn-9s.d.cts → types-hf2ruVdu.d.cts} +25 -1
- package/dist/{types-DdeVn-9s.d.ts → types-hf2ruVdu.d.ts} +25 -1
- package/package.json +1 -1
package/dist/core.js
CHANGED
|
@@ -432,9 +432,126 @@ function withCellUpdate(context, commitValue) {
|
|
|
432
432
|
};
|
|
433
433
|
}
|
|
434
434
|
|
|
435
|
+
// src/components/ui/table/features/cell-selection/pasteData.ts
|
|
436
|
+
function countLeadingEmptyCells(cells) {
|
|
437
|
+
let depth = 0;
|
|
438
|
+
while (depth < cells.length && cells[depth] === "") {
|
|
439
|
+
depth += 1;
|
|
440
|
+
}
|
|
441
|
+
return depth;
|
|
442
|
+
}
|
|
443
|
+
function looksLikeSubtreeIndentation(leadingEmptyCounts) {
|
|
444
|
+
if (leadingEmptyCounts.length === 0) return false;
|
|
445
|
+
const firstDepth = leadingEmptyCounts[0] ?? 0;
|
|
446
|
+
if (firstDepth !== 0) return false;
|
|
447
|
+
return leadingEmptyCounts.some((depth) => depth > 0);
|
|
448
|
+
}
|
|
449
|
+
function parseClipboardTSV(text) {
|
|
450
|
+
return parseClipboardTSVWithDepths(text).values;
|
|
451
|
+
}
|
|
452
|
+
function parseClipboardTSVWithDepths(text) {
|
|
453
|
+
if (!text) return { values: [], depths: [] };
|
|
454
|
+
const normalized = text.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
455
|
+
const withoutTrailing = normalized.replace(/\n+$/, "");
|
|
456
|
+
if (!withoutTrailing) return { values: [], depths: [] };
|
|
457
|
+
const rows = withoutTrailing.split("\n").map((line) => line.split(" "));
|
|
458
|
+
const leadingEmptyCounts = rows.map(countLeadingEmptyCells);
|
|
459
|
+
const treatAsDepth = looksLikeSubtreeIndentation(leadingEmptyCounts);
|
|
460
|
+
const values = [];
|
|
461
|
+
const depths = [];
|
|
462
|
+
for (let index = 0; index < rows.length; index += 1) {
|
|
463
|
+
const cells = rows[index] ?? [];
|
|
464
|
+
const depth = leadingEmptyCounts[index] ?? 0;
|
|
465
|
+
if (treatAsDepth) {
|
|
466
|
+
values.push(cells.slice(depth));
|
|
467
|
+
depths.push(depth);
|
|
468
|
+
} else {
|
|
469
|
+
values.push(cells);
|
|
470
|
+
depths.push(0);
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
return { values, depths };
|
|
474
|
+
}
|
|
475
|
+
function resolvePasteColumnIds(rows, startCol, width) {
|
|
476
|
+
if (width <= 0) return [];
|
|
477
|
+
const cells = rows[0]?.getVisibleCells() ?? [];
|
|
478
|
+
const columnIds = [];
|
|
479
|
+
for (let offset = 0; offset < width; offset += 1) {
|
|
480
|
+
const cell = cells[startCol + offset];
|
|
481
|
+
if (!cell) break;
|
|
482
|
+
columnIds.push(cell.column.id);
|
|
483
|
+
}
|
|
484
|
+
return columnIds;
|
|
485
|
+
}
|
|
486
|
+
function buildRowsPastePayload(rows, startRow, startCol, text, mode, endRow = startRow) {
|
|
487
|
+
const { values, depths } = parseClipboardTSVWithDepths(text);
|
|
488
|
+
if (values.length === 0) return null;
|
|
489
|
+
const width = Math.max(...values.map((row) => row.length), 0);
|
|
490
|
+
if (width === 0) return null;
|
|
491
|
+
const columnIds = resolvePasteColumnIds(rows, startCol, width);
|
|
492
|
+
if (columnIds.length === 0) return null;
|
|
493
|
+
const rowIds = [];
|
|
494
|
+
for (let offset = 0; offset < values.length; offset += 1) {
|
|
495
|
+
const row = rows[startRow + offset];
|
|
496
|
+
if (!row) break;
|
|
497
|
+
rowIds.push(row.id);
|
|
498
|
+
}
|
|
499
|
+
const anchorRow = rows[endRow] ?? rows[startRow];
|
|
500
|
+
return {
|
|
501
|
+
mode,
|
|
502
|
+
startRow,
|
|
503
|
+
startCol,
|
|
504
|
+
endRow,
|
|
505
|
+
rowIds,
|
|
506
|
+
anchorRowId: anchorRow?.id ?? "",
|
|
507
|
+
columnIds,
|
|
508
|
+
values,
|
|
509
|
+
depths
|
|
510
|
+
};
|
|
511
|
+
}
|
|
512
|
+
function isEditablePasteTarget(target) {
|
|
513
|
+
if (!(target instanceof HTMLElement)) return false;
|
|
514
|
+
const tag = target.tagName;
|
|
515
|
+
if (tag === "INPUT" || tag === "TEXTAREA" || tag === "SELECT") return true;
|
|
516
|
+
return Boolean(target.isContentEditable);
|
|
517
|
+
}
|
|
518
|
+
|
|
435
519
|
// src/components/ui/table/features/cell-selection/useCellSelection.ts
|
|
436
520
|
import { useCallback as useCallback2, useEffect as useEffect2, useRef as useRef2, useState as useState2 } from "react";
|
|
437
521
|
|
|
522
|
+
// src/components/ui/table/features/cell-selection/activeCellSelectionOwner.ts
|
|
523
|
+
var activeOwner = null;
|
|
524
|
+
var clearByOwner = /* @__PURE__ */ new Map();
|
|
525
|
+
function createCellSelectionOwner() {
|
|
526
|
+
return /* @__PURE__ */ Symbol("cell-selection-owner");
|
|
527
|
+
}
|
|
528
|
+
function registerCellSelectionOwner(owner, clearSelection) {
|
|
529
|
+
clearByOwner.set(owner, clearSelection);
|
|
530
|
+
return () => {
|
|
531
|
+
clearByOwner.delete(owner);
|
|
532
|
+
if (activeOwner === owner) {
|
|
533
|
+
activeOwner = null;
|
|
534
|
+
}
|
|
535
|
+
};
|
|
536
|
+
}
|
|
537
|
+
function claimCellSelectionOwner(owner) {
|
|
538
|
+
if (activeOwner === owner) return;
|
|
539
|
+
activeOwner = owner;
|
|
540
|
+
for (const [id, clearSelection] of clearByOwner) {
|
|
541
|
+
if (id !== owner) {
|
|
542
|
+
clearSelection();
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
function isActiveCellSelectionOwner(owner) {
|
|
547
|
+
return activeOwner === owner;
|
|
548
|
+
}
|
|
549
|
+
function releaseCellSelectionOwner(owner) {
|
|
550
|
+
if (activeOwner === owner) {
|
|
551
|
+
activeOwner = null;
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
|
|
438
555
|
// src/components/ui/table/features/cell-selection/cellSelection.ts
|
|
439
556
|
var INITIAL_DRAG_STATE = {
|
|
440
557
|
isSelecting: false,
|
|
@@ -912,19 +1029,31 @@ function extractRenderedCopyText(node, value, cellPosition, root) {
|
|
|
912
1029
|
function formatCopyCellText(rowData, columnDef, columnId, visibleRow, fallbackIndex, sourceCell, cellPosition, options) {
|
|
913
1030
|
const meta = columnDef.meta;
|
|
914
1031
|
const value = sourceCell ? sourceCell.getValue() : readRowColumnValue(rowData, columnDef);
|
|
1032
|
+
const row = visibleRow ?? createCopyRenderRow(rowData, fallbackIndex);
|
|
1033
|
+
const ctx = {
|
|
1034
|
+
value,
|
|
1035
|
+
row,
|
|
1036
|
+
index: row.index,
|
|
1037
|
+
columnId,
|
|
1038
|
+
cellProps: meta?.cellProps,
|
|
1039
|
+
update: () => {
|
|
1040
|
+
}
|
|
1041
|
+
};
|
|
1042
|
+
const copyValue = meta?.copyValue;
|
|
1043
|
+
if (typeof copyValue === "function") {
|
|
1044
|
+
try {
|
|
1045
|
+
return sanitizeClipboardCell(copyValue(ctx));
|
|
1046
|
+
} catch {
|
|
1047
|
+
return formatCellValue(value);
|
|
1048
|
+
}
|
|
1049
|
+
}
|
|
1050
|
+
if (copyValue === "value") {
|
|
1051
|
+
return formatCellValue(value);
|
|
1052
|
+
}
|
|
915
1053
|
const cellRender = meta?.cellRender;
|
|
916
1054
|
if (typeof cellRender === "function") {
|
|
917
1055
|
try {
|
|
918
|
-
const
|
|
919
|
-
const node = cellRender({
|
|
920
|
-
value,
|
|
921
|
-
row,
|
|
922
|
-
index: row.index,
|
|
923
|
-
columnId,
|
|
924
|
-
cellProps: meta?.cellProps,
|
|
925
|
-
update: () => {
|
|
926
|
-
}
|
|
927
|
-
});
|
|
1056
|
+
const node = cellRender(ctx);
|
|
928
1057
|
return extractRenderedCopyText(node, value, cellPosition, options?.root);
|
|
929
1058
|
} catch {
|
|
930
1059
|
return formatCellValue(value);
|
|
@@ -932,16 +1061,6 @@ function formatCopyCellText(rowData, columnDef, columnId, visibleRow, fallbackIn
|
|
|
932
1061
|
}
|
|
933
1062
|
if (options?.registry && meta?.kind && isPrimitiveCopyValue(value)) {
|
|
934
1063
|
try {
|
|
935
|
-
const row = visibleRow ?? createCopyRenderRow(rowData, fallbackIndex);
|
|
936
|
-
const ctx = {
|
|
937
|
-
value,
|
|
938
|
-
row,
|
|
939
|
-
index: row.index,
|
|
940
|
-
columnId,
|
|
941
|
-
cellProps: meta.cellProps,
|
|
942
|
-
update: () => {
|
|
943
|
-
}
|
|
944
|
-
};
|
|
945
1064
|
const renderer = resolveCellRenderer(options.registry, meta.kind, ctx);
|
|
946
1065
|
if (renderer) {
|
|
947
1066
|
const node = renderer.render(ctx);
|
|
@@ -1067,11 +1186,16 @@ function serializeCopyRowsToTSV(copyRows, visibleRows, bounds, depths, options)
|
|
|
1067
1186
|
const resolvedDepths = depths && depths.length === copyRows.length ? depths : copyRows.map((row) => getRowDepth(row));
|
|
1068
1187
|
const minDepth = Math.min(...resolvedDepths);
|
|
1069
1188
|
const visibleRowByOriginal = buildVisibleRowLookup(visibleRows);
|
|
1189
|
+
const copyableColumns = columnCells.flatMap((templateCell, colOffset) => {
|
|
1190
|
+
const meta = templateCell.column.columnDef.meta;
|
|
1191
|
+
if (meta?.copyValue === "omit") return [];
|
|
1192
|
+
return [{ templateCell, colOffset }];
|
|
1193
|
+
});
|
|
1070
1194
|
return copyRows.map((rowData, index) => {
|
|
1071
1195
|
const relativeDepth = Math.max(0, (resolvedDepths[index] ?? 0) - minDepth);
|
|
1072
1196
|
const visibleRow = visibleRowByOriginal.get(rowData);
|
|
1073
1197
|
const matchingCells = visibleRow?.getVisibleCells().slice(startCol, endCol + 1);
|
|
1074
|
-
const line =
|
|
1198
|
+
const line = copyableColumns.map(({ templateCell, colOffset }) => {
|
|
1075
1199
|
const sourceCell = matchingCells?.[colOffset];
|
|
1076
1200
|
const column = sourceCell?.column ?? templateCell.column;
|
|
1077
1201
|
return formatCopyCellText(
|
|
@@ -1165,90 +1289,6 @@ function hasFillExtension(sourceBounds, fillBounds) {
|
|
|
1165
1289
|
return fillBounds.startRow < sourceBounds.startRow || fillBounds.endRow > sourceBounds.endRow || fillBounds.startCol < sourceBounds.startCol || fillBounds.endCol > sourceBounds.endCol;
|
|
1166
1290
|
}
|
|
1167
1291
|
|
|
1168
|
-
// src/components/ui/table/features/cell-selection/pasteData.ts
|
|
1169
|
-
function countLeadingEmptyCells(cells) {
|
|
1170
|
-
let depth = 0;
|
|
1171
|
-
while (depth < cells.length && cells[depth] === "") {
|
|
1172
|
-
depth += 1;
|
|
1173
|
-
}
|
|
1174
|
-
return depth;
|
|
1175
|
-
}
|
|
1176
|
-
function looksLikeSubtreeIndentation(leadingEmptyCounts) {
|
|
1177
|
-
if (leadingEmptyCounts.length === 0) return false;
|
|
1178
|
-
const firstDepth = leadingEmptyCounts[0] ?? 0;
|
|
1179
|
-
if (firstDepth !== 0) return false;
|
|
1180
|
-
return leadingEmptyCounts.some((depth) => depth > 0);
|
|
1181
|
-
}
|
|
1182
|
-
function parseClipboardTSV(text) {
|
|
1183
|
-
return parseClipboardTSVWithDepths(text).values;
|
|
1184
|
-
}
|
|
1185
|
-
function parseClipboardTSVWithDepths(text) {
|
|
1186
|
-
if (!text) return { values: [], depths: [] };
|
|
1187
|
-
const normalized = text.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
1188
|
-
const withoutTrailing = normalized.replace(/\n+$/, "");
|
|
1189
|
-
if (!withoutTrailing) return { values: [], depths: [] };
|
|
1190
|
-
const rows = withoutTrailing.split("\n").map((line) => line.split(" "));
|
|
1191
|
-
const leadingEmptyCounts = rows.map(countLeadingEmptyCells);
|
|
1192
|
-
const treatAsDepth = looksLikeSubtreeIndentation(leadingEmptyCounts);
|
|
1193
|
-
const values = [];
|
|
1194
|
-
const depths = [];
|
|
1195
|
-
for (let index = 0; index < rows.length; index += 1) {
|
|
1196
|
-
const cells = rows[index] ?? [];
|
|
1197
|
-
const depth = leadingEmptyCounts[index] ?? 0;
|
|
1198
|
-
if (treatAsDepth) {
|
|
1199
|
-
values.push(cells.slice(depth));
|
|
1200
|
-
depths.push(depth);
|
|
1201
|
-
} else {
|
|
1202
|
-
values.push(cells);
|
|
1203
|
-
depths.push(0);
|
|
1204
|
-
}
|
|
1205
|
-
}
|
|
1206
|
-
return { values, depths };
|
|
1207
|
-
}
|
|
1208
|
-
function resolvePasteColumnIds(rows, startCol, width) {
|
|
1209
|
-
if (width <= 0) return [];
|
|
1210
|
-
const cells = rows[0]?.getVisibleCells() ?? [];
|
|
1211
|
-
const columnIds = [];
|
|
1212
|
-
for (let offset = 0; offset < width; offset += 1) {
|
|
1213
|
-
const cell = cells[startCol + offset];
|
|
1214
|
-
if (!cell) break;
|
|
1215
|
-
columnIds.push(cell.column.id);
|
|
1216
|
-
}
|
|
1217
|
-
return columnIds;
|
|
1218
|
-
}
|
|
1219
|
-
function buildRowsPastePayload(rows, startRow, startCol, text, mode, endRow = startRow) {
|
|
1220
|
-
const { values, depths } = parseClipboardTSVWithDepths(text);
|
|
1221
|
-
if (values.length === 0) return null;
|
|
1222
|
-
const width = Math.max(...values.map((row) => row.length), 0);
|
|
1223
|
-
if (width === 0) return null;
|
|
1224
|
-
const columnIds = resolvePasteColumnIds(rows, startCol, width);
|
|
1225
|
-
if (columnIds.length === 0) return null;
|
|
1226
|
-
const rowIds = [];
|
|
1227
|
-
for (let offset = 0; offset < values.length; offset += 1) {
|
|
1228
|
-
const row = rows[startRow + offset];
|
|
1229
|
-
if (!row) break;
|
|
1230
|
-
rowIds.push(row.id);
|
|
1231
|
-
}
|
|
1232
|
-
const anchorRow = rows[endRow] ?? rows[startRow];
|
|
1233
|
-
return {
|
|
1234
|
-
mode,
|
|
1235
|
-
startRow,
|
|
1236
|
-
startCol,
|
|
1237
|
-
endRow,
|
|
1238
|
-
rowIds,
|
|
1239
|
-
anchorRowId: anchorRow?.id ?? "",
|
|
1240
|
-
columnIds,
|
|
1241
|
-
values,
|
|
1242
|
-
depths
|
|
1243
|
-
};
|
|
1244
|
-
}
|
|
1245
|
-
function isEditablePasteTarget(target) {
|
|
1246
|
-
if (!(target instanceof HTMLElement)) return false;
|
|
1247
|
-
const tag = target.tagName;
|
|
1248
|
-
if (tag === "INPUT" || tag === "TEXTAREA" || tag === "SELECT") return true;
|
|
1249
|
-
return Boolean(target.isContentEditable);
|
|
1250
|
-
}
|
|
1251
|
-
|
|
1252
1292
|
// src/components/ui/table/features/cell-selection/useCellSelection.ts
|
|
1253
1293
|
function useCellSelection({
|
|
1254
1294
|
data,
|
|
@@ -1264,6 +1304,7 @@ function useCellSelection({
|
|
|
1264
1304
|
cellRendererRegistry,
|
|
1265
1305
|
rootRef
|
|
1266
1306
|
}) {
|
|
1307
|
+
const ownerRef = useRef2(createCellSelectionOwner());
|
|
1267
1308
|
const [dragState, setDragState] = useState2(INITIAL_DRAG_STATE);
|
|
1268
1309
|
const pendingPasteModeRef = useRef2(null);
|
|
1269
1310
|
const dragStateRef = useRef2(dragState);
|
|
@@ -1275,6 +1316,7 @@ function useCellSelection({
|
|
|
1275
1316
|
const handleCellMouseDown = useCallback2(
|
|
1276
1317
|
(rowIndex, colIndex, options) => {
|
|
1277
1318
|
if (!enabled) return;
|
|
1319
|
+
claimCellSelectionOwner(ownerRef.current);
|
|
1278
1320
|
setDragState((prev) => {
|
|
1279
1321
|
if (options?.shiftKey && prev.start) {
|
|
1280
1322
|
return {
|
|
@@ -1316,6 +1358,7 @@ function useCellSelection({
|
|
|
1316
1358
|
const handleFillHandleMouseDown = useCallback2(
|
|
1317
1359
|
(rowIndex, colIndex) => {
|
|
1318
1360
|
if (!enabled) return;
|
|
1361
|
+
claimCellSelectionOwner(ownerRef.current);
|
|
1319
1362
|
setDragState((prev) => {
|
|
1320
1363
|
const bounds = getCellSelectionBounds(prev.start, prev.end);
|
|
1321
1364
|
if (!bounds) return prev;
|
|
@@ -1330,14 +1373,27 @@ function useCellSelection({
|
|
|
1330
1373
|
},
|
|
1331
1374
|
[enabled]
|
|
1332
1375
|
);
|
|
1376
|
+
const clearSelection = useCallback2(() => {
|
|
1377
|
+
const prev = dragStateRef.current;
|
|
1378
|
+
if (prev.start === null && prev.end === null && !prev.isSelecting && !prev.isFillDragging) {
|
|
1379
|
+
return;
|
|
1380
|
+
}
|
|
1381
|
+
releaseCellSelectionOwner(ownerRef.current);
|
|
1382
|
+
dragStateRef.current = INITIAL_DRAG_STATE;
|
|
1383
|
+
setDragState(INITIAL_DRAG_STATE);
|
|
1384
|
+
}, []);
|
|
1333
1385
|
useEffect2(() => {
|
|
1334
1386
|
if (!enabled) {
|
|
1335
|
-
|
|
1387
|
+
clearSelection();
|
|
1336
1388
|
}
|
|
1337
|
-
}, [enabled]);
|
|
1389
|
+
}, [clearSelection, enabled]);
|
|
1390
|
+
useEffect2(() => {
|
|
1391
|
+
return registerCellSelectionOwner(ownerRef.current, clearSelection);
|
|
1392
|
+
}, [clearSelection]);
|
|
1338
1393
|
useEffect2(() => {
|
|
1339
1394
|
if (!enabled) return;
|
|
1340
1395
|
const handleKeyDown = (e) => {
|
|
1396
|
+
if (!isActiveCellSelectionOwner(ownerRef.current)) return;
|
|
1341
1397
|
if (e.ctrlKey || e.metaKey || e.altKey) return;
|
|
1342
1398
|
if (isEditablePasteTarget(e.target) || isEditablePasteTarget(document.activeElement)) {
|
|
1343
1399
|
return;
|
|
@@ -1403,6 +1459,7 @@ function useCellSelection({
|
|
|
1403
1459
|
useEffect2(() => {
|
|
1404
1460
|
if (!enabled) return;
|
|
1405
1461
|
const handleKeyDown = (e) => {
|
|
1462
|
+
if (!isActiveCellSelectionOwner(ownerRef.current)) return;
|
|
1406
1463
|
if (!activeSelectionBounds) return;
|
|
1407
1464
|
if (!(e.ctrlKey || e.metaKey)) return;
|
|
1408
1465
|
if (isEditablePasteTarget(e.target) || isEditablePasteTarget(document.activeElement)) {
|
|
@@ -1439,6 +1496,7 @@ function useCellSelection({
|
|
|
1439
1496
|
const pasteHandledRef = { current: false };
|
|
1440
1497
|
const ignoreNextPasteRef = { current: false };
|
|
1441
1498
|
const handleKeyDown = (e) => {
|
|
1499
|
+
if (!isActiveCellSelectionOwner(ownerRef.current)) return;
|
|
1442
1500
|
if (!activeSelectionBounds) return;
|
|
1443
1501
|
if (!(e.ctrlKey || e.metaKey)) return;
|
|
1444
1502
|
if (e.key.toLowerCase() !== "v") return;
|
|
@@ -1459,6 +1517,7 @@ function useCellSelection({
|
|
|
1459
1517
|
const text = await navigator.clipboard.readText();
|
|
1460
1518
|
if (pasteHandledRef.current) return;
|
|
1461
1519
|
if (pendingPasteModeRef.current !== mode) return;
|
|
1520
|
+
if (!isActiveCellSelectionOwner(ownerRef.current)) return;
|
|
1462
1521
|
if (!text) return;
|
|
1463
1522
|
pasteHandledRef.current = true;
|
|
1464
1523
|
emitRowsPaste(text, mode);
|
|
@@ -1468,6 +1527,7 @@ function useCellSelection({
|
|
|
1468
1527
|
})();
|
|
1469
1528
|
};
|
|
1470
1529
|
const handlePaste = (e) => {
|
|
1530
|
+
if (!isActiveCellSelectionOwner(ownerRef.current)) return;
|
|
1471
1531
|
if (!activeSelectionBounds) return;
|
|
1472
1532
|
if (isEditablePasteTarget(e.target) || isEditablePasteTarget(document.activeElement)) {
|
|
1473
1533
|
return;
|
|
@@ -1548,10 +1608,30 @@ function useCellSelection({
|
|
|
1548
1608
|
handleCellMouseDown,
|
|
1549
1609
|
handleCellMouseEnter,
|
|
1550
1610
|
handleFillHandleMouseDown,
|
|
1611
|
+
clearSelection,
|
|
1551
1612
|
copySelection
|
|
1552
1613
|
};
|
|
1553
1614
|
}
|
|
1554
1615
|
|
|
1616
|
+
// src/components/ui/table/features/selection-dismiss/isOutsideDismissTarget.ts
|
|
1617
|
+
var OVERLAY_DISMISS_IGNORE_SELECTOR = [
|
|
1618
|
+
'[role="dialog"]',
|
|
1619
|
+
'[role="alertdialog"]',
|
|
1620
|
+
'[role="menu"]',
|
|
1621
|
+
'[role="listbox"]',
|
|
1622
|
+
'[role="tooltip"]',
|
|
1623
|
+
'[aria-modal="true"]',
|
|
1624
|
+
"[data-radix-portal]",
|
|
1625
|
+
"[data-radix-popper-content-wrapper]",
|
|
1626
|
+
"[data-floating-ui-portal]",
|
|
1627
|
+
"[data-table-ignore-outside-dismiss]"
|
|
1628
|
+
].join(",");
|
|
1629
|
+
function isOverlayDismissIgnoreTarget(target) {
|
|
1630
|
+
const element = target instanceof Element ? target : target instanceof Node ? target.parentElement : null;
|
|
1631
|
+
if (!element) return false;
|
|
1632
|
+
return element.closest(OVERLAY_DISMISS_IGNORE_SELECTOR) !== null;
|
|
1633
|
+
}
|
|
1634
|
+
|
|
1555
1635
|
// src/components/ui/table/features/column-reorder/columnReorder.ts
|
|
1556
1636
|
function getColumnDefId(column) {
|
|
1557
1637
|
if (column.id != null && column.id !== "") return column.id;
|
|
@@ -2832,6 +2912,7 @@ function useGlideTable(options) {
|
|
|
2832
2912
|
handleCellMouseDown,
|
|
2833
2913
|
handleCellMouseEnter,
|
|
2834
2914
|
handleFillHandleMouseDown,
|
|
2915
|
+
clearSelection: clearCellSelection,
|
|
2835
2916
|
copySelection
|
|
2836
2917
|
} = useCellSelection({
|
|
2837
2918
|
data: tableData,
|
|
@@ -2847,6 +2928,37 @@ function useGlideTable(options) {
|
|
|
2847
2928
|
cellRendererRegistry,
|
|
2848
2929
|
rootRef
|
|
2849
2930
|
});
|
|
2931
|
+
const clearRowSelection = useCallback4(() => {
|
|
2932
|
+
if (rowSelectionMode === "none") return;
|
|
2933
|
+
const hasSelection = Object.values(rowSelection).some(Boolean);
|
|
2934
|
+
if (!hasSelection) return;
|
|
2935
|
+
if (onRowSelectionChange) {
|
|
2936
|
+
onRowSelectionChange(() => ({}));
|
|
2937
|
+
return;
|
|
2938
|
+
}
|
|
2939
|
+
setInternalRowSelection({});
|
|
2940
|
+
}, [onRowSelectionChange, rowSelection, rowSelectionMode]);
|
|
2941
|
+
useEffect5(() => {
|
|
2942
|
+
const clearAllSelections = () => {
|
|
2943
|
+
clearCellSelection();
|
|
2944
|
+
clearRowSelection();
|
|
2945
|
+
};
|
|
2946
|
+
const handleKeyDown = (event) => {
|
|
2947
|
+
if (event.key !== "Escape") return;
|
|
2948
|
+
if (event.defaultPrevented) return;
|
|
2949
|
+
if (isEditablePasteTarget(event.target) || isEditablePasteTarget(document.activeElement)) {
|
|
2950
|
+
return;
|
|
2951
|
+
}
|
|
2952
|
+
if (isOverlayDismissIgnoreTarget(event.target) || isOverlayDismissIgnoreTarget(document.activeElement)) {
|
|
2953
|
+
return;
|
|
2954
|
+
}
|
|
2955
|
+
clearAllSelections();
|
|
2956
|
+
};
|
|
2957
|
+
window.addEventListener("keydown", handleKeyDown);
|
|
2958
|
+
return () => {
|
|
2959
|
+
window.removeEventListener("keydown", handleKeyDown);
|
|
2960
|
+
};
|
|
2961
|
+
}, [clearCellSelection, clearRowSelection]);
|
|
2850
2962
|
const {
|
|
2851
2963
|
editingCell,
|
|
2852
2964
|
draftValue,
|