@lensui/lens-table 0.1.22 → 0.1.23

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.cjs CHANGED
@@ -746,48 +746,6 @@ function createRowDragHandleSvg() {
746
746
  }
747
747
  return svg;
748
748
  }
749
- function createHeaderDragHandleSvg() {
750
- const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
751
- svg.setAttribute("viewBox", "0 0 14 14");
752
- svg.setAttribute("aria-hidden", "true");
753
- for (const cy of [2.5, 7, 11.5]) {
754
- const circle = document.createElementNS("http://www.w3.org/2000/svg", "circle");
755
- circle.setAttribute("cx", "7");
756
- circle.setAttribute("cy", String(cy));
757
- circle.setAttribute("r", "1.25");
758
- svg.appendChild(circle);
759
- }
760
- return svg;
761
- }
762
- function createHeaderSortSvg(direction) {
763
- const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
764
- svg.setAttribute("viewBox", "0 0 14 14");
765
- svg.setAttribute("aria-hidden", "true");
766
- for (const [value, active] of [
767
- ["M3 5.5 7 1.5l4 4Z", direction === "asc"],
768
- ["M3 8.5 7 12.5l4-4Z", direction === "desc"]
769
- ]) {
770
- const path = document.createElementNS("http://www.w3.org/2000/svg", "path");
771
- path.setAttribute("d", value);
772
- if (active) path.classList.add("is-active");
773
- svg.appendChild(path);
774
- }
775
- return svg;
776
- }
777
- function createHeaderSearchSvg(active) {
778
- const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
779
- svg.setAttribute("viewBox", "0 0 14 14");
780
- svg.setAttribute("aria-hidden", "true");
781
- if (active) svg.classList.add("is-active");
782
- const circle = document.createElementNS("http://www.w3.org/2000/svg", "circle");
783
- circle.setAttribute("cx", "5.5");
784
- circle.setAttribute("cy", "5.5");
785
- circle.setAttribute("r", "4.25");
786
- const path = document.createElementNS("http://www.w3.org/2000/svg", "path");
787
- path.setAttribute("d", "m8.75 8.75 2.25 2.25");
788
- svg.append(circle, path);
789
- return svg;
790
- }
791
749
 
792
750
  // src/Table.tsx
793
751
  var import_adapter = require("@atlaskit/pragmatic-drag-and-drop/element/adapter");
