react-glide-table 2.2.0 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +58 -37
- package/dist/compound.cjs +589 -145
- package/dist/compound.d.cts +2 -2
- package/dist/compound.d.ts +2 -2
- package/dist/compound.js +493 -49
- package/dist/core.cjs +509 -141
- package/dist/core.d.cts +54 -10
- package/dist/core.d.ts +54 -10
- package/dist/core.js +396 -29
- package/dist/index.cjs +618 -172
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +494 -49
- package/dist/{types-Iot4g4sq.d.cts → types-DdeVn-9s.d.cts} +33 -2
- package/dist/{types-Iot4g4sq.d.ts → types-DdeVn-9s.d.ts} +33 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -750,6 +750,219 @@ function hasCellSelectionEdges(style) {
|
|
|
750
750
|
}
|
|
751
751
|
|
|
752
752
|
// src/components/ui/table/features/cell-selection/copyData.ts
|
|
753
|
+
import { isValidElement } from "react";
|
|
754
|
+
function isReactNodeIterable(node) {
|
|
755
|
+
return typeof node === "object" && node !== null && !isValidElement(node) && Symbol.iterator in node;
|
|
756
|
+
}
|
|
757
|
+
function getElementTypeName(type) {
|
|
758
|
+
if (typeof type === "string") return type;
|
|
759
|
+
if (typeof type === "function") {
|
|
760
|
+
const fn = type;
|
|
761
|
+
return fn.displayName || fn.name || "";
|
|
762
|
+
}
|
|
763
|
+
if (typeof type === "object" && type !== null) {
|
|
764
|
+
const component = type;
|
|
765
|
+
return component.displayName || component.render?.displayName || component.render?.name || "";
|
|
766
|
+
}
|
|
767
|
+
return "";
|
|
768
|
+
}
|
|
769
|
+
function isButtonReactElement(node) {
|
|
770
|
+
const typeName = getElementTypeName(node.type);
|
|
771
|
+
if (typeName === "button" || /button/i.test(typeName)) return true;
|
|
772
|
+
const props = node.props;
|
|
773
|
+
if (props.role === "button") return true;
|
|
774
|
+
if (typeName === "input" && props.type === "button") return true;
|
|
775
|
+
return false;
|
|
776
|
+
}
|
|
777
|
+
function isImageReactElement(node) {
|
|
778
|
+
const typeName = getElementTypeName(node.type);
|
|
779
|
+
return typeName === "img" || typeName === "image" || /image/i.test(typeName);
|
|
780
|
+
}
|
|
781
|
+
var IMAGE_URL_PROP_KEYS = ["src", "url", "href", "imageUrl", "srcUrl"];
|
|
782
|
+
function isLikelyUrl(value) {
|
|
783
|
+
const trimmed = value.trim();
|
|
784
|
+
if (!trimmed) return false;
|
|
785
|
+
if (/^(https?:|blob:|data:|\/\/)/i.test(trimmed)) return true;
|
|
786
|
+
if (trimmed.startsWith("/") && trimmed.includes("/")) return true;
|
|
787
|
+
return false;
|
|
788
|
+
}
|
|
789
|
+
function pickUrlFromUnknown(value) {
|
|
790
|
+
if (typeof value === "string") {
|
|
791
|
+
return isLikelyUrl(value) ? value.trim() : "";
|
|
792
|
+
}
|
|
793
|
+
if (Array.isArray(value)) {
|
|
794
|
+
return value.map((item) => pickUrlFromUnknown(item)).filter((item) => item.length > 0).join(", ");
|
|
795
|
+
}
|
|
796
|
+
if (value && typeof value === "object") {
|
|
797
|
+
const record = value;
|
|
798
|
+
for (const key of IMAGE_URL_PROP_KEYS) {
|
|
799
|
+
const candidate = record[key];
|
|
800
|
+
if (typeof candidate === "string" && candidate.trim()) {
|
|
801
|
+
return candidate.trim();
|
|
802
|
+
}
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
return "";
|
|
806
|
+
}
|
|
807
|
+
function imageElementText(node) {
|
|
808
|
+
const props = node.props;
|
|
809
|
+
for (const key of IMAGE_URL_PROP_KEYS) {
|
|
810
|
+
const candidate = props[key];
|
|
811
|
+
if (typeof candidate === "string" && candidate.trim()) {
|
|
812
|
+
return candidate.trim();
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
return "";
|
|
816
|
+
}
|
|
817
|
+
function reactNodeContainsImage(node) {
|
|
818
|
+
if (isValidElement(node)) {
|
|
819
|
+
if (isImageReactElement(node)) return true;
|
|
820
|
+
return reactNodeContainsImage(node.props.children);
|
|
821
|
+
}
|
|
822
|
+
if (isReactNodeIterable(node)) {
|
|
823
|
+
for (const child of node) {
|
|
824
|
+
if (reactNodeContainsImage(child)) return true;
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
return false;
|
|
828
|
+
}
|
|
829
|
+
function readImgUrl(img) {
|
|
830
|
+
const attr = img.getAttribute("src")?.trim() ?? "";
|
|
831
|
+
if (attr) return attr;
|
|
832
|
+
if (img instanceof HTMLImageElement) {
|
|
833
|
+
const current = img.currentSrc?.trim() ?? "";
|
|
834
|
+
if (current && current !== img.baseURI) return current;
|
|
835
|
+
}
|
|
836
|
+
return "";
|
|
837
|
+
}
|
|
838
|
+
function readDomImageUrls(rowIndex, colIndex, root) {
|
|
839
|
+
const scope = root ?? (typeof document === "undefined" ? null : document);
|
|
840
|
+
if (!scope) return "";
|
|
841
|
+
const cells = scope.querySelectorAll(
|
|
842
|
+
`[data-row-index="${rowIndex}"][data-col-index="${colIndex}"]`
|
|
843
|
+
);
|
|
844
|
+
for (const cell of cells) {
|
|
845
|
+
const urls = Array.from(cell.querySelectorAll("img")).flatMap((img) => {
|
|
846
|
+
const url = readImgUrl(img);
|
|
847
|
+
return url ? [url] : [];
|
|
848
|
+
});
|
|
849
|
+
if (urls.length > 0) return urls.join(", ");
|
|
850
|
+
}
|
|
851
|
+
return "";
|
|
852
|
+
}
|
|
853
|
+
function reactNodeToText(node) {
|
|
854
|
+
if (node == null || typeof node === "boolean") return "";
|
|
855
|
+
if (typeof node === "string" || typeof node === "number" || typeof node === "bigint") {
|
|
856
|
+
return String(node);
|
|
857
|
+
}
|
|
858
|
+
if (isReactNodeIterable(node)) {
|
|
859
|
+
let text = "";
|
|
860
|
+
for (const child of node) {
|
|
861
|
+
text += reactNodeToText(child);
|
|
862
|
+
}
|
|
863
|
+
return text;
|
|
864
|
+
}
|
|
865
|
+
if (isValidElement(node)) {
|
|
866
|
+
if (isButtonReactElement(node)) return "";
|
|
867
|
+
const props = node.props;
|
|
868
|
+
const childText = reactNodeToText(props.children);
|
|
869
|
+
if (childText) return childText;
|
|
870
|
+
const fromImage = imageElementText(node);
|
|
871
|
+
if (fromImage) return fromImage;
|
|
872
|
+
if (isImageReactElement(node)) return "";
|
|
873
|
+
if (typeof props.alt === "string" && props.alt) return props.alt;
|
|
874
|
+
if (typeof props.title === "string" && props.title) return props.title;
|
|
875
|
+
return "";
|
|
876
|
+
}
|
|
877
|
+
return "";
|
|
878
|
+
}
|
|
879
|
+
function sanitizeClipboardCell(text) {
|
|
880
|
+
return text.replace(/\s+/g, " ").trim();
|
|
881
|
+
}
|
|
882
|
+
function createCopyRenderRow(rowData, index) {
|
|
883
|
+
return {
|
|
884
|
+
id: getOriginalRowId(rowData) || String(index),
|
|
885
|
+
index,
|
|
886
|
+
original: rowData,
|
|
887
|
+
getIsCellDragSelected: () => false
|
|
888
|
+
};
|
|
889
|
+
}
|
|
890
|
+
function buildVisibleRowLookup(visibleRows) {
|
|
891
|
+
const lookup = /* @__PURE__ */ new Map();
|
|
892
|
+
for (const row of visibleRows) {
|
|
893
|
+
lookup.set(row.original, row);
|
|
894
|
+
}
|
|
895
|
+
return lookup;
|
|
896
|
+
}
|
|
897
|
+
function resolveCopyColumnId(cell) {
|
|
898
|
+
if (cell.column.id) return cell.column.id;
|
|
899
|
+
const columnDef = cell.column.columnDef;
|
|
900
|
+
if (columnDef.id) return columnDef.id;
|
|
901
|
+
if (columnDef.accessorKey != null && columnDef.accessorKey !== "") {
|
|
902
|
+
return String(columnDef.accessorKey);
|
|
903
|
+
}
|
|
904
|
+
return "";
|
|
905
|
+
}
|
|
906
|
+
function isPrimitiveCopyValue(value) {
|
|
907
|
+
return value == null || typeof value !== "object";
|
|
908
|
+
}
|
|
909
|
+
function extractRenderedCopyText(node, value, cellPosition, root) {
|
|
910
|
+
const rendered = sanitizeClipboardCell(reactNodeToText(node));
|
|
911
|
+
if (reactNodeContainsImage(node)) {
|
|
912
|
+
const fromDom = cellPosition != null ? sanitizeClipboardCell(
|
|
913
|
+
readDomImageUrls(cellPosition.rowIndex, cellPosition.colIndex, root)
|
|
914
|
+
) : "";
|
|
915
|
+
if (fromDom) return fromDom;
|
|
916
|
+
if (rendered && isLikelyUrl(rendered)) return rendered;
|
|
917
|
+
return sanitizeClipboardCell(pickUrlFromUnknown(value));
|
|
918
|
+
}
|
|
919
|
+
return rendered;
|
|
920
|
+
}
|
|
921
|
+
function formatCopyCellText(rowData, columnDef, columnId, visibleRow, fallbackIndex, sourceCell, cellPosition, options) {
|
|
922
|
+
const meta = columnDef.meta;
|
|
923
|
+
const value = sourceCell ? sourceCell.getValue() : readRowColumnValue(rowData, columnDef);
|
|
924
|
+
const cellRender = meta?.cellRender;
|
|
925
|
+
if (typeof cellRender === "function") {
|
|
926
|
+
try {
|
|
927
|
+
const row = visibleRow ?? createCopyRenderRow(rowData, fallbackIndex);
|
|
928
|
+
const node = cellRender({
|
|
929
|
+
value,
|
|
930
|
+
row,
|
|
931
|
+
index: row.index,
|
|
932
|
+
columnId,
|
|
933
|
+
cellProps: meta?.cellProps,
|
|
934
|
+
update: () => {
|
|
935
|
+
}
|
|
936
|
+
});
|
|
937
|
+
return extractRenderedCopyText(node, value, cellPosition, options?.root);
|
|
938
|
+
} catch {
|
|
939
|
+
return formatCellValue(value);
|
|
940
|
+
}
|
|
941
|
+
}
|
|
942
|
+
if (options?.registry && meta?.kind && isPrimitiveCopyValue(value)) {
|
|
943
|
+
try {
|
|
944
|
+
const row = visibleRow ?? createCopyRenderRow(rowData, fallbackIndex);
|
|
945
|
+
const ctx = {
|
|
946
|
+
value,
|
|
947
|
+
row,
|
|
948
|
+
index: row.index,
|
|
949
|
+
columnId,
|
|
950
|
+
cellProps: meta.cellProps,
|
|
951
|
+
update: () => {
|
|
952
|
+
}
|
|
953
|
+
};
|
|
954
|
+
const renderer = resolveCellRenderer(options.registry, meta.kind, ctx);
|
|
955
|
+
if (renderer) {
|
|
956
|
+
const node = renderer.render(ctx);
|
|
957
|
+
const rendered = extractRenderedCopyText(node, value, cellPosition, options.root);
|
|
958
|
+
if (rendered) return rendered;
|
|
959
|
+
}
|
|
960
|
+
} catch {
|
|
961
|
+
return formatCellValue(value);
|
|
962
|
+
}
|
|
963
|
+
}
|
|
964
|
+
return formatCellValue(value);
|
|
965
|
+
}
|
|
753
966
|
function formatPrimitive(value) {
|
|
754
967
|
if (value === null || value === void 0) return "";
|
|
755
968
|
if (typeof value === "string") return value;
|
|
@@ -855,37 +1068,47 @@ function collectCopyRowEntries(visibleRows, bounds, mode = "visible") {
|
|
|
855
1068
|
function collectCopyRows(visibleRows, bounds, mode = "visible") {
|
|
856
1069
|
return collectCopyRowEntries(visibleRows, bounds, mode).map((entry) => entry.row);
|
|
857
1070
|
}
|
|
858
|
-
function serializeCopyRowsToTSV(copyRows, visibleRows, bounds, depths) {
|
|
1071
|
+
function serializeCopyRowsToTSV(copyRows, visibleRows, bounds, depths, options) {
|
|
859
1072
|
if (copyRows.length === 0) return "";
|
|
860
1073
|
const { startCol, endCol } = bounds;
|
|
861
1074
|
const columnCells = visibleRows[0]?.getVisibleCells().slice(startCol, endCol + 1) ?? [];
|
|
862
1075
|
if (columnCells.length === 0) return "";
|
|
863
1076
|
const resolvedDepths = depths && depths.length === copyRows.length ? depths : copyRows.map((row) => getRowDepth(row));
|
|
864
1077
|
const minDepth = Math.min(...resolvedDepths);
|
|
1078
|
+
const visibleRowByOriginal = buildVisibleRowLookup(visibleRows);
|
|
865
1079
|
return copyRows.map((rowData, index) => {
|
|
866
1080
|
const relativeDepth = Math.max(0, (resolvedDepths[index] ?? 0) - minDepth);
|
|
867
|
-
const
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
1081
|
+
const visibleRow = visibleRowByOriginal.get(rowData);
|
|
1082
|
+
const matchingCells = visibleRow?.getVisibleCells().slice(startCol, endCol + 1);
|
|
1083
|
+
const line = columnCells.map((templateCell, colOffset) => {
|
|
1084
|
+
const sourceCell = matchingCells?.[colOffset];
|
|
1085
|
+
const column = sourceCell?.column ?? templateCell.column;
|
|
1086
|
+
return formatCopyCellText(
|
|
1087
|
+
rowData,
|
|
1088
|
+
column.columnDef,
|
|
1089
|
+
resolveCopyColumnId(sourceCell ?? templateCell),
|
|
1090
|
+
visibleRow,
|
|
1091
|
+
visibleRow?.index ?? index,
|
|
1092
|
+
sourceCell,
|
|
1093
|
+
visibleRow != null ? { rowIndex: visibleRow.index, colIndex: startCol + colOffset } : void 0,
|
|
1094
|
+
options
|
|
1095
|
+
);
|
|
1096
|
+
}).join(" ");
|
|
875
1097
|
return `${" ".repeat(relativeDepth)}${line}`;
|
|
876
1098
|
}).join("\n");
|
|
877
1099
|
}
|
|
878
|
-
function serializeSelectionToTSV(visibleRows, bounds, mode = "visible") {
|
|
1100
|
+
function serializeSelectionToTSV(visibleRows, bounds, mode = "visible", options) {
|
|
879
1101
|
const entries = collectCopyRowEntries(visibleRows, bounds, mode);
|
|
880
1102
|
return serializeCopyRowsToTSV(
|
|
881
1103
|
entries.map((entry) => entry.row),
|
|
882
1104
|
visibleRows,
|
|
883
1105
|
bounds,
|
|
884
|
-
entries.map((entry) => entry.depth)
|
|
1106
|
+
entries.map((entry) => entry.depth),
|
|
1107
|
+
options
|
|
885
1108
|
);
|
|
886
1109
|
}
|
|
887
|
-
async function writeSelectionToClipboard(visibleRows, bounds, mode = "visible") {
|
|
888
|
-
const text = serializeSelectionToTSV(visibleRows, bounds, mode);
|
|
1110
|
+
async function writeSelectionToClipboard(visibleRows, bounds, mode = "visible", options) {
|
|
1111
|
+
const text = serializeSelectionToTSV(visibleRows, bounds, mode, options);
|
|
889
1112
|
if (!text) return false;
|
|
890
1113
|
try {
|
|
891
1114
|
await navigator.clipboard.writeText(text);
|
|
@@ -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);
|
|
@@ -1170,15 +1395,28 @@ function useCellSelection({
|
|
|
1170
1395
|
async (options) => {
|
|
1171
1396
|
if (!enabled || !activeSelectionBounds) return false;
|
|
1172
1397
|
const mode = options?.includeDescendants && enableSubtreeCopy ? "subtree" : "visible";
|
|
1173
|
-
return writeSelectionToClipboard(rows, activeSelectionBounds, mode
|
|
1398
|
+
return writeSelectionToClipboard(rows, activeSelectionBounds, mode, {
|
|
1399
|
+
registry: cellRendererRegistry,
|
|
1400
|
+
root: rootRef?.current
|
|
1401
|
+
});
|
|
1174
1402
|
},
|
|
1175
|
-
[
|
|
1403
|
+
[
|
|
1404
|
+
activeSelectionBounds,
|
|
1405
|
+
cellRendererRegistry,
|
|
1406
|
+
enableSubtreeCopy,
|
|
1407
|
+
enabled,
|
|
1408
|
+
rootRef,
|
|
1409
|
+
rows
|
|
1410
|
+
]
|
|
1176
1411
|
);
|
|
1177
1412
|
useEffect2(() => {
|
|
1178
1413
|
if (!enabled) return;
|
|
1179
1414
|
const handleKeyDown = (e) => {
|
|
1180
1415
|
if (!activeSelectionBounds) return;
|
|
1181
1416
|
if (!(e.ctrlKey || e.metaKey)) return;
|
|
1417
|
+
if (isEditablePasteTarget(e.target) || isEditablePasteTarget(document.activeElement)) {
|
|
1418
|
+
return;
|
|
1419
|
+
}
|
|
1182
1420
|
const isSubtreeShortcut = enableSubtreeCopy && e.shiftKey && e.key.toLowerCase() === "c";
|
|
1183
1421
|
const isVisibleCopyShortcut = !e.shiftKey && e.key.toLowerCase() === "c";
|
|
1184
1422
|
if (!isSubtreeShortcut && !isVisibleCopyShortcut) return;
|
|
@@ -2433,6 +2671,10 @@ function useGlideTable(options) {
|
|
|
2433
2671
|
const [hoveredRowIndex, setHoveredRowIndex] = useState4(null);
|
|
2434
2672
|
const scrollRef = useRef5(null);
|
|
2435
2673
|
const rootRef = useRef5(null);
|
|
2674
|
+
const cellRendererRegistry = useMemo3(
|
|
2675
|
+
() => createCellRendererRegistry(cellRenderers),
|
|
2676
|
+
[cellRenderers]
|
|
2677
|
+
);
|
|
2436
2678
|
const shouldVirtualize = enableVirtualization && !enableRowSpan;
|
|
2437
2679
|
useEffect5(() => {
|
|
2438
2680
|
if (enableVirtualization && enableRowSpan) {
|
|
@@ -2616,7 +2858,9 @@ function useGlideTable(options) {
|
|
|
2616
2858
|
onDataChange,
|
|
2617
2859
|
onBatchChange,
|
|
2618
2860
|
onRowsPaste,
|
|
2619
|
-
onCellNavigate: handleCellNavigate
|
|
2861
|
+
onCellNavigate: handleCellNavigate,
|
|
2862
|
+
cellRendererRegistry,
|
|
2863
|
+
rootRef
|
|
2620
2864
|
});
|
|
2621
2865
|
const {
|
|
2622
2866
|
editingCell,
|
|
@@ -2626,10 +2870,6 @@ function useGlideTable(options) {
|
|
|
2626
2870
|
commitEdit,
|
|
2627
2871
|
cancelEdit
|
|
2628
2872
|
} = useCellEdit({ data: tableData, rows, onDataChange, onCellChange });
|
|
2629
|
-
const cellRendererRegistry = useMemo3(
|
|
2630
|
-
() => createCellRendererRegistry(cellRenderers),
|
|
2631
|
-
[cellRenderers]
|
|
2632
|
-
);
|
|
2633
2873
|
const commitRenderedCellValue = useCallback4(
|
|
2634
2874
|
(rowId, columnId, value) => commitCellValue({
|
|
2635
2875
|
data: tableData,
|
|
@@ -3011,7 +3251,9 @@ var DataTableContext = createContext(null);
|
|
|
3011
3251
|
function useDataTableRowContext() {
|
|
3012
3252
|
const context = use(DataTableContext);
|
|
3013
3253
|
if (!context) {
|
|
3014
|
-
throw new Error(
|
|
3254
|
+
throw new Error(
|
|
3255
|
+
"useDataTableRowContext must be used within a DataTableContextProvider"
|
|
3256
|
+
);
|
|
3015
3257
|
}
|
|
3016
3258
|
return context;
|
|
3017
3259
|
}
|
|
@@ -3056,16 +3298,140 @@ function ResolvedTableCell({
|
|
|
3056
3298
|
}
|
|
3057
3299
|
|
|
3058
3300
|
// src/components/ui/table/features/column-resize/columnResize.ts
|
|
3301
|
+
function clamp(value, min, max) {
|
|
3302
|
+
return Math.min(Math.max(value, min), max);
|
|
3303
|
+
}
|
|
3304
|
+
function floorOf(column) {
|
|
3305
|
+
return column.minWidth ?? 0;
|
|
3306
|
+
}
|
|
3307
|
+
function ceilOf(column) {
|
|
3308
|
+
return column.maxWidth ?? Number.POSITIVE_INFINITY;
|
|
3309
|
+
}
|
|
3310
|
+
function preferOf(column) {
|
|
3311
|
+
const floor = floorOf(column);
|
|
3312
|
+
const ceil = ceilOf(column);
|
|
3313
|
+
const preferred = column.maxWidth ?? column.minWidth ?? 0;
|
|
3314
|
+
return clamp(preferred, floor, Number.isFinite(ceil) ? ceil : preferred);
|
|
3315
|
+
}
|
|
3316
|
+
function resolveColumnLayoutWidths(containerWidth, columns) {
|
|
3317
|
+
const widths = /* @__PURE__ */ new Map();
|
|
3318
|
+
const fixed = [];
|
|
3319
|
+
const bounded = [];
|
|
3320
|
+
let flexCount = 0;
|
|
3321
|
+
for (const column of columns) {
|
|
3322
|
+
if (column.width != null) {
|
|
3323
|
+
fixed.push(column);
|
|
3324
|
+
} else if (column.minWidth != null || column.maxWidth != null) {
|
|
3325
|
+
bounded.push(column);
|
|
3326
|
+
} else {
|
|
3327
|
+
flexCount += 1;
|
|
3328
|
+
}
|
|
3329
|
+
}
|
|
3330
|
+
let used = 0;
|
|
3331
|
+
for (const column of fixed) {
|
|
3332
|
+
let size = column.width;
|
|
3333
|
+
if (column.minWidth != null) size = Math.max(size, column.minWidth);
|
|
3334
|
+
if (column.maxWidth != null) size = Math.min(size, column.maxWidth);
|
|
3335
|
+
widths.set(column.id, size);
|
|
3336
|
+
used += size;
|
|
3337
|
+
}
|
|
3338
|
+
if (bounded.length === 0) {
|
|
3339
|
+
return widths;
|
|
3340
|
+
}
|
|
3341
|
+
const boundedSizes = /* @__PURE__ */ new Map();
|
|
3342
|
+
let preferredSum = 0;
|
|
3343
|
+
let floorSum = 0;
|
|
3344
|
+
for (const column of bounded) {
|
|
3345
|
+
const preferred = preferOf(column);
|
|
3346
|
+
boundedSizes.set(column.id, preferred);
|
|
3347
|
+
preferredSum += preferred;
|
|
3348
|
+
floorSum += floorOf(column);
|
|
3349
|
+
}
|
|
3350
|
+
if (containerWidth > 0) {
|
|
3351
|
+
const remaining = Math.max(0, containerWidth - used);
|
|
3352
|
+
if (remaining >= preferredSum) {
|
|
3353
|
+
} else if (remaining >= floorSum) {
|
|
3354
|
+
let deficit = preferredSum - remaining;
|
|
3355
|
+
const open = bounded.map((column) => ({
|
|
3356
|
+
id: column.id,
|
|
3357
|
+
current: boundedSizes.get(column.id),
|
|
3358
|
+
floor: floorOf(column)
|
|
3359
|
+
}));
|
|
3360
|
+
while (deficit >= 1) {
|
|
3361
|
+
const shrinkable = open.filter((entry) => entry.current > entry.floor);
|
|
3362
|
+
if (shrinkable.length === 0) break;
|
|
3363
|
+
const portion = Math.floor(deficit / shrinkable.length);
|
|
3364
|
+
const rem = deficit % shrinkable.length;
|
|
3365
|
+
let consumed = 0;
|
|
3366
|
+
for (let index = 0; index < shrinkable.length; index += 1) {
|
|
3367
|
+
const entry = shrinkable[index];
|
|
3368
|
+
const reduce = Math.min(
|
|
3369
|
+
entry.current - entry.floor,
|
|
3370
|
+
portion + (index < rem ? 1 : 0)
|
|
3371
|
+
);
|
|
3372
|
+
entry.current -= reduce;
|
|
3373
|
+
consumed += reduce;
|
|
3374
|
+
}
|
|
3375
|
+
if (consumed === 0) break;
|
|
3376
|
+
deficit -= consumed;
|
|
3377
|
+
}
|
|
3378
|
+
for (const entry of open) {
|
|
3379
|
+
boundedSizes.set(entry.id, entry.current);
|
|
3380
|
+
}
|
|
3381
|
+
} else {
|
|
3382
|
+
for (const column of bounded) {
|
|
3383
|
+
boundedSizes.set(column.id, floorOf(column));
|
|
3384
|
+
}
|
|
3385
|
+
}
|
|
3386
|
+
}
|
|
3387
|
+
for (const [id, size] of boundedSizes) {
|
|
3388
|
+
widths.set(id, Math.round(size));
|
|
3389
|
+
}
|
|
3390
|
+
return widths;
|
|
3391
|
+
}
|
|
3059
3392
|
function getColumnSizeStyle(size, options) {
|
|
3060
|
-
const {
|
|
3061
|
-
|
|
3393
|
+
const {
|
|
3394
|
+
force = false,
|
|
3395
|
+
lockMax = false,
|
|
3396
|
+
minWidth,
|
|
3397
|
+
maxWidth,
|
|
3398
|
+
layoutWidth
|
|
3399
|
+
} = options ?? {};
|
|
3400
|
+
if (lockMax) {
|
|
3401
|
+
return {
|
|
3402
|
+
width: size,
|
|
3403
|
+
minWidth: size,
|
|
3404
|
+
maxWidth: size
|
|
3405
|
+
};
|
|
3406
|
+
}
|
|
3407
|
+
if (layoutWidth != null) {
|
|
3408
|
+
return {
|
|
3409
|
+
width: layoutWidth,
|
|
3410
|
+
minWidth: layoutWidth,
|
|
3411
|
+
maxWidth: layoutWidth
|
|
3412
|
+
};
|
|
3413
|
+
}
|
|
3414
|
+
const resolvedSize = size;
|
|
3415
|
+
const hasExplicitSize = force || size !== DATA_TABLE_COLUMN_SIZE;
|
|
3416
|
+
if (!hasExplicitSize && minWidth == null && maxWidth == null) {
|
|
3062
3417
|
return void 0;
|
|
3063
3418
|
}
|
|
3064
|
-
|
|
3065
|
-
|
|
3066
|
-
minWidth
|
|
3067
|
-
|
|
3068
|
-
|
|
3419
|
+
const style = {};
|
|
3420
|
+
if (hasExplicitSize) {
|
|
3421
|
+
const used = minWidth != null || maxWidth != null ? clamp(
|
|
3422
|
+
resolvedSize,
|
|
3423
|
+
minWidth ?? Number.NEGATIVE_INFINITY,
|
|
3424
|
+
maxWidth ?? Number.POSITIVE_INFINITY
|
|
3425
|
+
) : resolvedSize;
|
|
3426
|
+
style.width = used;
|
|
3427
|
+
style.minWidth = minWidth ?? used;
|
|
3428
|
+
} else if (minWidth != null) {
|
|
3429
|
+
style.minWidth = minWidth;
|
|
3430
|
+
}
|
|
3431
|
+
if (maxWidth != null) {
|
|
3432
|
+
style.maxWidth = maxWidth;
|
|
3433
|
+
}
|
|
3434
|
+
return style;
|
|
3069
3435
|
}
|
|
3070
3436
|
|
|
3071
3437
|
// src/components/ui/table/features/column-reorder/useColumnReorder.ts
|
|
@@ -3283,7 +3649,7 @@ function useColumnReorder(options) {
|
|
|
3283
3649
|
|
|
3284
3650
|
// src/components/ui/table/components/DataTable/DataTable.tsx
|
|
3285
3651
|
import { flexRender as flexRender2 } from "@tanstack/react-table";
|
|
3286
|
-
import { useMemo as useMemo4 } from "react";
|
|
3652
|
+
import { useEffect as useEffect8, useMemo as useMemo4, useState as useState6 } from "react";
|
|
3287
3653
|
|
|
3288
3654
|
// src/components/ui/table/components/DataTable/DataTableRow.tsx
|
|
3289
3655
|
import { flexRender } from "@tanstack/react-table";
|
|
@@ -3449,6 +3815,12 @@ function isInteractiveMouseTarget(target) {
|
|
|
3449
3815
|
].join(",");
|
|
3450
3816
|
return target.closest(interactiveSelector) !== null;
|
|
3451
3817
|
}
|
|
3818
|
+
function blurActiveElementOutside(container) {
|
|
3819
|
+
const active = document.activeElement;
|
|
3820
|
+
if (!(active instanceof HTMLElement) || active === document.body) return;
|
|
3821
|
+
if (container instanceof Node && container.contains(active)) return;
|
|
3822
|
+
active.blur();
|
|
3823
|
+
}
|
|
3452
3824
|
function resolveExpandCellIndex(cells, toggleField) {
|
|
3453
3825
|
if (!toggleField) return 0;
|
|
3454
3826
|
const matchedIndex = cells.findIndex(
|
|
@@ -3481,7 +3853,7 @@ function DataTableRow({
|
|
|
3481
3853
|
columnFreeze,
|
|
3482
3854
|
inlineSearch
|
|
3483
3855
|
} = useDataTableRowContext();
|
|
3484
|
-
const { enableColumnResize } = columnResize;
|
|
3856
|
+
const { enableColumnResize, layoutWidths } = columnResize;
|
|
3485
3857
|
const { enableColumnFreeze, offsets: freezeOffsets } = columnFreeze;
|
|
3486
3858
|
const {
|
|
3487
3859
|
enabled: enableInlineSearch,
|
|
@@ -3674,7 +4046,10 @@ function DataTableRow({
|
|
|
3674
4046
|
const hasSelectionEdges = hasCellSelectionEdges(selectionEdgeStyle);
|
|
3675
4047
|
const sizeStyle = getColumnSizeStyle(cell.column.getSize(), {
|
|
3676
4048
|
force: enableColumnResize,
|
|
3677
|
-
lockMax: enableColumnResize
|
|
4049
|
+
lockMax: enableColumnResize,
|
|
4050
|
+
minWidth: meta?.minWidth,
|
|
4051
|
+
maxWidth: meta?.maxWidth,
|
|
4052
|
+
layoutWidth: layoutWidths?.get(columnId)
|
|
3678
4053
|
});
|
|
3679
4054
|
const freezeOffset = enableColumnFreeze ? freezeOffsets.get(columnId) : void 0;
|
|
3680
4055
|
const freezeStyle = getColumnFreezeStyle(freezeOffset);
|
|
@@ -3714,6 +4089,7 @@ function DataTableRow({
|
|
|
3714
4089
|
if (!enableCellSelection) return;
|
|
3715
4090
|
if (isInteractiveMouseTarget(event.target)) return;
|
|
3716
4091
|
event.preventDefault();
|
|
4092
|
+
blurActiveElementOutside(event.currentTarget);
|
|
3717
4093
|
onCellMouseDown(
|
|
3718
4094
|
resolveCellRowIndex(event.clientY, event.currentTarget),
|
|
3719
4095
|
cellIndex,
|
|
@@ -3877,6 +4253,7 @@ function DataTableRow({
|
|
|
3877
4253
|
onMouseDown: (event) => {
|
|
3878
4254
|
event.stopPropagation();
|
|
3879
4255
|
event.preventDefault();
|
|
4256
|
+
blurActiveElementOutside(event.currentTarget);
|
|
3880
4257
|
onFillHandleMouseDown(rowIndex, cellIndex);
|
|
3881
4258
|
}
|
|
3882
4259
|
}
|
|
@@ -4206,17 +4583,74 @@ function DataTable({
|
|
|
4206
4583
|
const RowSlot = slots?.Row ?? DataTableRow;
|
|
4207
4584
|
const PendingSlot = slots?.Pending ?? DefaultPending;
|
|
4208
4585
|
const EmptySlot = slots?.Empty ?? DefaultEmpty;
|
|
4209
|
-
const freezeOffsets = rowContextValue.columnFreeze.offsets;
|
|
4210
4586
|
const headerGroups = getMergedHeaderGroups(table.getHeaderGroups());
|
|
4211
4587
|
const leafColumnIds = table.getVisibleLeafColumns().map((column) => column.id);
|
|
4588
|
+
const columnLayoutMetaSignature = table.getVisibleLeafColumns().map((column) => {
|
|
4589
|
+
const meta = column.columnDef.meta;
|
|
4590
|
+
return `${column.id}:${meta?.width ?? ""}:${meta?.minWidth ?? ""}:${meta?.maxWidth ?? ""}`;
|
|
4591
|
+
}).join("|");
|
|
4212
4592
|
const { isReordering, draggingColumnId, dropTarget, onHeaderPointerDown } = useColumnReorder({
|
|
4213
4593
|
enabled: enableColumnReorder,
|
|
4214
4594
|
columnOrder: leafColumnIds,
|
|
4215
4595
|
onColumnOrderChange: setColumnOrder
|
|
4216
4596
|
});
|
|
4597
|
+
const [containerWidth, setContainerWidth] = useState6(0);
|
|
4598
|
+
useEffect8(() => {
|
|
4599
|
+
if (enableColumnResize || isPending) return;
|
|
4600
|
+
const element = scrollRef.current;
|
|
4601
|
+
if (!element) return;
|
|
4602
|
+
const updateWidth = () => {
|
|
4603
|
+
setContainerWidth(Math.floor(element.clientWidth));
|
|
4604
|
+
};
|
|
4605
|
+
updateWidth();
|
|
4606
|
+
if (typeof ResizeObserver === "undefined") return;
|
|
4607
|
+
const observer = new ResizeObserver(() => {
|
|
4608
|
+
updateWidth();
|
|
4609
|
+
});
|
|
4610
|
+
observer.observe(element);
|
|
4611
|
+
return () => observer.disconnect();
|
|
4612
|
+
}, [enableColumnResize, isPending, scrollRef, rows.length, leafColumnIds.join("|")]);
|
|
4613
|
+
const layoutWidths = useMemo4(() => {
|
|
4614
|
+
if (enableColumnResize) return void 0;
|
|
4615
|
+
const columns = table.getVisibleLeafColumns().map((column) => ({
|
|
4616
|
+
id: column.id,
|
|
4617
|
+
width: column.columnDef.meta?.width,
|
|
4618
|
+
minWidth: column.columnDef.meta?.minWidth,
|
|
4619
|
+
maxWidth: column.columnDef.meta?.maxWidth
|
|
4620
|
+
}));
|
|
4621
|
+
return resolveColumnLayoutWidths(containerWidth, columns);
|
|
4622
|
+
}, [enableColumnResize, containerWidth, table, columnLayoutMetaSignature]);
|
|
4623
|
+
const freezeOffsets = useMemo4(() => {
|
|
4624
|
+
if (!enableColumnFreeze || enableColumnResize || !layoutWidths) {
|
|
4625
|
+
return rowContextValue.columnFreeze.offsets;
|
|
4626
|
+
}
|
|
4627
|
+
const columns = table.getVisibleLeafColumns().map((column) => ({
|
|
4628
|
+
id: column.id,
|
|
4629
|
+
size: layoutWidths.get(column.id) ?? column.getSize(),
|
|
4630
|
+
side: resolveColumnFreezeSide(column.columnDef.meta?.frozen)
|
|
4631
|
+
}));
|
|
4632
|
+
return buildColumnFreezeOffsets(columns);
|
|
4633
|
+
}, [
|
|
4634
|
+
enableColumnFreeze,
|
|
4635
|
+
enableColumnResize,
|
|
4636
|
+
layoutWidths,
|
|
4637
|
+
rowContextValue.columnFreeze.offsets,
|
|
4638
|
+
table
|
|
4639
|
+
]);
|
|
4217
4640
|
const contextValue = useMemo4(
|
|
4218
|
-
() => ({
|
|
4219
|
-
|
|
4641
|
+
() => ({
|
|
4642
|
+
...rowContextValue,
|
|
4643
|
+
classNames,
|
|
4644
|
+
columnFreeze: {
|
|
4645
|
+
...rowContextValue.columnFreeze,
|
|
4646
|
+
offsets: freezeOffsets
|
|
4647
|
+
},
|
|
4648
|
+
columnResize: {
|
|
4649
|
+
...rowContextValue.columnResize,
|
|
4650
|
+
layoutWidths
|
|
4651
|
+
}
|
|
4652
|
+
}),
|
|
4653
|
+
[rowContextValue, classNames, freezeOffsets, layoutWidths]
|
|
4220
4654
|
);
|
|
4221
4655
|
if (isPending) {
|
|
4222
4656
|
return /* @__PURE__ */ jsx7(
|
|
@@ -4295,7 +4729,10 @@ function DataTable({
|
|
|
4295
4729
|
const canResize = enableColumnResize && header.column.getCanResize();
|
|
4296
4730
|
const sizeStyle = getColumnSizeStyle(header.getSize(), {
|
|
4297
4731
|
force: enableColumnResize,
|
|
4298
|
-
lockMax: enableColumnResize
|
|
4732
|
+
lockMax: enableColumnResize,
|
|
4733
|
+
minWidth: header.column.columnDef.meta?.minWidth,
|
|
4734
|
+
maxWidth: header.column.columnDef.meta?.maxWidth,
|
|
4735
|
+
layoutWidth: layoutWidths?.get(header.column.id)
|
|
4299
4736
|
});
|
|
4300
4737
|
const freezeOffset = enableColumnFreeze ? resolveHeaderFreezeOffset(header.column, freezeOffsets) : void 0;
|
|
4301
4738
|
const freezeStyle = getColumnFreezeStyle(freezeOffset, {
|
|
@@ -4308,7 +4745,9 @@ function DataTable({
|
|
|
4308
4745
|
};
|
|
4309
4746
|
const isPlaceholder = header.isPlaceholder;
|
|
4310
4747
|
const leafColumns = header.column.getLeafColumns();
|
|
4311
|
-
const leafIds = leafColumns.map(
|
|
4748
|
+
const leafIds = leafColumns.map(
|
|
4749
|
+
(leafColumn) => leafColumn.id
|
|
4750
|
+
);
|
|
4312
4751
|
const isLeafHeader = !isPlaceholder && header.subHeaders.length === 0;
|
|
4313
4752
|
const canDrag = enableColumnReorder && !isPlaceholder && leafIds.length > 0 && leafColumns.every(
|
|
4314
4753
|
(leafColumn) => isColumnReorderable(leafColumn.columnDef.meta)
|
|
@@ -4464,7 +4903,7 @@ function DataTable({
|
|
|
4464
4903
|
}
|
|
4465
4904
|
|
|
4466
4905
|
// src/components/ui/table/components/Table/Table.tsx
|
|
4467
|
-
import { useCallback as useCallback7, useMemo as useMemo5, useState as
|
|
4906
|
+
import { useCallback as useCallback7, useMemo as useMemo5, useState as useState7 } from "react";
|
|
4468
4907
|
|
|
4469
4908
|
// src/components/ui/table/components/Table/buildColumnDef.tsx
|
|
4470
4909
|
import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
@@ -4501,6 +4940,8 @@ function buildColumnDef(props, sort, onSort) {
|
|
|
4501
4940
|
width,
|
|
4502
4941
|
minWidth,
|
|
4503
4942
|
maxWidth,
|
|
4943
|
+
minResizeWidth,
|
|
4944
|
+
maxResizeWidth,
|
|
4504
4945
|
resizable,
|
|
4505
4946
|
reorderable,
|
|
4506
4947
|
frozen,
|
|
@@ -4521,8 +4962,8 @@ function buildColumnDef(props, sort, onSort) {
|
|
|
4521
4962
|
id: field,
|
|
4522
4963
|
...!virtual ? { accessorKey: field } : {},
|
|
4523
4964
|
size: width ?? DATA_TABLE_COLUMN_SIZE,
|
|
4524
|
-
...
|
|
4525
|
-
...
|
|
4965
|
+
...minResizeWidth != null ? { minSize: minResizeWidth } : {},
|
|
4966
|
+
...maxResizeWidth != null ? { maxSize: maxResizeWidth } : {},
|
|
4526
4967
|
...resizable === false ? { enableResizing: false } : {},
|
|
4527
4968
|
header: sortable ? () => /* @__PURE__ */ jsx8(
|
|
4528
4969
|
SortableHeader,
|
|
@@ -4551,6 +4992,9 @@ function buildColumnDef(props, sort, onSort) {
|
|
|
4551
4992
|
cellRender: render,
|
|
4552
4993
|
frozen,
|
|
4553
4994
|
reorderable,
|
|
4995
|
+
width,
|
|
4996
|
+
minWidth,
|
|
4997
|
+
maxWidth,
|
|
4554
4998
|
className,
|
|
4555
4999
|
headerClassName
|
|
4556
5000
|
}
|
|
@@ -4596,10 +5040,10 @@ function countLeafColumns(nodes) {
|
|
|
4596
5040
|
}
|
|
4597
5041
|
|
|
4598
5042
|
// src/components/ui/table/components/Table/parseTableChildren.ts
|
|
4599
|
-
import { Children, isValidElement as
|
|
5043
|
+
import { Children, isValidElement as isValidElement3 } from "react";
|
|
4600
5044
|
|
|
4601
5045
|
// src/components/ui/table/components/Table/tableChildTypes.ts
|
|
4602
|
-
import { isValidElement } from "react";
|
|
5046
|
+
import { isValidElement as isValidElement2 } from "react";
|
|
4603
5047
|
var TABLE_HEADER_DISPLAY_NAME = "Table.Header";
|
|
4604
5048
|
var TABLE_BODY_DISPLAY_NAME = "Table.Body";
|
|
4605
5049
|
var TABLE_COLUMN_DISPLAY_NAME = "Table.Column";
|
|
@@ -4612,19 +5056,19 @@ function getComponentDisplayName(type) {
|
|
|
4612
5056
|
return void 0;
|
|
4613
5057
|
}
|
|
4614
5058
|
function isTableHeaderElement(child) {
|
|
4615
|
-
return
|
|
5059
|
+
return isValidElement2(child) && getComponentDisplayName(child.type) === TABLE_HEADER_DISPLAY_NAME;
|
|
4616
5060
|
}
|
|
4617
5061
|
function isTableBodyElement(child) {
|
|
4618
|
-
return
|
|
5062
|
+
return isValidElement2(child) && getComponentDisplayName(child.type) === TABLE_BODY_DISPLAY_NAME;
|
|
4619
5063
|
}
|
|
4620
5064
|
function isTableColumnElement(child) {
|
|
4621
|
-
return
|
|
5065
|
+
return isValidElement2(child) && getComponentDisplayName(child.type) === TABLE_COLUMN_DISPLAY_NAME;
|
|
4622
5066
|
}
|
|
4623
5067
|
function isTableColumnGroupElement(child) {
|
|
4624
|
-
return
|
|
5068
|
+
return isValidElement2(child) && getComponentDisplayName(child.type) === TABLE_COLUMN_GROUP_DISPLAY_NAME;
|
|
4625
5069
|
}
|
|
4626
5070
|
function isTablePaginationElement(child) {
|
|
4627
|
-
return
|
|
5071
|
+
return isValidElement2(child) && getComponentDisplayName(child.type) === TABLE_PAGINATION_DISPLAY_NAME;
|
|
4628
5072
|
}
|
|
4629
5073
|
|
|
4630
5074
|
// src/components/ui/table/components/Table/parseTableChildren.ts
|
|
@@ -4668,7 +5112,7 @@ function walkColumnTreeNodes(children) {
|
|
|
4668
5112
|
});
|
|
4669
5113
|
continue;
|
|
4670
5114
|
}
|
|
4671
|
-
if (
|
|
5115
|
+
if (isValidElement3(child)) {
|
|
4672
5116
|
const nested = child.props.children;
|
|
4673
5117
|
if (nested != null) {
|
|
4674
5118
|
result.push(...walkColumnTreeNodes(nested));
|
|
@@ -4798,7 +5242,7 @@ function TableRoot({
|
|
|
4798
5242
|
() => parseTableChildren(children),
|
|
4799
5243
|
[children]
|
|
4800
5244
|
);
|
|
4801
|
-
const [sort, setSort] =
|
|
5245
|
+
const [sort, setSort] = useState7(null);
|
|
4802
5246
|
const handleSort = useCallback7((field) => {
|
|
4803
5247
|
setSort((previous) => {
|
|
4804
5248
|
if (previous?.field !== field) {
|
|
@@ -4946,6 +5390,7 @@ export {
|
|
|
4946
5390
|
previousSearchIndex,
|
|
4947
5391
|
resolveCellRenderer,
|
|
4948
5392
|
resolveColumnFreezeSide,
|
|
5393
|
+
resolveColumnLayoutWidths,
|
|
4949
5394
|
resolveDataTableLabels,
|
|
4950
5395
|
resolveDropEdge,
|
|
4951
5396
|
resolveHeaderFreezeOffset,
|