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/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("useDataTableRowContext must be used within a DataTableContextProvider");
33
+ throw new Error(
34
+ "useDataTableRowContext must be used within a DataTableContextProvider"
35
+ );
34
36
  }
35
37
  return context;
36
38
  }
@@ -502,16 +504,140 @@ 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 { force = false, lockMax = false } = options ?? {};
507
- if (!force && size === DATA_TABLE_COLUMN_SIZE) {
599
+ const {
600
+ force = false,
601
+ lockMax = false,
602
+ minWidth,
603
+ maxWidth,
604
+ layoutWidth
605
+ } = options ?? {};
606
+ if (lockMax) {
607
+ return {
608
+ width: size,
609
+ minWidth: size,
610
+ maxWidth: size
611
+ };
612
+ }
613
+ if (layoutWidth != null) {
614
+ return {
615
+ width: layoutWidth,
616
+ minWidth: layoutWidth,
617
+ maxWidth: layoutWidth
618
+ };
619
+ }
620
+ const resolvedSize = size;
621
+ const hasExplicitSize = force || size !== DATA_TABLE_COLUMN_SIZE;
622
+ if (!hasExplicitSize && minWidth == null && maxWidth == null) {
508
623
  return void 0;
509
624
  }
510
- return {
511
- width: size,
512
- minWidth: size,
513
- ...lockMax ? { maxWidth: size } : {}
514
- };
625
+ const style = {};
626
+ if (hasExplicitSize) {
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;
634
+ } else if (minWidth != null) {
635
+ style.minWidth = minWidth;
636
+ }
637
+ if (maxWidth != null) {
638
+ style.maxWidth = maxWidth;
639
+ }
640
+ return style;
515
641
  }
516
642
 
517
643
  // src/components/ui/table/features/inline-search/inlineSearch.ts
@@ -1154,6 +1280,12 @@ function isInteractiveMouseTarget(target) {
1154
1280
  ].join(",");
1155
1281
  return target.closest(interactiveSelector) !== null;
