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/index.js
CHANGED
|
@@ -441,6 +441,90 @@ function withCellUpdate(context, commitValue) {
|
|
|
441
441
|
};
|
|
442
442
|
}
|
|
443
443
|
|
|
444
|
+
// src/components/ui/table/features/cell-selection/pasteData.ts
|
|
445
|
+
function countLeadingEmptyCells(cells) {
|
|
446
|
+
let depth = 0;
|
|
447
|
+
while (depth < cells.length && cells[depth] === "") {
|
|
448
|
+
depth += 1;
|
|
449
|
+
}
|
|
450
|
+
return depth;
|
|
451
|
+
}
|
|
452
|
+
function looksLikeSubtreeIndentation(leadingEmptyCounts) {
|
|
453
|
+
if (leadingEmptyCounts.length === 0) return false;
|
|
454
|
+
const firstDepth = leadingEmptyCounts[0] ?? 0;
|
|
455
|
+
if (firstDepth !== 0) return false;
|
|
456
|
+
return leadingEmptyCounts.some((depth) => depth > 0);
|
|
457
|
+
}
|
|
458
|
+
function parseClipboardTSV(text) {
|
|
459
|
+
return parseClipboardTSVWithDepths(text).values;
|
|
460
|
+
}
|
|
461
|
+
function parseClipboardTSVWithDepths(text) {
|
|
462
|
+
if (!text) return { values: [], depths: [] };
|
|
463
|
+
const normalized = text.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
464
|
+
const withoutTrailing = normalized.replace(/\n+$/, "");
|
|
465
|
+
if (!withoutTrailing) return { values: [], depths: [] };
|
|
466
|
+
const rows = withoutTrailing.split("\n").map((line) => line.split(" "));
|
|
467
|
+
const leadingEmptyCounts = rows.map(countLeadingEmptyCells);
|
|
468
|
+
const treatAsDepth = looksLikeSubtreeIndentation(leadingEmptyCounts);
|
|
469
|
+
const values = [];
|
|
470
|
+
const depths = [];
|
|
471
|
+
for (let index = 0; index < rows.length; index += 1) {
|
|
472
|
+
const cells = rows[index] ?? [];
|
|
473
|
+
const depth = leadingEmptyCounts[index] ?? 0;
|
|
474
|
+
if (treatAsDepth) {
|
|
475
|
+
values.push(cells.slice(depth));
|
|
476
|
+
depths.push(depth);
|
|
477
|
+
} else {
|
|
478
|
+
values.push(cells);
|
|
479
|
+
depths.push(0);
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
return { values, depths };
|
|
483
|
+
}
|
|
484
|
+
function resolvePasteColumnIds(rows, startCol, width) {
|
|
485
|
+
if (width <= 0) return [];
|
|
486
|
+
const cells = rows[0]?.getVisibleCells() ?? [];
|
|
487
|
+
const columnIds = [];
|
|
488
|
+
for (let offset = 0; offset < width; offset += 1) {
|
|
489
|
+
const cell = cells[startCol + offset];
|
|
490
|
+
if (!cell) break;
|
|
491
|
+
columnIds.push(cell.column.id);
|
|
492
|
+
}
|
|
493
|
+
return columnIds;
|
|
494
|
+
}
|
|
495
|
+
function buildRowsPastePayload(rows, startRow, startCol, text, mode, endRow = startRow) {
|
|
496
|
+
const { values, depths } = parseClipboardTSVWithDepths(text);
|
|
497
|
+
if (values.length === 0) return null;
|
|
498
|
+
const width = Math.max(...values.map((row) => row.length), 0);
|
|
499
|
+
if (width === 0) return null;
|
|
500
|
+
const columnIds = resolvePasteColumnIds(rows, startCol, width);
|
|
501
|
+
if (columnIds.length === 0) return null;
|
|
502
|
+
const rowIds = [];
|
|
503
|
+
for (let offset = 0; offset < values.length; offset += 1) {
|
|
504
|
+
const row = rows[startRow + offset];
|
|
505
|
+
if (!row) break;
|
|
506
|
+
rowIds.push(row.id);
|
|
507
|
+
}
|
|
508
|
+
const anchorRow = rows[endRow] ?? rows[startRow];
|
|
509
|
+
return {
|
|
510
|
+
mode,
|
|
511
|
+
startRow,
|
|
512
|
+
startCol,
|
|
513
|
+
endRow,
|
|
514
|
+
rowIds,
|
|
515
|
+
anchorRowId: anchorRow?.id ?? "",
|
|
516
|
+
columnIds,
|
|
517
|
+
values,
|
|
518
|
+
depths
|
|
519
|
+
};
|
|
520
|
+
}
|
|
521
|
+
function isEditablePasteTarget(target) {
|
|
522
|
+
if (!(target instanceof HTMLElement)) return false;
|
|
523
|
+
const tag = target.tagName;
|
|
524
|
+
if (tag === "INPUT" || tag === "TEXTAREA" || tag === "SELECT") return true;
|
|
525
|
+
return Boolean(target.isContentEditable);
|
|
526
|
+
}
|
|
527
|
+
|
|
444
528
|
// src/components/ui/table/features/cell-selection/useCellSelection.ts
|
|
445
529
|
import { useCallback as useCallback2, useEffect as useEffect2, useRef as useRef2, useState as useState2 } from "react";
|
|
446
530
|
|
|
@@ -750,6 +834,219 @@ function hasCellSelectionEdges(style) {
|
|
|
750
834
|
}
|
|
751
835
|
|
|
752
836
|
// src/components/ui/table/features/cell-selection/copyData.ts
|
|
837
|
+
import { isValidElement } from "react";
|
|
838
|
+
function isReactNodeIterable(node) {
|
|
839
|
+
return typeof node === "object" && node !== null && !isValidElement(node) && Symbol.iterator in node;
|
|
840
|
+
}
|
|
841
|
+
function getElementTypeName(type) {
|
|
842
|
+
if (typeof type === "string") return type;
|
|
843
|
+
if (typeof type === "function") {
|
|
844
|
+
const fn = type;
|
|
845
|
+
return fn.displayName || fn.name || "";
|
|
846
|
+
}
|
|
847
|
+
if (typeof type === "object" && type !== null) {
|
|
848
|
+
const component = type;
|
|
849
|
+
return component.displayName || component.render?.displayName || component.render?.name || "";
|
|
850
|
+
}
|
|
851
|
+
return "";
|
|
852
|
+
}
|
|
853
|
+
function isButtonReactElement(node) {
|
|
854
|
+
const typeName = getElementTypeName(node.type);
|
|
855
|
+
if (typeName === "button" || /button/i.test(typeName)) return true;
|
|
856
|
+
const props = node.props;
|
|
857
|
+
if (props.role === "button") return true;
|
|
858
|
+
if (typeName === "input" && props.type === "button") return true;
|
|
859
|
+
return false;
|
|
860
|
+
}
|
|
861
|
+
function isImageReactElement(node) {
|
|
862
|
+
const typeName = getElementTypeName(node.type);
|
|
863
|
+
return typeName === "img" || typeName === "image" || /image/i.test(typeName);
|
|
864
|
+
}
|
|
865
|
+
var IMAGE_URL_PROP_KEYS = ["src", "url", "href", "imageUrl", "srcUrl"];
|
|
866
|
+
function isLikelyUrl(value) {
|
|
867
|
+
const trimmed = value.trim();
|
|
868
|
+
if (!trimmed) return false;
|
|
869
|
+
if (/^(https?:|blob:|data:|\/\/)/i.test(trimmed)) return true;
|
|
870
|
+
if (trimmed.startsWith("/") && trimmed.includes("/")) return true;
|
|
871
|
+
return false;
|
|
872
|
+
}
|
|
873
|
+
function pickUrlFromUnknown(value) {
|
|
874
|
+
if (typeof value === "string") {
|
|
875
|
+
return isLikelyUrl(value) ? value.trim() : "";
|
|
876
|
+
}
|
|
877
|
+
if (Array.isArray(value)) {
|
|
878
|
+
return value.map((item) => pickUrlFromUnknown(item)).filter((item) => item.length > 0).join(", ");
|
|
879
|
+
}
|
|
880
|
+
if (value && typeof value === "object") {
|
|
881
|
+
const record = value;
|
|
882
|
+
for (const key of IMAGE_URL_PROP_KEYS) {
|
|
883
|
+
const candidate = record[key];
|
|
884
|
+
if (typeof candidate === "string" && candidate.trim()) {
|
|
885
|
+
return candidate.trim();
|
|
886
|
+
}
|
|
887
|
+
}
|
|
888
|
+
}
|
|
889
|
+
return "";
|
|
890
|
+
}
|
|
891
|
+
function imageElementText(node) {
|
|
892
|
+
const props = node.props;
|
|
893
|
+
for (const key of IMAGE_URL_PROP_KEYS) {
|
|
894
|
+
const candidate = props[key];
|
|
895
|
+
if (typeof candidate === "string" && candidate.trim()) {
|
|
896
|
+
return candidate.trim();
|
|
897
|
+
}
|
|
898
|
+
}
|
|
899
|
+
return "";
|
|
900
|
+
}
|
|
901
|
+
function reactNodeContainsImage(node) {
|
|
902
|
+
if (isValidElement(node)) {
|
|
903
|
+
if (isImageReactElement(node)) return true;
|
|
904
|
+
return reactNodeContainsImage(node.props.children);
|
|
905
|
+
}
|
|
906
|
+
if (isReactNodeIterable(node)) {
|
|
907
|
+
for (const child of node) {
|
|
908
|
+
if (reactNodeContainsImage(child)) return true;
|
|
909
|
+
}
|
|
910
|
+
}
|
|
911
|
+
return false;
|
|
912
|
+
}
|
|
913
|
+
function readImgUrl(img) {
|
|
914
|
+
const attr = img.getAttribute("src")?.trim() ?? "";
|
|
915
|
+
if (attr) return attr;
|
|
916
|
+
if (img instanceof HTMLImageElement) {
|
|
917
|
+
const current = img.currentSrc?.trim() ?? "";
|
|
918
|
+
if (current && current !== img.baseURI) return current;
|
|
919
|
+
}
|
|
920
|
+
return "";
|
|
921
|
+
}
|
|
922
|
+
function readDomImageUrls(rowIndex, colIndex, root) {
|
|
923
|
+
const scope = root ?? (typeof document === "undefined" ? null : document);
|
|
924
|
+
if (!scope) return "";
|
|
925
|
+
const cells = scope.querySelectorAll(
|
|
926
|
+
`[data-row-index="${rowIndex}"][data-col-index="${colIndex}"]`
|
|
927
|
+
);
|
|
928
|
+
for (const cell of cells) {
|
|
929
|
+
const urls = Array.from(cell.querySelectorAll("img")).flatMap((img) => {
|
|
930
|
+
const url = readImgUrl(img);
|
|
931
|
+
return url ? [url] : [];
|
|
932
|
+
});
|
|
933
|
+
if (urls.length > 0) return urls.join(", ");
|
|
934
|
+
}
|
|
935
|
+
return "";
|
|
936
|
+
}
|
|
937
|
+
function reactNodeToText(node) {
|
|
938
|
+
if (node == null || typeof node === "boolean") return "";
|
|
939
|
+
if (typeof node === "string" || typeof node === "number" || typeof node === "bigint") {
|
|
940
|
+
return String(node);
|
|
941
|
+
}
|
|
942
|
+
if (isReactNodeIterable(node)) {
|
|
943
|
+
let text = "";
|
|
944
|
+
for (const child of node) {
|
|
945
|
+
text += reactNodeToText(child);
|
|
946
|
+
}
|
|
947
|
+
return text;
|
|
948
|
+
}
|
|
949
|
+
if (isValidElement(node)) {
|
|
950
|
+
if (isButtonReactElement(node)) return "";
|
|
951
|
+
const props = node.props;
|
|
952
|
+
const childText = reactNodeToText(props.children);
|
|
953
|
+
if (childText) return childText;
|
|
954
|
+
const fromImage = imageElementText(node);
|
|
955
|
+
if (fromImage) return fromImage;
|
|
956
|
+
if (isImageReactElement(node)) return "";
|
|
957
|
+
if (typeof props.alt === "string" && props.alt) return props.alt;
|
|
958
|
+
if (typeof props.title === "string" && props.title) return props.title;
|
|
959
|
+
return "";
|
|
960
|
+
}
|
|
961
|
+
return "";
|
|
962
|
+
}
|
|
963
|
+
function sanitizeClipboardCell(text) {
|
|
964
|
+
return text.replace(/\s+/g, " ").trim();
|
|
965
|
+
}
|
|
966
|
+
function createCopyRenderRow(rowData, index) {
|
|
967
|
+
return {
|
|
968
|
+
id: getOriginalRowId(rowData) || String(index),
|
|
969
|
+
index,
|
|
970
|
+
original: rowData,
|
|
971
|
+
getIsCellDragSelected: () => false
|
|
972
|
+
};
|
|
973
|
+
}
|
|
974
|
+
function buildVisibleRowLookup(visibleRows) {
|
|
975
|
+
const lookup = /* @__PURE__ */ new Map();
|
|
976
|
+
for (const row of visibleRows) {
|
|
977
|
+
lookup.set(row.original, row);
|
|
978
|
+
}
|
|
979
|
+
return lookup;
|
|
980
|
+
}
|
|
981
|
+
function resolveCopyColumnId(cell) {
|
|
982
|
+
if (cell.column.id) return cell.column.id;
|
|
983
|
+
const columnDef = cell.column.columnDef;
|
|
984
|
+
if (columnDef.id) return columnDef.id;
|
|
985
|
+
if (columnDef.accessorKey != null && columnDef.accessorKey !== "") {
|
|
986
|
+
return String(columnDef.accessorKey);
|
|
987
|
+
}
|
|
988
|
+
return "";
|
|
989
|
+
}
|
|
990
|
+
function isPrimitiveCopyValue(value) {
|
|
991
|
+
return value == null || typeof value !== "object";
|
|
992
|
+
}
|
|
993
|
+
function extractRenderedCopyText(node, value, cellPosition, root) {
|
|
994
|
+
const rendered = sanitizeClipboardCell(reactNodeToText(node));
|
|
995
|
+
if (reactNodeContainsImage(node)) {
|
|
996
|
+
const fromDom = cellPosition != null ? sanitizeClipboardCell(
|
|
997
|
+
readDomImageUrls(cellPosition.rowIndex, cellPosition.colIndex, root)
|
|
998
|
+
) : "";
|
|
999
|
+
if (fromDom) return fromDom;
|
|
1000
|
+
if (rendered && isLikelyUrl(rendered)) return rendered;
|
|
1001
|
+
return sanitizeClipboardCell(pickUrlFromUnknown(value));
|
|
1002
|
+
}
|
|
1003
|
+
return rendered;
|
|
1004
|
+
}
|
|
1005
|
+
function formatCopyCellText(rowData, columnDef, columnId, visibleRow, fallbackIndex, sourceCell, cellPosition, options) {
|
|
1006
|
+
const meta = columnDef.meta;
|
|
1007
|
+
const value = sourceCell ? sourceCell.getValue() : readRowColumnValue(rowData, columnDef);
|
|
1008
|
+
const cellRender = meta?.cellRender;
|
|
1009
|
+
if (typeof cellRender === "function") {
|
|
1010
|
+
try {
|
|
1011
|
+
const row = visibleRow ?? createCopyRenderRow(rowData, fallbackIndex);
|
|
1012
|
+
const node = cellRender({
|
|
1013
|
+
value,
|
|
1014
|
+
row,
|
|
1015
|
+
index: row.index,
|
|
1016
|
+
columnId,
|
|
1017
|
+
cellProps: meta?.cellProps,
|
|
1018
|
+
update: () => {
|
|
1019
|
+
}
|
|
1020
|
+
});
|
|
1021
|
+
return extractRenderedCopyText(node, value, cellPosition, options?.root);
|
|
1022
|
+
} catch {
|
|
1023
|
+
return formatCellValue(value);
|
|
1024
|
+
}
|
|
1025
|
+
}
|
|
1026
|
+
if (options?.registry && meta?.kind && isPrimitiveCopyValue(value)) {
|
|
1027
|
+
try {
|
|
1028
|
+
const row = visibleRow ?? createCopyRenderRow(rowData, fallbackIndex);
|
|
1029
|
+
const ctx = {
|
|
1030
|
+
value,
|
|
1031
|
+
row,
|
|
1032
|
+
index: row.index,
|
|
1033
|
+
columnId,
|
|
1034
|
+
cellProps: meta.cellProps,
|
|
1035
|
+
update: () => {
|
|
1036
|
+
}
|
|
1037
|
+
};
|
|
1038
|
+
const renderer = resolveCellRenderer(options.registry, meta.kind, ctx);
|
|
1039
|
+
if (renderer) {
|
|
1040
|
+
const node = renderer.render(ctx);
|
|
1041
|
+
const rendered = extractRenderedCopyText(node, value, cellPosition, options.root);
|
|
1042
|
+
if (rendered) return rendered;
|
|
1043
|
+
}
|
|
1044
|
+
} catch {
|
|
1045
|
+
return formatCellValue(value);
|
|
1046
|
+
}
|
|
1047
|
+
}
|
|
1048
|
+
return formatCellValue(value);
|
|
1049
|
+
}
|
|
753
1050
|
function formatPrimitive(value) {
|
|
754
1051
|
if (value === null || value === void 0) return "";
|
|
755
1052
|
if (typeof value === "string") return value;
|
|
@@ -855,37 +1152,47 @@ function collectCopyRowEntries(visibleRows, bounds, mode = "visible") {
|
|
|
855
1152
|
function collectCopyRows(visibleRows, bounds, mode = "visible") {
|
|
856
1153
|
return collectCopyRowEntries(visibleRows, bounds, mode).map((entry) => entry.row);
|
|
857
1154
|
}
|
|
858
|
-
function serializeCopyRowsToTSV(copyRows, visibleRows, bounds, depths) {
|
|
1155
|
+
function serializeCopyRowsToTSV(copyRows, visibleRows, bounds, depths, options) {
|
|
859
1156
|
if (copyRows.length === 0) return "";
|
|
860
1157
|
const { startCol, endCol } = bounds;
|
|
861
1158
|
const columnCells = visibleRows[0]?.getVisibleCells().slice(startCol, endCol + 1) ?? [];
|
|
862
1159
|
if (columnCells.length === 0) return "";
|
|
863
1160
|
const resolvedDepths = depths && depths.length === copyRows.length ? depths : copyRows.map((row) => getRowDepth(row));
|
|
864
1161
|
const minDepth = Math.min(...resolvedDepths);
|
|
1162
|
+
const visibleRowByOriginal = buildVisibleRowLookup(visibleRows);
|
|
865
1163
|
return copyRows.map((rowData, index) => {
|
|
866
1164
|
const relativeDepth = Math.max(0, (resolvedDepths[index] ?? 0) - minDepth);
|
|
867
|
-
const
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
1165
|
+
const visibleRow = visibleRowByOriginal.get(rowData);
|
|
1166
|
+
const matchingCells = visibleRow?.getVisibleCells().slice(startCol, endCol + 1);
|
|
1167
|
+
const line = columnCells.map((templateCell, colOffset) => {
|
|
1168
|
+
const sourceCell = matchingCells?.[colOffset];
|
|
1169
|
+
const column = sourceCell?.column ?? templateCell.column;
|
|
1170
|
+
return formatCopyCellText(
|
|
1171
|
+
rowData,
|
|
1172
|
+
column.columnDef,
|
|
1173
|
+
resolveCopyColumnId(sourceCell ?? templateCell),
|
|
1174
|
+
visibleRow,
|
|
1175
|
+
visibleRow?.index ?? index,
|
|
1176
|
+
sourceCell,
|
|
1177
|
+
visibleRow != null ? { rowIndex: visibleRow.index, colIndex: startCol + colOffset } : void 0,
|
|
1178
|
+
options
|
|
1179
|
+
);
|
|
1180
|
+
}).join(" ");
|
|
875
1181
|
return `${" ".repeat(relativeDepth)}${line}`;
|
|
876
1182
|
}).join("\n");
|
|
877
1183
|
}
|
|
878
|
-
function serializeSelectionToTSV(visibleRows, bounds, mode = "visible") {
|
|
1184
|
+
function serializeSelectionToTSV(visibleRows, bounds, mode = "visible", options) {
|
|
879
1185
|
const entries = collectCopyRowEntries(visibleRows, bounds, mode);
|
|
880
1186
|
return serializeCopyRowsToTSV(
|
|
881
1187
|
entries.map((entry) => entry.row),
|
|
882
1188
|
visibleRows,
|
|
883
1189
|
bounds,
|
|
884
|
-
entries.map((entry) => entry.depth)
|
|
1190
|
+
entries.map((entry) => entry.depth),
|
|
1191
|
+
options
|
|
885
1192
|
);
|
|
886
1193
|
}
|
|
887
|
-
async function writeSelectionToClipboard(visibleRows, bounds, mode = "visible") {
|
|
888
|
-
const text = serializeSelectionToTSV(visibleRows, bounds, mode);
|
|
1194
|
+
async function writeSelectionToClipboard(visibleRows, bounds, mode = "visible", options) {
|
|
1195
|
+
const text = serializeSelectionToTSV(visibleRows, bounds, mode, options);
|
|
889
1196
|
if (!text) return false;
|
|
890
1197
|
try {
|
|
891
1198
|
await navigator.clipboard.writeText(text);
|
|
@@ -951,90 +1258,6 @@ function hasFillExtension(sourceBounds, fillBounds) {
|
|
|
951
1258
|
return fillBounds.startRow < sourceBounds.startRow || fillBounds.endRow > sourceBounds.endRow || fillBounds.startCol < sourceBounds.startCol || fillBounds.endCol > sourceBounds.endCol;
|
|
952
1259
|
}
|
|
953
1260
|
|
|
954
|
-
// src/components/ui/table/features/cell-selection/pasteData.ts
|
|
955
|
-
function countLeadingEmptyCells(cells) {
|
|
956
|
-
let depth = 0;
|
|
957
|
-
while (depth < cells.length && cells[depth] === "") {
|
|
958
|
-
depth += 1;
|
|
959
|
-
}
|
|
960
|
-
return depth;
|
|
961
|
-
}
|
|
962
|
-
function looksLikeSubtreeIndentation(leadingEmptyCounts) {
|
|
963
|
-
if (leadingEmptyCounts.length === 0) return false;
|
|
964
|
-
const firstDepth = leadingEmptyCounts[0] ?? 0;
|
|
965
|
-
if (firstDepth !== 0) return false;
|
|
966
|
-
return leadingEmptyCounts.some((depth) => depth > 0);
|
|
967
|
-
}
|
|
968
|
-
function parseClipboardTSV(text) {
|
|
969
|
-
return parseClipboardTSVWithDepths(text).values;
|
|
970
|
-
}
|
|
971
|
-
function parseClipboardTSVWithDepths(text) {
|
|
972
|
-
if (!text) return { values: [], depths: [] };
|
|
973
|
-
const normalized = text.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
974
|
-
const withoutTrailing = normalized.replace(/\n+$/, "");
|
|
975
|
-
if (!withoutTrailing) return { values: [], depths: [] };
|
|
976
|
-
const rows = withoutTrailing.split("\n").map((line) => line.split(" "));
|
|
977
|
-
const leadingEmptyCounts = rows.map(countLeadingEmptyCells);
|
|
978
|
-
const treatAsDepth = looksLikeSubtreeIndentation(leadingEmptyCounts);
|
|
979
|
-
const values = [];
|
|
980
|
-
const depths = [];
|
|
981
|
-
for (let index = 0; index < rows.length; index += 1) {
|
|
982
|
-
const cells = rows[index] ?? [];
|
|
983
|
-
const depth = leadingEmptyCounts[index] ?? 0;
|
|
984
|
-
if (treatAsDepth) {
|
|
985
|
-
values.push(cells.slice(depth));
|
|
986
|
-
depths.push(depth);
|
|
987
|
-
} else {
|
|
988
|
-
values.push(cells);
|
|
989
|
-
depths.push(0);
|
|
990
|
-
}
|
|
991
|
-
}
|
|
992
|
-
return { values, depths };
|
|
993
|
-
}
|
|
994
|
-
function resolvePasteColumnIds(rows, startCol, width) {
|
|
995
|
-
if (width <= 0) return [];
|
|
996
|
-
const cells = rows[0]?.getVisibleCells() ?? [];
|
|
997
|
-
const columnIds = [];
|
|
998
|
-
for (let offset = 0; offset < width; offset += 1) {
|
|
999
|
-
const cell = cells[startCol + offset];
|
|
1000
|
-
if (!cell) break;
|
|
1001
|
-
columnIds.push(cell.column.id);
|
|
1002
|
-
}
|
|
1003
|
-
return columnIds;
|
|
1004
|
-
}
|
|
1005
|
-
function buildRowsPastePayload(rows, startRow, startCol, text, mode, endRow = startRow) {
|
|
1006
|
-
const { values, depths } = parseClipboardTSVWithDepths(text);
|
|
1007
|
-
if (values.length === 0) return null;
|
|
1008
|
-
const width = Math.max(...values.map((row) => row.length), 0);
|
|
1009
|
-
if (width === 0) return null;
|
|
1010
|
-
const columnIds = resolvePasteColumnIds(rows, startCol, width);
|
|
1011
|
-
if (columnIds.length === 0) return null;
|
|
1012
|
-
const rowIds = [];
|
|
1013
|
-
for (let offset = 0; offset < values.length; offset += 1) {
|
|
1014
|
-
const row = rows[startRow + offset];
|
|
1015
|
-
if (!row) break;
|
|
1016
|
-
rowIds.push(row.id);
|
|
1017
|
-
}
|
|
1018
|
-
const anchorRow = rows[endRow] ?? rows[startRow];
|
|
1019
|
-
return {
|
|
1020
|
-
mode,
|
|
1021
|
-
startRow,
|
|
1022
|
-
startCol,
|
|
1023
|
-
endRow,
|
|
1024
|
-
rowIds,
|
|
1025
|
-
anchorRowId: anchorRow?.id ?? "",
|
|
1026
|
-
columnIds,
|
|
1027
|
-
values,
|
|
1028
|
-
depths
|
|
1029
|
-
};
|
|
1030
|
-
}
|
|
1031
|
-
function isEditablePasteTarget(target) {
|
|
1032
|
-
if (!(target instanceof HTMLElement)) return false;
|
|
1033
|
-
const tag = target.tagName;
|
|
1034
|
-
if (tag === "INPUT" || tag === "TEXTAREA" || tag === "SELECT") return true;
|
|
1035
|
-
return Boolean(target.isContentEditable);
|
|
1036
|
-
}
|
|
1037
|
-
|
|
1038
1261
|
// src/components/ui/table/features/cell-selection/useCellSelection.ts
|
|
1039
1262
|
function useCellSelection({
|
|
1040
1263
|
data,
|
|
@@ -1046,7 +1269,9 @@ function useCellSelection({
|
|
|
1046
1269
|
onDataChange,
|
|
1047
1270
|
onBatchChange,
|
|
1048
1271
|
onRowsPaste,
|
|
1049
|
-
onCellNavigate
|
|
1272
|
+
onCellNavigate,
|
|
1273
|
+
cellRendererRegistry,
|
|
1274
|
+
rootRef
|
|
1050
1275
|
}) {
|
|
1051
1276
|
const [dragState, setDragState] = useState2(INITIAL_DRAG_STATE);
|
|
1052
1277
|
const pendingPasteModeRef = useRef2(null);
|
|
@@ -1114,11 +1339,19 @@ function useCellSelection({
|
|
|
1114
1339
|
},
|
|
1115
1340
|
[enabled]
|
|
1116
1341
|
);
|
|
1342
|
+
const clearSelection = useCallback2(() => {
|
|
1343
|
+
const prev = dragStateRef.current;
|
|
1344
|
+
if (prev.start === null && prev.end === null && !prev.isSelecting && !prev.isFillDragging) {
|
|
1345
|
+
return;
|
|
1346
|
+
}
|
|
1347
|
+
dragStateRef.current = INITIAL_DRAG_STATE;
|
|
1348
|
+
setDragState(INITIAL_DRAG_STATE);
|
|
1349
|
+
}, []);
|
|
1117
1350
|
useEffect2(() => {
|
|
1118
1351
|
if (!enabled) {
|
|
1119
|
-
|
|
1352
|
+
clearSelection();
|
|
1120
1353
|
}
|
|
1121
|
-
}, [enabled]);
|
|
1354
|
+
}, [clearSelection, enabled]);
|
|
1122
1355
|
useEffect2(() => {
|
|
1123
1356
|
if (!enabled) return;
|
|
1124
1357
|
const handleKeyDown = (e) => {
|
|
@@ -1170,15 +1403,28 @@ function useCellSelection({
|
|
|
1170
1403
|
async (options) => {
|
|
1171
1404
|
if (!enabled || !activeSelectionBounds) return false;
|
|
1172
1405
|
const mode = options?.includeDescendants && enableSubtreeCopy ? "subtree" : "visible";
|
|
1173
|
-
return writeSelectionToClipboard(rows, activeSelectionBounds, mode
|
|
1406
|
+
return writeSelectionToClipboard(rows, activeSelectionBounds, mode, {
|
|
1407
|
+
registry: cellRendererRegistry,
|
|
1408
|
+
root: rootRef?.current
|
|
1409
|
+
});
|
|
1174
1410
|
},
|
|
1175
|
-
[
|
|
1411
|
+
[
|
|
1412
|
+
activeSelectionBounds,
|
|
1413
|
+
cellRendererRegistry,
|
|
1414
|
+
enableSubtreeCopy,
|
|
1415
|
+
enabled,
|
|
1416
|
+
rootRef,
|
|
1417
|
+
rows
|
|
1418
|
+
]
|
|
1176
1419
|
);
|
|
1177
1420
|
useEffect2(() => {
|
|
1178
1421
|
if (!enabled) return;
|
|
1179
1422
|
const handleKeyDown = (e) => {
|
|
1180
1423
|
if (!activeSelectionBounds) return;
|
|
1181
1424
|
if (!(e.ctrlKey || e.metaKey)) return;
|
|
1425
|
+
if (isEditablePasteTarget(e.target) || isEditablePasteTarget(document.activeElement)) {
|
|
1426
|
+
return;
|
|
1427
|
+
}
|
|
1182
1428
|
const isSubtreeShortcut = enableSubtreeCopy && e.shiftKey && e.key.toLowerCase() === "c";
|
|
1183
1429
|
const isVisibleCopyShortcut = !e.shiftKey && e.key.toLowerCase() === "c";
|
|
1184
1430
|
if (!isSubtreeShortcut && !isVisibleCopyShortcut) return;
|
|
@@ -1319,6 +1565,7 @@ function useCellSelection({
|
|
|
1319
1565
|
handleCellMouseDown,
|
|
1320
1566
|
handleCellMouseEnter,
|
|
1321
1567
|
handleFillHandleMouseDown,
|
|
1568
|
+
clearSelection,
|
|
1322
1569
|
copySelection
|
|
1323
1570
|
};
|
|
1324
1571
|
}
|
|
@@ -2433,6 +2680,10 @@ function useGlideTable(options) {
|
|
|
2433
2680
|
const [hoveredRowIndex, setHoveredRowIndex] = useState4(null);
|
|
2434
2681
|
const scrollRef = useRef5(null);
|
|
2435
2682
|
const rootRef = useRef5(null);
|
|
2683
|
+
const cellRendererRegistry = useMemo3(
|
|
2684
|
+
() => createCellRendererRegistry(cellRenderers),
|
|
2685
|
+
[cellRenderers]
|
|
2686
|
+
);
|
|
2436
2687
|
const shouldVirtualize = enableVirtualization && !enableRowSpan;
|
|
2437
2688
|
useEffect5(() => {
|
|
2438
2689
|
if (enableVirtualization && enableRowSpan) {
|
|
@@ -2605,6 +2856,7 @@ function useGlideTable(options) {
|
|
|
2605
2856
|
handleCellMouseDown,
|
|
2606
2857
|
handleCellMouseEnter,
|
|
2607
2858
|
handleFillHandleMouseDown,
|
|
2859
|
+
clearSelection: clearCellSelection,
|
|
2608
2860
|
copySelection
|
|
2609
2861
|
} = useCellSelection({
|
|
2610
2862
|
data: tableData,
|
|
@@ -2616,8 +2868,46 @@ function useGlideTable(options) {
|
|
|
2616
2868
|
onDataChange,
|
|
2617
2869
|
onBatchChange,
|
|
2618
2870
|
onRowsPaste,
|
|
2619
|
-
onCellNavigate: handleCellNavigate
|
|
2871
|
+
onCellNavigate: handleCellNavigate,
|
|
2872
|
+
cellRendererRegistry,
|
|
2873
|
+
rootRef
|
|
2620
2874
|
});
|
|
2875
|
+
const clearRowSelection = useCallback4(() => {
|
|
2876
|
+
if (rowSelectionMode === "none") return;
|
|
2877
|
+
const hasSelection = Object.values(rowSelection).some(Boolean);
|
|
2878
|
+
if (!hasSelection) return;
|
|
2879
|
+
if (onRowSelectionChange) {
|
|
2880
|
+
onRowSelectionChange(() => ({}));
|
|
2881
|
+
return;
|
|
2882
|
+
}
|
|
2883
|
+
setInternalRowSelection({});
|
|
2884
|
+
}, [onRowSelectionChange, rowSelection, rowSelectionMode]);
|
|
2885
|
+
useEffect5(() => {
|
|
2886
|
+
const clearAllSelections = () => {
|
|
2887
|
+
clearCellSelection();
|
|
2888
|
+
clearRowSelection();
|
|
2889
|
+
};
|
|
2890
|
+
const handleKeyDown = (event) => {
|
|
2891
|
+
if (event.key !== "Escape") return;
|
|
2892
|
+
if (event.defaultPrevented) return;
|
|
2893
|
+
if (isEditablePasteTarget(event.target) || isEditablePasteTarget(document.activeElement)) {
|
|
2894
|
+
return;
|
|
2895
|
+
}
|
|
2896
|
+
clearAllSelections();
|
|
2897
|
+
};
|
|
2898
|
+
const handleMouseDown = (event) => {
|
|
2899
|
+
const root = rootRef.current;
|
|
2900
|
+
if (!root) return;
|
|
2901
|
+
if (event.target instanceof Node && root.contains(event.target)) return;
|
|
2902
|
+
clearAllSelections();
|
|
2903
|
+
};
|
|
2904
|
+
window.addEventListener("keydown", handleKeyDown);
|
|
2905
|
+
document.addEventListener("mousedown", handleMouseDown);
|
|
2906
|
+
return () => {
|
|
2907
|
+
window.removeEventListener("keydown", handleKeyDown);
|
|
2908
|
+
document.removeEventListener("mousedown", handleMouseDown);
|
|
2909
|
+
};
|
|
2910
|
+
}, [clearCellSelection, clearRowSelection]);
|
|
2621
2911
|
const {
|
|
2622
2912
|
editingCell,
|
|
2623
2913
|
draftValue,
|
|
@@ -2626,10 +2916,6 @@ function useGlideTable(options) {
|
|
|
2626
2916
|
commitEdit,
|
|
2627
2917
|
cancelEdit
|
|
2628
2918
|
} = useCellEdit({ data: tableData, rows, onDataChange, onCellChange });
|
|
2629
|
-
const cellRendererRegistry = useMemo3(
|
|
2630
|
-
() => createCellRendererRegistry(cellRenderers),
|
|
2631
|
-
[cellRenderers]
|
|
2632
|
-
);
|
|
2633
2919
|
const commitRenderedCellValue = useCallback4(
|
|
2634
2920
|
(rowId, columnId, value) => commitCellValue({
|
|
2635
2921
|
data: tableData,
|
|
@@ -3011,7 +3297,9 @@ var DataTableContext = createContext(null);
|
|
|
3011
3297
|
function useDataTableRowContext() {
|
|
3012
3298
|
const context = use(DataTableContext);
|
|
3013
3299
|
if (!context) {
|
|
3014
|
-
throw new Error(
|
|
3300
|
+
throw new Error(
|
|
3301
|
+
"useDataTableRowContext must be used within a DataTableContextProvider"
|
|
3302
|
+
);
|
|
3015
3303
|
}
|
|
3016
3304
|
return context;
|
|
3017
3305
|
}
|
|
@@ -3056,8 +3344,105 @@ function ResolvedTableCell({
|
|
|
3056
3344
|
}
|
|
3057
3345
|
|
|
3058
3346
|
// src/components/ui/table/features/column-resize/columnResize.ts
|
|
3347
|
+
function clamp(value, min, max) {
|
|
3348
|
+
return Math.min(Math.max(value, min), max);
|
|
3349
|
+
}
|
|
3350
|
+
function floorOf(column) {
|
|
3351
|
+
return column.minWidth ?? 0;
|
|
3352
|
+
}
|
|
3353
|
+
function ceilOf(column) {
|
|
3354
|
+
return column.maxWidth ?? Number.POSITIVE_INFINITY;
|
|
3355
|
+
}
|
|
3356
|
+
function preferOf(column) {
|
|
3357
|
+
const floor = floorOf(column);
|
|
3358
|
+
const ceil = ceilOf(column);
|
|
3359
|
+
const preferred = column.maxWidth ?? column.minWidth ?? 0;
|
|
3360
|
+
return clamp(preferred, floor, Number.isFinite(ceil) ? ceil : preferred);
|
|
3361
|
+
}
|
|
3362
|
+
function resolveColumnLayoutWidths(containerWidth, columns) {
|
|
3363
|
+
const widths = /* @__PURE__ */ new Map();
|
|
3364
|
+
const fixed = [];
|
|
3365
|
+
const bounded = [];
|
|
3366
|
+
let flexCount = 0;
|
|
3367
|
+
for (const column of columns) {
|
|
3368
|
+
if (column.width != null) {
|
|
3369
|
+
fixed.push(column);
|
|
3370
|
+
} else if (column.minWidth != null || column.maxWidth != null) {
|
|
3371
|
+
bounded.push(column);
|
|
3372
|
+
} else {
|
|
3373
|
+
flexCount += 1;
|
|
3374
|
+
}
|
|
3375
|
+
}
|
|
3376
|
+
let used = 0;
|
|
3377
|
+
for (const column of fixed) {
|
|
3378
|
+
let size = column.width;
|
|
3379
|
+
if (column.minWidth != null) size = Math.max(size, column.minWidth);
|
|
3380
|
+
if (column.maxWidth != null) size = Math.min(size, column.maxWidth);
|
|
3381
|
+
widths.set(column.id, size);
|
|
3382
|
+
used += size;
|
|
3383
|
+
}
|
|
3384
|
+
if (bounded.length === 0) {
|
|
3385
|
+
return widths;
|
|
3386
|
+
}
|
|
3387
|
+
const boundedSizes = /* @__PURE__ */ new Map();
|
|
3388
|
+
let preferredSum = 0;
|
|
3389
|
+
let floorSum = 0;
|
|
3390
|
+
for (const column of bounded) {
|
|
3391
|
+
const preferred = preferOf(column);
|
|
3392
|
+
boundedSizes.set(column.id, preferred);
|
|
3393
|
+
preferredSum += preferred;
|
|
3394
|
+
floorSum += floorOf(column);
|
|
3395
|
+
}
|
|
3396
|
+
if (containerWidth > 0) {
|
|
3397
|
+
const remaining = Math.max(0, containerWidth - used);
|
|
3398
|
+
if (remaining >= preferredSum) {
|
|
3399
|
+
} else if (remaining >= floorSum) {
|
|
3400
|
+
let deficit = preferredSum - remaining;
|
|
3401
|
+
const open = bounded.map((column) => ({
|
|
3402
|
+
id: column.id,
|
|
3403
|
+
current: boundedSizes.get(column.id),
|
|
3404
|
+
floor: floorOf(column)
|
|
3405
|
+
}));
|
|
3406
|
+
while (deficit >= 1) {
|
|
3407
|
+
const shrinkable = open.filter((entry) => entry.current > entry.floor);
|
|
3408
|
+
if (shrinkable.length === 0) break;
|
|
3409
|
+
const portion = Math.floor(deficit / shrinkable.length);
|
|
3410
|
+
const rem = deficit % shrinkable.length;
|
|
3411
|
+
let consumed = 0;
|
|
3412
|
+
for (let index = 0; index < shrinkable.length; index += 1) {
|
|
3413
|
+
const entry = shrinkable[index];
|
|
3414
|
+
const reduce = Math.min(
|
|
3415
|
+
entry.current - entry.floor,
|
|
3416
|
+
portion + (index < rem ? 1 : 0)
|
|
3417
|
+
);
|
|
3418
|
+
entry.current -= reduce;
|
|
3419
|
+
consumed += reduce;
|
|
3420
|
+
}
|
|
3421
|
+
if (consumed === 0) break;
|
|
3422
|
+
deficit -= consumed;
|
|
3423
|
+
}
|
|
3424
|
+
for (const entry of open) {
|
|
3425
|
+
boundedSizes.set(entry.id, entry.current);
|
|
3426
|
+
}
|
|
3427
|
+
} else {
|
|
3428
|
+
for (const column of bounded) {
|
|
3429
|
+
boundedSizes.set(column.id, floorOf(column));
|
|
3430
|
+
}
|
|
3431
|
+
}
|
|
3432
|
+
}
|
|
3433
|
+
for (const [id, size] of boundedSizes) {
|
|
3434
|
+
widths.set(id, Math.round(size));
|
|
3435
|
+
}
|
|
3436
|
+
return widths;
|
|
3437
|
+
}
|
|
3059
3438
|
function getColumnSizeStyle(size, options) {
|
|
3060
|
-
const {
|
|
3439
|
+
const {
|
|
3440
|
+
force = false,
|
|
3441
|
+
lockMax = false,
|
|
3442
|
+
minWidth,
|
|
3443
|
+
maxWidth,
|
|
3444
|
+
layoutWidth
|
|
3445
|
+
} = options ?? {};
|
|
3061
3446
|
if (lockMax) {
|
|
3062
3447
|
return {
|
|
3063
3448
|
width: size,
|
|
@@ -3065,14 +3450,27 @@ function getColumnSizeStyle(size, options) {
|
|
|
3065
3450
|
maxWidth: size
|
|
3066
3451
|
};
|
|
3067
3452
|
}
|
|
3453
|
+
if (layoutWidth != null) {
|
|
3454
|
+
return {
|
|
3455
|
+
width: layoutWidth,
|
|
3456
|
+
minWidth: layoutWidth,
|
|
3457
|
+
maxWidth: layoutWidth
|
|
3458
|
+
};
|
|
3459
|
+
}
|
|
3460
|
+
const resolvedSize = size;
|
|
3068
3461
|
const hasExplicitSize = force || size !== DATA_TABLE_COLUMN_SIZE;
|
|
3069
3462
|
if (!hasExplicitSize && minWidth == null && maxWidth == null) {
|
|
3070
3463
|
return void 0;
|
|
3071
3464
|
}
|
|
3072
3465
|
const style = {};
|
|
3073
3466
|
if (hasExplicitSize) {
|
|
3074
|
-
|
|
3075
|
-
|
|
3467
|
+
const used = minWidth != null || maxWidth != null ? clamp(
|
|
3468
|
+
resolvedSize,
|
|
3469
|
+
minWidth ?? Number.NEGATIVE_INFINITY,
|
|
3470
|
+
maxWidth ?? Number.POSITIVE_INFINITY
|
|
3471
|
+
) : resolvedSize;
|
|
3472
|
+
style.width = used;
|
|
3473
|
+
style.minWidth = minWidth ?? used;
|
|
3076
3474
|
} else if (minWidth != null) {
|
|
3077
3475
|
style.minWidth = minWidth;
|
|
3078
3476
|
}
|
|
@@ -3297,7 +3695,7 @@ function useColumnReorder(options) {
|
|
|
3297
3695
|
|
|
3298
3696
|
// src/components/ui/table/components/DataTable/DataTable.tsx
|
|
3299
3697
|
import { flexRender as flexRender2 } from "@tanstack/react-table";
|
|
3300
|
-
import { useMemo as useMemo4 } from "react";
|
|
3698
|
+
import { useEffect as useEffect8, useMemo as useMemo4, useState as useState6 } from "react";
|
|
3301
3699
|
|
|
3302
3700
|
// src/components/ui/table/components/DataTable/DataTableRow.tsx
|
|
3303
3701
|
import { flexRender } from "@tanstack/react-table";
|
|
@@ -3463,6 +3861,12 @@ function isInteractiveMouseTarget(target) {
|
|
|
3463
3861
|
].join(",");
|
|
3464
3862
|
return target.closest(interactiveSelector) !== null;
|
|
3465
3863
|
}
|
|
3864
|
+
function blurActiveElementOutside(container) {
|
|
3865
|
+
const active = document.activeElement;
|
|
3866
|
+
if (!(active instanceof HTMLElement) || active === document.body) return;
|
|
3867
|
+
if (container instanceof Node && container.contains(active)) return;
|
|
3868
|
+
active.blur();
|
|
3869
|
+
}
|
|
3466
3870
|
function resolveExpandCellIndex(cells, toggleField) {
|
|
3467
3871
|
if (!toggleField) return 0;
|
|
3468
3872
|
const matchedIndex = cells.findIndex(
|
|
@@ -3495,7 +3899,7 @@ function DataTableRow({
|
|
|
3495
3899
|
columnFreeze,
|
|
3496
3900
|
inlineSearch
|
|
3497
3901
|
} = useDataTableRowContext();
|
|
3498
|
-
const { enableColumnResize } = columnResize;
|
|
3902
|
+
const { enableColumnResize, layoutWidths } = columnResize;
|
|
3499
3903
|
const { enableColumnFreeze, offsets: freezeOffsets } = columnFreeze;
|
|
3500
3904
|
const {
|
|
3501
3905
|
enabled: enableInlineSearch,
|
|
@@ -3690,7 +4094,8 @@ function DataTableRow({
|
|
|
3690
4094
|
force: enableColumnResize,
|
|
3691
4095
|
lockMax: enableColumnResize,
|
|
3692
4096
|
minWidth: meta?.minWidth,
|
|
3693
|
-
maxWidth: meta?.maxWidth
|
|
4097
|
+
maxWidth: meta?.maxWidth,
|
|
4098
|
+
layoutWidth: layoutWidths?.get(columnId)
|
|
3694
4099
|
});
|
|
3695
4100
|
const freezeOffset = enableColumnFreeze ? freezeOffsets.get(columnId) : void 0;
|
|
3696
4101
|
const freezeStyle = getColumnFreezeStyle(freezeOffset);
|
|
@@ -3730,6 +4135,7 @@ function DataTableRow({
|
|
|
3730
4135
|
if (!enableCellSelection) return;
|
|
3731
4136
|
if (isInteractiveMouseTarget(event.target)) return;
|
|
3732
4137
|
event.preventDefault();
|
|
4138
|
+
blurActiveElementOutside(event.currentTarget);
|
|
3733
4139
|
onCellMouseDown(
|
|
3734
4140
|
resolveCellRowIndex(event.clientY, event.currentTarget),
|
|
3735
4141
|
cellIndex,
|
|
@@ -3893,6 +4299,7 @@ function DataTableRow({
|
|
|
3893
4299
|
onMouseDown: (event) => {
|
|
3894
4300
|
event.stopPropagation();
|
|
3895
4301
|
event.preventDefault();
|
|
4302
|
+
blurActiveElementOutside(event.currentTarget);
|
|
3896
4303
|
onFillHandleMouseDown(rowIndex, cellIndex);
|
|
3897
4304
|
}
|
|
3898
4305
|
}
|
|
@@ -4222,17 +4629,74 @@ function DataTable({
|
|
|
4222
4629
|
const RowSlot = slots?.Row ?? DataTableRow;
|
|
4223
4630
|
const PendingSlot = slots?.Pending ?? DefaultPending;
|
|
4224
4631
|
const EmptySlot = slots?.Empty ?? DefaultEmpty;
|
|
4225
|
-
const freezeOffsets = rowContextValue.columnFreeze.offsets;
|
|
4226
4632
|
const headerGroups = getMergedHeaderGroups(table.getHeaderGroups());
|
|
4227
4633
|
const leafColumnIds = table.getVisibleLeafColumns().map((column) => column.id);
|
|
4634
|
+
const columnLayoutMetaSignature = table.getVisibleLeafColumns().map((column) => {
|
|
4635
|
+
const meta = column.columnDef.meta;
|
|
4636
|
+
return `${column.id}:${meta?.width ?? ""}:${meta?.minWidth ?? ""}:${meta?.maxWidth ?? ""}`;
|
|
4637
|
+
}).join("|");
|
|
4228
4638
|
const { isReordering, draggingColumnId, dropTarget, onHeaderPointerDown } = useColumnReorder({
|
|
4229
4639
|
enabled: enableColumnReorder,
|
|
4230
4640
|
columnOrder: leafColumnIds,
|
|
4231
4641
|
onColumnOrderChange: setColumnOrder
|
|
4232
4642
|
});
|
|
4643
|
+
const [containerWidth, setContainerWidth] = useState6(0);
|
|
4644
|
+
useEffect8(() => {
|
|
4645
|
+
if (enableColumnResize || isPending) return;
|
|
4646
|
+
const element = scrollRef.current;
|
|
4647
|
+
if (!element) return;
|
|
4648
|
+
const updateWidth = () => {
|
|
4649
|
+
setContainerWidth(Math.floor(element.clientWidth));
|
|
4650
|
+
};
|
|
4651
|
+
updateWidth();
|
|
4652
|
+
if (typeof ResizeObserver === "undefined") return;
|
|
4653
|
+
const observer = new ResizeObserver(() => {
|
|
4654
|
+
updateWidth();
|
|
4655
|
+
});
|
|
4656
|
+
observer.observe(element);
|
|
4657
|
+
return () => observer.disconnect();
|
|
4658
|
+
}, [enableColumnResize, isPending, scrollRef, rows.length, leafColumnIds.join("|")]);
|
|
4659
|
+
const layoutWidths = useMemo4(() => {
|
|
4660
|
+
if (enableColumnResize) return void 0;
|
|
4661
|
+
const columns = table.getVisibleLeafColumns().map((column) => ({
|
|
4662
|
+
id: column.id,
|
|
4663
|
+
width: column.columnDef.meta?.width,
|
|
4664
|
+
minWidth: column.columnDef.meta?.minWidth,
|
|
4665
|
+
maxWidth: column.columnDef.meta?.maxWidth
|
|
4666
|
+
}));
|
|
4667
|
+
return resolveColumnLayoutWidths(containerWidth, columns);
|
|
4668
|
+
}, [enableColumnResize, containerWidth, table, columnLayoutMetaSignature]);
|
|
4669
|
+
const freezeOffsets = useMemo4(() => {
|
|
4670
|
+
if (!enableColumnFreeze || enableColumnResize || !layoutWidths) {
|
|
4671
|
+
return rowContextValue.columnFreeze.offsets;
|
|
4672
|
+
}
|
|
4673
|
+
const columns = table.getVisibleLeafColumns().map((column) => ({
|
|
4674
|
+
id: column.id,
|
|
4675
|
+
size: layoutWidths.get(column.id) ?? column.getSize(),
|
|
4676
|
+
side: resolveColumnFreezeSide(column.columnDef.meta?.frozen)
|
|
4677
|
+
}));
|
|
4678
|
+
return buildColumnFreezeOffsets(columns);
|
|
4679
|
+
}, [
|
|
4680
|
+
enableColumnFreeze,
|
|
4681
|
+
enableColumnResize,
|
|
4682
|
+
layoutWidths,
|
|
4683
|
+
rowContextValue.columnFreeze.offsets,
|
|
4684
|
+
table
|
|
4685
|
+
]);
|
|
4233
4686
|
const contextValue = useMemo4(
|
|
4234
|
-
() => ({
|
|
4235
|
-
|
|
4687
|
+
() => ({
|
|
4688
|
+
...rowContextValue,
|
|
4689
|
+
classNames,
|
|
4690
|
+
columnFreeze: {
|
|
4691
|
+
...rowContextValue.columnFreeze,
|
|
4692
|
+
offsets: freezeOffsets
|
|
4693
|
+
},
|
|
4694
|
+
columnResize: {
|
|
4695
|
+
...rowContextValue.columnResize,
|
|
4696
|
+
layoutWidths
|
|
4697
|
+
}
|
|
4698
|
+
}),
|
|
4699
|
+
[rowContextValue, classNames, freezeOffsets, layoutWidths]
|
|
4236
4700
|
);
|
|
4237
4701
|
if (isPending) {
|
|
4238
4702
|
return /* @__PURE__ */ jsx7(
|
|
@@ -4313,7 +4777,8 @@ function DataTable({
|
|
|
4313
4777
|
force: enableColumnResize,
|
|
4314
4778
|
lockMax: enableColumnResize,
|
|
4315
4779
|
minWidth: header.column.columnDef.meta?.minWidth,
|
|
4316
|
-
maxWidth: header.column.columnDef.meta?.maxWidth
|
|
4780
|
+
maxWidth: header.column.columnDef.meta?.maxWidth,
|
|
4781
|
+
layoutWidth: layoutWidths?.get(header.column.id)
|
|
4317
4782
|
});
|
|
4318
4783
|
const freezeOffset = enableColumnFreeze ? resolveHeaderFreezeOffset(header.column, freezeOffsets) : void 0;
|
|
4319
4784
|
const freezeStyle = getColumnFreezeStyle(freezeOffset, {
|
|
@@ -4326,7 +4791,9 @@ function DataTable({
|
|
|
4326
4791
|
};
|
|
4327
4792
|
const isPlaceholder = header.isPlaceholder;
|
|
4328
4793
|
const leafColumns = header.column.getLeafColumns();
|
|
4329
|
-
const leafIds = leafColumns.map(
|
|
4794
|
+
const leafIds = leafColumns.map(
|
|
4795
|
+
(leafColumn) => leafColumn.id
|
|
4796
|
+
);
|
|
4330
4797
|
const isLeafHeader = !isPlaceholder && header.subHeaders.length === 0;
|
|
4331
4798
|
const canDrag = enableColumnReorder && !isPlaceholder && leafIds.length > 0 && leafColumns.every(
|
|
4332
4799
|
(leafColumn) => isColumnReorderable(leafColumn.columnDef.meta)
|
|
@@ -4482,7 +4949,7 @@ function DataTable({
|
|
|
4482
4949
|
}
|
|
4483
4950
|
|
|
4484
4951
|
// src/components/ui/table/components/Table/Table.tsx
|
|
4485
|
-
import { useCallback as useCallback7, useMemo as useMemo5, useState as
|
|
4952
|
+
import { useCallback as useCallback7, useMemo as useMemo5, useState as useState7 } from "react";
|
|
4486
4953
|
|
|
4487
4954
|
// src/components/ui/table/components/Table/buildColumnDef.tsx
|
|
4488
4955
|
import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
@@ -4571,6 +5038,7 @@ function buildColumnDef(props, sort, onSort) {
|
|
|
4571
5038
|
cellRender: render,
|
|
4572
5039
|
frozen,
|
|
4573
5040
|
reorderable,
|
|
5041
|
+
width,
|
|
4574
5042
|
minWidth,
|
|
4575
5043
|
maxWidth,
|
|
4576
5044
|
className,
|
|
@@ -4618,10 +5086,10 @@ function countLeafColumns(nodes) {
|
|
|
4618
5086
|
}
|
|
4619
5087
|
|
|
4620
5088
|
// src/components/ui/table/components/Table/parseTableChildren.ts
|
|
4621
|
-
import { Children, isValidElement as
|
|
5089
|
+
import { Children, isValidElement as isValidElement3 } from "react";
|
|
4622
5090
|
|
|
4623
5091
|
// src/components/ui/table/components/Table/tableChildTypes.ts
|
|
4624
|
-
import { isValidElement } from "react";
|
|
5092
|
+
import { isValidElement as isValidElement2 } from "react";
|
|
4625
5093
|
var TABLE_HEADER_DISPLAY_NAME = "Table.Header";
|
|
4626
5094
|
var TABLE_BODY_DISPLAY_NAME = "Table.Body";
|
|
4627
5095
|
var TABLE_COLUMN_DISPLAY_NAME = "Table.Column";
|
|
@@ -4634,19 +5102,19 @@ function getComponentDisplayName(type) {
|
|
|
4634
5102
|
return void 0;
|
|
4635
5103
|
}
|
|
4636
5104
|
function isTableHeaderElement(child) {
|
|
4637
|
-
return
|
|
5105
|
+
return isValidElement2(child) && getComponentDisplayName(child.type) === TABLE_HEADER_DISPLAY_NAME;
|
|
4638
5106
|
}
|
|
4639
5107
|
function isTableBodyElement(child) {
|
|
4640
|
-
return
|
|
5108
|
+
return isValidElement2(child) && getComponentDisplayName(child.type) === TABLE_BODY_DISPLAY_NAME;
|
|
4641
5109
|
}
|
|
4642
5110
|
function isTableColumnElement(child) {
|
|
4643
|
-
return
|
|
5111
|
+
return isValidElement2(child) && getComponentDisplayName(child.type) === TABLE_COLUMN_DISPLAY_NAME;
|
|
4644
5112
|
}
|
|
4645
5113
|
function isTableColumnGroupElement(child) {
|
|
4646
|
-
return
|
|
5114
|
+
return isValidElement2(child) && getComponentDisplayName(child.type) === TABLE_COLUMN_GROUP_DISPLAY_NAME;
|
|
4647
5115
|
}
|
|
4648
5116
|
function isTablePaginationElement(child) {
|
|
4649
|
-
return
|
|
5117
|
+
return isValidElement2(child) && getComponentDisplayName(child.type) === TABLE_PAGINATION_DISPLAY_NAME;
|
|
4650
5118
|
}
|
|
4651
5119
|
|
|
4652
5120
|
// src/components/ui/table/components/Table/parseTableChildren.ts
|
|
@@ -4690,7 +5158,7 @@ function walkColumnTreeNodes(children) {
|
|
|
4690
5158
|
});
|
|
4691
5159
|
continue;
|
|
4692
5160
|
}
|
|
4693
|
-
if (
|
|
5161
|
+
if (isValidElement3(child)) {
|
|
4694
5162
|
const nested = child.props.children;
|
|
4695
5163
|
if (nested != null) {
|
|
4696
5164
|
result.push(...walkColumnTreeNodes(nested));
|
|
@@ -4820,7 +5288,7 @@ function TableRoot({
|
|
|
4820
5288
|
() => parseTableChildren(children),
|
|
4821
5289
|
[children]
|
|
4822
5290
|
);
|
|
4823
|
-
const [sort, setSort] =
|
|
5291
|
+
const [sort, setSort] = useState7(null);
|
|
4824
5292
|
const handleSort = useCallback7((field) => {
|
|
4825
5293
|
setSort((previous) => {
|
|
4826
5294
|
if (previous?.field !== field) {
|
|
@@ -4968,6 +5436,7 @@ export {
|
|
|
4968
5436
|
previousSearchIndex,
|
|
4969
5437
|
resolveCellRenderer,
|
|
4970
5438
|
resolveColumnFreezeSide,
|
|
5439
|
+
resolveColumnLayoutWidths,
|
|
4971
5440
|
resolveDataTableLabels,
|
|
4972
5441
|
resolveDropEdge,
|
|
4973
5442
|
resolveHeaderFreezeOffset,
|