@@ -841,7 +799,6 @@ function getMinimumColumnWidth(column, columnDraggable = false) {
841
799
  function buildColumnMetrics(columns, columnDraggableOrOptions = false) {
842
800
  const options = typeof columnDraggableOrOptions === "boolean" ? { columnDraggable: columnDraggableOrOptions } : columnDraggableOrOptions;
843
801
  const columnDraggable = options.columnDraggable ?? false;
844
- const stretchExcludedIndices = options.stretchExcludedIndices ?? /* @__PURE__ */ new Set();
845
802
  let left = 0;
846
803
  const metrics = columns.map((column) => {
847
804
  const width = Math.max(getMinimumColumnWidth(column, columnDraggable), column.width ?? DEFAULT_COLUMN_WIDTH);
@@ -851,10 +808,9 @@ function buildColumnMetrics(columns, columnDraggableOrOptions = false) {
851
808
  });
852
809
  const viewportWidth = options.viewportWidth ?? 0;
853
810
  if (viewportWidth <= left || columns.length === 0) return metrics;
854
- const unsetWidthStretchable = columns.map((column, index) => ({ column, index })).filter(({ column, index }) => !stretchExcludedIndices.has(index) && column.width === void 0 && column.fixed === void 0 && !column.rowSelection && !column.rowDragHandle && !column.rowNumber);
855
- const allDataStretchable = columns.map((column, index) => ({ column, index })).filter(({ column }) => column.fixed === void 0 && !column.rowSelection && !column.rowDragHandle && !column.rowNumber);
856
- const dataStretchable = allDataStretchable.filter(({ index }) => !stretchExcludedIndices.has(index));
857
- const targets = unsetWidthStretchable.length > 0 ? unsetWidthStretchable : dataStretchable.length > 0 ? dataStretchable : allDataStretchable.slice(-1);
811
+ const unsetWidthStretchable = columns.map((column, index) => ({ column, index })).filter(({ column }) => column.width === void 0 && column.fixed === void 0 && !column.rowSelection && !column.rowDragHandle && !column.rowNumber);
812
+ const dataStretchable = columns.map((column, index) => ({ column, index })).filter(({ column }) => column.fixed === void 0 && !column.rowSelection && !column.rowDragHandle && !column.rowNumber);
813
+ const targets = unsetWidthStretchable.length > 0 ? unsetWidthStretchable : dataStretchable.length > 0 ? dataStretchable : [];
858
814
  if (targets.length === 0) return metrics;
859
815
  const extra = viewportWidth - left;
860
816
  const baseTotal = targets.reduce((sum, { index }) => sum + metrics[index].width, 0);
@@ -993,6 +949,8 @@ function paintGrid(options) {
993
949
  const getColumnX = (index) => {
994
950
  return columns[index].fixed === "left" ? leftOffsets.get(index) ?? 0 : columns[index].fixed === "right" ? width - (rightOffsets.get(index) ?? 0) - metrics[index].width : (scrollableLefts.get(index) ?? leftFixedWidth) - scrollLeft;
995
951
  };
952
+ const displayedContentRight = columns.reduce((right, _column, index) => Math.max(right, getColumnX(index) + metrics[index].width), 0);
953
+ const trailingBlankStart = displayedContentRight > 0 && displayedContentRight < width ? displayedContentRight : null;
996
954
  const getRowDragOffset = (rowIndex) => {
997
955
  if (!rowDragPreview || rowIndex === rowDragPreview.sourceIndex) return 0;
998
956
  if (rowDragPreview.sourceIndex < rowDragPreview.targetIndex) {
@@ -1001,6 +959,15 @@ function paintGrid(options) {
1001
959
  return rowIndex >= rowDragPreview.targetIndex && rowIndex < rowDragPreview.sourceIndex ? rowHeight : 0;
1002
960
  };
1003
961
  const rowBelowDragGap = rowDragPreview ? rowDragPreview.sourceIndex <= rowDragPreview.targetIndex ? rowDragPreview.targetIndex + 1 : rowDragPreview.targetIndex : -1;
962
+ if (striped && trailingBlankStart !== null) {
963
+ const rowStart = Math.max(0, range.rowStart);
964
+ for (let rowIndex = rowStart; rowIndex < range.rowEnd; rowIndex += 1) {
965
+ if (rowIndex % 2 === 0 || rowDragPreview?.sourceIndex === rowIndex) continue;
966
+ const y = bodyTop + rowIndex * rowHeight - scrollTop + getRowDragOffset(rowIndex);
967
+ ctx.fillStyle = colors.stripe;
968
+ ctx.fillRect(trailingBlankStart, y, width - trailingBlankStart, rowHeight);
969
+ }
970
+ }
1004
971
  const paintBodyColumns = (layer) => {
1005
972
  const rowStart = Math.max(0, range.rowStart - Math.max(0, options.maxRowSpan - 1));
1006
973
  for (let rowIndex = rowStart; rowIndex < range.rowEnd; rowIndex += 1) {
@@ -1316,6 +1283,10 @@ function paintGrid(options) {
1316
1283
  ctx.fillStyle = colors.grid;
1317
1284
  ctx.fillRect(rightFixedLeft - 1, 0, 1, height);
1318
1285
  }
1286
+ if (!verticalBorderless && trailingBlankStart !== null) {
1287
+ ctx.fillStyle = colors.grid;
1288
+ ctx.fillRect(Math.round(trailingBlankStart) - 1, 0, 1, height);
1289
+ }
1319
1290
  ctx.fillStyle = colors.grid;
1320
1291
  if (!horizontalBorderless && !frameBorderless) ctx.fillRect(0, 0, width, 1);
1321
1292
  if (!verticalBorderless && !frameBorderless) {
@@ -1728,7 +1699,6 @@ function TableInner({
1728
1699
  const contextMenuEnabled = contextMenuConfig !== false;
1729
1700
  const customContextMenuConfig = typeof contextMenuConfig === "object" ? contextMenuConfig : void 0;
1730
1701
  const [resizedColumnWidths, setResizedColumnWidths] = (0, import_react5.useState)({});
1731
- const [manuallyResizedColumnKeys, setManuallyResizedColumnKeys] = (0, import_react5.useState)(() => /* @__PURE__ */ new Set());
1732
1702
  const leafSourceColumns = (0, import_react5.useMemo)(() => flattenDataColumns(sourceColumns), [sourceColumns]);
1733
1703
  const sourceColumnWidthsRef = (0, import_react5.useRef)(new Map(leafSourceColumns.map((column) => [column.key, column.width])));
1734
1704
  const showRowCheckbox = Boolean(rowSelection) && (typeof rowSelection !== "object" || rowSelection.showCheckbox !== false);
@@ -1782,6 +1752,7 @@ function TableInner({
1782
1752
  const rowAnchorRef = (0, import_react5.useRef)(null);
1783
1753
  const columnAnchorRef = (0, import_react5.useRef)(null);
1784
1754
  const columnDragRef = (0, import_react5.useRef)(null);
1755
+ const columnOrderDragRef = (0, import_react5.useRef)(null);
1785
1756
  const dragGuideRef = (0, import_react5.useRef)(null);
1786
1757
  const rowDragGuideRef = (0, import_react5.useRef)(null);
1787
1758
  const selectionFocusRef = (0, import_react5.useRef)(null);
@@ -1850,10 +1821,6 @@ function TableInner({
1850
1821
  const previousSourceWidths = sourceColumnWidthsRef.current;
1851
1822
  const nextSourceWidths = new Map(leafSourceColumns.map((column) => [column.key, column.width]));
1852
1823
  sourceColumnWidthsRef.current = nextSourceWidths;
1853
- setManuallyResizedColumnKeys((current) => {
1854
- const next = new Set([...current].filter((key) => nextSourceWidths.has(key) && previousSourceWidths.get(key) === nextSourceWidths.get(key)));
1855
- return next.size === current.size ? current : next;
1856
- });
1857
1824
  setResizedColumnWidths((current) => {
1858
1825
  const sourceColumnByKey = new Map(leafSourceColumns.map((column) => [column.key, column]));
1859
1826
  let changed = false;
@@ -2115,14 +2082,11 @@ function TableInner({
2115
2082
  if (selection?.rowKey === editing.rowKey && selection.columnKey === editing.columnKey) return;
2116
2083
  setEditing(null);
2117
2084
  }, [editing, selection]);
2118
- const stretchExcludedIndices = (0, import_react5.useMemo)(() => new Set(
2119
- columns.flatMap((column, index) => manuallyResizedColumnKeys.has(column.key) ? [index] : [])
2120
- ), [columns, manuallyResizedColumnKeys]);
2085
+ const hasManualColumnWidths = Object.keys(resizedColumnWidths).length > 0;
2121
2086
  const metrics = (0, import_react5.useMemo)(() => buildColumnMetrics(columns, {
2122
2087
  columnDraggable,
2123
- viewportWidth: viewport.width,
2124
- stretchExcludedIndices
2125
- }), [columnDraggable, columns, stretchExcludedIndices, viewport.width]);
2088
+ viewportWidth: hasManualColumnWidths ? 0 : viewport.width
2089
+ }), [columnDraggable, columns, hasManualColumnWidths, viewport.width]);
2126
2090
  const contentWidth = metrics.length > 0 ? metrics[metrics.length - 1].right : 0;
2127
2091
  const contentHeight = rows.length * rowHeight;
2128
2092
  const fixedWidth = (0, import_react5.useMemo)(() => columns.reduce((width2, column, index) => column.fixed === "left" ? width2 + metrics[index].width : width2, 0), [columns, metrics]);
@@ -2907,7 +2871,6 @@ function TableInner({
2907
2871
  return headerDepth - 1;
2908
2872
  }, [headerDepth, headerRowHeights, headerRowOffsets]);
2909
2873
  const resizeColumn = (0, import_react5.useCallback)((columnKey, width2) => {
2910
- setManuallyResizedColumnKeys((current) => current.has(columnKey) ? current : new Set(current).add(columnKey));
2911
2874
  setResizedColumnWidths((current) => current[columnKey] === width2 ? current : { ...current, [columnKey]: width2 });
2912
2875
  onColumnResize?.(columnKey, width2);
2913
2876
  }, [onColumnResize]);
@@ -3052,284 +3015,104 @@ function TableInner({
3052
3015
  }, [bodyTop, rowHeight, rows.length]);
3053
3016
  (0, import_react5.useEffect)(() => {
3054
3017
  const canvas = canvasRef.current;
3055
- if (!canvas || !columnDraggable && !rowDraggable) return;
3056
- const getColumnDropIndex = (sourceIndex, targetIndex, edge) => resolveColumnDropIndex(sourceIndex, targetIndex, edge, columns.length);
3057
- const getHeaderColumn = (clientX, clientY) => {
3058
- const rect = canvas.getBoundingClientRect();
3059
- const headerY = fixedHeader ? 0 : -scrollRef.current.top;
3060
- const localY = clientY - rect.top;
3061
- if (localY < headerY || localY >= headerY + headerHeight) return -1;
3062
- return locateColumn(clientX);
3063
- };
3064
- const getHeaderDragCell = (clientX, clientY) => {
3065
- const cell = locateHeaderCell(clientX, clientY);
3066
- if (!cell || locateHeaderResizeCell(clientX, clientY)) return null;
3067
- if (cell.leaf && locateHeaderAction(clientX, cell.startIndex)) return null;
3068
- return cell;
3069
- };
3018
+ if (!canvas || !rowDraggable) return;
3070
3019
  const cleanupDrag = (0, import_adapter.draggable)({
3071
3020
  element: canvas,
3072
3021
  canDrag: ({ input }) => {
3073
- const headerDragCell = columnDraggable ? getHeaderDragCell(input.clientX, input.clientY) : null;
3074
- if (headerDragCell) return true;
3075
3022
  const columnIndex = locateColumn(input.clientX);
3076
- return rowDraggable && columnIndex >= 0 && Boolean(columns[columnIndex].rowDragHandle) && locateRow(input.clientY) >= 0;
3077
- },
3078
- getInitialData: ({ input }) => {
3079
- const headerDragCell = columnDraggable ? getHeaderDragCell(input.clientX, input.clientY) : null;
3080
- if (!headerDragCell) {
3081
- return { type: "table-row", sourceIndex: locateRow(input.clientY) };
3082
- }
3083
- const sourceIndex = headerDragCell.startIndex;
3084
- columnDragPreviewRef.current = { sourceIndex, targetIndex: sourceIndex };
3085
- validColumnDropRef.current = null;
3086
- return {
3087
- type: "table-column",
3088
- sourceIndex,
3089
- sourceKey: headerDragCell.key,
3090
- parentKey: headerDragCell.parentKey,
3091
- headerLevel: headerDragCell.level,
3092
- headerKind: headerDragCell.leaf ? "column" : "group",
3093
- fixed: columns[headerDragCell.startIndex]?.fixed
3094
- };
3023
+ return columnIndex >= 0 && Boolean(columns[columnIndex].rowDragHandle) && locateRow(input.clientY) >= 0;
3095
3024
  },
3025
+ getInitialData: ({ input }) => ({ type: "table-row", sourceIndex: locateRow(input.clientY) }),
3096
3026
  onGenerateDragPreview: ({ nativeSetDragImage, source, location }) => {
3097
3027
  const sourceIndex = Number(source.data.sourceIndex);
3098
3028
  const canvasRect = canvas.getBoundingClientRect();
3099
3029
  const input = location.current.input;
3100
- const previewOffset = source.data.type === "table-row" ? {
3030
+ const previewOffset = {
3101
3031
  x: Math.max(0, Math.min(canvasRect.width, input.clientX - canvasRect.left)) + 2,
3102
3032
  y: Math.max(0, Math.min(rowHeight, input.clientY - canvasRect.top - bodyTop - sourceIndex * rowHeight + scrollRef.current.top)) + 2
3103
- } : {
3104
- x: Math.max(0, Math.min(metrics[sourceIndex].width, input.clientX - canvasRect.left - getDisplayedColumnLeft(sourceIndex))),
3105
- y: Math.max(0, Math.min(canvasRect.height, input.clientY - canvasRect.top))
3106
3033
  };
3107
3034
  (0, import_set_custom_native_drag_preview.setCustomNativeDragPreview)({
3108
3035
  nativeSetDragImage,
3109
3036
  getOffset: () => previewOffset,
3110
3037
  render: ({ container }) => {
3111
- if (source.data.type === "table-row") {
3112
- const frame = document.createElement("div");
3113
- frame.className = "rvg-row-drag-preview-frame";
3114
- frame.style.width = `${canvasRect.width + 4}px`;
3115
- frame.style.height = `${rowHeight + 4}px`;
3116
- const preview2 = document.createElement("div");
3117
- preview2.className = "rvg-row-drag-preview";
3118
- preview2.style.width = `${canvasRect.width}px`;
3119
- preview2.style.height = `${rowHeight}px`;
3120
- const row = rows[sourceIndex];
3121
- const rowKey2 = getRowKey(row, sourceIndex);
3122
- columns.forEach((column2, columnIndex) => {
3123
- const left = getDisplayedColumnLeft(columnIndex);
3124
- const columnWidth2 = metrics[columnIndex].width;
3125
- if (left + columnWidth2 <= 0 || left >= canvasRect.width) return;
3126
- const cell = document.createElement("div");
3127
- cell.className = "rvg-row-drag-preview-cell";
3128
- cell.style.left = `${left}px`;
3129
- cell.style.width = `${columnWidth2}px`;
3130
- cell.style.justifyContent = column2.align === "right" ? "flex-end" : column2.align === "center" ? "center" : "flex-start";
3131
- if (column2.rowDragHandle) {
3132
- cell.appendChild(createRowDragHandleSvg());
3133
- } else if (column2.rowSelection) {
3134
- const checkbox = document.createElement("span");
3135
- checkbox.className = selectedRowKeySet.has(rowKey2) ? "rvg-preview-checkbox is-checked" : "rvg-preview-checkbox";
3136
- checkbox.textContent = selectedRowKeySet.has(rowKey2) ? "\u2713" : "";
3137
- cell.appendChild(checkbox);
3138
- } else {
3139
- cell.textContent = getCellLabel(sourceIndex, columnIndex);
3140
- }
3141
- if (selection?.rowKey === rowKey2 && selection.columnKey === column2.key) {
3142
- cell.classList.add("is-selected");
3143
- }
3144
- preview2.appendChild(cell);
3145
- });
3146
- frame.appendChild(preview2);
3147
- container.appendChild(frame);
3148
- return () => frame.remove();
3149
- }
3038
+ const frame = document.createElement("div");
3039
+ frame.className = "rvg-row-drag-preview-frame";
3040
+ frame.style.width = `${canvasRect.width + 4}px`;
3041
+ frame.style.height = `${rowHeight + 4}px`;
3150
3042
  const preview = document.createElement("div");
3151
- preview.className = "rvg-column-drag-preview";
3152
- const columnWidth = metrics[sourceIndex].width;
3153
- preview.style.width = `${columnWidth}px`;
3154
- preview.style.height = `${canvasRect.height}px`;
3155
- const column = columns[sourceIndex];
3156
- const header = document.createElement("div");
3157
- header.className = "rvg-column-drag-preview-header";
3158
- header.style.top = `${fixedHeader ? 0 : -scrollRef.current.top}px`;
3159
- header.style.height = `${headerHeight}px`;
3160
- header.style.justifyContent = column.align === "right" ? "flex-end" : column.align === "center" ? "center" : "flex-start";
3161
- header.textContent = column.title;
3162
- const visibleActions = getVisibleHeaderActions(column, columnWidth, columnDraggable, measureHeaderTitleWidth(sourceIndex), headerActionSlotWidth);
3163
- let actionRight = 2;
3164
- if (visibleActions.drag) {
3165
- const icon = createHeaderDragHandleSvg();
3166
- icon.classList.add("rvg-preview-header-icon");
3167
- icon.style.width = `${headerActionSize}px`;
3168
- icon.style.height = `${headerActionSize}px`;
3169
- icon.style.right = `${actionRight}px`;
3170
- header.appendChild(icon);
3171
- actionRight += headerActionSlotWidth;
3172
- }
3173
- if (visibleActions.sort) {
3174
- const direction = sortState?.columnKey === column.key ? sortState.direction : null;
3175
- const icon = createHeaderSortSvg(direction);
3176
- icon.classList.add("rvg-preview-header-icon");
3177
- icon.style.width = `${headerActionSize}px`;
3178
- icon.style.height = `${headerActionSize}px`;
3179
- icon.style.right = `${actionRight}px`;
3180
- header.appendChild(icon);
3181
- actionRight += headerActionSlotWidth;
3182
- }
3183
- if (visibleActions.filter) {
3184
- const icon = createHeaderSearchSvg(Boolean(filterValues[column.key]));
3185
- icon.classList.add("rvg-preview-header-icon", "rvg-preview-header-search-icon");
3186
- icon.style.width = `${headerActionSize}px`;
3187
- icon.style.height = `${headerActionSize}px`;
3188
- icon.style.right = `${actionRight}px`;
3189
- header.appendChild(icon);
3190
- }
3191
- preview.appendChild(header);
3192
- for (let rowIndex = domRange.rowStart; rowIndex < domRange.rowEnd; rowIndex += 1) {
3193
- const row = rows[rowIndex];
3194
- const rowKey2 = getRowKey(row, rowIndex);
3043
+ preview.className = "rvg-row-drag-preview";
3044
+ preview.style.width = `${canvasRect.width}px`;
3045
+ preview.style.height = `${rowHeight}px`;
3046
+ const row = rows[sourceIndex];
3047
+ const rowKey2 = getRowKey(row, sourceIndex);
3048
+ columns.forEach((column, columnIndex) => {
3049
+ const left = getDisplayedColumnLeft(columnIndex);
3050
+ const columnWidth = metrics[columnIndex].width;
3051
+ if (left + columnWidth <= 0 || left >= canvasRect.width) return;
3195
3052
  const cell = document.createElement("div");
3196
- cell.className = "rvg-column-drag-preview-cell";
3197
- cell.style.top = `${bodyTop + rowIndex * rowHeight - scrollRef.current.top}px`;
3198
- cell.style.height = `${rowHeight}px`;
3053
+ cell.className = "rvg-row-drag-preview-cell";
3054
+ cell.style.left = `${left}px`;
3055
+ cell.style.width = `${columnWidth}px`;
3199
3056
  cell.style.justifyContent = column.align === "right" ? "flex-end" : column.align === "center" ? "center" : "flex-start";
3200
- const key = `${typeof rowKey2}:${String(rowKey2)}\0${column.key}`;
3201
- if (selectedRowKeySet.has(rowKey2) || selectedColumnKeySet.has(column.key)) {
3202
- cell.classList.add("is-axis-selected");
3203
- }
3204
- if (!insertedRowKeys.has(rowKey2) && editedCellKeys.has(key)) cell.classList.add("is-edited");
3205
- if (selection?.rowKey === rowKey2 && selection.columnKey === column.key) {
3206
- cell.classList.remove("is-edited");
3207
- cell.classList.add("is-selected");
3057
+ if (column.rowDragHandle) {
3058
+ cell.appendChild(createRowDragHandleSvg());
3059
+ } else if (column.rowSelection) {
3060
+ const checkbox = document.createElement("span");
3061
+ checkbox.className = selectedRowKeySet.has(rowKey2) ? "rvg-preview-checkbox is-checked" : "rvg-preview-checkbox";
3062
+ checkbox.textContent = selectedRowKeySet.has(rowKey2) ? "\u2713" : "";
3063
+ cell.appendChild(checkbox);
3064
+ } else {
3065
+ cell.textContent = getCellLabel(sourceIndex, columnIndex);
3208
3066
  }
3209
- cell.textContent = getCellLabel(rowIndex, sourceIndex);
3067
+ if (selection?.rowKey === rowKey2 && selection.columnKey === column.key) cell.classList.add("is-selected");
3210
3068
  preview.appendChild(cell);
3211
- }
3212
- container.appendChild(preview);
3213
- return () => preview.remove();
3069
+ });
3070
+ frame.appendChild(preview);
3071
+ container.appendChild(frame);
3072
+ return () => frame.remove();
3214
3073
  }
3215
3074
  });
3216
3075
  },
3217
3076
  onDragStart: ({ source }) => {
3077
+ const sourceIndex = Number(source.data.sourceIndex);
3218
3078
  suppressClickRef.current = true;
3219
3079
  hideDragTooltips();
3220
3080
  document.documentElement.classList.add("rvg-is-dragging");
3221
3081
  canvas.style.cursor = "move";
3222
- if (source.data.type === "table-row") {
3223
- const sourceIndex = Number(source.data.sourceIndex);
3224
- setRowDragPreview({ sourceIndex, targetIndex: sourceIndex });
3225
- }
3082
+ setRowDragPreview({ sourceIndex, targetIndex: sourceIndex });
3226
3083
  },
3227
3084
  onDrag: ({ source, location }) => {
3228
3085
  const target = location.current.dropTargets[0]?.data;
3229
3086
  const sourceIndex = Number(source.data.sourceIndex);
3230
- if (source.data.type === "table-row") {
3231
- const rawTargetIndex = Number(target?.targetIndex);
3232
- if (!Number.isInteger(rawTargetIndex)) {
3233
- setRowDragPreview(null);
3234
- return setRowDragGuide(null);
3235
- }
3236
- const edge2 = target?.rowEdge;
3237
- let targetIndex2 = rawTargetIndex + (edge2 === "bottom" ? 1 : 0);
3238
- if (sourceIndex < targetIndex2) targetIndex2 -= 1;
3239
- targetIndex2 = Math.max(0, Math.min(rows.length - 1, targetIndex2));
3240
- setRowDragPreview((current) => current?.sourceIndex === sourceIndex && current.targetIndex === targetIndex2 ? current : { sourceIndex, targetIndex: targetIndex2 });
3241
- setRowDragGuide(bodyTop + rawTargetIndex * rowHeight - scrollRef.current.top + (edge2 === "bottom" ? rowHeight : 0));
3242
- return;
3243
- }
3244
- const targetIndex = Number(target?.targetIndex);
3245
- if (!Number.isInteger(targetIndex) || target?.headerKind !== source.data.headerKind || target?.parentKey !== source.data.parentKey || target?.fixed !== source.data.fixed) {
3246
- validColumnDropRef.current = null;
3247
- setColumnDropTarget(null);
3248
- setDragGuide(null);
3249
- return;
3250
- }
3251
- const edge = target?.columnEdge;
3252
- const destinationIndex = getColumnDropIndex(sourceIndex, targetIndex, edge);
3253
- columnDragPreviewRef.current = { sourceIndex, targetIndex: destinationIndex };
3254
- if (destinationIndex === sourceIndex) {
3255
- validColumnDropRef.current = null;
3256
- setColumnDropTarget(null);
3257
- setDragGuide(null);
3258
- return;
3259
- }
3260
- validColumnDropRef.current = {
3261
- sourceIndex,
3262
- targetIndex: destinationIndex,
3263
- rawTargetIndex: targetIndex,
3264
- targetKey: String(target.targetKey),
3265
- headerKind: source.data.headerKind === "group" ? "group" : "column",
3266
- parentKey: typeof source.data.parentKey === "string" ? source.data.parentKey : void 0,
3267
- fixed: source.data.fixed === "left" || source.data.fixed === "right" ? source.data.fixed : void 0,
3268
- columnEdge: edge === "right" ? "right" : "left"
3269
- };
3270
- const siblingCells = headerCells.filter((cell) => cell.level === Number(source.data.headerLevel) && (cell.leaf ? "column" : "group") === source.data.headerKind && cell.parentKey === source.data.parentKey && columns[cell.startIndex]?.fixed === source.data.fixed);
3271
- const targetEndIndex = Number.isInteger(target?.targetEndIndex) ? Number(target.targetEndIndex) : targetIndex;
3272
- const hoveredTargetCell = siblingCells.find((cell) => cell.startIndex === targetIndex && cell.endIndex === targetEndIndex);
3273
- if (!hoveredTargetCell) {
3274
- validColumnDropRef.current = null;
3275
- setColumnDropTarget(null);
3276
- setDragGuide(null);
3277
- return;
3278
- }
3279
- const highlightedCell = edge === "right" ? hoveredTargetCell : siblingCells.filter((cell) => cell.endIndex < hoveredTargetCell.startIndex).sort((left, right) => right.endIndex - left.endIndex)[0] ?? hoveredTargetCell;
3280
- setColumnDropTarget({ startIndex: highlightedCell.startIndex, endIndex: highlightedCell.endIndex });
3281
- const targetLeft = Number(target?.targetLeft);
3282
- const targetWidth = Number(target?.targetWidth);
3283
- if (!Number.isFinite(targetLeft) || !Number.isFinite(targetWidth)) {
3284
- validColumnDropRef.current = null;
3285
- setColumnDropTarget(null);
3286
- setDragGuide(null);
3087
+ const rawTargetIndex = Number(target?.targetIndex);
3088
+ if (!Number.isInteger(rawTargetIndex)) {
3089
+ setRowDragPreview(null);
3090
+ setRowDragGuide(null);
3287
3091
  return;
3288
3092
  }
3289
- const guideTop = headerRowOffsets[Number(source.data.headerLevel)] ?? 0;
3290
- setDragGuide(edge === "right" ? targetLeft + targetWidth : targetLeft, guideTop);
3093
+ const edge = target?.rowEdge;
3094
+ let targetIndex = rawTargetIndex + (edge === "bottom" ? 1 : 0);
3095
+ if (sourceIndex < targetIndex) targetIndex -= 1;
3096
+ targetIndex = Math.max(0, Math.min(rows.length - 1, targetIndex));
3097
+ setRowDragPreview((current) => current?.sourceIndex === sourceIndex && current.targetIndex === targetIndex ? current : { sourceIndex, targetIndex });
3098
+ setRowDragGuide(bodyTop + rawTargetIndex * rowHeight - scrollRef.current.top + (edge === "bottom" ? rowHeight : 0));
3291
3099
  },
3292
3100
  onDrop: ({ source, location }) => {
3293
- document.documentElement.classList.remove("rvg-is-dragging");
3294
3101
  const target = location.current.dropTargets[0]?.data;
3295
3102
  const sourceIndex = Number(source.data.sourceIndex);
3296
- if (source.data.type === "table-row") {
3297
- const rawTargetIndex = Number(target?.targetIndex);
3298
- let targetIndex = rawTargetIndex + (target?.rowEdge === "bottom" ? 1 : 0);
3299
- if (sourceIndex < targetIndex) targetIndex -= 1;
3300
- targetIndex = Math.max(0, Math.min(rows.length - 1, targetIndex));
3301
- scrollerRef.current?.classList.add("rvg-row-drop-settling");
3302
- setRowDragPreview(null);
3303
- setRowDragGuide(null);
3304
- canvas.style.cursor = "default";
3305
- if (Number.isInteger(rawTargetIndex) && sourceIndex !== targetIndex) applyRowOrder(sourceIndex, targetIndex);
3306
- requestAnimationFrame(() => {
3307
- requestAnimationFrame(() => scrollerRef.current?.classList.remove("rvg-row-drop-settling"));
3308
- });
3309
- window.setTimeout(() => {
3310
- suppressClickRef.current = false;
3311
- }, 0);
3312
- return;
3313
- }
3314
- const validDrop = validColumnDropRef.current;
3103
+ const rawTargetIndex = Number(target?.targetIndex);
3104
+ let targetIndex = rawTargetIndex + (target?.rowEdge === "bottom" ? 1 : 0);
3105
+ if (sourceIndex < targetIndex) targetIndex -= 1;
3106
+ targetIndex = Math.max(0, Math.min(rows.length - 1, targetIndex));
3107
+ scrollerRef.current?.classList.add("rvg-row-drop-settling");
3108
+ setRowDragPreview(null);
3109
+ setRowDragGuide(null);
3110
+ document.documentElement.classList.remove("rvg-is-dragging");
3315
3111
  canvas.style.cursor = "default";
3316
- setDragGuide(null);
3317
- setColumnDropTarget(null);
3318
- columnDragPreviewRef.current = null;
3319
- validColumnDropRef.current = null;
3320
- if (validDrop) {
3321
- applyColumnOrder(
3322
- validDrop.sourceIndex - utilityColumnCount,
3323
- validDrop.targetIndex - utilityColumnCount,
3324
- {
3325
- type: validDrop.headerKind,
3326
- sourceKey: String(source.data.sourceKey),
3327
- targetKey: validDrop.targetKey,
3328
- parentKey: validDrop.parentKey,
3329
- placement: resolveColumnDropPlacement(validDrop.columnEdge)
3330
- }
3331
- );
3332
- }
3112
+ if (Number.isInteger(rawTargetIndex) && sourceIndex !== targetIndex) applyRowOrder(sourceIndex, targetIndex);
3113
+ requestAnimationFrame(() => {
3114
+ requestAnimationFrame(() => scrollerRef.current?.classList.remove("rvg-row-drop-settling"));
3115
+ });
3333
3116
  window.setTimeout(() => {
3334
3117
  suppressClickRef.current = false;
3335
3118
  }, 0);
@@ -3337,43 +3120,14 @@ function TableInner({
3337
3120
  });
3338
3121
  const cleanupDrop = (0, import_adapter.dropTargetForElements)({
3339
3122
  element: canvas,
3340
- canDrop: ({ source }) => source.data.type === "table-column" || source.data.type === "table-row",
3123
+ canDrop: ({ source }) => source.data.type === "table-row",
3341
3124
  getDropEffect: () => "move",
3342
- getData: ({ input, element, source }) => {
3343
- if (source.data.type === "table-row") {
3344
- const targetIndex2 = locateRow(input.clientY);
3345
- if (targetIndex2 < 0) return { targetIndex: -1 };
3346
- const rowTop = bodyTop + targetIndex2 * rowHeight - scrollRef.current.top;
3347
- const rowEdge = input.clientY - canvas.getBoundingClientRect().top < rowTop + rowHeight / 2 ? "top" : "bottom";
3348
- return (0, import_closest_edge.attachClosestEdge)({ targetIndex: targetIndex2, rowEdge }, { element, input, allowedEdges: ["top", "bottom"] });
3349
- }
3350
- const hoveredColumnIndex = locateColumn(input.clientX);
3351
- const targetCell = locateHeaderCell(input.clientX, input.clientY) ?? headerCells.find((cell) => hoveredColumnIndex >= cell.startIndex && hoveredColumnIndex <= cell.endIndex && cell.level === Number(source.data.headerLevel) && (cell.leaf ? "column" : "group") === source.data.headerKind && cell.parentKey === source.data.parentKey);
3352
- if (!targetCell) return { targetIndex: -1 };
3353
- let targetIndex = targetCell.startIndex;
3354
- const targetFixed = columns[targetCell.startIndex]?.fixed;
3355
- const headerKind = targetCell.leaf ? "column" : "group";
3356
- if (source.data.headerKind !== headerKind || source.data.parentKey !== targetCell.parentKey || source.data.fixed !== targetFixed) return { targetIndex: -1 };
3357
- if (columns[targetIndex].rowSelection || columns[targetIndex].rowDragHandle || columns[targetIndex].rowNumber) {
3358
- const fixedSide = columns[Number(source.data.sourceIndex)]?.fixed;
3359
- targetIndex = columns.findIndex((column, index) => index > targetIndex && column.fixed === fixedSide && !column.rowSelection && !column.rowDragHandle && !column.rowNumber);
3360
- if (targetIndex < 0) return { targetIndex: -1 };
3361
- return { targetIndex, columnEdge: "left" };
3362
- }
3363
- const left = getHeaderCellLeft(targetCell);
3364
- const targetWidth = targetCell.leaf ? metrics[targetIndex].width : getHeaderCellWidth(targetCell);
3365
- const columnEdge = input.clientX - canvas.getBoundingClientRect().left < left + targetWidth / 2 ? "left" : "right";
3366
- return (0, import_closest_edge.attachClosestEdge)({
3367
- targetIndex,
3368
- targetEndIndex: targetCell.endIndex,
3369
- targetKey: targetCell.key,
3370
- parentKey: targetCell.parentKey,
3371
- headerKind,
3372
- fixed: targetFixed,
3373
- targetLeft: left,
3374
- targetWidth,
3375
- columnEdge
3376
- }, { element, input, allowedEdges: ["left", "right"] });
3125
+ getData: ({ input, element }) => {
3126
+ const targetIndex = locateRow(input.clientY);
3127
+ if (targetIndex < 0) return { targetIndex: -1 };
3128
+ const rowTop = bodyTop + targetIndex * rowHeight - scrollRef.current.top;
3129
+ const rowEdge = input.clientY - canvas.getBoundingClientRect().top < rowTop + rowHeight / 2 ? "top" : "bottom";
3130
+ return (0, import_closest_edge.attachClosestEdge)({ targetIndex, rowEdge }, { element, input, allowedEdges: ["top", "bottom"] });
3377
3131
  }
3378
3132
  });
3379
3133
  return () => {
@@ -3381,7 +3135,7 @@ function TableInner({
3381
3135
  cleanupDrag();
3382
3136
  cleanupDrop();
3383
3137
  };
3384
- }, [applyColumnOrder, applyRowOrder, bodyTop, columnDraggable, columns, filterValues, fixedHeader, getCellLabel, getDisplayedColumnLeft, getHeaderCellWidth, getRowKey, headerActionSize, headerActionSlotWidth, headerCells, headerHeight, hideDragTooltips, locateColumn, locateHeaderAction, locateHeaderCell, locateHeaderResizeCell, locateRow, measureHeaderTitleWidth, metrics, rowDraggable, rowHeight, rows, selectedRowKeySet, selection, setDragGuide, setRowDragGuide, sortState, utilityColumnCount]);
3138
+ }, [applyRowOrder, bodyTop, columns, getCellLabel, getDisplayedColumnLeft, getRowKey, hideDragTooltips, locateColumn, locateRow, metrics, rowDraggable, rowHeight, rows, selectedRowKeySet, selection, setRowDragGuide]);
3385
3139
  const locateCell = (0, import_react5.useCallback)((clientX, clientY) => {
3386
3140
  const canvas = canvasRef.current;
3387
3141
  if (!canvas) return null;
@@ -3828,6 +3582,113 @@ function TableInner({
3828
3582
  setResizeGuideX(null);
3829
3583
  setResizeGuideTop(0);
3830
3584
  }, []);
3585
+ const clearColumnOrderPointerDrag = (0, import_react5.useCallback)((canvas) => {
3586
+ columnOrderDragRef.current = null;
3587
+ columnDragPreviewRef.current = null;
3588
+ validColumnDropRef.current = null;
3589
+ setColumnDropTarget(null);
3590
+ setDragGuide(null);
3591
+ document.documentElement.classList.remove("rvg-is-dragging");
3592
+ canvas.style.cursor = "default";
3593
+ }, [setDragGuide]);
3594
+ const handleColumnOrderPointerDown = (0, import_react5.useCallback)((event) => {
3595
+ if (!columnDraggable || event.button !== 0 || columnDragRef.current) return;
3596
+ const sourceCell = locateHeaderCell(event.clientX, event.clientY);
3597
+ if (!sourceCell || locateHeaderResizeCell(event.clientX, event.clientY)) return;
3598
+ if (sourceCell.leaf && locateHeaderAction(event.clientX, sourceCell.startIndex)) return;
3599
+ const sourceColumn = columns[sourceCell.startIndex];
3600
+ if (!sourceColumn || sourceColumn.rowSelection || sourceColumn.rowDragHandle || sourceColumn.rowNumber) return;
3601
+ event.currentTarget.setPointerCapture(event.pointerId);
3602
+ columnOrderDragRef.current = {
3603
+ pointerId: event.pointerId,
3604
+ startX: event.clientX,
3605
+ startY: event.clientY,
3606
+ active: false,
3607
+ sourceCell
3608
+ };
3609
+ }, [columnDraggable, columns, locateHeaderAction, locateHeaderCell, locateHeaderResizeCell]);
3610
+ const handleColumnOrderPointerMove = (0, import_react5.useCallback)((event) => {
3611
+ const drag = columnOrderDragRef.current;
3612
+ if (!drag || drag.pointerId !== event.pointerId || columnDragRef.current) return;
3613
+ if (!drag.active) {
3614
+ if (Math.hypot(event.clientX - drag.startX, event.clientY - drag.startY) < 4) return;
3615
+ drag.active = true;
3616
+ suppressClickRef.current = true;
3617
+ hideDragTooltips();
3618
+ document.documentElement.classList.add("rvg-is-dragging");
3619
+ event.currentTarget.style.cursor = "move";
3620
+ }
3621
+ event.preventDefault();
3622
+ const sourceCell = drag.sourceCell;
3623
+ const hoveredColumnIndex = locateColumn(event.clientX);
3624
+ const targetCell = locateHeaderCell(event.clientX, event.clientY) ?? headerCells.find((cell) => hoveredColumnIndex >= cell.startIndex && hoveredColumnIndex <= cell.endIndex && cell.level === sourceCell.level && cell.leaf === sourceCell.leaf && cell.parentKey === sourceCell.parentKey && columns[cell.startIndex]?.fixed === columns[sourceCell.startIndex]?.fixed);
3625
+ if (!targetCell) {
3626
+ validColumnDropRef.current = null;
3627
+ setColumnDropTarget(null);
3628
+ setDragGuide(null);
3629
+ return;
3630
+ }
3631
+ const targetColumn = columns[targetCell.startIndex];
3632
+ if (!targetColumn || targetColumn.rowSelection || targetColumn.rowDragHandle || targetColumn.rowNumber || targetCell.leaf !== sourceCell.leaf || targetCell.parentKey !== sourceCell.parentKey || targetColumn.fixed !== columns[sourceCell.startIndex]?.fixed) {
3633
+ validColumnDropRef.current = null;
3634
+ setColumnDropTarget(null);
3635
+ setDragGuide(null);
3636
+ return;
3637
+ }
3638
+ const targetLeft = getHeaderCellLeft(targetCell);
3639
+ const targetWidth = getHeaderCellWidth(targetCell);
3640
+ const localX = event.clientX - event.currentTarget.getBoundingClientRect().left;
3641
+ const columnEdge = localX < targetLeft + targetWidth / 2 ? "left" : "right";
3642
+ const destinationIndex = resolveColumnDropIndex(
3643
+ sourceCell.startIndex,
3644
+ targetCell.startIndex,
3645
+ columnEdge,
3646
+ columns.length
3647
+ );
3648
+ columnDragPreviewRef.current = { sourceIndex: sourceCell.startIndex, targetIndex: destinationIndex };
3649
+ if (destinationIndex === sourceCell.startIndex) {
3650
+ validColumnDropRef.current = null;
3651
+ setColumnDropTarget(null);
3652
+ setDragGuide(null);
3653
+ return;
3654
+ }
3655
+ validColumnDropRef.current = {
3656
+ sourceIndex: sourceCell.startIndex,
3657
+ targetIndex: destinationIndex,
3658
+ rawTargetIndex: targetCell.startIndex,
3659
+ targetKey: targetCell.key,
3660
+ headerKind: sourceCell.leaf ? "column" : "group",
3661
+ parentKey: sourceCell.parentKey,
3662
+ fixed: targetColumn.fixed,
3663
+ columnEdge
3664
+ };
3665
+ setColumnDropTarget({ startIndex: targetCell.startIndex, endIndex: targetCell.endIndex });
3666
+ setDragGuide(columnEdge === "right" ? targetLeft + targetWidth : targetLeft, headerRowOffsets[sourceCell.level] ?? 0);
3667
+ }, [columns, getHeaderCellLeft, getHeaderCellWidth, headerCells, headerRowOffsets, hideDragTooltips, locateColumn, locateHeaderCell, setDragGuide]);
3668
+ const finishColumnOrderPointerDrag = (0, import_react5.useCallback)((event, apply) => {
3669
+ const drag = columnOrderDragRef.current;
3670
+ if (!drag || drag.pointerId !== event.pointerId) return;
3671
+ if (event.currentTarget.hasPointerCapture(event.pointerId)) event.currentTarget.releasePointerCapture(event.pointerId);
3672
+ const validDrop = validColumnDropRef.current;
3673
+ if (apply && drag.active && validDrop) {
3674
+ applyColumnOrder(
3675
+ validDrop.sourceIndex - utilityColumnCount,
3676
+ validDrop.targetIndex - utilityColumnCount,
3677
+ {
3678
+ type: validDrop.headerKind,
3679
+ sourceKey: drag.sourceCell.key,
3680
+ targetKey: validDrop.targetKey,
3681
+ parentKey: validDrop.parentKey,
3682
+ placement: resolveColumnDropPlacement(validDrop.columnEdge)
3683
+ }
3684
+ );
3685
+ }
3686
+ const wasActive = drag.active;
3687
+ clearColumnOrderPointerDrag(event.currentTarget);
3688
+ if (wasActive) window.setTimeout(() => {
3689
+ suppressClickRef.current = false;
3690
+ }, 0);
3691
+ }, [applyColumnOrder, clearColumnOrderPointerDrag, utilityColumnCount]);
3831
3692
  const queueSortStateChange = (0, import_react5.useCallback)((next) => {
3832
3693
  setSortState(next);
3833
3694
  }, []);
@@ -4641,7 +4502,7 @@ function TableInner({
4641
4502
  hideDragTooltips();
4642
4503
  return;
4643
4504
  }
4644
- if (columnDragRef.current) return;
4505
+ if (columnDragRef.current || columnOrderDragRef.current?.active) return;
4645
4506
  const rect = event.currentTarget.getBoundingClientRect();
4646
4507
  const localY = event.clientY - rect.top;
4647
4508
  const headerY = fixedHeader ? 0 : -scrollRef.current.top;
@@ -4758,20 +4619,22 @@ function TableInner({
4758
4619
  event.currentTarget.style.cursor = "move";
4759
4620
  }
4760
4621
  handleColumnPointerDown(event);
4622
+ if (!columnDragRef.current) handleColumnOrderPointerDown(event);
4761
4623
  beginRangeDrag(event);
4762
4624
  },
4763
4625
  onPointerMove: (event) => {
4764
4626
  handleColumnPointerMove(event);
4627
+ handleColumnOrderPointerMove(event);
4765
4628
  updateRangeDrag(event);
4766
4629
  },
4767
4630
  onPointerUp: (event) => {
4768
- document.documentElement.classList.remove("rvg-is-dragging");
4769
4631
  handleColumnPointerUp(event);
4632
+ finishColumnOrderPointerDrag(event, true);
4770
4633
  endRangeDrag(event);
4771
4634
  },
4772
4635
  onPointerCancel: (event) => {
4773
- document.documentElement.classList.remove("rvg-is-dragging");
4774
4636
  handleColumnPointerUp(event);
4637
+ finishColumnOrderPointerDrag(event, false);
4775
4638
  endRangeDrag(event);
4776
4639
  },
4777
4640
  onClick: (event) => {