react-glide-table 2.2.1 → 2.3.1
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 +33 -30
- package/dist/compound.cjs +690 -222
- package/dist/compound.d.cts +2 -2
- package/dist/compound.d.ts +2 -2
- package/dist/compound.js +594 -126
- package/dist/core.cjs +623 -223
- package/dist/core.d.cts +47 -7
- package/dist/core.d.ts +47 -7
- package/dist/core.js +510 -111
- package/dist/index.cjs +722 -252
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +598 -129
- package/dist/{types-CnsQ8GZb.d.cts → types-DdeVn-9s.d.cts} +23 -6
- package/dist/{types-CnsQ8GZb.d.ts → types-DdeVn-9s.d.ts} +23 -6
- package/package.json +1 -1
package/dist/core.cjs
CHANGED
|
@@ -80,6 +80,7 @@ __export(core_exports, {
|
|
|
80
80
|
previousSearchIndex: () => previousSearchIndex,
|
|
81
81
|
resolveCellRenderer: () => resolveCellRenderer,
|
|
82
82
|
resolveColumnFreezeSide: () => resolveColumnFreezeSide,
|
|
83
|
+
resolveColumnLayoutWidths: () => resolveColumnLayoutWidths,
|
|
83
84
|
resolveDataTableLabels: () => resolveDataTableLabels,
|
|
84
85
|
resolveDropEdge: () => resolveDropEdge,
|
|
85
86
|
resolveHeaderFreezeOffset: () => resolveHeaderFreezeOffset,
|
|
@@ -133,7 +134,7 @@ var DEFAULT_TREE_QTY_FIELD = "qty";
|
|
|
133
134
|
// src/core/useGlideTable.ts
|
|
134
135
|
var import_react_table = require("@tanstack/react-table");
|
|
135
136
|
var import_react_virtual = require("@tanstack/react-virtual");
|
|
136
|
-
var
|
|
137
|
+
var import_react6 = require("react");
|
|
137
138
|
|
|
138
139
|
// src/components/ui/table/constants.ts
|
|
139
140
|
var DATA_TABLE_ROW_HEIGHT = 44;
|
|
@@ -525,8 +526,92 @@ function withCellUpdate(context, commitValue) {
|
|
|
525
526
|
};
|
|
526
527
|
}
|
|
527
528
|
|
|
529
|
+
// src/components/ui/table/features/cell-selection/pasteData.ts
|
|
530
|
+
function countLeadingEmptyCells(cells) {
|
|
531
|
+
let depth = 0;
|
|
532
|
+
while (depth < cells.length && cells[depth] === "") {
|
|
533
|
+
depth += 1;
|
|
534
|
+
}
|
|
535
|
+
return depth;
|
|
536
|
+
}
|
|
537
|
+
function looksLikeSubtreeIndentation(leadingEmptyCounts) {
|
|
538
|
+
if (leadingEmptyCounts.length === 0) return false;
|
|
539
|
+
const firstDepth = leadingEmptyCounts[0] ?? 0;
|
|
540
|
+
if (firstDepth !== 0) return false;
|
|
541
|
+
return leadingEmptyCounts.some((depth) => depth > 0);
|
|
542
|
+
}
|
|
543
|
+
function parseClipboardTSV(text) {
|
|
544
|
+
return parseClipboardTSVWithDepths(text).values;
|
|
545
|
+
}
|
|
546
|
+
function parseClipboardTSVWithDepths(text) {
|
|
547
|
+
if (!text) return { values: [], depths: [] };
|
|
548
|
+
const normalized = text.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
549
|
+
const withoutTrailing = normalized.replace(/\n+$/, "");
|
|
550
|
+
if (!withoutTrailing) return { values: [], depths: [] };
|
|
551
|
+
const rows = withoutTrailing.split("\n").map((line) => line.split(" "));
|
|
552
|
+
const leadingEmptyCounts = rows.map(countLeadingEmptyCells);
|
|
553
|
+
const treatAsDepth = looksLikeSubtreeIndentation(leadingEmptyCounts);
|
|
554
|
+
const values = [];
|
|
555
|
+
const depths = [];
|
|
556
|
+
for (let index = 0; index < rows.length; index += 1) {
|
|
557
|
+
const cells = rows[index] ?? [];
|
|
558
|
+
const depth = leadingEmptyCounts[index] ?? 0;
|
|
559
|
+
if (treatAsDepth) {
|
|
560
|
+
values.push(cells.slice(depth));
|
|
561
|
+
depths.push(depth);
|
|
562
|
+
} else {
|
|
563
|
+
values.push(cells);
|
|
564
|
+
depths.push(0);
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
return { values, depths };
|
|
568
|
+
}
|
|
569
|
+
function resolvePasteColumnIds(rows, startCol, width) {
|
|
570
|
+
if (width <= 0) return [];
|
|
571
|
+
const cells = rows[0]?.getVisibleCells() ?? [];
|
|
572
|
+
const columnIds = [];
|
|
573
|
+
for (let offset = 0; offset < width; offset += 1) {
|
|
574
|
+
const cell = cells[startCol + offset];
|
|
575
|
+
if (!cell) break;
|
|
576
|
+
columnIds.push(cell.column.id);
|
|
577
|
+
}
|
|
578
|
+
return columnIds;
|
|
579
|
+
}
|
|
580
|
+
function buildRowsPastePayload(rows, startRow, startCol, text, mode, endRow = startRow) {
|
|
581
|
+
const { values, depths } = parseClipboardTSVWithDepths(text);
|
|
582
|
+
if (values.length === 0) return null;
|
|
583
|
+
const width = Math.max(...values.map((row) => row.length), 0);
|
|
584
|
+
if (width === 0) return null;
|
|
585
|
+
const columnIds = resolvePasteColumnIds(rows, startCol, width);
|
|
586
|
+
if (columnIds.length === 0) return null;
|
|
587
|
+
const rowIds = [];
|
|
588
|
+
for (let offset = 0; offset < values.length; offset += 1) {
|
|
589
|
+
const row = rows[startRow + offset];
|
|
590
|
+
if (!row) break;
|
|
591
|
+
rowIds.push(row.id);
|
|
592
|
+
}
|
|
593
|
+
const anchorRow = rows[endRow] ?? rows[startRow];
|
|
594
|
+
return {
|
|
595
|
+
mode,
|
|
596
|
+
startRow,
|
|
597
|
+
startCol,
|
|
598
|
+
endRow,
|
|
599
|
+
rowIds,
|
|
600
|
+
anchorRowId: anchorRow?.id ?? "",
|
|
601
|
+
columnIds,
|
|
602
|
+
values,
|
|
603
|
+
depths
|
|
604
|
+
};
|
|
605
|
+
}
|
|
606
|
+
function isEditablePasteTarget(target) {
|
|
607
|
+
if (!(target instanceof HTMLElement)) return false;
|
|
608
|
+
const tag = target.tagName;
|
|
609
|
+
if (tag === "INPUT" || tag === "TEXTAREA" || tag === "SELECT") return true;
|
|
610
|
+
return Boolean(target.isContentEditable);
|
|
611
|
+
}
|
|
612
|
+
|
|
528
613
|
// src/components/ui/table/features/cell-selection/useCellSelection.ts
|
|
529
|
-
var
|
|
614
|
+
var import_react3 = require("react");
|
|
530
615
|
|
|
531
616
|
// src/components/ui/table/features/cell-selection/cellSelection.ts
|
|
532
617
|
var INITIAL_DRAG_STATE = {
|
|
@@ -834,6 +919,219 @@ function hasCellSelectionEdges(style) {
|
|
|
834
919
|
}
|
|
835
920
|
|
|
836
921
|
// src/components/ui/table/features/cell-selection/copyData.ts
|
|
922
|
+
var import_react2 = require("react");
|
|
923
|
+
function isReactNodeIterable(node) {
|
|
924
|
+
return typeof node === "object" && node !== null && !(0, import_react2.isValidElement)(node) && Symbol.iterator in node;
|
|
925
|
+
}
|
|
926
|
+
function getElementTypeName(type) {
|
|
927
|
+
if (typeof type === "string") return type;
|
|
928
|
+
if (typeof type === "function") {
|
|
929
|
+
const fn = type;
|
|
930
|
+
return fn.displayName || fn.name || "";
|
|
931
|
+
}
|
|
932
|
+
if (typeof type === "object" && type !== null) {
|
|
933
|
+
const component = type;
|
|
934
|
+
return component.displayName || component.render?.displayName || component.render?.name || "";
|
|
935
|
+
}
|
|
936
|
+
return "";
|
|
937
|
+
}
|
|
938
|
+
function isButtonReactElement(node) {
|
|
939
|
+
const typeName = getElementTypeName(node.type);
|
|
940
|
+
if (typeName === "button" || /button/i.test(typeName)) return true;
|
|
941
|
+
const props = node.props;
|
|
942
|
+
if (props.role === "button") return true;
|
|
943
|
+
if (typeName === "input" && props.type === "button") return true;
|
|
944
|
+
return false;
|
|
945
|
+
}
|
|
946
|
+
function isImageReactElement(node) {
|
|
947
|
+
const typeName = getElementTypeName(node.type);
|
|
948
|
+
return typeName === "img" || typeName === "image" || /image/i.test(typeName);
|
|
949
|
+
}
|
|
950
|
+
var IMAGE_URL_PROP_KEYS = ["src", "url", "href", "imageUrl", "srcUrl"];
|
|
951
|
+
function isLikelyUrl(value) {
|
|
952
|
+
const trimmed = value.trim();
|
|
953
|
+
if (!trimmed) return false;
|
|
954
|
+
if (/^(https?:|blob:|data:|\/\/)/i.test(trimmed)) return true;
|
|
955
|
+
if (trimmed.startsWith("/") && trimmed.includes("/")) return true;
|
|
956
|
+
return false;
|
|
957
|
+
}
|
|
958
|
+
function pickUrlFromUnknown(value) {
|
|
959
|
+
if (typeof value === "string") {
|
|
960
|
+
return isLikelyUrl(value) ? value.trim() : "";
|
|
961
|
+
}
|
|
962
|
+
if (Array.isArray(value)) {
|
|
963
|
+
return value.map((item) => pickUrlFromUnknown(item)).filter((item) => item.length > 0).join(", ");
|
|
964
|
+
}
|
|
965
|
+
if (value && typeof value === "object") {
|
|
966
|
+
const record = value;
|
|
967
|
+
for (const key of IMAGE_URL_PROP_KEYS) {
|
|
968
|
+
const candidate = record[key];
|
|
969
|
+
if (typeof candidate === "string" && candidate.trim()) {
|
|
970
|
+
return candidate.trim();
|
|
971
|
+
}
|
|
972
|
+
}
|
|
973
|
+
}
|
|
974
|
+
return "";
|
|
975
|
+
}
|
|
976
|
+
function imageElementText(node) {
|
|
977
|
+
const props = node.props;
|
|
978
|
+
for (const key of IMAGE_URL_PROP_KEYS) {
|
|
979
|
+
const candidate = props[key];
|
|
980
|
+
if (typeof candidate === "string" && candidate.trim()) {
|
|
981
|
+
return candidate.trim();
|
|
982
|
+
}
|
|
983
|
+
}
|
|
984
|
+
return "";
|
|
985
|
+
}
|
|
986
|
+
function reactNodeContainsImage(node) {
|
|
987
|
+
if ((0, import_react2.isValidElement)(node)) {
|
|
988
|
+
if (isImageReactElement(node)) return true;
|
|
989
|
+
return reactNodeContainsImage(node.props.children);
|
|
990
|
+
}
|
|
991
|
+
if (isReactNodeIterable(node)) {
|
|
992
|
+
for (const child of node) {
|
|
993
|
+
if (reactNodeContainsImage(child)) return true;
|
|
994
|
+
}
|
|
995
|
+
}
|
|
996
|
+
return false;
|
|
997
|
+
}
|
|
998
|
+
function readImgUrl(img) {
|
|
999
|
+
const attr = img.getAttribute("src")?.trim() ?? "";
|
|
1000
|
+
if (attr) return attr;
|
|
1001
|
+
if (img instanceof HTMLImageElement) {
|
|
1002
|
+
const current = img.currentSrc?.trim() ?? "";
|
|
1003
|
+
if (current && current !== img.baseURI) return current;
|
|
1004
|
+
}
|
|
1005
|
+
return "";
|
|
1006
|
+
}
|
|
1007
|
+
function readDomImageUrls(rowIndex, colIndex, root) {
|
|
1008
|
+
const scope = root ?? (typeof document === "undefined" ? null : document);
|
|
1009
|
+
if (!scope) return "";
|
|
1010
|
+
const cells = scope.querySelectorAll(
|
|
1011
|
+
`[data-row-index="${rowIndex}"][data-col-index="${colIndex}"]`
|
|
1012
|
+
);
|
|
1013
|
+
for (const cell of cells) {
|
|
1014
|
+
const urls = Array.from(cell.querySelectorAll("img")).flatMap((img) => {
|
|
1015
|
+
const url = readImgUrl(img);
|
|
1016
|
+
return url ? [url] : [];
|
|
1017
|
+
});
|
|
1018
|
+
if (urls.length > 0) return urls.join(", ");
|
|
1019
|
+
}
|
|
1020
|
+
return "";
|
|
1021
|
+
}
|
|
1022
|
+
function reactNodeToText(node) {
|
|
1023
|
+
if (node == null || typeof node === "boolean") return "";
|
|
1024
|
+
if (typeof node === "string" || typeof node === "number" || typeof node === "bigint") {
|
|
1025
|
+
return String(node);
|
|
1026
|
+
}
|
|
1027
|
+
if (isReactNodeIterable(node)) {
|
|
1028
|
+
let text = "";
|
|
1029
|
+
for (const child of node) {
|
|
1030
|
+
text += reactNodeToText(child);
|
|
1031
|
+
}
|
|
1032
|
+
return text;
|
|
1033
|
+
}
|
|
1034
|
+
if ((0, import_react2.isValidElement)(node)) {
|
|
1035
|
+
if (isButtonReactElement(node)) return "";
|
|
1036
|
+
const props = node.props;
|
|
1037
|
+
const childText = reactNodeToText(props.children);
|
|
1038
|
+
if (childText) return childText;
|
|
1039
|
+
const fromImage = imageElementText(node);
|
|
1040
|
+
if (fromImage) return fromImage;
|
|
1041
|
+
if (isImageReactElement(node)) return "";
|
|
1042
|
+
if (typeof props.alt === "string" && props.alt) return props.alt;
|
|
1043
|
+
if (typeof props.title === "string" && props.title) return props.title;
|
|
1044
|
+
return "";
|
|
1045
|
+
}
|
|
1046
|
+
return "";
|
|
1047
|
+
}
|
|
1048
|
+
function sanitizeClipboardCell(text) {
|
|
1049
|
+
return text.replace(/\s+/g, " ").trim();
|
|
1050
|
+
}
|
|
1051
|
+
function createCopyRenderRow(rowData, index) {
|
|
1052
|
+
return {
|
|
1053
|
+
id: getOriginalRowId(rowData) || String(index),
|
|
1054
|
+
index,
|
|
1055
|
+
original: rowData,
|
|
1056
|
+
getIsCellDragSelected: () => false
|
|
1057
|
+
};
|
|
1058
|
+
}
|
|
1059
|
+
function buildVisibleRowLookup(visibleRows) {
|
|
1060
|
+
const lookup = /* @__PURE__ */ new Map();
|
|
1061
|
+
for (const row of visibleRows) {
|
|
1062
|
+
lookup.set(row.original, row);
|
|
1063
|
+
}
|
|
1064
|
+
return lookup;
|
|
1065
|
+
}
|
|
1066
|
+
function resolveCopyColumnId(cell) {
|
|
1067
|
+
if (cell.column.id) return cell.column.id;
|
|
1068
|
+
const columnDef = cell.column.columnDef;
|
|
1069
|
+
if (columnDef.id) return columnDef.id;
|
|
1070
|
+
if (columnDef.accessorKey != null && columnDef.accessorKey !== "") {
|
|
1071
|
+
return String(columnDef.accessorKey);
|
|
1072
|
+
}
|
|
1073
|
+
return "";
|
|
1074
|
+
}
|
|
1075
|
+
function isPrimitiveCopyValue(value) {
|
|
1076
|
+
return value == null || typeof value !== "object";
|
|
1077
|
+
}
|
|
1078
|
+
function extractRenderedCopyText(node, value, cellPosition, root) {
|
|
1079
|
+
const rendered = sanitizeClipboardCell(reactNodeToText(node));
|
|
1080
|
+
if (reactNodeContainsImage(node)) {
|
|
1081
|
+
const fromDom = cellPosition != null ? sanitizeClipboardCell(
|
|
1082
|
+
readDomImageUrls(cellPosition.rowIndex, cellPosition.colIndex, root)
|
|
1083
|
+
) : "";
|
|
1084
|
+
if (fromDom) return fromDom;
|
|
1085
|
+
if (rendered && isLikelyUrl(rendered)) return rendered;
|
|
1086
|
+
return sanitizeClipboardCell(pickUrlFromUnknown(value));
|
|
1087
|
+
}
|
|
1088
|
+
return rendered;
|
|
1089
|
+
}
|
|
1090
|
+
function formatCopyCellText(rowData, columnDef, columnId, visibleRow, fallbackIndex, sourceCell, cellPosition, options) {
|
|
1091
|
+
const meta = columnDef.meta;
|
|
1092
|
+
const value = sourceCell ? sourceCell.getValue() : readRowColumnValue(rowData, columnDef);
|
|
1093
|
+
const cellRender = meta?.cellRender;
|
|
1094
|
+
if (typeof cellRender === "function") {
|
|
1095
|
+
try {
|
|
1096
|
+
const row = visibleRow ?? createCopyRenderRow(rowData, fallbackIndex);
|
|
1097
|
+
const node = cellRender({
|
|
1098
|
+
value,
|
|
1099
|
+
row,
|
|
1100
|
+
index: row.index,
|
|
1101
|
+
columnId,
|
|
1102
|
+
cellProps: meta?.cellProps,
|
|
1103
|
+
update: () => {
|
|
1104
|
+
}
|
|
1105
|
+
});
|
|
1106
|
+
return extractRenderedCopyText(node, value, cellPosition, options?.root);
|
|
1107
|
+
} catch {
|
|
1108
|
+
return formatCellValue(value);
|
|
1109
|
+
}
|
|
1110
|
+
}
|
|
1111
|
+
if (options?.registry && meta?.kind && isPrimitiveCopyValue(value)) {
|
|
1112
|
+
try {
|
|
1113
|
+
const row = visibleRow ?? createCopyRenderRow(rowData, fallbackIndex);
|
|
1114
|
+
const ctx = {
|
|
1115
|
+
value,
|
|
1116
|
+
row,
|
|
1117
|
+
index: row.index,
|
|
1118
|
+
columnId,
|
|
1119
|
+
cellProps: meta.cellProps,
|
|
1120
|
+
update: () => {
|
|
1121
|
+
}
|
|
1122
|
+
};
|
|
1123
|
+
const renderer = resolveCellRenderer(options.registry, meta.kind, ctx);
|
|
1124
|
+
if (renderer) {
|
|
1125
|
+
const node = renderer.render(ctx);
|
|
1126
|
+
const rendered = extractRenderedCopyText(node, value, cellPosition, options.root);
|
|
1127
|
+
if (rendered) return rendered;
|
|
1128
|
+
}
|
|
1129
|
+
} catch {
|
|
1130
|
+
return formatCellValue(value);
|
|
1131
|
+
}
|
|
1132
|
+
}
|
|
1133
|
+
return formatCellValue(value);
|
|
1134
|
+
}
|
|
837
1135
|
function formatPrimitive(value) {
|
|
838
1136
|
if (value === null || value === void 0) return "";
|
|
839
1137
|
if (typeof value === "string") return value;
|
|
@@ -939,37 +1237,47 @@ function collectCopyRowEntries(visibleRows, bounds, mode = "visible") {
|
|
|
939
1237
|
function collectCopyRows(visibleRows, bounds, mode = "visible") {
|
|
940
1238
|
return collectCopyRowEntries(visibleRows, bounds, mode).map((entry) => entry.row);
|
|
941
1239
|
}
|
|
942
|
-
function serializeCopyRowsToTSV(copyRows, visibleRows, bounds, depths) {
|
|
1240
|
+
function serializeCopyRowsToTSV(copyRows, visibleRows, bounds, depths, options) {
|
|
943
1241
|
if (copyRows.length === 0) return "";
|
|
944
1242
|
const { startCol, endCol } = bounds;
|
|
945
1243
|
const columnCells = visibleRows[0]?.getVisibleCells().slice(startCol, endCol + 1) ?? [];
|
|
946
1244
|
if (columnCells.length === 0) return "";
|
|
947
1245
|
const resolvedDepths = depths && depths.length === copyRows.length ? depths : copyRows.map((row) => getRowDepth(row));
|
|
948
1246
|
const minDepth = Math.min(...resolvedDepths);
|
|
1247
|
+
const visibleRowByOriginal = buildVisibleRowLookup(visibleRows);
|
|
949
1248
|
return copyRows.map((rowData, index) => {
|
|
950
1249
|
const relativeDepth = Math.max(0, (resolvedDepths[index] ?? 0) - minDepth);
|
|
951
|
-
const
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
1250
|
+
const visibleRow = visibleRowByOriginal.get(rowData);
|
|
1251
|
+
const matchingCells = visibleRow?.getVisibleCells().slice(startCol, endCol + 1);
|
|
1252
|
+
const line = columnCells.map((templateCell, colOffset) => {
|
|
1253
|
+
const sourceCell = matchingCells?.[colOffset];
|
|
1254
|
+
const column = sourceCell?.column ?? templateCell.column;
|
|
1255
|
+
return formatCopyCellText(
|
|
1256
|
+
rowData,
|
|
1257
|
+
column.columnDef,
|
|
1258
|
+
resolveCopyColumnId(sourceCell ?? templateCell),
|
|
1259
|
+
visibleRow,
|
|
1260
|
+
visibleRow?.index ?? index,
|
|
1261
|
+
sourceCell,
|
|
1262
|
+
visibleRow != null ? { rowIndex: visibleRow.index, colIndex: startCol + colOffset } : void 0,
|
|
1263
|
+
options
|
|
1264
|
+
);
|
|
1265
|
+
}).join(" ");
|
|
959
1266
|
return `${" ".repeat(relativeDepth)}${line}`;
|
|
960
1267
|
}).join("\n");
|
|
961
1268
|
}
|
|
962
|
-
function serializeSelectionToTSV(visibleRows, bounds, mode = "visible") {
|
|
1269
|
+
function serializeSelectionToTSV(visibleRows, bounds, mode = "visible", options) {
|
|
963
1270
|
const entries = collectCopyRowEntries(visibleRows, bounds, mode);
|
|
964
1271
|
return serializeCopyRowsToTSV(
|
|
965
1272
|
entries.map((entry) => entry.row),
|
|
966
1273
|
visibleRows,
|
|
967
1274
|
bounds,
|
|
968
|
-
entries.map((entry) => entry.depth)
|
|
1275
|
+
entries.map((entry) => entry.depth),
|
|
1276
|
+
options
|
|
969
1277
|
);
|
|
970
1278
|
}
|
|
971
|
-
async function writeSelectionToClipboard(visibleRows, bounds, mode = "visible") {
|
|
972
|
-
const text = serializeSelectionToTSV(visibleRows, bounds, mode);
|
|
1279
|
+
async function writeSelectionToClipboard(visibleRows, bounds, mode = "visible", options) {
|
|
1280
|
+
const text = serializeSelectionToTSV(visibleRows, bounds, mode, options);
|
|
973
1281
|
if (!text) return false;
|
|
974
1282
|
try {
|
|
975
1283
|
await navigator.clipboard.writeText(text);
|
|
@@ -1035,90 +1343,6 @@ function hasFillExtension(sourceBounds, fillBounds) {
|
|
|
1035
1343
|
return fillBounds.startRow < sourceBounds.startRow || fillBounds.endRow > sourceBounds.endRow || fillBounds.startCol < sourceBounds.startCol || fillBounds.endCol > sourceBounds.endCol;
|
|
1036
1344
|
}
|
|
1037
1345
|
|
|
1038
|
-
// src/components/ui/table/features/cell-selection/pasteData.ts
|
|
1039
|
-
function countLeadingEmptyCells(cells) {
|
|
1040
|
-
let depth = 0;
|
|
1041
|
-
while (depth < cells.length && cells[depth] === "") {
|
|
1042
|
-
depth += 1;
|
|
1043
|
-
}
|
|
1044
|
-
return depth;
|
|
1045
|
-
}
|
|
1046
|
-
function looksLikeSubtreeIndentation(leadingEmptyCounts) {
|
|
1047
|
-
if (leadingEmptyCounts.length === 0) return false;
|
|
1048
|
-
const firstDepth = leadingEmptyCounts[0] ?? 0;
|
|
1049
|
-
if (firstDepth !== 0) return false;
|
|
1050
|
-
return leadingEmptyCounts.some((depth) => depth > 0);
|
|
1051
|
-
}
|
|
1052
|
-
function parseClipboardTSV(text) {
|
|
1053
|
-
return parseClipboardTSVWithDepths(text).values;
|
|
1054
|
-
}
|
|
1055
|
-
function parseClipboardTSVWithDepths(text) {
|
|
1056
|
-
if (!text) return { values: [], depths: [] };
|
|
1057
|
-
const normalized = text.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
1058
|
-
const withoutTrailing = normalized.replace(/\n+$/, "");
|
|
1059
|
-
if (!withoutTrailing) return { values: [], depths: [] };
|
|
1060
|
-
const rows = withoutTrailing.split("\n").map((line) => line.split(" "));
|
|
1061
|
-
const leadingEmptyCounts = rows.map(countLeadingEmptyCells);
|
|
1062
|
-
const treatAsDepth = looksLikeSubtreeIndentation(leadingEmptyCounts);
|
|
1063
|
-
const values = [];
|
|
1064
|
-
const depths = [];
|
|
1065
|
-
for (let index = 0; index < rows.length; index += 1) {
|
|
1066
|
-
const cells = rows[index] ?? [];
|
|
1067
|
-
const depth = leadingEmptyCounts[index] ?? 0;
|
|
1068
|
-
if (treatAsDepth) {
|
|
1069
|
-
values.push(cells.slice(depth));
|
|
1070
|
-
depths.push(depth);
|
|
1071
|
-
} else {
|
|
1072
|
-
values.push(cells);
|
|
1073
|
-
depths.push(0);
|
|
1074
|
-
}
|
|
1075
|
-
}
|
|
1076
|
-
return { values, depths };
|
|
1077
|
-
}
|
|
1078
|
-
function resolvePasteColumnIds(rows, startCol, width) {
|
|
1079
|
-
if (width <= 0) return [];
|
|
1080
|
-
const cells = rows[0]?.getVisibleCells() ?? [];
|
|
1081
|
-
const columnIds = [];
|
|
1082
|
-
for (let offset = 0; offset < width; offset += 1) {
|
|
1083
|
-
const cell = cells[startCol + offset];
|
|
1084
|
-
if (!cell) break;
|
|
1085
|
-
columnIds.push(cell.column.id);
|
|
1086
|
-
}
|
|
1087
|
-
return columnIds;
|
|
1088
|
-
}
|
|
1089
|
-
function buildRowsPastePayload(rows, startRow, startCol, text, mode, endRow = startRow) {
|
|
1090
|
-
const { values, depths } = parseClipboardTSVWithDepths(text);
|
|
1091
|
-
if (values.length === 0) return null;
|
|
1092
|
-
const width = Math.max(...values.map((row) => row.length), 0);
|
|
1093
|
-
if (width === 0) return null;
|
|
1094
|
-
const columnIds = resolvePasteColumnIds(rows, startCol, width);
|
|
1095
|
-
if (columnIds.length === 0) return null;
|
|
1096
|
-
const rowIds = [];
|
|
1097
|
-
for (let offset = 0; offset < values.length; offset += 1) {
|
|
1098
|
-
const row = rows[startRow + offset];
|
|
1099
|
-
if (!row) break;
|
|
1100
|
-
rowIds.push(row.id);
|
|
1101
|
-
}
|
|
1102
|
-
const anchorRow = rows[endRow] ?? rows[startRow];
|
|
1103
|
-
return {
|
|
1104
|
-
mode,
|
|
1105
|
-
startRow,
|
|
1106
|
-
startCol,
|
|
1107
|
-
endRow,
|
|
1108
|
-
rowIds,
|
|
1109
|
-
anchorRowId: anchorRow?.id ?? "",
|
|
1110
|
-
columnIds,
|
|
1111
|
-
values,
|
|
1112
|
-
depths
|
|
1113
|
-
};
|
|
1114
|
-
}
|
|
1115
|
-
function isEditablePasteTarget(target) {
|
|
1116
|
-
if (!(target instanceof HTMLElement)) return false;
|
|
1117
|
-
const tag = target.tagName;
|
|
1118
|
-
if (tag === "INPUT" || tag === "TEXTAREA" || tag === "SELECT") return true;
|
|
1119
|
-
return Boolean(target.isContentEditable);
|
|
1120
|
-
}
|
|
1121
|
-
|
|
1122
1346
|
// src/components/ui/table/features/cell-selection/useCellSelection.ts
|
|
1123
1347
|
function useCellSelection({
|
|
1124
1348
|
data,
|
|
@@ -1130,17 +1354,19 @@ function useCellSelection({
|
|
|
1130
1354
|
onDataChange,
|
|
1131
1355
|
onBatchChange,
|
|
1132
1356
|
onRowsPaste,
|
|
1133
|
-
onCellNavigate
|
|
1357
|
+
onCellNavigate,
|
|
1358
|
+
cellRendererRegistry,
|
|
1359
|
+
rootRef
|
|
1134
1360
|
}) {
|
|
1135
|
-
const [dragState, setDragState] = (0,
|
|
1136
|
-
const pendingPasteModeRef = (0,
|
|
1137
|
-
const dragStateRef = (0,
|
|
1138
|
-
const onCellNavigateRef = (0,
|
|
1361
|
+
const [dragState, setDragState] = (0, import_react3.useState)(INITIAL_DRAG_STATE);
|
|
1362
|
+
const pendingPasteModeRef = (0, import_react3.useRef)(null);
|
|
1363
|
+
const dragStateRef = (0, import_react3.useRef)(dragState);
|
|
1364
|
+
const onCellNavigateRef = (0, import_react3.useRef)(onCellNavigate);
|
|
1139
1365
|
dragStateRef.current = dragState;
|
|
1140
1366
|
onCellNavigateRef.current = onCellNavigate;
|
|
1141
1367
|
const cellSelectionBounds = getCellSelectionBounds(dragState.start, dragState.end);
|
|
1142
1368
|
const activeSelectionBounds = enabled ? getActiveSelectionBounds(dragState, cellSelectionBounds) : null;
|
|
1143
|
-
const handleCellMouseDown = (0,
|
|
1369
|
+
const handleCellMouseDown = (0, import_react3.useCallback)(
|
|
1144
1370
|
(rowIndex, colIndex, options) => {
|
|
1145
1371
|
if (!enabled) return;
|
|
1146
1372
|
setDragState((prev) => {
|
|
@@ -1166,7 +1392,7 @@ function useCellSelection({
|
|
|
1166
1392
|
},
|
|
1167
1393
|
[enabled]
|
|
1168
1394
|
);
|
|
1169
|
-
const handleCellMouseEnter = (0,
|
|
1395
|
+
const handleCellMouseEnter = (0, import_react3.useCallback)(
|
|
1170
1396
|
(rowIndex, colIndex) => {
|
|
1171
1397
|
if (!enabled) return;
|
|
1172
1398
|
setDragState((prev) => {
|
|
@@ -1181,7 +1407,7 @@ function useCellSelection({
|
|
|
1181
1407
|
},
|
|
1182
1408
|
[enabled]
|
|
1183
1409
|
);
|
|
1184
|
-
const handleFillHandleMouseDown = (0,
|
|
1410
|
+
const handleFillHandleMouseDown = (0, import_react3.useCallback)(
|
|
1185
1411
|
(rowIndex, colIndex) => {
|
|
1186
1412
|
if (!enabled) return;
|
|
1187
1413
|
setDragState((prev) => {
|
|
@@ -1198,12 +1424,20 @@ function useCellSelection({
|
|
|
1198
1424
|
},
|
|
1199
1425
|
[enabled]
|
|
1200
1426
|
);
|
|
1201
|
-
(0,
|
|
1427
|
+
const clearSelection = (0, import_react3.useCallback)(() => {
|
|
1428
|
+
const prev = dragStateRef.current;
|
|
1429
|
+
if (prev.start === null && prev.end === null && !prev.isSelecting && !prev.isFillDragging) {
|
|
1430
|
+
return;
|
|
1431
|
+
}
|
|
1432
|
+
dragStateRef.current = INITIAL_DRAG_STATE;
|
|
1433
|
+
setDragState(INITIAL_DRAG_STATE);
|
|
1434
|
+
}, []);
|
|
1435
|
+
(0, import_react3.useEffect)(() => {
|
|
1202
1436
|
if (!enabled) {
|
|
1203
|
-
|
|
1437
|
+
clearSelection();
|
|
1204
1438
|
}
|
|
1205
|
-
}, [enabled]);
|
|
1206
|
-
(0,
|
|
1439
|
+
}, [clearSelection, enabled]);
|
|
1440
|
+
(0, import_react3.useEffect)(() => {
|
|
1207
1441
|
if (!enabled) return;
|
|
1208
1442
|
const handleKeyDown = (e) => {
|
|
1209
1443
|
if (e.ctrlKey || e.metaKey || e.altKey) return;
|
|
@@ -1250,19 +1484,32 @@ function useCellSelection({
|
|
|
1250
1484
|
window.addEventListener("keydown", handleKeyDown);
|
|
1251
1485
|
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
1252
1486
|
}, [columnCount, enabled, rows]);
|
|
1253
|
-
const copySelection = (0,
|
|
1487
|
+
const copySelection = (0, import_react3.useCallback)(
|
|
1254
1488
|
async (options) => {
|
|
1255
1489
|
if (!enabled || !activeSelectionBounds) return false;
|
|
1256
1490
|
const mode = options?.includeDescendants && enableSubtreeCopy ? "subtree" : "visible";
|
|
1257
|
-
return writeSelectionToClipboard(rows, activeSelectionBounds, mode
|
|
1491
|
+
return writeSelectionToClipboard(rows, activeSelectionBounds, mode, {
|
|
1492
|
+
registry: cellRendererRegistry,
|
|
1493
|
+
root: rootRef?.current
|
|
1494
|
+
});
|
|
1258
1495
|
},
|
|
1259
|
-
[
|
|
1496
|
+
[
|
|
1497
|
+
activeSelectionBounds,
|
|
1498
|
+
cellRendererRegistry,
|
|
1499
|
+
enableSubtreeCopy,
|
|
1500
|
+
enabled,
|
|
1501
|
+
rootRef,
|
|
1502
|
+
rows
|
|
1503
|
+
]
|
|
1260
1504
|
);
|
|
1261
|
-
(0,
|
|
1505
|
+
(0, import_react3.useEffect)(() => {
|
|
1262
1506
|
if (!enabled) return;
|
|
1263
1507
|
const handleKeyDown = (e) => {
|
|
1264
1508
|
if (!activeSelectionBounds) return;
|
|
1265
1509
|
if (!(e.ctrlKey || e.metaKey)) return;
|
|
1510
|
+
if (isEditablePasteTarget(e.target) || isEditablePasteTarget(document.activeElement)) {
|
|
1511
|
+
return;
|
|
1512
|
+
}
|
|
1266
1513
|
const isSubtreeShortcut = enableSubtreeCopy && e.shiftKey && e.key.toLowerCase() === "c";
|
|
1267
1514
|
const isVisibleCopyShortcut = !e.shiftKey && e.key.toLowerCase() === "c";
|
|
1268
1515
|
if (!isSubtreeShortcut && !isVisibleCopyShortcut) return;
|
|
@@ -1272,7 +1519,7 @@ function useCellSelection({
|
|
|
1272
1519
|
window.addEventListener("keydown", handleKeyDown);
|
|
1273
1520
|
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
1274
1521
|
}, [activeSelectionBounds, copySelection, enableSubtreeCopy, enabled]);
|
|
1275
|
-
const emitRowsPaste = (0,
|
|
1522
|
+
const emitRowsPaste = (0, import_react3.useCallback)(
|
|
1276
1523
|
(text, mode) => {
|
|
1277
1524
|
if (!onRowsPaste || !activeSelectionBounds) return false;
|
|
1278
1525
|
const payload = buildRowsPastePayload(
|
|
@@ -1289,7 +1536,7 @@ function useCellSelection({
|
|
|
1289
1536
|
},
|
|
1290
1537
|
[activeSelectionBounds, onRowsPaste, rows]
|
|
1291
1538
|
);
|
|
1292
|
-
(0,
|
|
1539
|
+
(0, import_react3.useEffect)(() => {
|
|
1293
1540
|
if (!enabled || !onRowsPaste) return;
|
|
1294
1541
|
const pasteHandledRef = { current: false };
|
|
1295
1542
|
const ignoreNextPasteRef = { current: false };
|
|
@@ -1357,7 +1604,7 @@ function useCellSelection({
|
|
|
1357
1604
|
enabled,
|
|
1358
1605
|
onRowsPaste
|
|
1359
1606
|
]);
|
|
1360
|
-
(0,
|
|
1607
|
+
(0, import_react3.useEffect)(() => {
|
|
1361
1608
|
if (!enabled) return;
|
|
1362
1609
|
const handleMouseUp = () => {
|
|
1363
1610
|
setDragState((prev) => {
|
|
@@ -1403,6 +1650,7 @@ function useCellSelection({
|
|
|
1403
1650
|
handleCellMouseDown,
|
|
1404
1651
|
handleCellMouseEnter,
|
|
1405
1652
|
handleFillHandleMouseDown,
|
|
1653
|
+
clearSelection,
|
|
1406
1654
|
copySelection
|
|
1407
1655
|
};
|
|
1408
1656
|
}
|
|
@@ -1800,7 +2048,7 @@ function collectAncestorKeysToExpand(corpusRow, expandedRows) {
|
|
|
1800
2048
|
}
|
|
1801
2049
|
|
|
1802
2050
|
// src/components/ui/table/features/inline-search/useInlineSearch.ts
|
|
1803
|
-
var
|
|
2051
|
+
var import_react4 = require("react");
|
|
1804
2052
|
var EMPTY_MATCH_KEYS = /* @__PURE__ */ new Set();
|
|
1805
2053
|
function useInlineSearch({
|
|
1806
2054
|
enabled = false,
|
|
@@ -1817,46 +2065,46 @@ function useInlineSearch({
|
|
|
1817
2065
|
onNavigateToResult,
|
|
1818
2066
|
rootRef
|
|
1819
2067
|
}) {
|
|
1820
|
-
const searchInputId = (0,
|
|
1821
|
-
const searchInputRef = (0,
|
|
1822
|
-
const [internalShowSearch, setInternalShowSearch] = (0,
|
|
1823
|
-
const [internalSearchValue, setInternalSearchValue] = (0,
|
|
1824
|
-
const [internalResults, setInternalResults] = (0,
|
|
2068
|
+
const searchInputId = (0, import_react4.useId)();
|
|
2069
|
+
const searchInputRef = (0, import_react4.useRef)(null);
|
|
2070
|
+
const [internalShowSearch, setInternalShowSearch] = (0, import_react4.useState)(false);
|
|
2071
|
+
const [internalSearchValue, setInternalSearchValue] = (0, import_react4.useState)("");
|
|
2072
|
+
const [internalResults, setInternalResults] = (0, import_react4.useState)(
|
|
1825
2073
|
[]
|
|
1826
2074
|
);
|
|
1827
|
-
const [searchStatus, setSearchStatus] = (0,
|
|
1828
|
-
const searchStatusRef = (0,
|
|
2075
|
+
const [searchStatus, setSearchStatus] = (0, import_react4.useState)();
|
|
2076
|
+
const searchStatusRef = (0, import_react4.useRef)(searchStatus);
|
|
1829
2077
|
searchStatusRef.current = searchStatus;
|
|
1830
|
-
const abortControllerRef = (0,
|
|
1831
|
-
const searchHandleRef = (0,
|
|
1832
|
-
const initialStartRowRef = (0,
|
|
2078
|
+
const abortControllerRef = (0, import_react4.useRef)(null);
|
|
2079
|
+
const searchHandleRef = (0, import_react4.useRef)(void 0);
|
|
2080
|
+
const initialStartRowRef = (0, import_react4.useRef)(initialStartRow);
|
|
1833
2081
|
initialStartRowRef.current = initialStartRow;
|
|
1834
|
-
const getCellValueRef = (0,
|
|
2082
|
+
const getCellValueRef = (0, import_react4.useRef)(getCellValue);
|
|
1835
2083
|
getCellValueRef.current = getCellValue;
|
|
1836
2084
|
const showSearch = controlledShowSearch ?? internalShowSearch;
|
|
1837
2085
|
const searchValue = controlledSearchValue ?? internalSearchValue;
|
|
1838
2086
|
const searchResults = controlledSearchResults ?? internalResults;
|
|
1839
|
-
const setSearchValue = (0,
|
|
2087
|
+
const setSearchValue = (0, import_react4.useCallback)(
|
|
1840
2088
|
(value) => {
|
|
1841
2089
|
setInternalSearchValue(value);
|
|
1842
2090
|
onSearchValueChange?.(value);
|
|
1843
2091
|
},
|
|
1844
2092
|
[onSearchValueChange]
|
|
1845
2093
|
);
|
|
1846
|
-
const cancelSearch = (0,
|
|
2094
|
+
const cancelSearch = (0, import_react4.useCallback)(() => {
|
|
1847
2095
|
if (searchHandleRef.current !== void 0) {
|
|
1848
2096
|
window.cancelAnimationFrame(searchHandleRef.current);
|
|
1849
2097
|
searchHandleRef.current = void 0;
|
|
1850
2098
|
}
|
|
1851
2099
|
abortControllerRef.current?.abort();
|
|
1852
2100
|
}, []);
|
|
1853
|
-
const emitResultsChanged = (0,
|
|
2101
|
+
const emitResultsChanged = (0, import_react4.useCallback)(
|
|
1854
2102
|
(results, navIndex) => {
|
|
1855
2103
|
onSearchResultsChanged?.(results, navIndex);
|
|
1856
2104
|
},
|
|
1857
2105
|
[onSearchResultsChanged]
|
|
1858
2106
|
);
|
|
1859
|
-
const navigateToIndex = (0,
|
|
2107
|
+
const navigateToIndex = (0, import_react4.useCallback)(
|
|
1860
2108
|
(results, navIndex) => {
|
|
1861
2109
|
if (onSearchResultsChanged) return;
|
|
1862
2110
|
if (navIndex < 0 || navIndex >= results.length) return;
|
|
@@ -1866,7 +2114,7 @@ function useInlineSearch({
|
|
|
1866
2114
|
},
|
|
1867
2115
|
[onNavigateToResult, onSearchResultsChanged]
|
|
1868
2116
|
);
|
|
1869
|
-
const beginSearch = (0,
|
|
2117
|
+
const beginSearch = (0, import_react4.useCallback)(
|
|
1870
2118
|
(query) => {
|
|
1871
2119
|
if (controlledSearchResults !== void 0) return;
|
|
1872
2120
|
const totalRows = rowCount;
|
|
@@ -1938,12 +2186,12 @@ function useInlineSearch({
|
|
|
1938
2186
|
rowCount
|
|
1939
2187
|
]
|
|
1940
2188
|
);
|
|
1941
|
-
const openSearch = (0,
|
|
2189
|
+
const openSearch = (0, import_react4.useCallback)(() => {
|
|
1942
2190
|
if (controlledShowSearch === void 0) {
|
|
1943
2191
|
setInternalShowSearch(true);
|
|
1944
2192
|
}
|
|
1945
2193
|
}, [controlledShowSearch]);
|
|
1946
|
-
const closeSearch = (0,
|
|
2194
|
+
const closeSearch = (0, import_react4.useCallback)(() => {
|
|
1947
2195
|
if (controlledShowSearch === void 0) {
|
|
1948
2196
|
setInternalShowSearch(false);
|
|
1949
2197
|
}
|
|
@@ -1958,7 +2206,7 @@ function useInlineSearch({
|
|
|
1958
2206
|
emitResultsChanged,
|
|
1959
2207
|
onSearchClose
|
|
1960
2208
|
]);
|
|
1961
|
-
const goToNext = (0,
|
|
2209
|
+
const goToNext = (0, import_react4.useCallback)(() => {
|
|
1962
2210
|
if (!searchStatus || searchStatus.results === 0) return;
|
|
1963
2211
|
const newIndex = nextSearchIndex(
|
|
1964
2212
|
searchStatus.selectedIndex,
|
|
@@ -1968,7 +2216,7 @@ function useInlineSearch({
|
|
|
1968
2216
|
emitResultsChanged(searchResults, newIndex);
|
|
1969
2217
|
navigateToIndex(searchResults, newIndex);
|
|
1970
2218
|
}, [emitResultsChanged, navigateToIndex, searchResults, searchStatus]);
|
|
1971
|
-
const goToPrevious = (0,
|
|
2219
|
+
const goToPrevious = (0, import_react4.useCallback)(() => {
|
|
1972
2220
|
if (!searchStatus || searchStatus.results === 0) return;
|
|
1973
2221
|
const newIndex = previousSearchIndex(
|
|
1974
2222
|
searchStatus.selectedIndex,
|
|
@@ -1978,7 +2226,7 @@ function useInlineSearch({
|
|
|
1978
2226
|
emitResultsChanged(searchResults, newIndex);
|
|
1979
2227
|
navigateToIndex(searchResults, newIndex);
|
|
1980
2228
|
}, [emitResultsChanged, navigateToIndex, searchResults, searchStatus]);
|
|
1981
|
-
(0,
|
|
2229
|
+
(0, import_react4.useEffect)(() => {
|
|
1982
2230
|
if (controlledSearchResults === void 0) return;
|
|
1983
2231
|
if (controlledSearchResults.length > 0) {
|
|
1984
2232
|
setSearchStatus((current) => ({
|
|
@@ -1990,7 +2238,7 @@ function useInlineSearch({
|
|
|
1990
2238
|
setSearchStatus(void 0);
|
|
1991
2239
|
}
|
|
1992
2240
|
}, [controlledSearchResults, rowCount]);
|
|
1993
|
-
(0,
|
|
2241
|
+
(0, import_react4.useEffect)(() => {
|
|
1994
2242
|
if (!enabled) return;
|
|
1995
2243
|
setSearchStatus(void 0);
|
|
1996
2244
|
setInternalResults([]);
|
|
@@ -2003,7 +2251,7 @@ function useInlineSearch({
|
|
|
2003
2251
|
cancelSearch();
|
|
2004
2252
|
}
|
|
2005
2253
|
}, [enabled, showSearch]);
|
|
2006
|
-
(0,
|
|
2254
|
+
(0, import_react4.useEffect)(() => {
|
|
2007
2255
|
if (!enabled || !showSearch) return;
|
|
2008
2256
|
if (controlledSearchResults !== void 0) return;
|
|
2009
2257
|
if (searchValue.trim() === "") {
|
|
@@ -2023,7 +2271,7 @@ function useInlineSearch({
|
|
|
2023
2271
|
searchValue,
|
|
2024
2272
|
showSearch
|
|
2025
2273
|
]);
|
|
2026
|
-
(0,
|
|
2274
|
+
(0, import_react4.useEffect)(() => {
|
|
2027
2275
|
if (!enabled) return;
|
|
2028
2276
|
const handleKeyDown = (event) => {
|
|
2029
2277
|
if (!(event.ctrlKey || event.metaKey)) return;
|
|
@@ -2050,12 +2298,12 @@ function useInlineSearch({
|
|
|
2050
2298
|
window.addEventListener("keydown", handleKeyDown, true);
|
|
2051
2299
|
return () => window.removeEventListener("keydown", handleKeyDown, true);
|
|
2052
2300
|
}, [controlledShowSearch, enabled, rootRef, showSearch]);
|
|
2053
|
-
(0,
|
|
2054
|
-
const searchMatchKeys = (0,
|
|
2301
|
+
(0, import_react4.useEffect)(() => () => cancelSearch(), [cancelSearch]);
|
|
2302
|
+
const searchMatchKeys = (0, import_react4.useMemo)(
|
|
2055
2303
|
() => buildSearchMatchKeys(searchResults),
|
|
2056
2304
|
[searchResults]
|
|
2057
2305
|
);
|
|
2058
|
-
const activeMatch = (0,
|
|
2306
|
+
const activeMatch = (0, import_react4.useMemo)(() => {
|
|
2059
2307
|
if (!searchStatus || searchStatus.selectedIndex < 0) return null;
|
|
2060
2308
|
return searchResults[searchStatus.selectedIndex] ?? null;
|
|
2061
2309
|
}, [searchResults, searchStatus]);
|
|
@@ -2098,7 +2346,7 @@ function useInlineSearch({
|
|
|
2098
2346
|
}
|
|
2099
2347
|
|
|
2100
2348
|
// src/components/ui/table/features/row-expand/row-expand.ts
|
|
2101
|
-
var
|
|
2349
|
+
var import_react5 = require("react");
|
|
2102
2350
|
function getFieldValue(row, key) {
|
|
2103
2351
|
return row[key];
|
|
2104
2352
|
}
|
|
@@ -2128,12 +2376,12 @@ var useConvertTreeData = ({
|
|
|
2128
2376
|
expandedRows,
|
|
2129
2377
|
onExpandedRowsChange
|
|
2130
2378
|
}) => {
|
|
2131
|
-
const onExpandedRowsChangeRef = (0,
|
|
2132
|
-
const hasInitializedRef = (0,
|
|
2133
|
-
(0,
|
|
2379
|
+
const onExpandedRowsChangeRef = (0, import_react5.useRef)(onExpandedRowsChange);
|
|
2380
|
+
const hasInitializedRef = (0, import_react5.useRef)(false);
|
|
2381
|
+
(0, import_react5.useEffect)(() => {
|
|
2134
2382
|
onExpandedRowsChangeRef.current = onExpandedRowsChange;
|
|
2135
2383
|
}, [onExpandedRowsChange]);
|
|
2136
|
-
(0,
|
|
2384
|
+
(0, import_react5.useEffect)(() => {
|
|
2137
2385
|
if (!data || data.length === 0) {
|
|
2138
2386
|
hasInitializedRef.current = false;
|
|
2139
2387
|
return;
|
|
@@ -2143,7 +2391,7 @@ var useConvertTreeData = ({
|
|
|
2143
2391
|
onExpandedRowsChangeRef.current?.(new Set(ids));
|
|
2144
2392
|
hasInitializedRef.current = true;
|
|
2145
2393
|
}, [enabled, data, toggleField]);
|
|
2146
|
-
const processedData = (0,
|
|
2394
|
+
const processedData = (0, import_react5.useMemo)(() => {
|
|
2147
2395
|
if (!enabled || !data || data.length === 0) return [];
|
|
2148
2396
|
const flattenedData = [];
|
|
2149
2397
|
const flattenItems = (items) => {
|
|
@@ -2207,7 +2455,7 @@ var useConvertTreeData = ({
|
|
|
2207
2455
|
});
|
|
2208
2456
|
return rootItems;
|
|
2209
2457
|
}, [enabled, data, toggleField, childField, flattenField]);
|
|
2210
|
-
const flattenTree = (0,
|
|
2458
|
+
const flattenTree = (0, import_react5.useMemo)(() => {
|
|
2211
2459
|
if (!enabled) return [];
|
|
2212
2460
|
const flatten = (nodes, result = [], level = 0) => {
|
|
2213
2461
|
nodes.forEach((node, index) => {
|
|
@@ -2257,7 +2505,7 @@ var useConvertTreeData = ({
|
|
|
2257
2505
|
preventExpand,
|
|
2258
2506
|
expandedRows
|
|
2259
2507
|
]);
|
|
2260
|
-
const sortedData = (0,
|
|
2508
|
+
const sortedData = (0, import_react5.useMemo)(() => {
|
|
2261
2509
|
if (!enabled) {
|
|
2262
2510
|
return data ?? [];
|
|
2263
2511
|
}
|
|
@@ -2484,7 +2732,7 @@ function useGlideTable(options) {
|
|
|
2484
2732
|
searchResults,
|
|
2485
2733
|
onSearchResultsChanged
|
|
2486
2734
|
} = options;
|
|
2487
|
-
const labels = (0,
|
|
2735
|
+
const labels = (0, import_react6.useMemo)(() => {
|
|
2488
2736
|
const resolved = resolveDataTableLabels(labelsProp);
|
|
2489
2737
|
return {
|
|
2490
2738
|
...resolved,
|
|
@@ -2495,17 +2743,21 @@ function useGlideTable(options) {
|
|
|
2495
2743
|
}, [labelsProp, emptyText, loadingText, selectionLabel]);
|
|
2496
2744
|
const enableExpand = Boolean(toggleField);
|
|
2497
2745
|
const resolvedEnableSubtreeCopy = enableSubtreeCopy ?? enableExpand;
|
|
2498
|
-
const [internalRowSelection, setInternalRowSelection] = (0,
|
|
2499
|
-
const [internalColumnSizing, setInternalColumnSizing] = (0,
|
|
2500
|
-
const [internalColumnOrder, setInternalColumnOrder] = (0,
|
|
2501
|
-
const [internalExpandedRows, setInternalExpandedRows] = (0,
|
|
2746
|
+
const [internalRowSelection, setInternalRowSelection] = (0, import_react6.useState)({});
|
|
2747
|
+
const [internalColumnSizing, setInternalColumnSizing] = (0, import_react6.useState)({});
|
|
2748
|
+
const [internalColumnOrder, setInternalColumnOrder] = (0, import_react6.useState)([]);
|
|
2749
|
+
const [internalExpandedRows, setInternalExpandedRows] = (0, import_react6.useState)(
|
|
2502
2750
|
() => /* @__PURE__ */ new Set()
|
|
2503
2751
|
);
|
|
2504
|
-
const [hoveredRowIndex, setHoveredRowIndex] = (0,
|
|
2505
|
-
const scrollRef = (0,
|
|
2506
|
-
const rootRef = (0,
|
|
2752
|
+
const [hoveredRowIndex, setHoveredRowIndex] = (0, import_react6.useState)(null);
|
|
2753
|
+
const scrollRef = (0, import_react6.useRef)(null);
|
|
2754
|
+
const rootRef = (0, import_react6.useRef)(null);
|
|
2755
|
+
const cellRendererRegistry = (0, import_react6.useMemo)(
|
|
2756
|
+
() => createCellRendererRegistry(cellRenderers),
|
|
2757
|
+
[cellRenderers]
|
|
2758
|
+
);
|
|
2507
2759
|
const shouldVirtualize = enableVirtualization && !enableRowSpan;
|
|
2508
|
-
(0,
|
|
2760
|
+
(0, import_react6.useEffect)(() => {
|
|
2509
2761
|
if (enableVirtualization && enableRowSpan) {
|
|
2510
2762
|
console.warn(
|
|
2511
2763
|
"[useGlideTable] enableRowSpan is on; virtualization is disabled to preserve cell merges."
|
|
@@ -2519,11 +2771,11 @@ function useGlideTable(options) {
|
|
|
2519
2771
|
);
|
|
2520
2772
|
const columnSizing = controlledColumnSizing ?? internalColumnSizing;
|
|
2521
2773
|
const columnOrder = controlledColumnOrder ?? internalColumnOrder;
|
|
2522
|
-
const tableColumns = (0,
|
|
2774
|
+
const tableColumns = (0, import_react6.useMemo)(() => {
|
|
2523
2775
|
if (!enableColumnReorder) return columns;
|
|
2524
2776
|
return applyLeafColumnOrder(columns, columnOrder);
|
|
2525
2777
|
}, [columnOrder, columns, enableColumnReorder]);
|
|
2526
|
-
const setColumnOrder = (0,
|
|
2778
|
+
const setColumnOrder = (0, import_react6.useCallback)(
|
|
2527
2779
|
(next) => {
|
|
2528
2780
|
if (onColumnOrderChange) {
|
|
2529
2781
|
onColumnOrderChange(next);
|
|
@@ -2534,7 +2786,7 @@ function useGlideTable(options) {
|
|
|
2534
2786
|
[onColumnOrderChange]
|
|
2535
2787
|
);
|
|
2536
2788
|
const expandedRows = controlledExpandedRows ?? internalExpandedRows;
|
|
2537
|
-
const handleExpandedRowsChange = (0,
|
|
2789
|
+
const handleExpandedRowsChange = (0, import_react6.useCallback)(
|
|
2538
2790
|
(next) => {
|
|
2539
2791
|
if (onExpandedRowsChange) {
|
|
2540
2792
|
onExpandedRowsChange(next);
|
|
@@ -2595,13 +2847,13 @@ function useGlideTable(options) {
|
|
|
2595
2847
|
getCoreRowModel: (0, import_react_table.getCoreRowModel)(),
|
|
2596
2848
|
getRowId: getRowId ? (originalRow, index) => getRowId(originalRow, index) : (_originalRow, index) => String(index)
|
|
2597
2849
|
});
|
|
2598
|
-
const rowSpanColumnKeys = (0,
|
|
2850
|
+
const rowSpanColumnKeys = (0, import_react6.useMemo)(() => {
|
|
2599
2851
|
if (!enableRowSpan) return [];
|
|
2600
2852
|
return collectRowSpanColumns(columns);
|
|
2601
2853
|
}, [enableRowSpan, columns]);
|
|
2602
2854
|
const primaryRowSpanKey = rowSpanColumnKeys[0]?.rowSpanKey;
|
|
2603
2855
|
const primaryRowSpanColumnId = rowSpanColumnKeys[0]?.columnId;
|
|
2604
|
-
const columnRowSpanMap = (0,
|
|
2856
|
+
const columnRowSpanMap = (0, import_react6.useMemo)(
|
|
2605
2857
|
() => buildColumnRowSpanMap(tableData, rowSpanColumnKeys),
|
|
2606
2858
|
[tableData, rowSpanColumnKeys]
|
|
2607
2859
|
);
|
|
@@ -2610,7 +2862,7 @@ function useGlideTable(options) {
|
|
|
2610
2862
|
const rows = table.getRowModel().rows;
|
|
2611
2863
|
const columnCount = table.getAllLeafColumns().length || 1;
|
|
2612
2864
|
const visibleLeafColumns = table.getVisibleLeafColumns();
|
|
2613
|
-
const columnFreezeOffsets = (0,
|
|
2865
|
+
const columnFreezeOffsets = (0, import_react6.useMemo)(() => {
|
|
2614
2866
|
if (!enableColumnFreeze) return EMPTY_COLUMN_FREEZE_OFFSETS;
|
|
2615
2867
|
return buildColumnFreezeOffsets(
|
|
2616
2868
|
visibleLeafColumns.map((column) => ({
|
|
@@ -2630,14 +2882,14 @@ function useGlideTable(options) {
|
|
|
2630
2882
|
const totalSize = rowVirtualizer.getTotalSize();
|
|
2631
2883
|
const paddingTop = virtualRows.length > 0 ? virtualRows[0]?.start ?? 0 : 0;
|
|
2632
2884
|
const paddingBottom = virtualRows.length > 0 ? totalSize - (virtualRows[virtualRows.length - 1]?.end ?? 0) : 0;
|
|
2633
|
-
const selectedRowIndices = (0,
|
|
2885
|
+
const selectedRowIndices = (0, import_react6.useMemo)(() => {
|
|
2634
2886
|
const indices = /* @__PURE__ */ new Set();
|
|
2635
2887
|
for (const selectedRow of selectedRows) {
|
|
2636
2888
|
indices.add(selectedRow.index);
|
|
2637
2889
|
}
|
|
2638
2890
|
return indices;
|
|
2639
2891
|
}, [selectedRows]);
|
|
2640
|
-
const scrollCellIntoView = (0,
|
|
2892
|
+
const scrollCellIntoView = (0, import_react6.useCallback)(
|
|
2641
2893
|
(rowIndex, colIndex, options2) => {
|
|
2642
2894
|
const align = options2?.align ?? "nearest";
|
|
2643
2895
|
const blockAlign = align === "center" ? "center" : "nearest";
|
|
@@ -2664,7 +2916,7 @@ function useGlideTable(options) {
|
|
|
2664
2916
|
},
|
|
2665
2917
|
[rowVirtualizer, shouldVirtualize]
|
|
2666
2918
|
);
|
|
2667
|
-
const handleCellNavigate = (0,
|
|
2919
|
+
const handleCellNavigate = (0, import_react6.useCallback)(
|
|
2668
2920
|
(position) => {
|
|
2669
2921
|
scrollCellIntoView(position.row, position.col, { align: "nearest" });
|
|
2670
2922
|
},
|
|
@@ -2676,6 +2928,7 @@ function useGlideTable(options) {
|
|
|
2676
2928
|
handleCellMouseDown,
|
|
2677
2929
|
handleCellMouseEnter,
|
|
2678
2930
|
handleFillHandleMouseDown,
|
|
2931
|
+
clearSelection: clearCellSelection,
|
|
2679
2932
|
copySelection
|
|
2680
2933
|
} = useCellSelection({
|
|
2681
2934
|
data: tableData,
|
|
@@ -2687,8 +2940,46 @@ function useGlideTable(options) {
|
|
|
2687
2940
|
onDataChange,
|
|
2688
2941
|
onBatchChange,
|
|
2689
2942
|
onRowsPaste,
|
|
2690
|
-
onCellNavigate: handleCellNavigate
|
|
2943
|
+
onCellNavigate: handleCellNavigate,
|
|
2944
|
+
cellRendererRegistry,
|
|
2945
|
+
rootRef
|
|
2691
2946
|
});
|
|
2947
|
+
const clearRowSelection = (0, import_react6.useCallback)(() => {
|
|
2948
|
+
if (rowSelectionMode === "none") return;
|
|
2949
|
+
const hasSelection = Object.values(rowSelection).some(Boolean);
|
|
2950
|
+
if (!hasSelection) return;
|
|
2951
|
+
if (onRowSelectionChange) {
|
|
2952
|
+
onRowSelectionChange(() => ({}));
|
|
2953
|
+
return;
|
|
2954
|
+
}
|
|
2955
|
+
setInternalRowSelection({});
|
|
2956
|
+
}, [onRowSelectionChange, rowSelection, rowSelectionMode]);
|
|
2957
|
+
(0, import_react6.useEffect)(() => {
|
|
2958
|
+
const clearAllSelections = () => {
|
|
2959
|
+
clearCellSelection();
|
|
2960
|
+
clearRowSelection();
|
|
2961
|
+
};
|
|
2962
|
+
const handleKeyDown = (event) => {
|
|
2963
|
+
if (event.key !== "Escape") return;
|
|
2964
|
+
if (event.defaultPrevented) return;
|
|
2965
|
+
if (isEditablePasteTarget(event.target) || isEditablePasteTarget(document.activeElement)) {
|
|
2966
|
+
return;
|
|
2967
|
+
}
|
|
2968
|
+
clearAllSelections();
|
|
2969
|
+
};
|
|
2970
|
+
const handleMouseDown = (event) => {
|
|
2971
|
+
const root = rootRef.current;
|
|
2972
|
+
if (!root) return;
|
|
2973
|
+
if (event.target instanceof Node && root.contains(event.target)) return;
|
|
2974
|
+
clearAllSelections();
|
|
2975
|
+
};
|
|
2976
|
+
window.addEventListener("keydown", handleKeyDown);
|
|
2977
|
+
document.addEventListener("mousedown", handleMouseDown);
|
|
2978
|
+
return () => {
|
|
2979
|
+
window.removeEventListener("keydown", handleKeyDown);
|
|
2980
|
+
document.removeEventListener("mousedown", handleMouseDown);
|
|
2981
|
+
};
|
|
2982
|
+
}, [clearCellSelection, clearRowSelection]);
|
|
2692
2983
|
const {
|
|
2693
2984
|
editingCell,
|
|
2694
2985
|
draftValue,
|
|
@@ -2697,11 +2988,7 @@ function useGlideTable(options) {
|
|
|
2697
2988
|
commitEdit,
|
|
2698
2989
|
cancelEdit
|
|
2699
2990
|
} = useCellEdit({ data: tableData, rows, onDataChange, onCellChange });
|
|
2700
|
-
const
|
|
2701
|
-
() => createCellRendererRegistry(cellRenderers),
|
|
2702
|
-
[cellRenderers]
|
|
2703
|
-
);
|
|
2704
|
-
const commitRenderedCellValue = (0, import_react5.useCallback)(
|
|
2991
|
+
const commitRenderedCellValue = (0, import_react6.useCallback)(
|
|
2705
2992
|
(rowId, columnId, value) => commitCellValue({
|
|
2706
2993
|
data: tableData,
|
|
2707
2994
|
rows,
|
|
@@ -2713,11 +3000,11 @@ function useGlideTable(options) {
|
|
|
2713
3000
|
}),
|
|
2714
3001
|
[onCellChange, onDataChange, rows, tableData]
|
|
2715
3002
|
);
|
|
2716
|
-
const getCellContext = (0,
|
|
3003
|
+
const getCellContext = (0, import_react6.useCallback)(
|
|
2717
3004
|
(cell) => withCellUpdate(cell.getContext(), commitRenderedCellValue),
|
|
2718
3005
|
[commitRenderedCellValue]
|
|
2719
3006
|
);
|
|
2720
|
-
const handleCellMouseDownWithCommit = (0,
|
|
3007
|
+
const handleCellMouseDownWithCommit = (0, import_react6.useCallback)(
|
|
2721
3008
|
(rowIndex, colIndex, options2) => {
|
|
2722
3009
|
const isSameEditingCell = editingCell?.rowIndex === rowIndex && editingCell?.colIndex === colIndex;
|
|
2723
3010
|
if (editingCell && !isSameEditingCell && !commitEdit()) {
|
|
@@ -2727,7 +3014,7 @@ function useGlideTable(options) {
|
|
|
2727
3014
|
},
|
|
2728
3015
|
[commitEdit, editingCell, handleCellMouseDown]
|
|
2729
3016
|
);
|
|
2730
|
-
const navigateToSearchResult = (0,
|
|
3017
|
+
const navigateToSearchResult = (0, import_react6.useCallback)(
|
|
2731
3018
|
(item) => {
|
|
2732
3019
|
const [colIndex, rowIndex] = item;
|
|
2733
3020
|
handleCellMouseDownWithCommit(rowIndex, colIndex);
|
|
@@ -2735,7 +3022,7 @@ function useGlideTable(options) {
|
|
|
2735
3022
|
},
|
|
2736
3023
|
[handleCellMouseDownWithCommit, scrollCellIntoView]
|
|
2737
3024
|
);
|
|
2738
|
-
const resolveSearchRowId = (0,
|
|
3025
|
+
const resolveSearchRowId = (0, import_react6.useCallback)(
|
|
2739
3026
|
(row, index) => {
|
|
2740
3027
|
if (getRowId) return getRowId(row, index);
|
|
2741
3028
|
if (enableExpand) {
|
|
@@ -2759,7 +3046,7 @@ function useGlideTable(options) {
|
|
|
2759
3046
|
},
|
|
2760
3047
|
[enableExpand, getRowId, toggleField]
|
|
2761
3048
|
);
|
|
2762
|
-
const searchCorpus = (0,
|
|
3049
|
+
const searchCorpus = (0, import_react6.useMemo)(() => {
|
|
2763
3050
|
if (!enableInlineSearch) return [];
|
|
2764
3051
|
if (enableExpand && toggleField) {
|
|
2765
3052
|
return buildTreeSearchCorpus(tableData, {
|
|
@@ -2775,16 +3062,16 @@ function useGlideTable(options) {
|
|
|
2775
3062
|
tableData,
|
|
2776
3063
|
toggleField
|
|
2777
3064
|
]);
|
|
2778
|
-
const searchCorpusRef = (0,
|
|
3065
|
+
const searchCorpusRef = (0, import_react6.useRef)(searchCorpus);
|
|
2779
3066
|
searchCorpusRef.current = searchCorpus;
|
|
2780
|
-
const visibleRowIndexById = (0,
|
|
3067
|
+
const visibleRowIndexById = (0, import_react6.useMemo)(() => {
|
|
2781
3068
|
const map = /* @__PURE__ */ new Map();
|
|
2782
3069
|
for (const row of rows) {
|
|
2783
3070
|
map.set(resolveSearchRowId(row.original, row.index), row.index);
|
|
2784
3071
|
}
|
|
2785
3072
|
return map;
|
|
2786
3073
|
}, [resolveSearchRowId, rows]);
|
|
2787
|
-
const getSearchCellValue = (0,
|
|
3074
|
+
const getSearchCellValue = (0, import_react6.useCallback)(
|
|
2788
3075
|
(rowIndex, colIndex) => {
|
|
2789
3076
|
const corpusRow = searchCorpusRef.current[rowIndex];
|
|
2790
3077
|
const column = visibleLeafColumns[colIndex];
|
|
@@ -2807,14 +3094,14 @@ function useGlideTable(options) {
|
|
|
2807
3094
|
},
|
|
2808
3095
|
[rows, visibleLeafColumns, visibleRowIndexById]
|
|
2809
3096
|
);
|
|
2810
|
-
const pendingSearchNavRef = (0,
|
|
2811
|
-
const focusSearchResult = (0,
|
|
3097
|
+
const pendingSearchNavRef = (0, import_react6.useRef)(null);
|
|
3098
|
+
const focusSearchResult = (0, import_react6.useCallback)(
|
|
2812
3099
|
(colIndex, visibleRowIndex) => {
|
|
2813
3100
|
navigateToSearchResult([colIndex, visibleRowIndex]);
|
|
2814
3101
|
},
|
|
2815
3102
|
[navigateToSearchResult]
|
|
2816
3103
|
);
|
|
2817
|
-
const navigateToCorpusSearchResult = (0,
|
|
3104
|
+
const navigateToCorpusSearchResult = (0, import_react6.useCallback)(
|
|
2818
3105
|
(item) => {
|
|
2819
3106
|
const [colIndex, corpusRowIndex] = item;
|
|
2820
3107
|
const corpusRow = searchCorpusRef.current[corpusRowIndex];
|
|
@@ -2847,7 +3134,7 @@ function useGlideTable(options) {
|
|
|
2847
3134
|
visibleRowIndexById
|
|
2848
3135
|
]
|
|
2849
3136
|
);
|
|
2850
|
-
(0,
|
|
3137
|
+
(0, import_react6.useEffect)(() => {
|
|
2851
3138
|
const pending = pendingSearchNavRef.current;
|
|
2852
3139
|
if (!pending) return;
|
|
2853
3140
|
const visibleRowIndex = visibleRowIndexById.get(pending.rowId);
|
|
@@ -2871,7 +3158,7 @@ function useGlideTable(options) {
|
|
|
2871
3158
|
onNavigateToResult: navigateToCorpusSearchResult,
|
|
2872
3159
|
rootRef
|
|
2873
3160
|
});
|
|
2874
|
-
const visibleSearchMatchKeys = (0,
|
|
3161
|
+
const visibleSearchMatchKeys = (0, import_react6.useMemo)(() => {
|
|
2875
3162
|
if (!enableInlineSearch) return EMPTY_SEARCH_MATCH_KEYS;
|
|
2876
3163
|
return mapSearchResultsToVisibleKeys(
|
|
2877
3164
|
inlineSearch.searchResults,
|
|
@@ -2884,7 +3171,7 @@ function useGlideTable(options) {
|
|
|
2884
3171
|
searchCorpus,
|
|
2885
3172
|
visibleRowIndexById
|
|
2886
3173
|
]);
|
|
2887
|
-
const visibleActiveMatch = (0,
|
|
3174
|
+
const visibleActiveMatch = (0, import_react6.useMemo)(() => {
|
|
2888
3175
|
if (!enableInlineSearch || !inlineSearch.activeMatch) return null;
|
|
2889
3176
|
return mapSearchResultToVisibleItem(
|
|
2890
3177
|
inlineSearch.activeMatch,
|
|
@@ -2897,13 +3184,13 @@ function useGlideTable(options) {
|
|
|
2897
3184
|
searchCorpus,
|
|
2898
3185
|
visibleRowIndexById
|
|
2899
3186
|
]);
|
|
2900
|
-
const clearHover = (0,
|
|
3187
|
+
const clearHover = (0, import_react6.useCallback)(() => {
|
|
2901
3188
|
setHoveredRowIndex(null);
|
|
2902
3189
|
}, []);
|
|
2903
|
-
const handleRowHover = (0,
|
|
3190
|
+
const handleRowHover = (0, import_react6.useCallback)((rowIndex, _rowData) => {
|
|
2904
3191
|
setHoveredRowIndex(rowIndex);
|
|
2905
3192
|
}, []);
|
|
2906
|
-
const handleToggleSelect = (0,
|
|
3193
|
+
const handleToggleSelect = (0, import_react6.useCallback)(
|
|
2907
3194
|
(row) => {
|
|
2908
3195
|
if (!row.getCanSelect()) return;
|
|
2909
3196
|
if (preserveRowSelection && row.getIsSelected()) {
|
|
@@ -2913,14 +3200,14 @@ function useGlideTable(options) {
|
|
|
2913
3200
|
},
|
|
2914
3201
|
[preserveRowSelection]
|
|
2915
3202
|
);
|
|
2916
|
-
const handleToggleExpand = (0,
|
|
3203
|
+
const handleToggleExpand = (0, import_react6.useCallback)(
|
|
2917
3204
|
(rowKey) => {
|
|
2918
3205
|
if (preventExpand) return;
|
|
2919
3206
|
handleExpandedRowsChange(toggleExpandedRowId(rowKey, expandedRows));
|
|
2920
3207
|
},
|
|
2921
3208
|
[preventExpand, handleExpandedRowsChange, expandedRows]
|
|
2922
3209
|
);
|
|
2923
|
-
const rowContextValue = (0,
|
|
3210
|
+
const rowContextValue = (0, import_react6.useMemo)(() => {
|
|
2924
3211
|
return {
|
|
2925
3212
|
rowSpan: {
|
|
2926
3213
|
enableRowSpan,
|
|
@@ -3019,12 +3306,12 @@ function useGlideTable(options) {
|
|
|
3019
3306
|
visibleSearchMatchKeys,
|
|
3020
3307
|
visibleActiveMatch
|
|
3021
3308
|
]);
|
|
3022
|
-
const copySelectionRef = (0,
|
|
3023
|
-
(0,
|
|
3309
|
+
const copySelectionRef = (0, import_react6.useRef)(copySelection);
|
|
3310
|
+
(0, import_react6.useEffect)(() => {
|
|
3024
3311
|
copySelectionRef.current = copySelection;
|
|
3025
3312
|
}, [copySelection]);
|
|
3026
|
-
const stableCopySelection = (0,
|
|
3027
|
-
(0,
|
|
3313
|
+
const stableCopySelection = (0, import_react6.useCallback)((options2) => copySelectionRef.current(options2), []);
|
|
3314
|
+
(0, import_react6.useEffect)(() => {
|
|
3028
3315
|
onCopyActionsReady?.({ copySelection: stableCopySelection });
|
|
3029
3316
|
}, [onCopyActionsReady, stableCopySelection]);
|
|
3030
3317
|
return {
|
|
@@ -3073,16 +3360,18 @@ function useGlideTable(options) {
|
|
|
3073
3360
|
}
|
|
3074
3361
|
|
|
3075
3362
|
// src/components/ui/table/features/cell-render/ResolvedTableCell.tsx
|
|
3076
|
-
var
|
|
3363
|
+
var import_react8 = require("react");
|
|
3077
3364
|
|
|
3078
3365
|
// src/components/ui/table/DataTableContext.tsx
|
|
3079
|
-
var
|
|
3366
|
+
var import_react7 = require("react");
|
|
3080
3367
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
3081
|
-
var DataTableContext = (0,
|
|
3368
|
+
var DataTableContext = (0, import_react7.createContext)(null);
|
|
3082
3369
|
function useDataTableRowContext() {
|
|
3083
|
-
const context = (0,
|
|
3370
|
+
const context = (0, import_react7.use)(DataTableContext);
|
|
3084
3371
|
if (!context) {
|
|
3085
|
-
throw new Error(
|
|
3372
|
+
throw new Error(
|
|
3373
|
+
"useDataTableRowContext must be used within a DataTableContextProvider"
|
|
3374
|
+
);
|
|
3086
3375
|
}
|
|
3087
3376
|
return context;
|
|
3088
3377
|
}
|
|
@@ -3096,7 +3385,7 @@ function ResolvedTableCell({
|
|
|
3096
3385
|
const meta = column.columnDef.meta;
|
|
3097
3386
|
const value = getValue();
|
|
3098
3387
|
const columnId = column.id;
|
|
3099
|
-
const update = (0,
|
|
3388
|
+
const update = (0, import_react8.useCallback)(
|
|
3100
3389
|
(next) => {
|
|
3101
3390
|
cellRender.commitValue(row.id, columnId, next);
|
|
3102
3391
|
},
|
|
@@ -3121,8 +3410,105 @@ function ResolvedTableCell({
|
|
|
3121
3410
|
}
|
|
3122
3411
|
|
|
3123
3412
|
// src/components/ui/table/features/column-resize/columnResize.ts
|
|
3413
|
+
function clamp(value, min, max) {
|
|
3414
|
+
return Math.min(Math.max(value, min), max);
|
|
3415
|
+
}
|
|
3416
|
+
function floorOf(column) {
|
|
3417
|
+
return column.minWidth ?? 0;
|
|
3418
|
+
}
|
|
3419
|
+
function ceilOf(column) {
|
|
3420
|
+
return column.maxWidth ?? Number.POSITIVE_INFINITY;
|
|
3421
|
+
}
|
|
3422
|
+
function preferOf(column) {
|
|
3423
|
+
const floor = floorOf(column);
|
|
3424
|
+
const ceil = ceilOf(column);
|
|
3425
|
+
const preferred = column.maxWidth ?? column.minWidth ?? 0;
|
|
3426
|
+
return clamp(preferred, floor, Number.isFinite(ceil) ? ceil : preferred);
|
|
3427
|
+
}
|
|
3428
|
+
function resolveColumnLayoutWidths(containerWidth, columns) {
|
|
3429
|
+
const widths = /* @__PURE__ */ new Map();
|
|
3430
|
+
const fixed = [];
|
|
3431
|
+
const bounded = [];
|
|
3432
|
+
let flexCount = 0;
|
|
3433
|
+
for (const column of columns) {
|
|
3434
|
+
if (column.width != null) {
|
|
3435
|
+
fixed.push(column);
|
|
3436
|
+
} else if (column.minWidth != null || column.maxWidth != null) {
|
|
3437
|
+
bounded.push(column);
|
|
3438
|
+
} else {
|
|
3439
|
+
flexCount += 1;
|
|
3440
|
+
}
|
|
3441
|
+
}
|
|
3442
|
+
let used = 0;
|
|
3443
|
+
for (const column of fixed) {
|
|
3444
|
+
let size = column.width;
|
|
3445
|
+
if (column.minWidth != null) size = Math.max(size, column.minWidth);
|
|
3446
|
+
if (column.maxWidth != null) size = Math.min(size, column.maxWidth);
|
|
3447
|
+
widths.set(column.id, size);
|
|
3448
|
+
used += size;
|
|
3449
|
+
}
|
|
3450
|
+
if (bounded.length === 0) {
|
|
3451
|
+
return widths;
|
|
3452
|
+
}
|
|
3453
|
+
const boundedSizes = /* @__PURE__ */ new Map();
|
|
3454
|
+
let preferredSum = 0;
|
|
3455
|
+
let floorSum = 0;
|
|
3456
|
+
for (const column of bounded) {
|
|
3457
|
+
const preferred = preferOf(column);
|
|
3458
|
+
boundedSizes.set(column.id, preferred);
|
|
3459
|
+
preferredSum += preferred;
|
|
3460
|
+
floorSum += floorOf(column);
|
|
3461
|
+
}
|
|
3462
|
+
if (containerWidth > 0) {
|
|
3463
|
+
const remaining = Math.max(0, containerWidth - used);
|
|
3464
|
+
if (remaining >= preferredSum) {
|
|
3465
|
+
} else if (remaining >= floorSum) {
|
|
3466
|
+
let deficit = preferredSum - remaining;
|
|
3467
|
+
const open = bounded.map((column) => ({
|
|
3468
|
+
id: column.id,
|
|
3469
|
+
current: boundedSizes.get(column.id),
|
|
3470
|
+
floor: floorOf(column)
|
|
3471
|
+
}));
|
|
3472
|
+
while (deficit >= 1) {
|
|
3473
|
+
const shrinkable = open.filter((entry) => entry.current > entry.floor);
|
|
3474
|
+
if (shrinkable.length === 0) break;
|
|
3475
|
+
const portion = Math.floor(deficit / shrinkable.length);
|
|
3476
|
+
const rem = deficit % shrinkable.length;
|
|
3477
|
+
let consumed = 0;
|
|
3478
|
+
for (let index = 0; index < shrinkable.length; index += 1) {
|
|
3479
|
+
const entry = shrinkable[index];
|
|
3480
|
+
const reduce = Math.min(
|
|
3481
|
+
entry.current - entry.floor,
|
|
3482
|
+
portion + (index < rem ? 1 : 0)
|
|
3483
|
+
);
|
|
3484
|
+
entry.current -= reduce;
|
|
3485
|
+
consumed += reduce;
|
|
3486
|
+
}
|
|
3487
|
+
if (consumed === 0) break;
|
|
3488
|
+
deficit -= consumed;
|
|
3489
|
+
}
|
|
3490
|
+
for (const entry of open) {
|
|
3491
|
+
boundedSizes.set(entry.id, entry.current);
|
|
3492
|
+
}
|
|
3493
|
+
} else {
|
|
3494
|
+
for (const column of bounded) {
|
|
3495
|
+
boundedSizes.set(column.id, floorOf(column));
|
|
3496
|
+
}
|
|
3497
|
+
}
|
|
3498
|
+
}
|
|
3499
|
+
for (const [id, size] of boundedSizes) {
|
|
3500
|
+
widths.set(id, Math.round(size));
|
|
3501
|
+
}
|
|
3502
|
+
return widths;
|
|
3503
|
+
}
|
|
3124
3504
|
function getColumnSizeStyle(size, options) {
|
|
3125
|
-
const {
|
|
3505
|
+
const {
|
|
3506
|
+
force = false,
|
|
3507
|
+
lockMax = false,
|
|
3508
|
+
minWidth,
|
|
3509
|
+
maxWidth,
|
|
3510
|
+
layoutWidth
|
|
3511
|
+
} = options ?? {};
|
|
3126
3512
|
if (lockMax) {
|
|
3127
3513
|
return {
|
|
3128
3514
|
width: size,
|
|
@@ -3130,14 +3516,27 @@ function getColumnSizeStyle(size, options) {
|
|
|
3130
3516
|
maxWidth: size
|
|
3131
3517
|
};
|
|
3132
3518
|
}
|
|
3519
|
+
if (layoutWidth != null) {
|
|
3520
|
+
return {
|
|
3521
|
+
width: layoutWidth,
|
|
3522
|
+
minWidth: layoutWidth,
|
|
3523
|
+
maxWidth: layoutWidth
|
|
3524
|
+
};
|
|
3525
|
+
}
|
|
3526
|
+
const resolvedSize = size;
|
|
3133
3527
|
const hasExplicitSize = force || size !== DATA_TABLE_COLUMN_SIZE;
|
|
3134
3528
|
if (!hasExplicitSize && minWidth == null && maxWidth == null) {
|
|
3135
3529
|
return void 0;
|
|
3136
3530
|
}
|
|
3137
3531
|
const style = {};
|
|
3138
3532
|
if (hasExplicitSize) {
|
|
3139
|
-
|
|
3140
|
-
|
|
3533
|
+
const used = minWidth != null || maxWidth != null ? clamp(
|
|
3534
|
+
resolvedSize,
|
|
3535
|
+
minWidth ?? Number.NEGATIVE_INFINITY,
|
|
3536
|
+
maxWidth ?? Number.POSITIVE_INFINITY
|
|
3537
|
+
) : resolvedSize;
|
|
3538
|
+
style.width = used;
|
|
3539
|
+
style.minWidth = minWidth ?? used;
|
|
3141
3540
|
} else if (minWidth != null) {
|
|
3142
3541
|
style.minWidth = minWidth;
|
|
3143
3542
|
}
|
|
@@ -3148,7 +3547,7 @@ function getColumnSizeStyle(size, options) {
|
|
|
3148
3547
|
}
|
|
3149
3548
|
|
|
3150
3549
|
// src/components/ui/table/features/column-reorder/useColumnReorder.ts
|
|
3151
|
-
var
|
|
3550
|
+
var import_react9 = require("react");
|
|
3152
3551
|
function hitTestReorderHeader(table, clientX, clientY) {
|
|
3153
3552
|
const headers = Array.from(
|
|
3154
3553
|
table.querySelectorAll(
|
|
@@ -3196,19 +3595,19 @@ function readTargetIds(table, columnId) {
|
|
|
3196
3595
|
}
|
|
3197
3596
|
function useColumnReorder(options) {
|
|
3198
3597
|
const { enabled, columnOrder, onColumnOrderChange } = options;
|
|
3199
|
-
const sessionRef = (0,
|
|
3200
|
-
const columnOrderRef = (0,
|
|
3201
|
-
const onColumnOrderChangeRef = (0,
|
|
3202
|
-
const [draggingColumnId, setDraggingColumnId] = (0,
|
|
3203
|
-
const [dropTarget, setDropTarget] = (0,
|
|
3598
|
+
const sessionRef = (0, import_react9.useRef)(null);
|
|
3599
|
+
const columnOrderRef = (0, import_react9.useRef)(columnOrder);
|
|
3600
|
+
const onColumnOrderChangeRef = (0, import_react9.useRef)(onColumnOrderChange);
|
|
3601
|
+
const [draggingColumnId, setDraggingColumnId] = (0, import_react9.useState)(null);
|
|
3602
|
+
const [dropTarget, setDropTarget] = (0, import_react9.useState)(
|
|
3204
3603
|
null
|
|
3205
3604
|
);
|
|
3206
|
-
const dropTargetRef = (0,
|
|
3207
|
-
const previousUserSelectRef = (0,
|
|
3605
|
+
const dropTargetRef = (0, import_react9.useRef)(dropTarget);
|
|
3606
|
+
const previousUserSelectRef = (0, import_react9.useRef)(null);
|
|
3208
3607
|
columnOrderRef.current = columnOrder;
|
|
3209
3608
|
onColumnOrderChangeRef.current = onColumnOrderChange;
|
|
3210
3609
|
dropTargetRef.current = dropTarget;
|
|
3211
|
-
const resetDrag = (0,
|
|
3610
|
+
const resetDrag = (0, import_react9.useCallback)(() => {
|
|
3212
3611
|
sessionRef.current = null;
|
|
3213
3612
|
setDraggingColumnId(null);
|
|
3214
3613
|
setDropTarget(null);
|
|
@@ -3224,15 +3623,15 @@ function useColumnReorder(options) {
|
|
|
3224
3623
|
}
|
|
3225
3624
|
document.body.style.removeProperty("user-select");
|
|
3226
3625
|
}, []);
|
|
3227
|
-
(0,
|
|
3626
|
+
(0, import_react9.useEffect)(() => {
|
|
3228
3627
|
if (!enabled) resetDrag();
|
|
3229
3628
|
}, [enabled, resetDrag]);
|
|
3230
|
-
(0,
|
|
3629
|
+
(0, import_react9.useEffect)(() => {
|
|
3231
3630
|
return () => {
|
|
3232
3631
|
resetDrag();
|
|
3233
3632
|
};
|
|
3234
3633
|
}, [resetDrag]);
|
|
3235
|
-
const onHeaderPointerDown = (0,
|
|
3634
|
+
const onHeaderPointerDown = (0, import_react9.useCallback)(
|
|
3236
3635
|
(event, meta) => {
|
|
3237
3636
|
if (!enabled || !meta.canDrag) return;
|
|
3238
3637
|
if (event.button !== 0) return;
|
|
@@ -3255,7 +3654,7 @@ function useColumnReorder(options) {
|
|
|
3255
3654
|
},
|
|
3256
3655
|
[enabled]
|
|
3257
3656
|
);
|
|
3258
|
-
(0,
|
|
3657
|
+
(0, import_react9.useEffect)(() => {
|
|
3259
3658
|
if (!enabled) return;
|
|
3260
3659
|
const onPointerMove = (event) => {
|
|
3261
3660
|
const session = sessionRef.current;
|
|
@@ -3416,6 +3815,7 @@ function useColumnReorder(options) {
|
|
|
3416
3815
|
previousSearchIndex,
|
|
3417
3816
|
resolveCellRenderer,
|
|
3418
3817
|
resolveColumnFreezeSide,
|
|
3818
|
+
resolveColumnLayoutWidths,
|
|
3419
3819
|
resolveDataTableLabels,
|
|
3420
3820
|
resolveDropEdge,
|
|
3421
3821
|
resolveHeaderFreezeOffset,
|