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/compound.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// src/components/ui/table/components/DataTable/DataTable.tsx
|
|
2
2
|
import { flexRender as flexRender2 } from "@tanstack/react-table";
|
|
3
|
-
import { useMemo as useMemo4 } from "react";
|
|
3
|
+
import { useEffect as useEffect8, useMemo as useMemo4, useState as useState6 } from "react";
|
|
4
4
|
|
|
5
5
|
// src/components/ui/table/components/DataTable/DataTableRow.tsx
|
|
6
6
|
import { flexRender } from "@tanstack/react-table";
|
|
@@ -30,7 +30,9 @@ var DataTableContext = createContext(null);
|
|
|
30
30
|
function useDataTableRowContext() {
|
|
31
31
|
const context = use(DataTableContext);
|
|
32
32
|
if (!context) {
|
|
33
|
-
throw new Error(
|
|
33
|
+
throw new Error(
|
|
34
|
+
"useDataTableRowContext must be used within a DataTableContextProvider"
|
|
35
|
+
);
|
|
34
36
|
}
|
|
35
37
|
return context;
|
|
36
38
|
}
|
|
@@ -502,8 +504,105 @@ function flattenHeaderLeaves(column) {
|
|
|
502
504
|
}
|
|
503
505
|
|
|
504
506
|
// src/components/ui/table/features/column-resize/columnResize.ts
|
|
507
|
+
function clamp(value, min, max) {
|
|
508
|
+
return Math.min(Math.max(value, min), max);
|
|
509
|
+
}
|
|
510
|
+
function floorOf(column) {
|
|
511
|
+
return column.minWidth ?? 0;
|
|
512
|
+
}
|
|
513
|
+
function ceilOf(column) {
|
|
514
|
+
return column.maxWidth ?? Number.POSITIVE_INFINITY;
|
|
515
|
+
}
|
|
516
|
+
function preferOf(column) {
|
|
517
|
+
const floor = floorOf(column);
|
|
518
|
+
const ceil = ceilOf(column);
|
|
519
|
+
const preferred = column.maxWidth ?? column.minWidth ?? 0;
|
|
520
|
+
return clamp(preferred, floor, Number.isFinite(ceil) ? ceil : preferred);
|
|
521
|
+
}
|
|
522
|
+
function resolveColumnLayoutWidths(containerWidth, columns) {
|
|
523
|
+
const widths = /* @__PURE__ */ new Map();
|
|
524
|
+
const fixed = [];
|
|
525
|
+
const bounded = [];
|
|
526
|
+
let flexCount = 0;
|
|
527
|
+
for (const column of columns) {
|
|
528
|
+
if (column.width != null) {
|
|
529
|
+
fixed.push(column);
|
|
530
|
+
} else if (column.minWidth != null || column.maxWidth != null) {
|
|
531
|
+
bounded.push(column);
|
|
532
|
+
} else {
|
|
533
|
+
flexCount += 1;
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
let used = 0;
|
|
537
|
+
for (const column of fixed) {
|
|
538
|
+
let size = column.width;
|
|
539
|
+
if (column.minWidth != null) size = Math.max(size, column.minWidth);
|
|
540
|
+
if (column.maxWidth != null) size = Math.min(size, column.maxWidth);
|
|
541
|
+
widths.set(column.id, size);
|
|
542
|
+
used += size;
|
|
543
|
+
}
|
|
544
|
+
if (bounded.length === 0) {
|
|
545
|
+
return widths;
|
|
546
|
+
}
|
|
547
|
+
const boundedSizes = /* @__PURE__ */ new Map();
|
|
548
|
+
let preferredSum = 0;
|
|
549
|
+
let floorSum = 0;
|
|
550
|
+
for (const column of bounded) {
|
|
551
|
+
const preferred = preferOf(column);
|
|
552
|
+
boundedSizes.set(column.id, preferred);
|
|
553
|
+
preferredSum += preferred;
|
|
554
|
+
floorSum += floorOf(column);
|
|
555
|
+
}
|
|
556
|
+
if (containerWidth > 0) {
|
|
557
|
+
const remaining = Math.max(0, containerWidth - used);
|
|
558
|
+
if (remaining >= preferredSum) {
|
|
559
|
+
} else if (remaining >= floorSum) {
|
|
560
|
+
let deficit = preferredSum - remaining;
|
|
561
|
+
const open = bounded.map((column) => ({
|
|
562
|
+
id: column.id,
|
|
563
|
+
current: boundedSizes.get(column.id),
|
|
564
|
+
floor: floorOf(column)
|
|
565
|
+
}));
|
|
566
|
+
while (deficit >= 1) {
|
|
567
|
+
const shrinkable = open.filter((entry) => entry.current > entry.floor);
|
|
568
|
+
if (shrinkable.length === 0) break;
|
|
569
|
+
const portion = Math.floor(deficit / shrinkable.length);
|
|
570
|
+
const rem = deficit % shrinkable.length;
|
|
571
|
+
let consumed = 0;
|
|
572
|
+
for (let index = 0; index < shrinkable.length; index += 1) {
|
|
573
|
+
const entry = shrinkable[index];
|
|
574
|
+
const reduce = Math.min(
|
|
575
|
+
entry.current - entry.floor,
|
|
576
|
+
portion + (index < rem ? 1 : 0)
|
|
577
|
+
);
|
|
578
|
+
entry.current -= reduce;
|
|
579
|
+
consumed += reduce;
|
|
580
|
+
}
|
|
581
|
+
if (consumed === 0) break;
|
|
582
|
+
deficit -= consumed;
|
|
583
|
+
}
|
|
584
|
+
for (const entry of open) {
|
|
585
|
+
boundedSizes.set(entry.id, entry.current);
|
|
586
|
+
}
|
|
587
|
+
} else {
|
|
588
|
+
for (const column of bounded) {
|
|
589
|
+
boundedSizes.set(column.id, floorOf(column));
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
for (const [id, size] of boundedSizes) {
|
|
594
|
+
widths.set(id, Math.round(size));
|
|
595
|
+
}
|
|
596
|
+
return widths;
|
|
597
|
+
}
|
|
505
598
|
function getColumnSizeStyle(size, options) {
|
|
506
|
-
const {
|
|
599
|
+
const {
|
|
600
|
+
force = false,
|
|
601
|
+
lockMax = false,
|
|
602
|
+
minWidth,
|
|
603
|
+
maxWidth,
|
|
604
|
+
layoutWidth
|
|
605
|
+
} = options ?? {};
|
|
507
606
|
if (lockMax) {
|
|
508
607
|
return {
|
|
509
608
|
width: size,
|
|
@@ -511,14 +610,27 @@ function getColumnSizeStyle(size, options) {
|
|
|
511
610
|
maxWidth: size
|
|
512
611
|
};
|
|
513
612
|
}
|
|
613
|
+
if (layoutWidth != null) {
|
|
614
|
+
return {
|
|
615
|
+
width: layoutWidth,
|
|
616
|
+
minWidth: layoutWidth,
|
|
617
|
+
maxWidth: layoutWidth
|
|
618
|
+
};
|
|
619
|
+
}
|
|
620
|
+
const resolvedSize = size;
|
|
514
621
|
const hasExplicitSize = force || size !== DATA_TABLE_COLUMN_SIZE;
|
|
515
622
|
if (!hasExplicitSize && minWidth == null && maxWidth == null) {
|
|
516
623
|
return void 0;
|
|
517
624
|
}
|
|
518
625
|
const style = {};
|
|
519
626
|
if (hasExplicitSize) {
|
|
520
|
-
|
|
521
|
-
|
|
627
|
+
const used = minWidth != null || maxWidth != null ? clamp(
|
|
628
|
+
resolvedSize,
|
|
629
|
+
minWidth ?? Number.NEGATIVE_INFINITY,
|
|
630
|
+
maxWidth ?? Number.POSITIVE_INFINITY
|
|
631
|
+
) : resolvedSize;
|
|
632
|
+
style.width = used;
|
|
633
|
+
style.minWidth = minWidth ?? used;
|
|
522
634
|
} else if (minWidth != null) {
|
|
523
635
|
style.minWidth = minWidth;
|
|
524
636
|
}
|
|
@@ -1168,6 +1280,12 @@ function isInteractiveMouseTarget(target) {
|
|
|
1168
1280
|
].join(",");
|
|
1169
1281
|
return target.closest(interactiveSelector) !== null;
|
|
1170
1282
|
}
|
|
1283
|
+
function blurActiveElementOutside(container) {
|
|
1284
|
+
const active = document.activeElement;
|
|
1285
|
+
if (!(active instanceof HTMLElement) || active === document.body) return;
|
|
1286
|
+
if (container instanceof Node && container.contains(active)) return;
|
|
1287
|
+
active.blur();
|
|
1288
|
+
}
|
|
1171
1289
|
function resolveExpandCellIndex(cells, toggleField) {
|
|
1172
1290
|
if (!toggleField) return 0;
|
|
1173
1291
|
const matchedIndex = cells.findIndex(
|
|
@@ -1200,7 +1318,7 @@ function DataTableRow({
|
|
|
1200
1318
|
columnFreeze,
|
|
1201
1319
|
inlineSearch
|
|
1202
1320
|
} = useDataTableRowContext();
|
|
1203
|
-
const { enableColumnResize } = columnResize;
|
|
1321
|
+
const { enableColumnResize, layoutWidths } = columnResize;
|
|
1204
1322
|
const { enableColumnFreeze, offsets: freezeOffsets } = columnFreeze;
|
|
1205
1323
|
const {
|
|
1206
1324
|
enabled: enableInlineSearch,
|
|
@@ -1395,7 +1513,8 @@ function DataTableRow({
|
|
|
1395
1513
|
force: enableColumnResize,
|
|
1396
1514
|
lockMax: enableColumnResize,
|
|
1397
1515
|
minWidth: meta?.minWidth,
|
|
1398
|
-
maxWidth: meta?.maxWidth
|
|
1516
|
+
maxWidth: meta?.maxWidth,
|
|
1517
|
+
layoutWidth: layoutWidths?.get(columnId)
|
|
1399
1518
|
});
|
|
1400
1519
|
const freezeOffset = enableColumnFreeze ? freezeOffsets.get(columnId) : void 0;
|
|
1401
1520
|
const freezeStyle = getColumnFreezeStyle(freezeOffset);
|
|
@@ -1435,6 +1554,7 @@ function DataTableRow({
|
|
|
1435
1554
|
if (!enableCellSelection) return;
|
|
1436
1555
|
if (isInteractiveMouseTarget(event.target)) return;
|
|
1437
1556
|
event.preventDefault();
|
|
1557
|
+
blurActiveElementOutside(event.currentTarget);
|
|
1438
1558
|
onCellMouseDown(
|
|
1439
1559
|
resolveCellRowIndex(event.clientY, event.currentTarget),
|
|
1440
1560
|
cellIndex,
|
|
@@ -1598,6 +1718,7 @@ function DataTableRow({
|
|
|
1598
1718
|
onMouseDown: (event) => {
|
|
1599
1719
|
event.stopPropagation();
|
|
1600
1720
|
event.preventDefault();
|
|
1721
|
+
blurActiveElementOutside(event.currentTarget);
|
|
1601
1722
|
onFillHandleMouseDown(rowIndex, cellIndex);
|
|
1602
1723
|
}
|
|
1603
1724
|
}
|
|
@@ -2525,10 +2646,304 @@ function formatDefaultCellValue(value) {
|
|
|
2525
2646
|
return String(value);
|
|
2526
2647
|
}
|
|
2527
2648
|
|
|
2649
|
+
// src/components/ui/table/features/cell-selection/pasteData.ts
|
|
2650
|
+
function countLeadingEmptyCells(cells) {
|
|
2651
|
+
let depth = 0;
|
|
2652
|
+
while (depth < cells.length && cells[depth] === "") {
|
|
2653
|
+
depth += 1;
|
|
2654
|
+
}
|
|
2655
|
+
return depth;
|
|
2656
|
+
}
|
|
2657
|
+
function looksLikeSubtreeIndentation(leadingEmptyCounts) {
|
|
2658
|
+
if (leadingEmptyCounts.length === 0) return false;
|
|
2659
|
+
const firstDepth = leadingEmptyCounts[0] ?? 0;
|
|
2660
|
+
if (firstDepth !== 0) return false;
|
|
2661
|
+
return leadingEmptyCounts.some((depth) => depth > 0);
|
|
2662
|
+
}
|
|
2663
|
+
function parseClipboardTSVWithDepths(text) {
|
|
2664
|
+
if (!text) return { values: [], depths: [] };
|
|
2665
|
+
const normalized = text.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
2666
|
+
const withoutTrailing = normalized.replace(/\n+$/, "");
|
|
2667
|
+
if (!withoutTrailing) return { values: [], depths: [] };
|
|
2668
|
+
const rows = withoutTrailing.split("\n").map((line) => line.split(" "));
|
|
2669
|
+
const leadingEmptyCounts = rows.map(countLeadingEmptyCells);
|
|
2670
|
+
const treatAsDepth = looksLikeSubtreeIndentation(leadingEmptyCounts);
|
|
2671
|
+
const values = [];
|
|
2672
|
+
const depths = [];
|
|
2673
|
+
for (let index = 0; index < rows.length; index += 1) {
|
|
2674
|
+
const cells = rows[index] ?? [];
|
|
2675
|
+
const depth = leadingEmptyCounts[index] ?? 0;
|
|
2676
|
+
if (treatAsDepth) {
|
|
2677
|
+
values.push(cells.slice(depth));
|
|
2678
|
+
depths.push(depth);
|
|
2679
|
+
} else {
|
|
2680
|
+
values.push(cells);
|
|
2681
|
+
depths.push(0);
|
|
2682
|
+
}
|
|
2683
|
+
}
|
|
2684
|
+
return { values, depths };
|
|
2685
|
+
}
|
|
2686
|
+
function resolvePasteColumnIds(rows, startCol, width) {
|
|
2687
|
+
if (width <= 0) return [];
|
|
2688
|
+
const cells = rows[0]?.getVisibleCells() ?? [];
|
|
2689
|
+
const columnIds = [];
|
|
2690
|
+
for (let offset = 0; offset < width; offset += 1) {
|
|
2691
|
+
const cell = cells[startCol + offset];
|
|
2692
|
+
if (!cell) break;
|
|
2693
|
+
columnIds.push(cell.column.id);
|
|
2694
|
+
}
|
|
2695
|
+
return columnIds;
|
|
2696
|
+
}
|
|
2697
|
+
function buildRowsPastePayload(rows, startRow, startCol, text, mode, endRow = startRow) {
|
|
2698
|
+
const { values, depths } = parseClipboardTSVWithDepths(text);
|
|
2699
|
+
if (values.length === 0) return null;
|
|
2700
|
+
const width = Math.max(...values.map((row) => row.length), 0);
|
|
2701
|
+
if (width === 0) return null;
|
|
2702
|
+
const columnIds = resolvePasteColumnIds(rows, startCol, width);
|
|
2703
|
+
if (columnIds.length === 0) return null;
|
|
2704
|
+
const rowIds = [];
|
|
2705
|
+
for (let offset = 0; offset < values.length; offset += 1) {
|
|
2706
|
+
const row = rows[startRow + offset];
|
|
2707
|
+
if (!row) break;
|
|
2708
|
+
rowIds.push(row.id);
|
|
2709
|
+
}
|
|
2710
|
+
const anchorRow = rows[endRow] ?? rows[startRow];
|
|
2711
|
+
return {
|
|
2712
|
+
mode,
|
|
2713
|
+
startRow,
|
|
2714
|
+
startCol,
|
|
2715
|
+
endRow,
|
|
2716
|
+
rowIds,
|
|
2717
|
+
anchorRowId: anchorRow?.id ?? "",
|
|
2718
|
+
columnIds,
|
|
2719
|
+
values,
|
|
2720
|
+
depths
|
|
2721
|
+
};
|
|
2722
|
+
}
|
|
2723
|
+
function isEditablePasteTarget(target) {
|
|
2724
|
+
if (!(target instanceof HTMLElement)) return false;
|
|
2725
|
+
const tag = target.tagName;
|
|
2726
|
+
if (tag === "INPUT" || tag === "TEXTAREA" || tag === "SELECT") return true;
|
|
2727
|
+
return Boolean(target.isContentEditable);
|
|
2728
|
+
}
|
|
2729
|
+
|
|
2528
2730
|
// src/components/ui/table/features/cell-selection/useCellSelection.ts
|
|
2529
2731
|
import { useCallback as useCallback3, useEffect as useEffect5, useRef as useRef5, useState as useState3 } from "react";
|
|
2530
2732
|
|
|
2531
2733
|
// src/components/ui/table/features/cell-selection/copyData.ts
|
|
2734
|
+
import { isValidElement } from "react";
|
|
2735
|
+
function isReactNodeIterable(node) {
|
|
2736
|
+
return typeof node === "object" && node !== null && !isValidElement(node) && Symbol.iterator in node;
|
|
2737
|
+
}
|
|
2738
|
+
function getElementTypeName(type) {
|
|
2739
|
+
if (typeof type === "string") return type;
|
|
2740
|
+
if (typeof type === "function") {
|
|
2741
|
+
const fn = type;
|
|
2742
|
+
return fn.displayName || fn.name || "";
|
|
2743
|
+
}
|
|
2744
|
+
if (typeof type === "object" && type !== null) {
|
|
2745
|
+
const component = type;
|
|
2746
|
+
return component.displayName || component.render?.displayName || component.render?.name || "";
|
|
2747
|
+
}
|
|
2748
|
+
return "";
|
|
2749
|
+
}
|
|
2750
|
+
function isButtonReactElement(node) {
|
|
2751
|
+
const typeName = getElementTypeName(node.type);
|
|
2752
|
+
if (typeName === "button" || /button/i.test(typeName)) return true;
|
|
2753
|
+
const props = node.props;
|
|
2754
|
+
if (props.role === "button") return true;
|
|
2755
|
+
if (typeName === "input" && props.type === "button") return true;
|
|
2756
|
+
return false;
|
|
2757
|
+
}
|
|
2758
|
+
function isImageReactElement(node) {
|
|
2759
|
+
const typeName = getElementTypeName(node.type);
|
|
2760
|
+
return typeName === "img" || typeName === "image" || /image/i.test(typeName);
|
|
2761
|
+
}
|
|
2762
|
+
var IMAGE_URL_PROP_KEYS = ["src", "url", "href", "imageUrl", "srcUrl"];
|
|
2763
|
+
function isLikelyUrl(value) {
|
|
2764
|
+
const trimmed = value.trim();
|
|
2765
|
+
if (!trimmed) return false;
|
|
2766
|
+
if (/^(https?:|blob:|data:|\/\/)/i.test(trimmed)) return true;
|
|
2767
|
+
if (trimmed.startsWith("/") && trimmed.includes("/")) return true;
|
|
2768
|
+
return false;
|
|
2769
|
+
}
|
|
2770
|
+
function pickUrlFromUnknown(value) {
|
|
2771
|
+
if (typeof value === "string") {
|
|
2772
|
+
return isLikelyUrl(value) ? value.trim() : "";
|
|
2773
|
+
}
|
|
2774
|
+
if (Array.isArray(value)) {
|
|
2775
|
+
return value.map((item) => pickUrlFromUnknown(item)).filter((item) => item.length > 0).join(", ");
|
|
2776
|
+
}
|
|
2777
|
+
if (value && typeof value === "object") {
|
|
2778
|
+
const record = value;
|
|
2779
|
+
for (const key of IMAGE_URL_PROP_KEYS) {
|
|
2780
|
+
const candidate = record[key];
|
|
2781
|
+
if (typeof candidate === "string" && candidate.trim()) {
|
|
2782
|
+
return candidate.trim();
|
|
2783
|
+
}
|
|
2784
|
+
}
|
|
2785
|
+
}
|
|
2786
|
+
return "";
|
|
2787
|
+
}
|
|
2788
|
+
function imageElementText(node) {
|
|
2789
|
+
const props = node.props;
|
|
2790
|
+
for (const key of IMAGE_URL_PROP_KEYS) {
|
|
2791
|
+
const candidate = props[key];
|
|
2792
|
+
if (typeof candidate === "string" && candidate.trim()) {
|
|
2793
|
+
return candidate.trim();
|
|
2794
|
+
}
|
|
2795
|
+
}
|
|
2796
|
+
return "";
|
|
2797
|
+
}
|
|
2798
|
+
function reactNodeContainsImage(node) {
|
|
2799
|
+
if (isValidElement(node)) {
|
|
2800
|
+
if (isImageReactElement(node)) return true;
|
|
2801
|
+
return reactNodeContainsImage(node.props.children);
|
|
2802
|
+
}
|
|
2803
|
+
if (isReactNodeIterable(node)) {
|
|
2804
|
+
for (const child of node) {
|
|
2805
|
+
if (reactNodeContainsImage(child)) return true;
|
|
2806
|
+
}
|
|
2807
|
+
}
|
|
2808
|
+
return false;
|
|
2809
|
+
}
|
|
2810
|
+
function readImgUrl(img) {
|
|
2811
|
+
const attr = img.getAttribute("src")?.trim() ?? "";
|
|
2812
|
+
if (attr) return attr;
|
|
2813
|
+
if (img instanceof HTMLImageElement) {
|
|
2814
|
+
const current = img.currentSrc?.trim() ?? "";
|
|
2815
|
+
if (current && current !== img.baseURI) return current;
|
|
2816
|
+
}
|
|
2817
|
+
return "";
|
|
2818
|
+
}
|
|
2819
|
+
function readDomImageUrls(rowIndex, colIndex, root) {
|
|
2820
|
+
const scope = root ?? (typeof document === "undefined" ? null : document);
|
|
2821
|
+
if (!scope) return "";
|
|
2822
|
+
const cells = scope.querySelectorAll(
|
|
2823
|
+
`[data-row-index="${rowIndex}"][data-col-index="${colIndex}"]`
|
|
2824
|
+
);
|
|
2825
|
+
for (const cell of cells) {
|
|
2826
|
+
const urls = Array.from(cell.querySelectorAll("img")).flatMap((img) => {
|
|
2827
|
+
const url = readImgUrl(img);
|
|
2828
|
+
return url ? [url] : [];
|
|
2829
|
+
});
|
|
2830
|
+
if (urls.length > 0) return urls.join(", ");
|
|
2831
|
+
}
|
|
2832
|
+
return "";
|
|
2833
|
+
}
|
|
2834
|
+
function reactNodeToText(node) {
|
|
2835
|
+
if (node == null || typeof node === "boolean") return "";
|
|
2836
|
+
if (typeof node === "string" || typeof node === "number" || typeof node === "bigint") {
|
|
2837
|
+
return String(node);
|
|
2838
|
+
}
|
|
2839
|
+
if (isReactNodeIterable(node)) {
|
|
2840
|
+
let text = "";
|
|
2841
|
+
for (const child of node) {
|
|
2842
|
+
text += reactNodeToText(child);
|
|
2843
|
+
}
|
|
2844
|
+
return text;
|
|
2845
|
+
}
|
|
2846
|
+
if (isValidElement(node)) {
|
|
2847
|
+
if (isButtonReactElement(node)) return "";
|
|
2848
|
+
const props = node.props;
|
|
2849
|
+
const childText = reactNodeToText(props.children);
|
|
2850
|
+
if (childText) return childText;
|
|
2851
|
+
const fromImage = imageElementText(node);
|
|
2852
|
+
if (fromImage) return fromImage;
|
|
2853
|
+
if (isImageReactElement(node)) return "";
|
|
2854
|
+
if (typeof props.alt === "string" && props.alt) return props.alt;
|
|
2855
|
+
if (typeof props.title === "string" && props.title) return props.title;
|
|
2856
|
+
return "";
|
|
2857
|
+
}
|
|
2858
|
+
return "";
|
|
2859
|
+
}
|
|
2860
|
+
function sanitizeClipboardCell(text) {
|
|
2861
|
+
return text.replace(/\s+/g, " ").trim();
|
|
2862
|
+
}
|
|
2863
|
+
function createCopyRenderRow(rowData, index) {
|
|
2864
|
+
return {
|
|
2865
|
+
id: getOriginalRowId(rowData) || String(index),
|
|
2866
|
+
index,
|
|
2867
|
+
original: rowData,
|
|
2868
|
+
getIsCellDragSelected: () => false
|
|
2869
|
+
};
|
|
2870
|
+
}
|
|
2871
|
+
function buildVisibleRowLookup(visibleRows) {
|
|
2872
|
+
const lookup = /* @__PURE__ */ new Map();
|
|
2873
|
+
for (const row of visibleRows) {
|
|
2874
|
+
lookup.set(row.original, row);
|
|
2875
|
+
}
|
|
2876
|
+
return lookup;
|
|
2877
|
+
}
|
|
2878
|
+
function resolveCopyColumnId(cell) {
|
|
2879
|
+
if (cell.column.id) return cell.column.id;
|
|
2880
|
+
const columnDef = cell.column.columnDef;
|
|
2881
|
+
if (columnDef.id) return columnDef.id;
|
|
2882
|
+
if (columnDef.accessorKey != null && columnDef.accessorKey !== "") {
|
|
2883
|
+
return String(columnDef.accessorKey);
|
|
2884
|
+
}
|
|
2885
|
+
return "";
|
|
2886
|
+
}
|
|
2887
|
+
function isPrimitiveCopyValue(value) {
|
|
2888
|
+
return value == null || typeof value !== "object";
|
|
2889
|
+
}
|
|
2890
|
+
function extractRenderedCopyText(node, value, cellPosition, root) {
|
|
2891
|
+
const rendered = sanitizeClipboardCell(reactNodeToText(node));
|
|
2892
|
+
if (reactNodeContainsImage(node)) {
|
|
2893
|
+
const fromDom = cellPosition != null ? sanitizeClipboardCell(
|
|
2894
|
+
readDomImageUrls(cellPosition.rowIndex, cellPosition.colIndex, root)
|
|
2895
|
+
) : "";
|
|
2896
|
+
if (fromDom) return fromDom;
|
|
2897
|
+
if (rendered && isLikelyUrl(rendered)) return rendered;
|
|
2898
|
+
return sanitizeClipboardCell(pickUrlFromUnknown(value));
|
|
2899
|
+
}
|
|
2900
|
+
return rendered;
|
|
2901
|
+
}
|
|
2902
|
+
function formatCopyCellText(rowData, columnDef, columnId, visibleRow, fallbackIndex, sourceCell, cellPosition, options) {
|
|
2903
|
+
const meta = columnDef.meta;
|
|
2904
|
+
const value = sourceCell ? sourceCell.getValue() : readRowColumnValue(rowData, columnDef);
|
|
2905
|
+
const cellRender = meta?.cellRender;
|
|
2906
|
+
if (typeof cellRender === "function") {
|
|
2907
|
+
try {
|
|
2908
|
+
const row = visibleRow ?? createCopyRenderRow(rowData, fallbackIndex);
|
|
2909
|
+
const node = cellRender({
|
|
2910
|
+
value,
|
|
2911
|
+
row,
|
|
2912
|
+
index: row.index,
|
|
2913
|
+
columnId,
|
|
2914
|
+
cellProps: meta?.cellProps,
|
|
2915
|
+
update: () => {
|
|
2916
|
+
}
|
|
2917
|
+
});
|
|
2918
|
+
return extractRenderedCopyText(node, value, cellPosition, options?.root);
|
|
2919
|
+
} catch {
|
|
2920
|
+
return formatCellValue(value);
|
|
2921
|
+
}
|
|
2922
|
+
}
|
|
2923
|
+
if (options?.registry && meta?.kind && isPrimitiveCopyValue(value)) {
|
|
2924
|
+
try {
|
|
2925
|
+
const row = visibleRow ?? createCopyRenderRow(rowData, fallbackIndex);
|
|
2926
|
+
const ctx = {
|
|
2927
|
+
value,
|
|
2928
|
+
row,
|
|
2929
|
+
index: row.index,
|
|
2930
|
+
columnId,
|
|
2931
|
+
cellProps: meta.cellProps,
|
|
2932
|
+
update: () => {
|
|
2933
|
+
}
|
|
2934
|
+
};
|
|
2935
|
+
const renderer = resolveCellRenderer(options.registry, meta.kind, ctx);
|
|
2936
|
+
if (renderer) {
|
|
2937
|
+
const node = renderer.render(ctx);
|
|
2938
|
+
const rendered = extractRenderedCopyText(node, value, cellPosition, options.root);
|
|
2939
|
+
if (rendered) return rendered;
|
|
2940
|
+
}
|
|
2941
|
+
} catch {
|
|
2942
|
+
return formatCellValue(value);
|
|
2943
|
+
}
|
|
2944
|
+
}
|
|
2945
|
+
return formatCellValue(value);
|
|
2946
|
+
}
|
|
2532
2947
|
function formatPrimitive(value) {
|
|
2533
2948
|
if (value === null || value === void 0) return "";
|
|
2534
2949
|
if (typeof value === "string") return value;
|
|
@@ -2615,37 +3030,47 @@ function collectCopyRowEntries(visibleRows, bounds, mode = "visible") {
|
|
|
2615
3030
|
}
|
|
2616
3031
|
return result;
|
|
2617
3032
|
}
|
|
2618
|
-
function serializeCopyRowsToTSV(copyRows, visibleRows, bounds, depths) {
|
|
3033
|
+
function serializeCopyRowsToTSV(copyRows, visibleRows, bounds, depths, options) {
|
|
2619
3034
|
if (copyRows.length === 0) return "";
|
|
2620
3035
|
const { startCol, endCol } = bounds;
|
|
2621
3036
|
const columnCells = visibleRows[0]?.getVisibleCells().slice(startCol, endCol + 1) ?? [];
|
|
2622
3037
|
if (columnCells.length === 0) return "";
|
|
2623
3038
|
const resolvedDepths = depths && depths.length === copyRows.length ? depths : copyRows.map((row) => getRowDepth(row));
|
|
2624
3039
|
const minDepth = Math.min(...resolvedDepths);
|
|
3040
|
+
const visibleRowByOriginal = buildVisibleRowLookup(visibleRows);
|
|
2625
3041
|
return copyRows.map((rowData, index) => {
|
|
2626
3042
|
const relativeDepth = Math.max(0, (resolvedDepths[index] ?? 0) - minDepth);
|
|
2627
|
-
const
|
|
2628
|
-
|
|
2629
|
-
|
|
2630
|
-
|
|
2631
|
-
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
|
|
3043
|
+
const visibleRow = visibleRowByOriginal.get(rowData);
|
|
3044
|
+
const matchingCells = visibleRow?.getVisibleCells().slice(startCol, endCol + 1);
|
|
3045
|
+
const line = columnCells.map((templateCell, colOffset) => {
|
|
3046
|
+
const sourceCell = matchingCells?.[colOffset];
|
|
3047
|
+
const column = sourceCell?.column ?? templateCell.column;
|
|
3048
|
+
return formatCopyCellText(
|
|
3049
|
+
rowData,
|
|
3050
|
+
column.columnDef,
|
|
3051
|
+
resolveCopyColumnId(sourceCell ?? templateCell),
|
|
3052
|
+
visibleRow,
|
|
3053
|
+
visibleRow?.index ?? index,
|
|
3054
|
+
sourceCell,
|
|
3055
|
+
visibleRow != null ? { rowIndex: visibleRow.index, colIndex: startCol + colOffset } : void 0,
|
|
3056
|
+
options
|
|
3057
|
+
);
|
|
3058
|
+
}).join(" ");
|
|
2635
3059
|
return `${" ".repeat(relativeDepth)}${line}`;
|
|
2636
3060
|
}).join("\n");
|
|
2637
3061
|
}
|
|
2638
|
-
function serializeSelectionToTSV(visibleRows, bounds, mode = "visible") {
|
|
3062
|
+
function serializeSelectionToTSV(visibleRows, bounds, mode = "visible", options) {
|
|
2639
3063
|
const entries = collectCopyRowEntries(visibleRows, bounds, mode);
|
|
2640
3064
|
return serializeCopyRowsToTSV(
|
|
2641
3065
|
entries.map((entry) => entry.row),
|
|
2642
3066
|
visibleRows,
|
|
2643
3067
|
bounds,
|
|
2644
|
-
entries.map((entry) => entry.depth)
|
|
3068
|
+
entries.map((entry) => entry.depth),
|
|
3069
|
+
options
|
|
2645
3070
|
);
|
|
2646
3071
|
}
|
|
2647
|
-
async function writeSelectionToClipboard(visibleRows, bounds, mode = "visible") {
|
|
2648
|
-
const text = serializeSelectionToTSV(visibleRows, bounds, mode);
|
|
3072
|
+
async function writeSelectionToClipboard(visibleRows, bounds, mode = "visible", options) {
|
|
3073
|
+
const text = serializeSelectionToTSV(visibleRows, bounds, mode, options);
|
|
2649
3074
|
if (!text) return false;
|
|
2650
3075
|
try {
|
|
2651
3076
|
await navigator.clipboard.writeText(text);
|
|
@@ -2711,87 +3136,6 @@ function hasFillExtension(sourceBounds, fillBounds) {
|
|
|
2711
3136
|
return fillBounds.startRow < sourceBounds.startRow || fillBounds.endRow > sourceBounds.endRow || fillBounds.startCol < sourceBounds.startCol || fillBounds.endCol > sourceBounds.endCol;
|
|
2712
3137
|
}
|
|
2713
3138
|
|
|
2714
|
-
// src/components/ui/table/features/cell-selection/pasteData.ts
|
|
2715
|
-
function countLeadingEmptyCells(cells) {
|
|
2716
|
-
let depth = 0;
|
|
2717
|
-
while (depth < cells.length && cells[depth] === "") {
|
|
2718
|
-
depth += 1;
|
|
2719
|
-
}
|
|
2720
|
-
return depth;
|
|
2721
|
-
}
|
|
2722
|
-
function looksLikeSubtreeIndentation(leadingEmptyCounts) {
|
|
2723
|
-
if (leadingEmptyCounts.length === 0) return false;
|
|
2724
|
-
const firstDepth = leadingEmptyCounts[0] ?? 0;
|
|
2725
|
-
if (firstDepth !== 0) return false;
|
|
2726
|
-
return leadingEmptyCounts.some((depth) => depth > 0);
|
|
2727
|
-
}
|
|
2728
|
-
function parseClipboardTSVWithDepths(text) {
|
|
2729
|
-
if (!text) return { values: [], depths: [] };
|
|
2730
|
-
const normalized = text.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
2731
|
-
const withoutTrailing = normalized.replace(/\n+$/, "");
|
|
2732
|
-
if (!withoutTrailing) return { values: [], depths: [] };
|
|
2733
|
-
const rows = withoutTrailing.split("\n").map((line) => line.split(" "));
|
|
2734
|
-
const leadingEmptyCounts = rows.map(countLeadingEmptyCells);
|
|
2735
|
-
const treatAsDepth = looksLikeSubtreeIndentation(leadingEmptyCounts);
|
|
2736
|
-
const values = [];
|
|
2737
|
-
const depths = [];
|
|
2738
|
-
for (let index = 0; index < rows.length; index += 1) {
|
|
2739
|
-
const cells = rows[index] ?? [];
|
|
2740
|
-
const depth = leadingEmptyCounts[index] ?? 0;
|
|
2741
|
-
if (treatAsDepth) {
|
|
2742
|
-
values.push(cells.slice(depth));
|
|
2743
|
-
depths.push(depth);
|
|
2744
|
-
} else {
|
|
2745
|
-
values.push(cells);
|
|
2746
|
-
depths.push(0);
|
|
2747
|
-
}
|
|
2748
|
-
}
|
|
2749
|
-
return { values, depths };
|
|
2750
|
-
}
|
|
2751
|
-
function resolvePasteColumnIds(rows, startCol, width) {
|
|
2752
|
-
if (width <= 0) return [];
|
|
2753
|
-
const cells = rows[0]?.getVisibleCells() ?? [];
|
|
2754
|
-
const columnIds = [];
|
|
2755
|
-
for (let offset = 0; offset < width; offset += 1) {
|
|
2756
|
-
const cell = cells[startCol + offset];
|
|
2757
|
-
if (!cell) break;
|
|
2758
|
-
columnIds.push(cell.column.id);
|
|
2759
|
-
}
|
|
2760
|
-
return columnIds;
|
|
2761
|
-
}
|
|
2762
|
-
function buildRowsPastePayload(rows, startRow, startCol, text, mode, endRow = startRow) {
|
|
2763
|
-
const { values, depths } = parseClipboardTSVWithDepths(text);
|
|
2764
|
-
if (values.length === 0) return null;
|
|
2765
|
-
const width = Math.max(...values.map((row) => row.length), 0);
|
|
2766
|
-
if (width === 0) return null;
|
|
2767
|
-
const columnIds = resolvePasteColumnIds(rows, startCol, width);
|
|
2768
|
-
if (columnIds.length === 0) return null;
|
|
2769
|
-
const rowIds = [];
|
|
2770
|
-
for (let offset = 0; offset < values.length; offset += 1) {
|
|
2771
|
-
const row = rows[startRow + offset];
|
|
2772
|
-
if (!row) break;
|
|
2773
|
-
rowIds.push(row.id);
|
|
2774
|
-
}
|
|
2775
|
-
const anchorRow = rows[endRow] ?? rows[startRow];
|
|
2776
|
-
return {
|
|
2777
|
-
mode,
|
|
2778
|
-
startRow,
|
|
2779
|
-
startCol,
|
|
2780
|
-
endRow,
|
|
2781
|
-
rowIds,
|
|
2782
|
-
anchorRowId: anchorRow?.id ?? "",
|
|
2783
|
-
columnIds,
|
|
2784
|
-
values,
|
|
2785
|
-
depths
|
|
2786
|
-
};
|
|
2787
|
-
}
|
|
2788
|
-
function isEditablePasteTarget(target) {
|
|
2789
|
-
if (!(target instanceof HTMLElement)) return false;
|
|
2790
|
-
const tag = target.tagName;
|
|
2791
|
-
if (tag === "INPUT" || tag === "TEXTAREA" || tag === "SELECT") return true;
|
|
2792
|
-
return Boolean(target.isContentEditable);
|
|
2793
|
-
}
|
|
2794
|
-
|
|
2795
3139
|
// src/components/ui/table/features/cell-selection/useCellSelection.ts
|
|
2796
3140
|
function useCellSelection({
|
|
2797
3141
|
data,
|
|
@@ -2803,7 +3147,9 @@ function useCellSelection({
|
|
|
2803
3147
|
onDataChange,
|
|
2804
3148
|
onBatchChange,
|
|
2805
3149
|
onRowsPaste,
|
|
2806
|
-
onCellNavigate
|
|
3150
|
+
onCellNavigate,
|
|
3151
|
+
cellRendererRegistry,
|
|
3152
|
+
rootRef
|
|
2807
3153
|
}) {
|
|
2808
3154
|
const [dragState, setDragState] = useState3(INITIAL_DRAG_STATE);
|
|
2809
3155
|
const pendingPasteModeRef = useRef5(null);
|
|
@@ -2871,11 +3217,19 @@ function useCellSelection({
|
|
|
2871
3217
|
},
|
|
2872
3218
|
[enabled]
|
|
2873
3219
|
);
|
|
3220
|
+
const clearSelection = useCallback3(() => {
|
|
3221
|
+
const prev = dragStateRef.current;
|
|
3222
|
+
if (prev.start === null && prev.end === null && !prev.isSelecting && !prev.isFillDragging) {
|
|
3223
|
+
return;
|
|
3224
|
+
}
|
|
3225
|
+
dragStateRef.current = INITIAL_DRAG_STATE;
|
|
3226
|
+
setDragState(INITIAL_DRAG_STATE);
|
|
3227
|
+
}, []);
|
|
2874
3228
|
useEffect5(() => {
|
|
2875
3229
|
if (!enabled) {
|
|
2876
|
-
|
|
3230
|
+
clearSelection();
|
|
2877
3231
|
}
|
|
2878
|
-
}, [enabled]);
|
|
3232
|
+
}, [clearSelection, enabled]);
|
|
2879
3233
|
useEffect5(() => {
|
|
2880
3234
|
if (!enabled) return;
|
|
2881
3235
|
const handleKeyDown = (e) => {
|
|
@@ -2927,15 +3281,28 @@ function useCellSelection({
|
|
|
2927
3281
|
async (options) => {
|
|
2928
3282
|
if (!enabled || !activeSelectionBounds) return false;
|
|
2929
3283
|
const mode = options?.includeDescendants && enableSubtreeCopy ? "subtree" : "visible";
|
|
2930
|
-
return writeSelectionToClipboard(rows, activeSelectionBounds, mode
|
|
3284
|
+
return writeSelectionToClipboard(rows, activeSelectionBounds, mode, {
|
|
3285
|
+
registry: cellRendererRegistry,
|
|
3286
|
+
root: rootRef?.current
|
|
3287
|
+
});
|
|
2931
3288
|
},
|
|
2932
|
-
[
|
|
3289
|
+
[
|
|
3290
|
+
activeSelectionBounds,
|
|
3291
|
+
cellRendererRegistry,
|
|
3292
|
+
enableSubtreeCopy,
|
|
3293
|
+
enabled,
|
|
3294
|
+
rootRef,
|
|
3295
|
+
rows
|
|
3296
|
+
]
|
|
2933
3297
|
);
|
|
2934
3298
|
useEffect5(() => {
|
|
2935
3299
|
if (!enabled) return;
|
|
2936
3300
|
const handleKeyDown = (e) => {
|
|
2937
3301
|
if (!activeSelectionBounds) return;
|
|
2938
3302
|
if (!(e.ctrlKey || e.metaKey)) return;
|
|
3303
|
+
if (isEditablePasteTarget(e.target) || isEditablePasteTarget(document.activeElement)) {
|
|
3304
|
+
return;
|
|
3305
|
+
}
|
|
2939
3306
|
const isSubtreeShortcut = enableSubtreeCopy && e.shiftKey && e.key.toLowerCase() === "c";
|
|
2940
3307
|
const isVisibleCopyShortcut = !e.shiftKey && e.key.toLowerCase() === "c";
|
|
2941
3308
|
if (!isSubtreeShortcut && !isVisibleCopyShortcut) return;
|
|
@@ -3076,6 +3443,7 @@ function useCellSelection({
|
|
|
3076
3443
|
handleCellMouseDown,
|
|
3077
3444
|
handleCellMouseEnter,
|
|
3078
3445
|
handleFillHandleMouseDown,
|
|
3446
|
+
clearSelection,
|
|
3079
3447
|
copySelection
|
|
3080
3448
|
};
|
|
3081
3449
|
}
|
|
@@ -3498,6 +3866,10 @@ function useGlideTable(options) {
|
|
|
3498
3866
|
const [hoveredRowIndex, setHoveredRowIndex] = useState5(null);
|
|
3499
3867
|
const scrollRef = useRef7(null);
|
|
3500
3868
|
const rootRef = useRef7(null);
|
|
3869
|
+
const cellRendererRegistry = useMemo3(
|
|
3870
|
+
() => createCellRendererRegistry(cellRenderers),
|
|
3871
|
+
[cellRenderers]
|
|
3872
|
+
);
|
|
3501
3873
|
const shouldVirtualize = enableVirtualization && !enableRowSpan;
|
|
3502
3874
|
useEffect7(() => {
|
|
3503
3875
|
if (enableVirtualization && enableRowSpan) {
|
|
@@ -3670,6 +4042,7 @@ function useGlideTable(options) {
|
|
|
3670
4042
|
handleCellMouseDown,
|
|
3671
4043
|
handleCellMouseEnter,
|
|
3672
4044
|
handleFillHandleMouseDown,
|
|
4045
|
+
clearSelection: clearCellSelection,
|
|
3673
4046
|
copySelection
|
|
3674
4047
|
} = useCellSelection({
|
|
3675
4048
|
data: tableData,
|
|
@@ -3681,8 +4054,46 @@ function useGlideTable(options) {
|
|
|
3681
4054
|
onDataChange,
|
|
3682
4055
|
onBatchChange,
|
|
3683
4056
|
onRowsPaste,
|
|
3684
|
-
onCellNavigate: handleCellNavigate
|
|
4057
|
+
onCellNavigate: handleCellNavigate,
|
|
4058
|
+
cellRendererRegistry,
|
|
4059
|
+
rootRef
|
|
3685
4060
|
});
|
|
4061
|
+
const clearRowSelection = useCallback5(() => {
|
|
4062
|
+
if (rowSelectionMode === "none") return;
|
|
4063
|
+
const hasSelection = Object.values(rowSelection).some(Boolean);
|
|
4064
|
+
if (!hasSelection) return;
|
|
4065
|
+
if (onRowSelectionChange) {
|
|
4066
|
+
onRowSelectionChange(() => ({}));
|
|
4067
|
+
return;
|
|
4068
|
+
}
|
|
4069
|
+
setInternalRowSelection({});
|
|
4070
|
+
}, [onRowSelectionChange, rowSelection, rowSelectionMode]);
|
|
4071
|
+
useEffect7(() => {
|
|
4072
|
+
const clearAllSelections = () => {
|
|
4073
|
+
clearCellSelection();
|
|
4074
|
+
clearRowSelection();
|
|
4075
|
+
};
|
|
4076
|
+
const handleKeyDown = (event) => {
|
|
4077
|
+
if (event.key !== "Escape") return;
|
|
4078
|
+
if (event.defaultPrevented) return;
|
|
4079
|
+
if (isEditablePasteTarget(event.target) || isEditablePasteTarget(document.activeElement)) {
|
|
4080
|
+
return;
|
|
4081
|
+
}
|
|
4082
|
+
clearAllSelections();
|
|
4083
|
+
};
|
|
4084
|
+
const handleMouseDown = (event) => {
|
|
4085
|
+
const root = rootRef.current;
|
|
4086
|
+
if (!root) return;
|
|
4087
|
+
if (event.target instanceof Node && root.contains(event.target)) return;
|
|
4088
|
+
clearAllSelections();
|
|
4089
|
+
};
|
|
4090
|
+
window.addEventListener("keydown", handleKeyDown);
|
|
4091
|
+
document.addEventListener("mousedown", handleMouseDown);
|
|
4092
|
+
return () => {
|
|
4093
|
+
window.removeEventListener("keydown", handleKeyDown);
|
|
4094
|
+
document.removeEventListener("mousedown", handleMouseDown);
|
|
4095
|
+
};
|
|
4096
|
+
}, [clearCellSelection, clearRowSelection]);
|
|
3686
4097
|
const {
|
|
3687
4098
|
editingCell,
|
|
3688
4099
|
draftValue,
|
|
@@ -3691,10 +4102,6 @@ function useGlideTable(options) {
|
|
|
3691
4102
|
commitEdit,
|
|
3692
4103
|
cancelEdit
|
|
3693
4104
|
} = useCellEdit({ data: tableData, rows, onDataChange, onCellChange });
|
|
3694
|
-
const cellRendererRegistry = useMemo3(
|
|
3695
|
-
() => createCellRendererRegistry(cellRenderers),
|
|
3696
|
-
[cellRenderers]
|
|
3697
|
-
);
|
|
3698
4105
|
const commitRenderedCellValue = useCallback5(
|
|
3699
4106
|
(rowId, columnId, value) => commitCellValue({
|
|
3700
4107
|
data: tableData,
|
|
@@ -4152,17 +4559,74 @@ function DataTable({
|
|
|
4152
4559
|
const RowSlot = slots?.Row ?? DataTableRow;
|
|
4153
4560
|
const PendingSlot = slots?.Pending ?? DefaultPending;
|
|
4154
4561
|
const EmptySlot = slots?.Empty ?? DefaultEmpty;
|
|
4155
|
-
const freezeOffsets = rowContextValue.columnFreeze.offsets;
|
|
4156
4562
|
const headerGroups = getMergedHeaderGroups(table.getHeaderGroups());
|
|
4157
4563
|
const leafColumnIds = table.getVisibleLeafColumns().map((column) => column.id);
|
|
4564
|
+
const columnLayoutMetaSignature = table.getVisibleLeafColumns().map((column) => {
|
|
4565
|
+
const meta = column.columnDef.meta;
|
|
4566
|
+
return `${column.id}:${meta?.width ?? ""}:${meta?.minWidth ?? ""}:${meta?.maxWidth ?? ""}`;
|
|
4567
|
+
}).join("|");
|
|
4158
4568
|
const { isReordering, draggingColumnId, dropTarget, onHeaderPointerDown } = useColumnReorder({
|
|
4159
4569
|
enabled: enableColumnReorder,
|
|
4160
4570
|
columnOrder: leafColumnIds,
|
|
4161
4571
|
onColumnOrderChange: setColumnOrder
|
|
4162
4572
|
});
|
|
4573
|
+
const [containerWidth, setContainerWidth] = useState6(0);
|
|
4574
|
+
useEffect8(() => {
|
|
4575
|
+
if (enableColumnResize || isPending) return;
|
|
4576
|
+
const element = scrollRef.current;
|
|
4577
|
+
if (!element) return;
|
|
4578
|
+
const updateWidth = () => {
|
|
4579
|
+
setContainerWidth(Math.floor(element.clientWidth));
|
|
4580
|
+
};
|
|
4581
|
+
updateWidth();
|
|
4582
|
+
if (typeof ResizeObserver === "undefined") return;
|
|
4583
|
+
const observer = new ResizeObserver(() => {
|
|
4584
|
+
updateWidth();
|
|
4585
|
+
});
|
|
4586
|
+
observer.observe(element);
|
|
4587
|
+
return () => observer.disconnect();
|
|
4588
|
+
}, [enableColumnResize, isPending, scrollRef, rows.length, leafColumnIds.join("|")]);
|
|
4589
|
+
const layoutWidths = useMemo4(() => {
|
|
4590
|
+
if (enableColumnResize) return void 0;
|
|
4591
|
+
const columns = table.getVisibleLeafColumns().map((column) => ({
|
|
4592
|
+
id: column.id,
|
|
4593
|
+
width: column.columnDef.meta?.width,
|
|
4594
|
+
minWidth: column.columnDef.meta?.minWidth,
|
|
4595
|
+
maxWidth: column.columnDef.meta?.maxWidth
|
|
4596
|
+
}));
|
|
4597
|
+
return resolveColumnLayoutWidths(containerWidth, columns);
|
|
4598
|
+
}, [enableColumnResize, containerWidth, table, columnLayoutMetaSignature]);
|
|
4599
|
+
const freezeOffsets = useMemo4(() => {
|
|
4600
|
+
if (!enableColumnFreeze || enableColumnResize || !layoutWidths) {
|
|
4601
|
+
return rowContextValue.columnFreeze.offsets;
|
|
4602
|
+
}
|
|
4603
|
+
const columns = table.getVisibleLeafColumns().map((column) => ({
|
|
4604
|
+
id: column.id,
|
|
4605
|
+
size: layoutWidths.get(column.id) ?? column.getSize(),
|
|
4606
|
+
side: resolveColumnFreezeSide(column.columnDef.meta?.frozen)
|
|
4607
|
+
}));
|
|
4608
|
+
return buildColumnFreezeOffsets(columns);
|
|
4609
|
+
}, [
|
|
4610
|
+
enableColumnFreeze,
|
|
4611
|
+
enableColumnResize,
|
|
4612
|
+
layoutWidths,
|
|
4613
|
+
rowContextValue.columnFreeze.offsets,
|
|
4614
|
+
table
|
|
4615
|
+
]);
|
|
4163
4616
|
const contextValue = useMemo4(
|
|
4164
|
-
() => ({
|
|
4165
|
-
|
|
4617
|
+
() => ({
|
|
4618
|
+
...rowContextValue,
|
|
4619
|
+
classNames,
|
|
4620
|
+
columnFreeze: {
|
|
4621
|
+
...rowContextValue.columnFreeze,
|
|
4622
|
+
offsets: freezeOffsets
|
|
4623
|
+
},
|
|
4624
|
+
columnResize: {
|
|
4625
|
+
...rowContextValue.columnResize,
|
|
4626
|
+
layoutWidths
|
|
4627
|
+
}
|
|
4628
|
+
}),
|
|
4629
|
+
[rowContextValue, classNames, freezeOffsets, layoutWidths]
|
|
4166
4630
|
);
|
|
4167
4631
|
if (isPending) {
|
|
4168
4632
|
return /* @__PURE__ */ jsx7(
|
|
@@ -4243,7 +4707,8 @@ function DataTable({
|
|
|
4243
4707
|
force: enableColumnResize,
|
|
4244
4708
|
lockMax: enableColumnResize,
|
|
4245
4709
|
minWidth: header.column.columnDef.meta?.minWidth,
|
|
4246
|
-
maxWidth: header.column.columnDef.meta?.maxWidth
|
|
4710
|
+
maxWidth: header.column.columnDef.meta?.maxWidth,
|
|
4711
|
+
layoutWidth: layoutWidths?.get(header.column.id)
|
|
4247
4712
|
});
|
|
4248
4713
|
const freezeOffset = enableColumnFreeze ? resolveHeaderFreezeOffset(header.column, freezeOffsets) : void 0;
|
|
4249
4714
|
const freezeStyle = getColumnFreezeStyle(freezeOffset, {
|
|
@@ -4256,7 +4721,9 @@ function DataTable({
|
|
|
4256
4721
|
};
|
|
4257
4722
|
const isPlaceholder = header.isPlaceholder;
|
|
4258
4723
|
const leafColumns = header.column.getLeafColumns();
|
|
4259
|
-
const leafIds = leafColumns.map(
|
|
4724
|
+
const leafIds = leafColumns.map(
|
|
4725
|
+
(leafColumn) => leafColumn.id
|
|
4726
|
+
);
|
|
4260
4727
|
const isLeafHeader = !isPlaceholder && header.subHeaders.length === 0;
|
|
4261
4728
|
const canDrag = enableColumnReorder && !isPlaceholder && leafIds.length > 0 && leafColumns.every(
|
|
4262
4729
|
(leafColumn) => isColumnReorderable(leafColumn.columnDef.meta)
|
|
@@ -4412,7 +4879,7 @@ function DataTable({
|
|
|
4412
4879
|
}
|
|
4413
4880
|
|
|
4414
4881
|
// src/components/ui/table/components/Table/Table.tsx
|
|
4415
|
-
import { useCallback as useCallback7, useMemo as useMemo5, useState as
|
|
4882
|
+
import { useCallback as useCallback7, useMemo as useMemo5, useState as useState7 } from "react";
|
|
4416
4883
|
|
|
4417
4884
|
// src/components/ui/table/features/cell-render/ResolvedTableCell.tsx
|
|
4418
4885
|
import { useCallback as useCallback6 } from "react";
|
|
@@ -4535,6 +5002,7 @@ function buildColumnDef(props, sort, onSort) {
|
|
|
4535
5002
|
cellRender: render,
|
|
4536
5003
|
frozen,
|
|
4537
5004
|
reorderable,
|
|
5005
|
+
width,
|
|
4538
5006
|
minWidth,
|
|
4539
5007
|
maxWidth,
|
|
4540
5008
|
className,
|
|
@@ -4582,10 +5050,10 @@ function countLeafColumns(nodes) {
|
|
|
4582
5050
|
}
|
|
4583
5051
|
|
|
4584
5052
|
// src/components/ui/table/components/Table/parseTableChildren.ts
|
|
4585
|
-
import { Children, isValidElement as
|
|
5053
|
+
import { Children, isValidElement as isValidElement3 } from "react";
|
|
4586
5054
|
|
|
4587
5055
|
// src/components/ui/table/components/Table/tableChildTypes.ts
|
|
4588
|
-
import { isValidElement } from "react";
|
|
5056
|
+
import { isValidElement as isValidElement2 } from "react";
|
|
4589
5057
|
var TABLE_HEADER_DISPLAY_NAME = "Table.Header";
|
|
4590
5058
|
var TABLE_BODY_DISPLAY_NAME = "Table.Body";
|
|
4591
5059
|
var TABLE_COLUMN_DISPLAY_NAME = "Table.Column";
|
|
@@ -4598,19 +5066,19 @@ function getComponentDisplayName(type) {
|
|
|
4598
5066
|
return void 0;
|
|
4599
5067
|
}
|
|
4600
5068
|
function isTableHeaderElement(child) {
|
|
4601
|
-
return
|
|
5069
|
+
return isValidElement2(child) && getComponentDisplayName(child.type) === TABLE_HEADER_DISPLAY_NAME;
|
|
4602
5070
|
}
|
|
4603
5071
|
function isTableBodyElement(child) {
|
|
4604
|
-
return
|
|
5072
|
+
return isValidElement2(child) && getComponentDisplayName(child.type) === TABLE_BODY_DISPLAY_NAME;
|
|
4605
5073
|
}
|
|
4606
5074
|
function isTableColumnElement(child) {
|
|
4607
|
-
return
|
|
5075
|
+
return isValidElement2(child) && getComponentDisplayName(child.type) === TABLE_COLUMN_DISPLAY_NAME;
|
|
4608
5076
|
}
|
|
4609
5077
|
function isTableColumnGroupElement(child) {
|
|
4610
|
-
return
|
|
5078
|
+
return isValidElement2(child) && getComponentDisplayName(child.type) === TABLE_COLUMN_GROUP_DISPLAY_NAME;
|
|
4611
5079
|
}
|
|
4612
5080
|
function isTablePaginationElement(child) {
|
|
4613
|
-
return
|
|
5081
|
+
return isValidElement2(child) && getComponentDisplayName(child.type) === TABLE_PAGINATION_DISPLAY_NAME;
|
|
4614
5082
|
}
|
|
4615
5083
|
|
|
4616
5084
|
// src/components/ui/table/components/Table/parseTableChildren.ts
|
|
@@ -4654,7 +5122,7 @@ function walkColumnTreeNodes(children) {
|
|
|
4654
5122
|
});
|
|
4655
5123
|
continue;
|
|
4656
5124
|
}
|
|
4657
|
-
if (
|
|
5125
|
+
if (isValidElement3(child)) {
|
|
4658
5126
|
const nested = child.props.children;
|
|
4659
5127
|
if (nested != null) {
|
|
4660
5128
|
result.push(...walkColumnTreeNodes(nested));
|
|
@@ -4784,7 +5252,7 @@ function TableRoot({
|
|
|
4784
5252
|
() => parseTableChildren(children),
|
|
4785
5253
|
[children]
|
|
4786
5254
|
);
|
|
4787
|
-
const [sort, setSort] =
|
|
5255
|
+
const [sort, setSort] = useState7(null);
|
|
4788
5256
|
const handleSort = useCallback7((field) => {
|
|
4789
5257
|
setSort((previous) => {
|
|
4790
5258
|
if (previous?.field !== field) {
|