1156
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
+ }
1157
1289
  function resolveExpandCellIndex(cells, toggleField) {
1158
1290
  if (!toggleField) return 0;
1159
1291
  const matchedIndex = cells.findIndex(
@@ -1186,7 +1318,7 @@ function DataTableRow({
1186
1318
  columnFreeze,
1187
1319
  inlineSearch
1188
1320
  } = useDataTableRowContext();
1189
- const { enableColumnResize } = columnResize;
1321
+ const { enableColumnResize, layoutWidths } = columnResize;
1190
1322
  const { enableColumnFreeze, offsets: freezeOffsets } = columnFreeze;
1191
1323
  const {
1192
1324
  enabled: enableInlineSearch,
@@ -1379,7 +1511,10 @@ function DataTableRow({
1379
1511
  const hasSelectionEdges = hasCellSelectionEdges(selectionEdgeStyle);
1380
1512
  const sizeStyle = getColumnSizeStyle(cell.column.getSize(), {
1381
1513
  force: enableColumnResize,
1382
- lockMax: enableColumnResize
1514
+ lockMax: enableColumnResize,
1515
+ minWidth: meta?.minWidth,
1516
+ maxWidth: meta?.maxWidth,
1517
+ layoutWidth: layoutWidths?.get(columnId)
1383
1518
  });
1384
1519
  const freezeOffset = enableColumnFreeze ? freezeOffsets.get(columnId) : void 0;
1385
1520
  const freezeStyle = getColumnFreezeStyle(freezeOffset);
@@ -1419,6 +1554,7 @@ function DataTableRow({
1419
1554
  if (!enableCellSelection) return;
1420
1555
  if (isInteractiveMouseTarget(event.target)) return;
1421
1556
  event.preventDefault();
1557
+ blurActiveElementOutside(event.currentTarget);
1422
1558
  onCellMouseDown(
1423
1559
  resolveCellRowIndex(event.clientY, event.currentTarget),
1424
1560
  cellIndex,
@@ -1582,6 +1718,7 @@ function DataTableRow({
1582
1718
  onMouseDown: (event) => {
1583
1719
  event.stopPropagation();
1584
1720
  event.preventDefault();
1721
+ blurActiveElementOutside(event.currentTarget);
1585
1722
  onFillHandleMouseDown(rowIndex, cellIndex);
1586
1723
  }
1587
1724
  }
@@ -2513,6 +2650,219 @@ function formatDefaultCellValue(value) {
2513
2650
  import { useCallback as useCallback3, useEffect as useEffect5, useRef as useRef5, useState as useState3 } from "react";
2514
2651
 
2515
2652
  // src/components/ui/table/features/cell-selection/copyData.ts
2653
+ import { isValidElement } from "react";
2654
+ function isReactNodeIterable(node) {
2655
+ return typeof node === "object" && node !== null && !isValidElement(node) && Symbol.iterator in node;
2656
+ }
2657
+ function getElementTypeName(type) {
2658
+ if (typeof type === "string") return type;
2659
+ if (typeof type === "function") {
2660
+ const fn = type;
2661
+ return fn.displayName || fn.name || "";
2662
+ }
2663
+ if (typeof type === "object" && type !== null) {
2664
+ const component = type;
2665
+ return component.displayName || component.render?.displayName || component.render?.name || "";
2666
+ }
2667
+ return "";
2668
+ }
2669
+ function isButtonReactElement(node) {
2670
+ const typeName = getElementTypeName(node.type);
2671
+ if (typeName === "button" || /button/i.test(typeName)) return true;
2672
+ const props = node.props;
2673
+ if (props.role === "button") return true;
2674
+ if (typeName === "input" && props.type === "button") return true;
2675
+ return false;
2676
+ }
2677
+ function isImageReactElement(node) {
2678
+ const typeName = getElementTypeName(node.type);
2679
+ return typeName === "img" || typeName === "image" || /image/i.test(typeName);
2680
+ }
2681
+ var IMAGE_URL_PROP_KEYS = ["src", "url", "href", "imageUrl", "srcUrl"];
2682
+ function isLikelyUrl(value) {
2683
+ const trimmed = value.trim();
2684
+ if (!trimmed) return false;
2685
+ if (/^(https?:|blob:|data:|\/\/)/i.test(trimmed)) return true;
2686
+ if (trimmed.startsWith("/") && trimmed.includes("/")) return true;
2687
+ return false;
2688
+ }
2689
+ function pickUrlFromUnknown(value) {
2690
+ if (typeof value === "string") {
2691
+ return isLikelyUrl(value) ? value.trim() : "";
2692
+ }
2693
+ if (Array.isArray(value)) {
2694
+ return value.map((item) => pickUrlFromUnknown(item)).filter((item) => item.length > 0).join(", ");
2695
+ }
2696
+ if (value && typeof value === "object") {
2697
+ const record = value;
2698
+ for (const key of IMAGE_URL_PROP_KEYS) {
2699
+ const candidate = record[key];
2700
+ if (typeof candidate === "string" && candidate.trim()) {
2701
+ return candidate.trim();
2702
+ }
2703
+ }
2704
+ }
2705
+ return "";
2706
+ }
2707
+ function imageElementText(node) {
2708
+ const props = node.props;
2709
+ for (const key of IMAGE_URL_PROP_KEYS) {
2710
+ const candidate = props[key];
2711
+ if (typeof candidate === "string" && candidate.trim()) {
2712
+ return candidate.trim();
2713
+ }
2714
+ }
2715
+ return "";
2716
+ }
2717
+ function reactNodeContainsImage(node) {
2718
+ if (isValidElement(node)) {
2719
+ if (isImageReactElement(node)) return true;
2720
+ return reactNodeContainsImage(node.props.children);
2721
+ }
2722
+ if (isReactNodeIterable(node)) {
2723
+ for (const child of node) {
2724
+ if (reactNodeContainsImage(child)) return true;
2725
+ }
2726
+ }
2727
+ return false;
2728
+ }
2729
+ function readImgUrl(img) {
2730
+ const attr = img.getAttribute("src")?.trim() ?? "";
2731
+ if (attr) return attr;
2732
+ if (img instanceof HTMLImageElement) {
2733
+ const current = img.currentSrc?.trim() ?? "";
2734
+ if (current && current !== img.baseURI) return current;
2735
+ }
2736
+ return "";
2737
+ }
2738
+ function readDomImageUrls(rowIndex, colIndex, root) {
2739
+ const scope = root ?? (typeof document === "undefined" ? null : document);
2740
+ if (!scope) return "";
2741
+ const cells = scope.querySelectorAll(
2742
+ `[data-row-index="${rowIndex}"][data-col-index="${colIndex}"]`
2743
+ );
2744
+ for (const cell of cells) {
2745
+ const urls = Array.from(cell.querySelectorAll("img")).flatMap((img) => {
2746
+ const url = readImgUrl(img);
2747
+ return url ? [url] : [];
2748
+ });
2749
+ if (urls.length > 0) return urls.join(", ");
2750
+ }
2751
+ return "";
2752
+ }
2753
+ function reactNodeToText(node) {
2754
+ if (node == null || typeof node === "boolean") return "";
2755
+ if (typeof node === "string" || typeof node === "number" || typeof node === "bigint") {
2756
+ return String(node);
2757
+ }
2758
+ if (isReactNodeIterable(node)) {
2759
+ let text = "";
2760
+ for (const child of node) {
2761
+ text += reactNodeToText(child);
2762
+ }
2763
+ return text;
2764
+ }
2765
+ if (isValidElement(node)) {
2766
+ if (isButtonReactElement(node)) return "";
2767
+ const props = node.props;
2768
+ const childText = reactNodeToText(props.children);
2769
+ if (childText) return childText;
2770
+ const fromImage = imageElementText(node);
2771
+ if (fromImage) return fromImage;
2772
+ if (isImageReactElement(node)) return "";
2773
+ if (typeof props.alt === "string" && props.alt) return props.alt;
2774
+ if (typeof props.title === "string" && props.title) return props.title;
2775
+ return "";
2776
+ }
2777
+ return "";
2778
+ }
2779
+ function sanitizeClipboardCell(text) {
2780
+ return text.replace(/\s+/g, " ").trim();
2781
+ }
2782
+ function createCopyRenderRow(rowData, index) {
2783
+ return {
2784
+ id: getOriginalRowId(rowData) || String(index),
2785
+ index,
2786
+ original: rowData,
2787
+ getIsCellDragSelected: () => false
2788
+ };
2789
+ }
2790
+ function buildVisibleRowLookup(visibleRows) {
2791
+ const lookup = /* @__PURE__ */ new Map();
2792
+ for (const row of visibleRows) {
2793
+ lookup.set(row.original, row);
2794
+ }
2795
+ return lookup;
2796
+ }
2797
+ function resolveCopyColumnId(cell) {
2798
+ if (cell.column.id) return cell.column.id;
2799
+ const columnDef = cell.column.columnDef;
2800
+ if (columnDef.id) return columnDef.id;
2801
+ if (columnDef.accessorKey != null && columnDef.accessorKey !== "") {
2802
+ return String(columnDef.accessorKey);
2803
+ }
2804
+ return "";
2805
+ }
2806
+ function isPrimitiveCopyValue(value) {
2807
+ return value == null || typeof value !== "object";
2808
+ }
2809
+ function extractRenderedCopyText(node, value, cellPosition, root) {
2810
+ const rendered = sanitizeClipboardCell(reactNodeToText(node));
2811
+ if (reactNodeContainsImage(node)) {
2812
+ const fromDom = cellPosition != null ? sanitizeClipboardCell(
2813
+ readDomImageUrls(cellPosition.rowIndex, cellPosition.colIndex, root)
2814
+ ) : "";
2815
+ if (fromDom) return fromDom;
2816
+ if (rendered && isLikelyUrl(rendered)) return rendered;
2817
+ return sanitizeClipboardCell(pickUrlFromUnknown(value));
2818
+ }
2819
+ return rendered;
2820
+ }
2821
+ function formatCopyCellText(rowData, columnDef, columnId, visibleRow, fallbackIndex, sourceCell, cellPosition, options) {
2822
+ const meta = columnDef.meta;
2823
+ const value = sourceCell ? sourceCell.getValue() : readRowColumnValue(rowData, columnDef);
2824
+ const cellRender = meta?.cellRender;
2825
+ if (typeof cellRender === "function") {
2826
+ try {
2827
+ const row = visibleRow ?? createCopyRenderRow(rowData, fallbackIndex);
2828
+ const node = cellRender({
2829
+ value,
2830
+ row,
2831
+ index: row.index,
2832
+ columnId,
2833
+ cellProps: meta?.cellProps,
2834
+ update: () => {
2835
+ }
2836
+ });
2837
+ return extractRenderedCopyText(node, value, cellPosition, options?.root);
2838
+ } catch {
2839
+ return formatCellValue(value);
2840
+ }
2841
+ }
2842
+ if (options?.registry && meta?.kind && isPrimitiveCopyValue(value)) {
2843
+ try {
2844
+ const row = visibleRow ?? createCopyRenderRow(rowData, fallbackIndex);
2845
+ const ctx = {
2846
+ value,
2847
+ row,
2848
+ index: row.index,
2849
+ columnId,
2850
+ cellProps: meta.cellProps,
2851
+ update: () => {
2852
+ }
2853
+ };
2854
+ const renderer = resolveCellRenderer(options.registry, meta.kind, ctx);
2855
+ if (renderer) {
2856
+ const node = renderer.render(ctx);
2857
+ const rendered = extractRenderedCopyText(node, value, cellPosition, options.root);
2858
+ if (rendered) return rendered;
2859
+ }
2860
+ } catch {
2861
+ return formatCellValue(value);
2862
+ }
2863
+ }
2864
+ return formatCellValue(value);
2865
+ }
2516
2866
  function formatPrimitive(value) {
2517
2867
  if (value === null || value === void 0) return "";
2518
2868
  if (typeof value === "string") return value;
@@ -2599,37 +2949,47 @@ function collectCopyRowEntries(visibleRows, bounds, mode = "visible") {
2599
2949
  }
2600
2950
  return result;
2601
2951
  }
2602
- function serializeCopyRowsToTSV(copyRows, visibleRows, bounds, depths) {
2952
+ function serializeCopyRowsToTSV(copyRows, visibleRows, bounds, depths, options) {
2603
2953
  if (copyRows.length === 0) return "";
2604
2954
  const { startCol, endCol } = bounds;
2605
2955
  const columnCells = visibleRows[0]?.getVisibleCells().slice(startCol, endCol + 1) ?? [];
2606
2956
  if (columnCells.length === 0) return "";
2607
2957
  const resolvedDepths = depths && depths.length === copyRows.length ? depths : copyRows.map((row) => getRowDepth(row));
2608
2958
  const minDepth = Math.min(...resolvedDepths);
2959
+ const visibleRowByOriginal = buildVisibleRowLookup(visibleRows);
2609
2960
  return copyRows.map((rowData, index) => {
2610
2961
  const relativeDepth = Math.max(0, (resolvedDepths[index] ?? 0) - minDepth);
2611
- const line = columnCells.map(
2612
- (cell) => formatCellValue(
2613
- readRowColumnValue(
2614
- rowData,
2615
- cell.column.columnDef
2616
- )
2617
- )
2618
- ).join(" ");
2962
+ const visibleRow = visibleRowByOriginal.get(rowData);
2963
+ const matchingCells = visibleRow?.getVisibleCells().slice(startCol, endCol + 1);
2964
+ const line = columnCells.map((templateCell, colOffset) => {
2965
+ const sourceCell = matchingCells?.[colOffset];
2966
+ const column = sourceCell?.column ?? templateCell.column;
2967
+ return formatCopyCellText(
2968
+ rowData,
2969
+ column.columnDef,
2970
+ resolveCopyColumnId(sourceCell ?? templateCell),
2971
+ visibleRow,
2972
+ visibleRow?.index ?? index,
2973
+ sourceCell,
2974
+ visibleRow != null ? { rowIndex: visibleRow.index, colIndex: startCol + colOffset } : void 0,
2975
+ options
2976
+ );
2977
+ }).join(" ");
2619
2978
  return `${" ".repeat(relativeDepth)}${line}`;
2620
2979
  }).join("\n");
2621
2980
  }
2622
- function serializeSelectionToTSV(visibleRows, bounds, mode = "visible") {
2981
+ function serializeSelectionToTSV(visibleRows, bounds, mode = "visible", options) {
2623
2982
  const entries = collectCopyRowEntries(visibleRows, bounds, mode);
2624
2983
  return serializeCopyRowsToTSV(
2625
2984
  entries.map((entry) => entry.row),
2626
2985
  visibleRows,
2627
2986
  bounds,
2628
- entries.map((entry) => entry.depth)
2987
+ entries.map((entry) => entry.depth),
2988
+ options
2629
2989
  );
2630
2990
  }
2631
- async function writeSelectionToClipboard(visibleRows, bounds, mode = "visible") {
2632
- const text = serializeSelectionToTSV(visibleRows, bounds, mode);
2991
+ async function writeSelectionToClipboard(visibleRows, bounds, mode = "visible", options) {
2992
+ const text = serializeSelectionToTSV(visibleRows, bounds, mode, options);
2633
2993
  if (!text) return false;
2634
2994
  try {
2635
2995
  await navigator.clipboard.writeText(text);
@@ -2787,7 +3147,9 @@ function useCellSelection({
2787
3147
  onDataChange,
2788
3148
  onBatchChange,
2789
3149
  onRowsPaste,
2790
- onCellNavigate
3150
+ onCellNavigate,
3151
+ cellRendererRegistry,
3152
+ rootRef
2791
3153
  }) {
2792
3154
  const [dragState, setDragState] = useState3(INITIAL_DRAG_STATE);
2793
3155
  const pendingPasteModeRef = useRef5(null);
@@ -2911,15 +3273,28 @@ function useCellSelection({
2911
3273
  async (options) => {
2912
3274
  if (!enabled || !activeSelectionBounds) return false;
2913
3275
  const mode = options?.includeDescendants && enableSubtreeCopy ? "subtree" : "visible";
2914
- return writeSelectionToClipboard(rows, activeSelectionBounds, mode);
3276
+ return writeSelectionToClipboard(rows, activeSelectionBounds, mode, {
3277
+ registry: cellRendererRegistry,
3278
+ root: rootRef?.current
3279
+ });
2915
3280
  },
2916
- [activeSelectionBounds, enableSubtreeCopy, enabled, rows]
3281
+ [
3282
+ activeSelectionBounds,
3283
+ cellRendererRegistry,
3284
+ enableSubtreeCopy,
3285
+ enabled,
3286
+ rootRef,
3287
+ rows
3288
+ ]
2917
3289
  );
2918
3290
  useEffect5(() => {
2919
3291
  if (!enabled) return;
2920
3292
  const handleKeyDown = (e) => {
2921
3293
  if (!activeSelectionBounds) return;
2922
3294
  if (!(e.ctrlKey || e.metaKey)) return;
3295
+ if (isEditablePasteTarget(e.target) || isEditablePasteTarget(document.activeElement)) {
3296
+ return;
3297
+ }
2923
3298
  const isSubtreeShortcut = enableSubtreeCopy && e.shiftKey && e.key.toLowerCase() === "c";
2924
3299
  const isVisibleCopyShortcut = !e.shiftKey && e.key.toLowerCase() === "c";
2925
3300
  if (!isSubtreeShortcut && !isVisibleCopyShortcut) return;
@@ -3482,6 +3857,10 @@ function useGlideTable(options) {
3482
3857
  const [hoveredRowIndex, setHoveredRowIndex] = useState5(null);
3483
3858
  const scrollRef = useRef7(null);
3484
3859
  const rootRef = useRef7(null);
3860
+ const cellRendererRegistry = useMemo3(
3861
+ () => createCellRendererRegistry(cellRenderers),
3862
+ [cellRenderers]
3863
+ );
3485
3864
  const shouldVirtualize = enableVirtualization && !enableRowSpan;
3486
3865
  useEffect7(() => {
3487
3866
  if (enableVirtualization && enableRowSpan) {
@@ -3665,7 +4044,9 @@ function useGlideTable(options) {
3665
4044
  onDataChange,
3666
4045
  onBatchChange,
3667
4046
  onRowsPaste,
3668
- onCellNavigate: handleCellNavigate
4047
+ onCellNavigate: handleCellNavigate,
4048
+ cellRendererRegistry,
4049
+ rootRef
3669
4050
  });
3670
4051
  const {
3671
4052
  editingCell,
@@ -3675,10 +4056,6 @@ function useGlideTable(options) {
3675
4056
  commitEdit,
3676
4057
  cancelEdit
3677
4058
  } = useCellEdit({ data: tableData, rows, onDataChange, onCellChange });
3678
- const cellRendererRegistry = useMemo3(
3679
- () => createCellRendererRegistry(cellRenderers),
3680
- [cellRenderers]
3681
- );
3682
4059
  const commitRenderedCellValue = useCallback5(
3683
4060
  (rowId, columnId, value) => commitCellValue({
3684
4061
  data: tableData,
@@ -4136,17 +4513,74 @@ function DataTable({
4136
4513
  const RowSlot = slots?.Row ?? DataTableRow;
4137
4514
  const PendingSlot = slots?.Pending ?? DefaultPending;
4138
4515
  const EmptySlot = slots?.Empty ?? DefaultEmpty;
4139
- const freezeOffsets = rowContextValue.columnFreeze.offsets;
4140
4516
  const headerGroups = getMergedHeaderGroups(table.getHeaderGroups());
4141
4517
  const leafColumnIds = table.getVisibleLeafColumns().map((column) => column.id);
4518
+ const columnLayoutMetaSignature = table.getVisibleLeafColumns().map((column) => {
4519
+ const meta = column.columnDef.meta;
4520
+ return `${column.id}:${meta?.width ?? ""}:${meta?.minWidth ?? ""}:${meta?.maxWidth ?? ""}`;
4521
+ }).join("|");
4142
4522
  const { isReordering, draggingColumnId, dropTarget, onHeaderPointerDown } = useColumnReorder({
4143
4523
  enabled: enableColumnReorder,
4144
4524
  columnOrder: leafColumnIds,
4145
4525
  onColumnOrderChange: setColumnOrder
4146
4526
  });
4527
+ const [containerWidth, setContainerWidth] = useState6(0);
4528
+ useEffect8(() => {
4529
+ if (enableColumnResize || isPending) return;
4530
+ const element = scrollRef.current;
4531
+ if (!element) return;
4532
+ const updateWidth = () => {
4533
+ setContainerWidth(Math.floor(element.clientWidth));
4534
+ };
4535
+ updateWidth();
4536
+ if (typeof ResizeObserver === "undefined") return;
4537
+ const observer = new ResizeObserver(() => {
4538
+ updateWidth();
4539
+ });
4540
+ observer.observe(element);
4541
+ return () => observer.disconnect();
4542
+ }, [enableColumnResize, isPending, scrollRef, rows.length, leafColumnIds.join("|")]);
4543
+ const layoutWidths = useMemo4(() => {
4544
+ if (enableColumnResize) return void 0;
4545
+ const columns = table.getVisibleLeafColumns().map((column) => ({
4546
+ id: column.id,
4547
+ width: column.columnDef.meta?.width,
4548
+ minWidth: column.columnDef.meta?.minWidth,
4549
+ maxWidth: column.columnDef.meta?.maxWidth
4550
+ }));
4551
+ return resolveColumnLayoutWidths(containerWidth, columns);
4552
+ }, [enableColumnResize, containerWidth, table, columnLayoutMetaSignature]);
4553
+ const freezeOffsets = useMemo4(() => {
4554
+ if (!enableColumnFreeze || enableColumnResize || !layoutWidths) {
4555
+ return rowContextValue.columnFreeze.offsets;
4556
+ }
4557
+ const columns = table.getVisibleLeafColumns().map((column) => ({
4558
+ id: column.id,
4559
+ size: layoutWidths.get(column.id) ?? column.getSize(),
4560
+ side: resolveColumnFreezeSide(column.columnDef.meta?.frozen)
4561
+ }));
4562
+ return buildColumnFreezeOffsets(columns);
4563
+ }, [
4564
+ enableColumnFreeze,
4565
+ enableColumnResize,
4566
+ layoutWidths,
4567
+ rowContextValue.columnFreeze.offsets,
4568
+ table
4569
+ ]);
4147
4570
  const contextValue = useMemo4(
4148
- () => ({ ...rowContextValue, classNames }),
4149
- [rowContextValue, classNames]
4571
+ () => ({
4572
+ ...rowContextValue,
4573
+ classNames,
4574
+ columnFreeze: {
4575
+ ...rowContextValue.columnFreeze,
4576
+ offsets: freezeOffsets
4577
+ },
4578
+ columnResize: {
4579
+ ...rowContextValue.columnResize,
4580
+ layoutWidths
4581
+ }
4582
+ }),
4583
+ [rowContextValue, classNames, freezeOffsets, layoutWidths]
4150
4584
  );
4151
4585
  if (isPending) {
4152
4586
  return /* @__PURE__ */ jsx7(
@@ -4225,7 +4659,10 @@ function DataTable({
4225
4659
  const canResize = enableColumnResize && header.column.getCanResize();
4226
4660
  const sizeStyle = getColumnSizeStyle(header.getSize(), {
4227
4661
  force: enableColumnResize,
4228
- lockMax: enableColumnResize
4662
+ lockMax: enableColumnResize,
4663
+ minWidth: header.column.columnDef.meta?.minWidth,
4664
+ maxWidth: header.column.columnDef.meta?.maxWidth,
4665
+ layoutWidth: layoutWidths?.get(header.column.id)
4229
4666
  });
4230
4667
  const freezeOffset = enableColumnFreeze ? resolveHeaderFreezeOffset(header.column, freezeOffsets) : void 0;
4231
4668
  const freezeStyle = getColumnFreezeStyle(freezeOffset, {
@@ -4238,7 +4675,9 @@ function DataTable({
4238
4675
  };
4239
4676
  const isPlaceholder = header.isPlaceholder;
4240
4677
  const leafColumns = header.column.getLeafColumns();
4241
- const leafIds = leafColumns.map((leafColumn) => leafColumn.id);
4678
+ const leafIds = leafColumns.map(
4679
+ (leafColumn) => leafColumn.id
4680
+ );
4242
4681
  const isLeafHeader = !isPlaceholder && header.subHeaders.length === 0;
4243
4682
  const canDrag = enableColumnReorder && !isPlaceholder && leafIds.length > 0 && leafColumns.every(
4244
4683
  (leafColumn) => isColumnReorderable(leafColumn.columnDef.meta)
@@ -4394,7 +4833,7 @@ function DataTable({
4394
4833
  }
4395
4834
 
4396
4835
  // src/components/ui/table/components/Table/Table.tsx
4397
- import { useCallback as useCallback7, useMemo as useMemo5, useState as useState6 } from "react";
4836
+ import { useCallback as useCallback7, useMemo as useMemo5, useState as useState7 } from "react";
4398
4837
 
4399
4838
  // src/components/ui/table/features/cell-render/ResolvedTableCell.tsx
4400
4839
  import { useCallback as useCallback6 } from "react";
@@ -4465,6 +4904,8 @@ function buildColumnDef(props, sort, onSort) {
4465
4904
  width,
4466
4905
  minWidth,
4467
4906
  maxWidth,
4907
+ minResizeWidth,
4908
+ maxResizeWidth,
4468
4909
  resizable,
4469
4910
  reorderable,
4470
4911
  frozen,
@@ -4485,8 +4926,8 @@ function buildColumnDef(props, sort, onSort) {
4485
4926
  id: field,
4486
4927
  ...!virtual ? { accessorKey: field } : {},
4487
4928
  size: width ?? DATA_TABLE_COLUMN_SIZE,
4488
- ...minWidth != null ? { minSize: minWidth } : {},
4489
- ...maxWidth != null ? { maxSize: maxWidth } : {},
4929
+ ...minResizeWidth != null ? { minSize: minResizeWidth } : {},
4930
+ ...maxResizeWidth != null ? { maxSize: maxResizeWidth } : {},
4490
4931
  ...resizable === false ? { enableResizing: false } : {},
4491
4932
  header: sortable ? () => /* @__PURE__ */ jsx8(
4492
4933
  SortableHeader,
@@ -4515,6 +4956,9 @@ function buildColumnDef(props, sort, onSort) {
4515
4956
  cellRender: render,
4516
4957
  frozen,
4517
4958
  reorderable,
4959
+ width,
4960
+ minWidth,
4961
+ maxWidth,
4518
4962
  className,
4519
4963
  headerClassName
4520
4964
  }
@@ -4560,10 +5004,10 @@ function countLeafColumns(nodes) {
4560
5004
  }
4561
5005
 
4562
5006
  // src/components/ui/table/components/Table/parseTableChildren.ts
4563
- import { Children, isValidElement as isValidElement2 } from "react";
5007
+ import { Children, isValidElement as isValidElement3 } from "react";
4564
5008
 
4565
5009
  // src/components/ui/table/components/Table/tableChildTypes.ts
4566
- import { isValidElement } from "react";
5010
+ import { isValidElement as isValidElement2 } from "react";
4567
5011
  var TABLE_HEADER_DISPLAY_NAME = "Table.Header";
4568
5012
  var TABLE_BODY_DISPLAY_NAME = "Table.Body";
4569
5013
  var TABLE_COLUMN_DISPLAY_NAME = "Table.Column";
@@ -4576,19 +5020,19 @@ function getComponentDisplayName(type) {
4576
5020
  return void 0;
4577
5021
  }
4578
5022
  function isTableHeaderElement(child) {
4579
- return isValidElement(child) && getComponentDisplayName(child.type) === TABLE_HEADER_DISPLAY_NAME;
5023
+ return isValidElement2(child) && getComponentDisplayName(child.type) === TABLE_HEADER_DISPLAY_NAME;
4580
5024
  }
4581
5025
  function isTableBodyElement(child) {
4582
- return isValidElement(child) && getComponentDisplayName(child.type) === TABLE_BODY_DISPLAY_NAME;
5026
+ return isValidElement2(child) && getComponentDisplayName(child.type) === TABLE_BODY_DISPLAY_NAME;
4583
5027
  }
4584
5028
  function isTableColumnElement(child) {
4585
- return isValidElement(child) && getComponentDisplayName(child.type) === TABLE_COLUMN_DISPLAY_NAME;
5029
+ return isValidElement2(child) && getComponentDisplayName(child.type) === TABLE_COLUMN_DISPLAY_NAME;
4586
5030
  }
4587
5031
  function isTableColumnGroupElement(child) {
4588
- return isValidElement(child) && getComponentDisplayName(child.type) === TABLE_COLUMN_GROUP_DISPLAY_NAME;
5032
+ return isValidElement2(child) && getComponentDisplayName(child.type) === TABLE_COLUMN_GROUP_DISPLAY_NAME;
4589
5033
  }
4590
5034
  function isTablePaginationElement(child) {
4591
- return isValidElement(child) && getComponentDisplayName(child.type) === TABLE_PAGINATION_DISPLAY_NAME;
5035
+ return isValidElement2(child) && getComponentDisplayName(child.type) === TABLE_PAGINATION_DISPLAY_NAME;
4592
5036
  }
4593
5037
 
4594
5038
  // src/components/ui/table/components/Table/parseTableChildren.ts
@@ -4632,7 +5076,7 @@ function walkColumnTreeNodes(children) {
4632
5076
  });
4633
5077
  continue;
4634
5078
  }
4635
- if (isValidElement2(child)) {
5079
+ if (isValidElement3(child)) {
4636
5080
  const nested = child.props.children;
4637
5081
  if (nested != null) {
4638
5082
  result.push(...walkColumnTreeNodes(nested));
@@ -4762,7 +5206,7 @@ function TableRoot({
4762
5206
  () => parseTableChildren(children),
4763
5207
  [children]
4764
5208
  );
4765
- const [sort, setSort] = useState6(null);
5209
+ const [sort, setSort] = useState7(null);
4766
5210
  const handleSort = useCallback7((field) => {
4767
5211
  setSort((previous) => {
4768
5212
  if (previous?.field !== field) {