react-glide-table 2.2.1 → 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/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 line = columnCells.map(
868
- (cell) => formatCellValue(
869
- readRowColumnValue(
870
- rowData,
871
- cell.column.columnDef
872
- )
873
- )
874
- ).join(" ");
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
- [activeSelectionBounds, enableSubtreeCopy, enabled, rows]
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("useDataTableRowContext must be used within a DataTableContextProvider");
3254
+ throw new Error(
3255
+ "useDataTableRowContext must be used within a DataTableContextProvider"
3256
+ );
3015
3257
  }
3016
3258
  return context;
3017
3259
  }
@@ -3056,8 +3298,105 @@ 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 { force = false, lockMax = false, minWidth, maxWidth } = options ?? {};
3393
+ const {
3394
+ force = false,
3395
+ lockMax = false,
3396
+ minWidth,
3397
+ maxWidth,
3398
+ layoutWidth
3399
+ } = options ?? {};
3061
3400
  if (lockMax) {
3062
3401
  return {
3063
3402
  width: size,
@@ -3065,14 +3404,27 @@ function getColumnSizeStyle(size, options) {
3065
3404
  maxWidth: size
3066
3405
  };
3067
3406
  }
3407
+ if (layoutWidth != null) {
3408
+ return {
3409
+ width: layoutWidth,
3410
+ minWidth: layoutWidth,
3411
+ maxWidth: layoutWidth
3412
+ };
3413
+ }
3414
+ const resolvedSize = size;
3068
3415
  const hasExplicitSize = force || size !== DATA_TABLE_COLUMN_SIZE;
3069
3416
  if (!hasExplicitSize && minWidth == null && maxWidth == null) {
3070
3417
  return void 0;
3071
3418
  }
3072
3419
  const style = {};
3073
3420
  if (hasExplicitSize) {
3074
- style.width = size;
3075
- style.minWidth = minWidth ?? size;
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;
3076
3428
  } else if (minWidth != null) {
3077
3429
  style.minWidth = minWidth;
3078
3430
  }
@@ -3297,7 +3649,7 @@ function useColumnReorder(options) {
3297
3649
 
3298
3650
  // src/components/ui/table/components/DataTable/DataTable.tsx
3299
3651
  import { flexRender as flexRender2 } from "@tanstack/react-table";
3300
- import { useMemo as useMemo4 } from "react";
3652
+ import { useEffect as useEffect8, useMemo as useMemo4, useState as useState6 } from "react";
3301
3653
 
3302
3654
  // src/components/ui/table/components/DataTable/DataTableRow.tsx
3303
3655
  import { flexRender } from "@tanstack/react-table";
@@ -3463,6 +3815,12 @@ function isInteractiveMouseTarget(target) {
3463
3815
  ].join(",");
3464
3816
  return target.closest(interactiveSelector) !== null;
3465
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
+ }
3466
3824
  function resolveExpandCellIndex(cells, toggleField) {
3467
3825
  if (!toggleField) return 0;
3468
3826
  const matchedIndex = cells.findIndex(
@@ -3495,7 +3853,7 @@ function DataTableRow({
3495
3853
  columnFreeze,
3496
3854
  inlineSearch
3497
3855
  } = useDataTableRowContext();
3498
- const { enableColumnResize } = columnResize;
3856
+ const { enableColumnResize, layoutWidths } = columnResize;
3499
3857
  const { enableColumnFreeze, offsets: freezeOffsets } = columnFreeze;
3500
3858
  const {
3501
3859
  enabled: enableInlineSearch,
@@ -3690,7 +4048,8 @@ function DataTableRow({
3690
4048
  force: enableColumnResize,
3691
4049
  lockMax: enableColumnResize,
3692
4050
  minWidth: meta?.minWidth,
3693
- maxWidth: meta?.maxWidth
4051
+ maxWidth: meta?.maxWidth,
4052
+ layoutWidth: layoutWidths?.get(columnId)
3694
4053
  });
3695
4054
  const freezeOffset = enableColumnFreeze ? freezeOffsets.get(columnId) : void 0;
3696
4055
  const freezeStyle = getColumnFreezeStyle(freezeOffset);
@@ -3730,6 +4089,7 @@ function DataTableRow({
3730
4089
  if (!enableCellSelection) return;
3731
4090
  if (isInteractiveMouseTarget(event.target)) return;
3732
4091
  event.preventDefault();
4092
+ blurActiveElementOutside(event.currentTarget);
3733
4093
  onCellMouseDown(
3734
4094
  resolveCellRowIndex(event.clientY, event.currentTarget),
3735
4095
  cellIndex,
@@ -3893,6 +4253,7 @@ function DataTableRow({
3893
4253
  onMouseDown: (event) => {
3894
4254
  event.stopPropagation();
3895
4255
  event.preventDefault();
4256
+ blurActiveElementOutside(event.currentTarget);
3896
4257
  onFillHandleMouseDown(rowIndex, cellIndex);
3897
4258
  }
3898
4259
  }
@@ -4222,17 +4583,74 @@ function DataTable({
4222
4583
  const RowSlot = slots?.Row ?? DataTableRow;
4223
4584
  const PendingSlot = slots?.Pending ?? DefaultPending;
4224
4585
  const EmptySlot = slots?.Empty ?? DefaultEmpty;
4225
- const freezeOffsets = rowContextValue.columnFreeze.offsets;
4226
4586
  const headerGroups = getMergedHeaderGroups(table.getHeaderGroups());
4227
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("|");
4228
4592
  const { isReordering, draggingColumnId, dropTarget, onHeaderPointerDown } = useColumnReorder({
4229
4593
  enabled: enableColumnReorder,
4230
4594
  columnOrder: leafColumnIds,
4231
4595
  onColumnOrderChange: setColumnOrder
4232
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
+ ]);
4233
4640
  const contextValue = useMemo4(
4234
- () => ({ ...rowContextValue, classNames }),
4235
- [rowContextValue, classNames]
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]
4236
4654
  );
4237
4655
  if (isPending) {
4238
4656
  return /* @__PURE__ */ jsx7(
@@ -4313,7 +4731,8 @@ function DataTable({
4313
4731
  force: enableColumnResize,
4314
4732
  lockMax: enableColumnResize,
4315
4733
  minWidth: header.column.columnDef.meta?.minWidth,
4316
- maxWidth: header.column.columnDef.meta?.maxWidth
4734
+ maxWidth: header.column.columnDef.meta?.maxWidth,
4735
+ layoutWidth: layoutWidths?.get(header.column.id)
4317
4736
  });
4318
4737
  const freezeOffset = enableColumnFreeze ? resolveHeaderFreezeOffset(header.column, freezeOffsets) : void 0;
4319
4738
  const freezeStyle = getColumnFreezeStyle(freezeOffset, {
@@ -4326,7 +4745,9 @@ function DataTable({
4326
4745
  };
4327
4746
  const isPlaceholder = header.isPlaceholder;
4328
4747
  const leafColumns = header.column.getLeafColumns();
4329
- const leafIds = leafColumns.map((leafColumn) => leafColumn.id);
4748
+ const leafIds = leafColumns.map(
4749
+ (leafColumn) => leafColumn.id
4750
+ );
4330
4751
  const isLeafHeader = !isPlaceholder && header.subHeaders.length === 0;
4331
4752
  const canDrag = enableColumnReorder && !isPlaceholder && leafIds.length > 0 && leafColumns.every(
4332
4753
  (leafColumn) => isColumnReorderable(leafColumn.columnDef.meta)
@@ -4482,7 +4903,7 @@ function DataTable({
4482
4903
  }
4483
4904
 
4484
4905
  // src/components/ui/table/components/Table/Table.tsx
4485
- import { useCallback as useCallback7, useMemo as useMemo5, useState as useState6 } from "react";
4906
+ import { useCallback as useCallback7, useMemo as useMemo5, useState as useState7 } from "react";
4486
4907
 
4487
4908
  // src/components/ui/table/components/Table/buildColumnDef.tsx
4488
4909
  import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
@@ -4571,6 +4992,7 @@ function buildColumnDef(props, sort, onSort) {
4571
4992
  cellRender: render,
4572
4993
  frozen,
4573
4994
  reorderable,
4995
+ width,
4574
4996
  minWidth,
4575
4997
  maxWidth,
4576
4998
  className,
@@ -4618,10 +5040,10 @@ function countLeafColumns(nodes) {
4618
5040
  }
4619
5041
 
4620
5042
  // src/components/ui/table/components/Table/parseTableChildren.ts
4621
- import { Children, isValidElement as isValidElement2 } from "react";
5043
+ import { Children, isValidElement as isValidElement3 } from "react";
4622
5044
 
4623
5045
  // src/components/ui/table/components/Table/tableChildTypes.ts
4624
- import { isValidElement } from "react";
5046
+ import { isValidElement as isValidElement2 } from "react";
4625
5047
  var TABLE_HEADER_DISPLAY_NAME = "Table.Header";
4626
5048
  var TABLE_BODY_DISPLAY_NAME = "Table.Body";
4627
5049
  var TABLE_COLUMN_DISPLAY_NAME = "Table.Column";
@@ -4634,19 +5056,19 @@ function getComponentDisplayName(type) {
4634
5056
  return void 0;
4635
5057
  }
4636
5058
  function isTableHeaderElement(child) {
4637
- return isValidElement(child) && getComponentDisplayName(child.type) === TABLE_HEADER_DISPLAY_NAME;
5059
+ return isValidElement2(child) && getComponentDisplayName(child.type) === TABLE_HEADER_DISPLAY_NAME;
4638
5060
  }
4639
5061
  function isTableBodyElement(child) {
4640
- return isValidElement(child) && getComponentDisplayName(child.type) === TABLE_BODY_DISPLAY_NAME;
5062
+ return isValidElement2(child) && getComponentDisplayName(child.type) === TABLE_BODY_DISPLAY_NAME;
4641
5063
  }
4642
5064
  function isTableColumnElement(child) {
4643
- return isValidElement(child) && getComponentDisplayName(child.type) === TABLE_COLUMN_DISPLAY_NAME;
5065
+ return isValidElement2(child) && getComponentDisplayName(child.type) === TABLE_COLUMN_DISPLAY_NAME;
4644
5066
  }
4645
5067
  function isTableColumnGroupElement(child) {
4646
- return isValidElement(child) && getComponentDisplayName(child.type) === TABLE_COLUMN_GROUP_DISPLAY_NAME;
5068
+ return isValidElement2(child) && getComponentDisplayName(child.type) === TABLE_COLUMN_GROUP_DISPLAY_NAME;
4647
5069
  }
4648
5070
  function isTablePaginationElement(child) {
4649
- return isValidElement(child) && getComponentDisplayName(child.type) === TABLE_PAGINATION_DISPLAY_NAME;
5071
+ return isValidElement2(child) && getComponentDisplayName(child.type) === TABLE_PAGINATION_DISPLAY_NAME;
4650
5072
  }
4651
5073
 
4652
5074
  // src/components/ui/table/components/Table/parseTableChildren.ts
@@ -4690,7 +5112,7 @@ function walkColumnTreeNodes(children) {
4690
5112
  });
4691
5113
  continue;
4692
5114
  }
4693
- if (isValidElement2(child)) {
5115
+ if (isValidElement3(child)) {
4694
5116
  const nested = child.props.children;
4695
5117
  if (nested != null) {
4696
5118
  result.push(...walkColumnTreeNodes(nested));
@@ -4820,7 +5242,7 @@ function TableRoot({
4820
5242
  () => parseTableChildren(children),
4821
5243
  [children]
4822
5244
  );
4823
- const [sort, setSort] = useState6(null);
5245
+ const [sort, setSort] = useState7(null);
4824
5246
  const handleSort = useCallback7((field) => {
4825
5247
  setSort((previous) => {
4826
5248
  if (previous?.field !== field) {
@@ -4968,6 +5390,7 @@ export {
4968
5390
  previousSearchIndex,
4969
5391
  resolveCellRenderer,
4970
5392
  resolveColumnFreezeSide,
5393
+ resolveColumnLayoutWidths,
4971
5394
  resolveDataTableLabels,
4972
5395
  resolveDropEdge,
4973
5396
  resolveHeaderFreezeOffset,