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/compound.js
CHANGED
|
@@ -2646,9 +2646,123 @@ function formatDefaultCellValue(value) {
|
|
|
2646
2646
|
return String(value);
|
|
2647
2647
|
}
|
|
2648
2648
|
|
|
2649
|
+
// src/components/ui/table/features/cell-selection/pasteData.ts
|
|
2650
|
+
function countLeadingEmptyCells(cells) {
|
|
2651
|
+
let depth = 0;
|
|
2652
|
+
while (depth < cells.length && cells[depth] === "") {
|
|
2653
|
+
depth += 1;
|
|
2654
|
+
}
|
|
2655
|
+
return depth;
|
|
2656
|
+
}
|
|
2657
|
+
function looksLikeSubtreeIndentation(leadingEmptyCounts) {
|
|
2658
|
+
if (leadingEmptyCounts.length === 0) return false;
|
|
2659
|
+
const firstDepth = leadingEmptyCounts[0] ?? 0;
|
|
2660
|
+
if (firstDepth !== 0) return false;
|
|
2661
|
+
return leadingEmptyCounts.some((depth) => depth > 0);
|
|
2662
|
+
}
|
|
2663
|
+
function parseClipboardTSVWithDepths(text) {
|
|
2664
|
+
if (!text) return { values: [], depths: [] };
|
|
2665
|
+
const normalized = text.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
2666
|
+
const withoutTrailing = normalized.replace(/\n+$/, "");
|
|
2667
|
+
if (!withoutTrailing) return { values: [], depths: [] };
|
|
2668
|
+
const rows = withoutTrailing.split("\n").map((line) => line.split(" "));
|
|
2669
|
+
const leadingEmptyCounts = rows.map(countLeadingEmptyCells);
|
|
2670
|
+
const treatAsDepth = looksLikeSubtreeIndentation(leadingEmptyCounts);
|
|
2671
|
+
const values = [];
|
|
2672
|
+
const depths = [];
|
|
2673
|
+
for (let index = 0; index < rows.length; index += 1) {
|
|
2674
|
+
const cells = rows[index] ?? [];
|
|
2675
|
+
const depth = leadingEmptyCounts[index] ?? 0;
|
|
2676
|
+
if (treatAsDepth) {
|
|
2677
|
+
values.push(cells.slice(depth));
|
|
2678
|
+
depths.push(depth);
|
|
2679
|
+
} else {
|
|
2680
|
+
values.push(cells);
|
|
2681
|
+
depths.push(0);
|
|
2682
|
+
}
|
|
2683
|
+
}
|
|
2684
|
+
return { values, depths };
|
|
2685
|
+
}
|
|
2686
|
+
function resolvePasteColumnIds(rows, startCol, width) {
|
|
2687
|
+
if (width <= 0) return [];
|
|
2688
|
+
const cells = rows[0]?.getVisibleCells() ?? [];
|
|
2689
|
+
const columnIds = [];
|
|
2690
|
+
for (let offset = 0; offset < width; offset += 1) {
|
|
2691
|
+
const cell = cells[startCol + offset];
|
|
2692
|
+
if (!cell) break;
|
|
2693
|
+
columnIds.push(cell.column.id);
|
|
2694
|
+
}
|
|
2695
|
+
return columnIds;
|
|
2696
|
+
}
|
|
2697
|
+
function buildRowsPastePayload(rows, startRow, startCol, text, mode, endRow = startRow) {
|
|
2698
|
+
const { values, depths } = parseClipboardTSVWithDepths(text);
|
|
2699
|
+
if (values.length === 0) return null;
|
|
2700
|
+
const width = Math.max(...values.map((row) => row.length), 0);
|
|
2701
|
+
if (width === 0) return null;
|
|
2702
|
+
const columnIds = resolvePasteColumnIds(rows, startCol, width);
|
|
2703
|
+
if (columnIds.length === 0) return null;
|
|
2704
|
+
const rowIds = [];
|
|
2705
|
+
for (let offset = 0; offset < values.length; offset += 1) {
|
|
2706
|
+
const row = rows[startRow + offset];
|
|
2707
|
+
if (!row) break;
|
|
2708
|
+
rowIds.push(row.id);
|
|
2709
|
+
}
|
|
2710
|
+
const anchorRow = rows[endRow] ?? rows[startRow];
|
|
2711
|
+
return {
|
|
2712
|
+
mode,
|
|
2713
|
+
startRow,
|
|
2714
|
+
startCol,
|
|
2715
|
+
endRow,
|
|
2716
|
+
rowIds,
|
|
2717
|
+
anchorRowId: anchorRow?.id ?? "",
|
|
2718
|
+
columnIds,
|
|
2719
|
+
values,
|
|
2720
|
+
depths
|
|
2721
|
+
};
|
|
2722
|
+
}
|
|
2723
|
+
function isEditablePasteTarget(target) {
|
|
2724
|
+
if (!(target instanceof HTMLElement)) return false;
|
|
2725
|
+
const tag = target.tagName;
|
|
2726
|
+
if (tag === "INPUT" || tag === "TEXTAREA" || tag === "SELECT") return true;
|
|
2727
|
+
return Boolean(target.isContentEditable);
|
|
2728
|
+
}
|
|
2729
|
+
|
|
2649
2730
|
// src/components/ui/table/features/cell-selection/useCellSelection.ts
|
|
2650
2731
|
import { useCallback as useCallback3, useEffect as useEffect5, useRef as useRef5, useState as useState3 } from "react";
|
|
2651
2732
|
|
|
2733
|
+
// src/components/ui/table/features/cell-selection/activeCellSelectionOwner.ts
|
|
2734
|
+
var activeOwner = null;
|
|
2735
|
+
var clearByOwner = /* @__PURE__ */ new Map();
|
|
2736
|
+
function createCellSelectionOwner() {
|
|
2737
|
+
return /* @__PURE__ */ Symbol("cell-selection-owner");
|
|
2738
|
+
}
|
|
2739
|
+
function registerCellSelectionOwner(owner, clearSelection) {
|
|
2740
|
+
clearByOwner.set(owner, clearSelection);
|
|
2741
|
+
return () => {
|
|
2742
|
+
clearByOwner.delete(owner);
|
|
2743
|
+
if (activeOwner === owner) {
|
|
2744
|
+
activeOwner = null;
|
|
2745
|
+
}
|
|
2746
|
+
};
|
|
2747
|
+
}
|
|
2748
|
+
function claimCellSelectionOwner(owner) {
|
|
2749
|
+
if (activeOwner === owner) return;
|
|
2750
|
+
activeOwner = owner;
|
|
2751
|
+
for (const [id, clearSelection] of clearByOwner) {
|
|
2752
|
+
if (id !== owner) {
|
|
2753
|
+
clearSelection();
|
|
2754
|
+
}
|
|
2755
|
+
}
|
|
2756
|
+
}
|
|
2757
|
+
function isActiveCellSelectionOwner(owner) {
|
|
2758
|
+
return activeOwner === owner;
|
|
2759
|
+
}
|
|
2760
|
+
function releaseCellSelectionOwner(owner) {
|
|
2761
|
+
if (activeOwner === owner) {
|
|
2762
|
+
activeOwner = null;
|
|
2763
|
+
}
|
|
2764
|
+
}
|
|
2765
|
+
|
|
2652
2766
|
// src/components/ui/table/features/cell-selection/copyData.ts
|
|
2653
2767
|
import { isValidElement } from "react";
|
|
2654
2768
|
function isReactNodeIterable(node) {
|
|
@@ -2821,19 +2935,31 @@ function extractRenderedCopyText(node, value, cellPosition, root) {
|
|
|
2821
2935
|
function formatCopyCellText(rowData, columnDef, columnId, visibleRow, fallbackIndex, sourceCell, cellPosition, options) {
|
|
2822
2936
|
const meta = columnDef.meta;
|
|
2823
2937
|
const value = sourceCell ? sourceCell.getValue() : readRowColumnValue(rowData, columnDef);
|
|
2938
|
+
const row = visibleRow ?? createCopyRenderRow(rowData, fallbackIndex);
|
|
2939
|
+
const ctx = {
|
|
2940
|
+
value,
|
|
2941
|
+
row,
|
|
2942
|
+
index: row.index,
|
|
2943
|
+
columnId,
|
|
2944
|
+
cellProps: meta?.cellProps,
|
|
2945
|
+
update: () => {
|
|
2946
|
+
}
|
|
2947
|
+
};
|
|
2948
|
+
const copyValue = meta?.copyValue;
|
|
2949
|
+
if (typeof copyValue === "function") {
|
|
2950
|
+
try {
|
|
2951
|
+
return sanitizeClipboardCell(copyValue(ctx));
|
|
2952
|
+
} catch {
|
|
2953
|
+
return formatCellValue(value);
|
|
2954
|
+
}
|
|
2955
|
+
}
|
|
2956
|
+
if (copyValue === "value") {
|
|
2957
|
+
return formatCellValue(value);
|
|
2958
|
+
}
|
|
2824
2959
|
const cellRender = meta?.cellRender;
|
|
2825
2960
|
if (typeof cellRender === "function") {
|
|
2826
2961
|
try {
|
|
2827
|
-
const
|
|
2828
|
-
const node = cellRender({
|
|
2829
|
-
value,
|
|
2830
|
-
row,
|
|
2831
|
-
index: row.index,
|
|
2832
|
-
columnId,
|
|
2833
|
-
cellProps: meta?.cellProps,
|
|
2834
|
-
update: () => {
|
|
2835
|
-
}
|
|
2836
|
-
});
|
|
2962
|
+
const node = cellRender(ctx);
|
|
2837
2963
|
return extractRenderedCopyText(node, value, cellPosition, options?.root);
|
|
2838
2964
|
} catch {
|
|
2839
2965
|
return formatCellValue(value);
|
|
@@ -2841,16 +2967,6 @@ function formatCopyCellText(rowData, columnDef, columnId, visibleRow, fallbackIn
|
|
|
2841
2967
|
}
|
|
2842
2968
|
if (options?.registry && meta?.kind && isPrimitiveCopyValue(value)) {
|
|
2843
2969
|
try {
|
|
2844
|
-
const row = visibleRow ?? createCopyRenderRow(rowData, fallbackIndex);
|
|
2845
|
-
const ctx = {
|
|
2846
|
-
value,
|
|
2847
|
-
row,
|
|
2848
|
-
index: row.index,
|
|
2849
|
-
columnId,
|
|
2850
|
-
cellProps: meta.cellProps,
|
|
2851
|
-
update: () => {
|
|
2852
|
-
}
|
|
2853
|
-
};
|
|
2854
2970
|
const renderer = resolveCellRenderer(options.registry, meta.kind, ctx);
|
|
2855
2971
|
if (renderer) {
|
|
2856
2972
|
const node = renderer.render(ctx);
|
|
@@ -2957,11 +3073,16 @@ function serializeCopyRowsToTSV(copyRows, visibleRows, bounds, depths, options)
|
|
|
2957
3073
|
const resolvedDepths = depths && depths.length === copyRows.length ? depths : copyRows.map((row) => getRowDepth(row));
|
|
2958
3074
|
const minDepth = Math.min(...resolvedDepths);
|
|
2959
3075
|
const visibleRowByOriginal = buildVisibleRowLookup(visibleRows);
|
|
3076
|
+
const copyableColumns = columnCells.flatMap((templateCell, colOffset) => {
|
|
3077
|
+
const meta = templateCell.column.columnDef.meta;
|
|
3078
|
+
if (meta?.copyValue === "omit") return [];
|
|
3079
|
+
return [{ templateCell, colOffset }];
|
|
3080
|
+
});
|
|
2960
3081
|
return copyRows.map((rowData, index) => {
|
|
2961
3082
|
const relativeDepth = Math.max(0, (resolvedDepths[index] ?? 0) - minDepth);
|
|
2962
3083
|
const visibleRow = visibleRowByOriginal.get(rowData);
|
|
2963
3084
|
const matchingCells = visibleRow?.getVisibleCells().slice(startCol, endCol + 1);
|
|
2964
|
-
const line =
|
|
3085
|
+
const line = copyableColumns.map(({ templateCell, colOffset }) => {
|
|
2965
3086
|
const sourceCell = matchingCells?.[colOffset];
|
|
2966
3087
|
const column = sourceCell?.column ?? templateCell.column;
|
|
2967
3088
|
return formatCopyCellText(
|
|
@@ -3055,87 +3176,6 @@ function hasFillExtension(sourceBounds, fillBounds) {
|
|
|
3055
3176
|
return fillBounds.startRow < sourceBounds.startRow || fillBounds.endRow > sourceBounds.endRow || fillBounds.startCol < sourceBounds.startCol || fillBounds.endCol > sourceBounds.endCol;
|
|
3056
3177
|
}
|
|
3057
3178
|
|
|
3058
|
-
// src/components/ui/table/features/cell-selection/pasteData.ts
|
|
3059
|
-
function countLeadingEmptyCells(cells) {
|
|
3060
|
-
let depth = 0;
|
|
3061
|
-
while (depth < cells.length && cells[depth] === "") {
|
|
3062
|
-
depth += 1;
|
|
3063
|
-
}
|
|
3064
|
-
return depth;
|
|
3065
|
-
}
|
|
3066
|
-
function looksLikeSubtreeIndentation(leadingEmptyCounts) {
|
|
3067
|
-
if (leadingEmptyCounts.length === 0) return false;
|
|
3068
|
-
const firstDepth = leadingEmptyCounts[0] ?? 0;
|
|
3069
|
-
if (firstDepth !== 0) return false;
|
|
3070
|
-
return leadingEmptyCounts.some((depth) => depth > 0);
|
|
3071
|
-
}
|
|
3072
|
-
function parseClipboardTSVWithDepths(text) {
|
|
3073
|
-
if (!text) return { values: [], depths: [] };
|
|
3074
|
-
const normalized = text.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
3075
|
-
const withoutTrailing = normalized.replace(/\n+$/, "");
|
|
3076
|
-
if (!withoutTrailing) return { values: [], depths: [] };
|
|
3077
|
-
const rows = withoutTrailing.split("\n").map((line) => line.split(" "));
|
|
3078
|
-
const leadingEmptyCounts = rows.map(countLeadingEmptyCells);
|
|
3079
|
-
const treatAsDepth = looksLikeSubtreeIndentation(leadingEmptyCounts);
|
|
3080
|
-
const values = [];
|
|
3081
|
-
const depths = [];
|
|
3082
|
-
for (let index = 0; index < rows.length; index += 1) {
|
|
3083
|
-
const cells = rows[index] ?? [];
|
|
3084
|
-
const depth = leadingEmptyCounts[index] ?? 0;
|
|
3085
|
-
if (treatAsDepth) {
|
|
3086
|
-
values.push(cells.slice(depth));
|
|
3087
|
-
depths.push(depth);
|
|
3088
|
-
} else {
|
|
3089
|
-
values.push(cells);
|
|
3090
|
-
depths.push(0);
|
|
3091
|
-
}
|
|
3092
|
-
}
|
|
3093
|
-
return { values, depths };
|
|
3094
|
-
}
|
|
3095
|
-
function resolvePasteColumnIds(rows, startCol, width) {
|
|
3096
|
-
if (width <= 0) return [];
|
|
3097
|
-
const cells = rows[0]?.getVisibleCells() ?? [];
|
|
3098
|
-
const columnIds = [];
|
|
3099
|
-
for (let offset = 0; offset < width; offset += 1) {
|
|
3100
|
-
const cell = cells[startCol + offset];
|
|
3101
|
-
if (!cell) break;
|
|
3102
|
-
columnIds.push(cell.column.id);
|
|
3103
|
-
}
|
|
3104
|
-
return columnIds;
|
|
3105
|
-
}
|
|
3106
|
-
function buildRowsPastePayload(rows, startRow, startCol, text, mode, endRow = startRow) {
|
|
3107
|
-
const { values, depths } = parseClipboardTSVWithDepths(text);
|
|
3108
|
-
if (values.length === 0) return null;
|
|
3109
|
-
const width = Math.max(...values.map((row) => row.length), 0);
|
|
3110
|
-
if (width === 0) return null;
|
|
3111
|
-
const columnIds = resolvePasteColumnIds(rows, startCol, width);
|
|
3112
|
-
if (columnIds.length === 0) return null;
|
|
3113
|
-
const rowIds = [];
|
|
3114
|
-
for (let offset = 0; offset < values.length; offset += 1) {
|
|
3115
|
-
const row = rows[startRow + offset];
|
|
3116
|
-
if (!row) break;
|
|
3117
|
-
rowIds.push(row.id);
|
|
3118
|
-
}
|
|
3119
|
-
const anchorRow = rows[endRow] ?? rows[startRow];
|
|
3120
|
-
return {
|
|
3121
|
-
mode,
|
|
3122
|
-
startRow,
|
|
3123
|
-
startCol,
|
|
3124
|
-
endRow,
|
|
3125
|
-
rowIds,
|
|
3126
|
-
anchorRowId: anchorRow?.id ?? "",
|
|
3127
|
-
columnIds,
|
|
3128
|
-
values,
|
|
3129
|
-
depths
|
|
3130
|
-
};
|
|
3131
|
-
}
|
|
3132
|
-
function isEditablePasteTarget(target) {
|
|
3133
|
-
if (!(target instanceof HTMLElement)) return false;
|
|
3134
|
-
const tag = target.tagName;
|
|
3135
|
-
if (tag === "INPUT" || tag === "TEXTAREA" || tag === "SELECT") return true;
|
|
3136
|
-
return Boolean(target.isContentEditable);
|
|
3137
|
-
}
|
|
3138
|
-
|
|
3139
3179
|
// src/components/ui/table/features/cell-selection/useCellSelection.ts
|
|
3140
3180
|
function useCellSelection({
|
|
3141
3181
|
data,
|
|
@@ -3151,6 +3191,7 @@ function useCellSelection({
|
|
|
3151
3191
|
cellRendererRegistry,
|
|
3152
3192
|
rootRef
|
|
3153
3193
|
}) {
|
|
3194
|
+
const ownerRef = useRef5(createCellSelectionOwner());
|
|
3154
3195
|
const [dragState, setDragState] = useState3(INITIAL_DRAG_STATE);
|
|
3155
3196
|
const pendingPasteModeRef = useRef5(null);
|
|
3156
3197
|
const dragStateRef = useRef5(dragState);
|
|
@@ -3162,6 +3203,7 @@ function useCellSelection({
|
|
|
3162
3203
|
const handleCellMouseDown = useCallback3(
|
|
3163
3204
|
(rowIndex, colIndex, options) => {
|
|
3164
3205
|
if (!enabled) return;
|
|
3206
|
+
claimCellSelectionOwner(ownerRef.current);
|
|
3165
3207
|
setDragState((prev) => {
|
|
3166
3208
|
if (options?.shiftKey && prev.start) {
|
|
3167
3209
|
return {
|
|
@@ -3203,6 +3245,7 @@ function useCellSelection({
|
|
|
3203
3245
|
const handleFillHandleMouseDown = useCallback3(
|
|
3204
3246
|
(rowIndex, colIndex) => {
|
|
3205
3247
|
if (!enabled) return;
|
|
3248
|
+
claimCellSelectionOwner(ownerRef.current);
|
|
3206
3249
|
setDragState((prev) => {
|
|
3207
3250
|
const bounds = getCellSelectionBounds(prev.start, prev.end);
|
|
3208
3251
|
if (!bounds) return prev;
|
|
@@ -3217,14 +3260,27 @@ function useCellSelection({
|
|
|
3217
3260
|
},
|
|
3218
3261
|
[enabled]
|
|
3219
3262
|
);
|
|
3263
|
+
const clearSelection = useCallback3(() => {
|
|
3264
|
+
const prev = dragStateRef.current;
|
|
3265
|
+
if (prev.start === null && prev.end === null && !prev.isSelecting && !prev.isFillDragging) {
|
|
3266
|
+
return;
|
|
3267
|
+
}
|
|
3268
|
+
releaseCellSelectionOwner(ownerRef.current);
|
|
3269
|
+
dragStateRef.current = INITIAL_DRAG_STATE;
|
|
3270
|
+
setDragState(INITIAL_DRAG_STATE);
|
|
3271
|
+
}, []);
|
|
3220
3272
|
useEffect5(() => {
|
|
3221
3273
|
if (!enabled) {
|
|
3222
|
-
|
|
3274
|
+
clearSelection();
|
|
3223
3275
|
}
|
|
3224
|
-
}, [enabled]);
|
|
3276
|
+
}, [clearSelection, enabled]);
|
|
3277
|
+
useEffect5(() => {
|
|
3278
|
+
return registerCellSelectionOwner(ownerRef.current, clearSelection);
|
|
3279
|
+
}, [clearSelection]);
|
|
3225
3280
|
useEffect5(() => {
|
|
3226
3281
|
if (!enabled) return;
|
|
3227
3282
|
const handleKeyDown = (e) => {
|
|
3283
|
+
if (!isActiveCellSelectionOwner(ownerRef.current)) return;
|
|
3228
3284
|
if (e.ctrlKey || e.metaKey || e.altKey) return;
|
|
3229
3285
|
if (isEditablePasteTarget(e.target) || isEditablePasteTarget(document.activeElement)) {
|
|
3230
3286
|
return;
|
|
@@ -3290,6 +3346,7 @@ function useCellSelection({
|
|
|
3290
3346
|
useEffect5(() => {
|
|
3291
3347
|
if (!enabled) return;
|
|
3292
3348
|
const handleKeyDown = (e) => {
|
|
3349
|
+
if (!isActiveCellSelectionOwner(ownerRef.current)) return;
|
|
3293
3350
|
if (!activeSelectionBounds) return;
|
|
3294
3351
|
if (!(e.ctrlKey || e.metaKey)) return;
|
|
3295
3352
|
if (isEditablePasteTarget(e.target) || isEditablePasteTarget(document.activeElement)) {
|
|
@@ -3326,6 +3383,7 @@ function useCellSelection({
|
|
|
3326
3383
|
const pasteHandledRef = { current: false };
|
|
3327
3384
|
const ignoreNextPasteRef = { current: false };
|
|
3328
3385
|
const handleKeyDown = (e) => {
|
|
3386
|
+
if (!isActiveCellSelectionOwner(ownerRef.current)) return;
|
|
3329
3387
|
if (!activeSelectionBounds) return;
|
|
3330
3388
|
if (!(e.ctrlKey || e.metaKey)) return;
|
|
3331
3389
|
if (e.key.toLowerCase() !== "v") return;
|
|
@@ -3346,6 +3404,7 @@ function useCellSelection({
|
|
|
3346
3404
|
const text = await navigator.clipboard.readText();
|
|
3347
3405
|
if (pasteHandledRef.current) return;
|
|
3348
3406
|
if (pendingPasteModeRef.current !== mode) return;
|
|
3407
|
+
if (!isActiveCellSelectionOwner(ownerRef.current)) return;
|
|
3349
3408
|
if (!text) return;
|
|
3350
3409
|
pasteHandledRef.current = true;
|
|
3351
3410
|
emitRowsPaste(text, mode);
|
|
@@ -3355,6 +3414,7 @@ function useCellSelection({
|
|
|
3355
3414
|
})();
|
|
3356
3415
|
};
|
|
3357
3416
|
const handlePaste = (e) => {
|
|
3417
|
+
if (!isActiveCellSelectionOwner(ownerRef.current)) return;
|
|
3358
3418
|
if (!activeSelectionBounds) return;
|
|
3359
3419
|
if (isEditablePasteTarget(e.target) || isEditablePasteTarget(document.activeElement)) {
|
|
3360
3420
|
return;
|
|
@@ -3435,10 +3495,30 @@ function useCellSelection({
|
|
|
3435
3495
|
handleCellMouseDown,
|
|
3436
3496
|
handleCellMouseEnter,
|
|
3437
3497
|
handleFillHandleMouseDown,
|
|
3498
|
+
clearSelection,
|
|
3438
3499
|
copySelection
|
|
3439
3500
|
};
|
|
3440
3501
|
}
|
|
3441
3502
|
|
|
3503
|
+
// src/components/ui/table/features/selection-dismiss/isOutsideDismissTarget.ts
|
|
3504
|
+
var OVERLAY_DISMISS_IGNORE_SELECTOR = [
|
|
3505
|
+
'[role="dialog"]',
|
|
3506
|
+
'[role="alertdialog"]',
|
|
3507
|
+
'[role="menu"]',
|
|
3508
|
+
'[role="listbox"]',
|
|
3509
|
+
'[role="tooltip"]',
|
|
3510
|
+
'[aria-modal="true"]',
|
|
3511
|
+
"[data-radix-portal]",
|
|
3512
|
+
"[data-radix-popper-content-wrapper]",
|
|
3513
|
+
"[data-floating-ui-portal]",
|
|
3514
|
+
"[data-table-ignore-outside-dismiss]"
|
|
3515
|
+
].join(",");
|
|
3516
|
+
function isOverlayDismissIgnoreTarget(target) {
|
|
3517
|
+
const element = target instanceof Element ? target : target instanceof Node ? target.parentElement : null;
|
|
3518
|
+
if (!element) return false;
|
|
3519
|
+
return element.closest(OVERLAY_DISMISS_IGNORE_SELECTOR) !== null;
|
|
3520
|
+
}
|
|
3521
|
+
|
|
3442
3522
|
// src/components/ui/table/features/inline-search/useInlineSearch.ts
|
|
3443
3523
|
import {
|
|
3444
3524
|
useCallback as useCallback4,
|
|
@@ -4033,6 +4113,7 @@ function useGlideTable(options) {
|
|
|
4033
4113
|
handleCellMouseDown,
|
|
4034
4114
|
handleCellMouseEnter,
|
|
4035
4115
|
handleFillHandleMouseDown,
|
|
4116
|
+
clearSelection: clearCellSelection,
|
|
4036
4117
|
copySelection
|
|
4037
4118
|
} = useCellSelection({
|
|
4038
4119
|
data: tableData,
|
|
@@ -4048,6 +4129,37 @@ function useGlideTable(options) {
|
|
|
4048
4129
|
cellRendererRegistry,
|
|
4049
4130
|
rootRef
|
|
4050
4131
|
});
|
|
4132
|
+
const clearRowSelection = useCallback5(() => {
|
|
4133
|
+
if (rowSelectionMode === "none") return;
|
|
4134
|
+
const hasSelection = Object.values(rowSelection).some(Boolean);
|
|
4135
|
+
if (!hasSelection) return;
|
|
4136
|
+
if (onRowSelectionChange) {
|
|
4137
|
+
onRowSelectionChange(() => ({}));
|
|
4138
|
+
return;
|
|
4139
|
+
}
|
|
4140
|
+
setInternalRowSelection({});
|
|
4141
|
+
}, [onRowSelectionChange, rowSelection, rowSelectionMode]);
|
|
4142
|
+
useEffect7(() => {
|
|
4143
|
+
const clearAllSelections = () => {
|
|
4144
|
+
clearCellSelection();
|
|
4145
|
+
clearRowSelection();
|
|
4146
|
+
};
|
|
4147
|
+
const handleKeyDown = (event) => {
|
|
4148
|
+
if (event.key !== "Escape") return;
|
|
4149
|
+
if (event.defaultPrevented) return;
|
|
4150
|
+
if (isEditablePasteTarget(event.target) || isEditablePasteTarget(document.activeElement)) {
|
|
4151
|
+
return;
|
|
4152
|
+
}
|
|
4153
|
+
if (isOverlayDismissIgnoreTarget(event.target) || isOverlayDismissIgnoreTarget(document.activeElement)) {
|
|
4154
|
+
return;
|
|
4155
|
+
}
|
|
4156
|
+
clearAllSelections();
|
|
4157
|
+
};
|
|
4158
|
+
window.addEventListener("keydown", handleKeyDown);
|
|
4159
|
+
return () => {
|
|
4160
|
+
window.removeEventListener("keydown", handleKeyDown);
|
|
4161
|
+
};
|
|
4162
|
+
}, [clearCellSelection, clearRowSelection]);
|
|
4051
4163
|
const {
|
|
4052
4164
|
editingCell,
|
|
4053
4165
|
draftValue,
|
|
@@ -4920,7 +5032,8 @@ function buildColumnDef(props, sort, onSort) {
|
|
|
4920
5032
|
cellProps,
|
|
4921
5033
|
className,
|
|
4922
5034
|
headerClassName,
|
|
4923
|
-
render
|
|
5035
|
+
render,
|
|
5036
|
+
copyValue
|
|
4924
5037
|
} = props;
|
|
4925
5038
|
return {
|
|
4926
5039
|
id: field,
|
|
@@ -4954,6 +5067,7 @@ function buildColumnDef(props, sort, onSort) {
|
|
|
4954
5067
|
kind,
|
|
4955
5068
|
cellProps,
|
|
4956
5069
|
cellRender: render,
|
|
5070
|
+
copyValue,
|
|
4957
5071
|
frozen,
|
|
4958
5072
|
reorderable,
|
|
4959
5073
|
width,
|