@lensui/lens-table 0.1.21 → 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.
Files changed (3) hide show
  1. package/dist/index.cjs +202 -328
  2. package/dist/index.js +202 -328
  3. package/package.json +1 -1
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");
@@ -991,6 +949,8 @@ function paintGrid(options) {
991
949
  const getColumnX = (index) => {
992
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;
993
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;
994
954
  const getRowDragOffset = (rowIndex) => {
995
955
  if (!rowDragPreview || rowIndex === rowDragPreview.sourceIndex) return 0;
996
956
  if (rowDragPreview.sourceIndex < rowDragPreview.targetIndex) {
@@ -999,6 +959,15 @@ function paintGrid(options) {
999
959
  return rowIndex >= rowDragPreview.targetIndex && rowIndex < rowDragPreview.sourceIndex ? rowHeight : 0;
1000
960
  };
1001
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
+ }
1002
971
  const paintBodyColumns = (layer) => {
1003
972
  const rowStart = Math.max(0, range.rowStart - Math.max(0, options.maxRowSpan - 1));
1004
973
  for (let rowIndex = rowStart; rowIndex < range.rowEnd; rowIndex += 1) {
@@ -1314,6 +1283,10 @@ function paintGrid(options) {
1314
1283
  ctx.fillStyle = colors.grid;
1315
1284
  ctx.fillRect(rightFixedLeft - 1, 0, 1, height);
1316
1285
  }
1286
+ if (!verticalBorderless && trailingBlankStart !== null) {
1287
+ ctx.fillStyle = colors.grid;
1288
+ ctx.fillRect(Math.round(trailingBlankStart) - 1, 0, 1, height);
1289
+ }
1317
1290
  ctx.fillStyle = colors.grid;
1318
1291
  if (!horizontalBorderless && !frameBorderless) ctx.fillRect(0, 0, width, 1);
1319
1292
  if (!verticalBorderless && !frameBorderless) {
@@ -1448,6 +1421,13 @@ function useControllableValue(value, defaultValue, onChange) {
1448
1421
 
1449
1422
  // src/Table.tsx
1450
1423
  var import_jsx_runtime7 = require("react/jsx-runtime");
1424
+ function resolveColumnDropIndex(sourceIndex, targetIndex, edge, columnCount) {
1425
+ const insertionIndex = targetIndex + (edge === "right" ? 1 : 0) - (sourceIndex < targetIndex ? 1 : 0);
1426
+ return Math.max(0, Math.min(columnCount - 1, insertionIndex));
1427
+ }
1428
+ function resolveColumnDropPlacement(edge) {
1429
+ return edge === "right" ? "after" : "before";
1430
+ }
1451
1431
  var ANNOTATION_COLORS = ["#f44336", "#ff7a45", "#f5a623", "#f2c94c", "#52c41a", "#13a8a8", "#1677ff", "#597ef7", "#9254de", "#eb2f96"];
1452
1432
  var FALLBACK_HEIGHT = 480;
1453
1433
  var EMPTY_BODY_HEIGHT = 240;
@@ -1772,6 +1752,7 @@ function TableInner({
1772
1752
  const rowAnchorRef = (0, import_react5.useRef)(null);
1773
1753
  const columnAnchorRef = (0, import_react5.useRef)(null);
1774
1754
  const columnDragRef = (0, import_react5.useRef)(null);
1755
+ const columnOrderDragRef = (0, import_react5.useRef)(null);
1775
1756
  const dragGuideRef = (0, import_react5.useRef)(null);
1776
1757
  const rowDragGuideRef = (0, import_react5.useRef)(null);
1777
1758
  const selectionFocusRef = (0, import_react5.useRef)(null);
@@ -3034,291 +3015,104 @@ function TableInner({
3034
3015
  }, [bodyTop, rowHeight, rows.length]);
3035
3016
  (0, import_react5.useEffect)(() => {
3036
3017
  const canvas = canvasRef.current;
3037
- if (!canvas || !columnDraggable && !rowDraggable) return;
3038
- const getColumnDropIndex = (sourceIndex, targetIndex, edge) => {
3039
- if (edge === "right") return targetIndex;
3040
- const destinationIndex = targetIndex - (sourceIndex < targetIndex ? 1 : 0);
3041
- return Math.max(0, Math.min(columns.length - 1, destinationIndex));
3042
- };
3043
- const getColumnDropPlacement = (sourceIndex, targetIndex, edge) => {
3044
- if (edge !== "right") return "before";
3045
- return targetIndex < sourceIndex ? "before" : "after";
3046
- };
3047
- const getHeaderColumn = (clientX, clientY) => {
3048
- const rect = canvas.getBoundingClientRect();
3049
- const headerY = fixedHeader ? 0 : -scrollRef.current.top;
3050
- const localY = clientY - rect.top;
3051
- if (localY < headerY || localY >= headerY + headerHeight) return -1;
3052
- return locateColumn(clientX);
3053
- };
3054
- const getHeaderDragCell = (clientX, clientY) => {
3055
- const cell = locateHeaderCell(clientX, clientY);
3056
- if (!cell) return null;
3057
- return locateHeaderCellDragHandle(clientX, cell) && !locateHeaderResizeCell(clientX, clientY) ? cell : null;
3058
- };
3018
+ if (!canvas || !rowDraggable) return;
3059
3019
  const cleanupDrag = (0, import_adapter.draggable)({
3060
3020
  element: canvas,
3061
3021
  canDrag: ({ input }) => {
3062
- const headerDragCell = columnDraggable ? getHeaderDragCell(input.clientX, input.clientY) : null;
3063
- if (headerDragCell) return true;
3064
3022
  const columnIndex = locateColumn(input.clientX);
3065
- return rowDraggable && columnIndex >= 0 && Boolean(columns[columnIndex].rowDragHandle) && locateRow(input.clientY) >= 0;
3066
- },
3067
- getInitialData: ({ input }) => {
3068
- const headerDragCell = columnDraggable ? getHeaderDragCell(input.clientX, input.clientY) : null;
3069
- if (!headerDragCell) {
3070
- return { type: "table-row", sourceIndex: locateRow(input.clientY) };
3071
- }
3072
- const sourceIndex = headerDragCell.startIndex;
3073
- columnDragPreviewRef.current = { sourceIndex, targetIndex: sourceIndex };
3074
- validColumnDropRef.current = null;
3075
- return {
3076
- type: "table-column",
3077
- sourceIndex,
3078
- sourceKey: headerDragCell.key,
3079
- parentKey: headerDragCell.parentKey,
3080
- headerLevel: headerDragCell.level,
3081
- headerKind: headerDragCell.leaf ? "column" : "group",
3082
- fixed: columns[headerDragCell.startIndex]?.fixed
3083
- };
3023
+ return columnIndex >= 0 && Boolean(columns[columnIndex].rowDragHandle) && locateRow(input.clientY) >= 0;
3084
3024
  },
3025
+ getInitialData: ({ input }) => ({ type: "table-row", sourceIndex: locateRow(input.clientY) }),
3085
3026
  onGenerateDragPreview: ({ nativeSetDragImage, source, location }) => {
3086
3027
  const sourceIndex = Number(source.data.sourceIndex);
3087
3028
  const canvasRect = canvas.getBoundingClientRect();
3088
3029
  const input = location.current.input;
3089
- const previewOffset = source.data.type === "table-row" ? {
3030
+ const previewOffset = {
3090
3031
  x: Math.max(0, Math.min(canvasRect.width, input.clientX - canvasRect.left)) + 2,
3091
3032
  y: Math.max(0, Math.min(rowHeight, input.clientY - canvasRect.top - bodyTop - sourceIndex * rowHeight + scrollRef.current.top)) + 2
3092
- } : {
3093
- x: Math.max(0, Math.min(metrics[sourceIndex].width, input.clientX - canvasRect.left - getDisplayedColumnLeft(sourceIndex))),
3094
- y: Math.max(0, Math.min(canvasRect.height, input.clientY - canvasRect.top))
3095
3033
  };
3096
3034
  (0, import_set_custom_native_drag_preview.setCustomNativeDragPreview)({
3097
3035
  nativeSetDragImage,
3098
3036
  getOffset: () => previewOffset,
3099
3037
  render: ({ container }) => {
3100
- if (source.data.type === "table-row") {
3101
- const frame = document.createElement("div");
3102
- frame.className = "rvg-row-drag-preview-frame";
3103
- frame.style.width = `${canvasRect.width + 4}px`;
3104
- frame.style.height = `${rowHeight + 4}px`;
3105
- const preview2 = document.createElement("div");
3106
- preview2.className = "rvg-row-drag-preview";
3107
- preview2.style.width = `${canvasRect.width}px`;
3108
- preview2.style.height = `${rowHeight}px`;
3109
- const row = rows[sourceIndex];
3110
- const rowKey2 = getRowKey(row, sourceIndex);
3111
- columns.forEach((column2, columnIndex) => {
3112
- const left = getDisplayedColumnLeft(columnIndex);
3113
- const columnWidth2 = metrics[columnIndex].width;
3114
- if (left + columnWidth2 <= 0 || left >= canvasRect.width) return;
3115
- const cell = document.createElement("div");
3116
- cell.className = "rvg-row-drag-preview-cell";
3117
- cell.style.left = `${left}px`;
3118
- cell.style.width = `${columnWidth2}px`;
3119
- cell.style.justifyContent = column2.align === "right" ? "flex-end" : column2.align === "center" ? "center" : "flex-start";
3120
- if (column2.rowDragHandle) {
3121
- cell.appendChild(createRowDragHandleSvg());
3122
- } else if (column2.rowSelection) {
3123
- const checkbox = document.createElement("span");
3124
- checkbox.className = selectedRowKeySet.has(rowKey2) ? "rvg-preview-checkbox is-checked" : "rvg-preview-checkbox";
3125
- checkbox.textContent = selectedRowKeySet.has(rowKey2) ? "\u2713" : "";
3126
- cell.appendChild(checkbox);
3127
- } else {
3128
- cell.textContent = getCellLabel(sourceIndex, columnIndex);
3129
- }
3130
- if (selection?.rowKey === rowKey2 && selection.columnKey === column2.key) {
3131
- cell.classList.add("is-selected");
3132
- }
3133
- preview2.appendChild(cell);
3134
- });
3135
- frame.appendChild(preview2);
3136
- container.appendChild(frame);
3137
- return () => frame.remove();
3138
- }
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`;
3139
3042
  const preview = document.createElement("div");
3140
- preview.className = "rvg-column-drag-preview";
3141
- const columnWidth = metrics[sourceIndex].width;
3142
- preview.style.width = `${columnWidth}px`;
3143
- preview.style.height = `${canvasRect.height}px`;
3144
- const column = columns[sourceIndex];
3145
- const header = document.createElement("div");
3146
- header.className = "rvg-column-drag-preview-header";
3147
- header.style.top = `${fixedHeader ? 0 : -scrollRef.current.top}px`;
3148
- header.style.height = `${headerHeight}px`;
3149
- header.style.justifyContent = column.align === "right" ? "flex-end" : column.align === "center" ? "center" : "flex-start";
3150
- header.textContent = column.title;
3151
- const visibleActions = getVisibleHeaderActions(column, columnWidth, columnDraggable, measureHeaderTitleWidth(sourceIndex), headerActionSlotWidth);
3152
- let actionRight = 2;
3153
- if (visibleActions.drag) {
3154
- const icon = createHeaderDragHandleSvg();
3155
- icon.classList.add("rvg-preview-header-icon");
3156
- icon.style.width = `${headerActionSize}px`;
3157
- icon.style.height = `${headerActionSize}px`;
3158
- icon.style.right = `${actionRight}px`;
3159
- header.appendChild(icon);
3160
- actionRight += headerActionSlotWidth;
3161
- }
3162
- if (visibleActions.sort) {
3163
- const direction = sortState?.columnKey === column.key ? sortState.direction : null;
3164
- const icon = createHeaderSortSvg(direction);
3165
- icon.classList.add("rvg-preview-header-icon");
3166
- icon.style.width = `${headerActionSize}px`;
3167
- icon.style.height = `${headerActionSize}px`;
3168
- icon.style.right = `${actionRight}px`;
3169
- header.appendChild(icon);
3170
- actionRight += headerActionSlotWidth;
3171
- }
3172
- if (visibleActions.filter) {
3173
- const icon = createHeaderSearchSvg(Boolean(filterValues[column.key]));
3174
- icon.classList.add("rvg-preview-header-icon", "rvg-preview-header-search-icon");
3175
- icon.style.width = `${headerActionSize}px`;
3176
- icon.style.height = `${headerActionSize}px`;
3177
- icon.style.right = `${actionRight}px`;
3178
- header.appendChild(icon);
3179
- }
3180
- preview.appendChild(header);
3181
- for (let rowIndex = domRange.rowStart; rowIndex < domRange.rowEnd; rowIndex += 1) {
3182
- const row = rows[rowIndex];
3183
- 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;
3184
3052
  const cell = document.createElement("div");
3185
- cell.className = "rvg-column-drag-preview-cell";
3186
- cell.style.top = `${bodyTop + rowIndex * rowHeight - scrollRef.current.top}px`;
3187
- 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`;
3188
3056
  cell.style.justifyContent = column.align === "right" ? "flex-end" : column.align === "center" ? "center" : "flex-start";
3189
- const key = `${typeof rowKey2}:${String(rowKey2)}\0${column.key}`;
3190
- if (selectedRowKeySet.has(rowKey2) || selectedColumnKeySet.has(column.key)) {
3191
- cell.classList.add("is-axis-selected");
3192
- }
3193
- if (!insertedRowKeys.has(rowKey2) && editedCellKeys.has(key)) cell.classList.add("is-edited");
3194
- if (selection?.rowKey === rowKey2 && selection.columnKey === column.key) {
3195
- cell.classList.remove("is-edited");
3196
- 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);
3197
3066
  }
3198
- cell.textContent = getCellLabel(rowIndex, sourceIndex);
3067
+ if (selection?.rowKey === rowKey2 && selection.columnKey === column.key) cell.classList.add("is-selected");
3199
3068
  preview.appendChild(cell);
3200
- }
3201
- container.appendChild(preview);
3202
- return () => preview.remove();
3069
+ });
3070
+ frame.appendChild(preview);
3071
+ container.appendChild(frame);
3072
+ return () => frame.remove();
3203
3073
  }
3204
3074
  });
3205
3075
  },
3206
3076
  onDragStart: ({ source }) => {
3077
+ const sourceIndex = Number(source.data.sourceIndex);
3207
3078
  suppressClickRef.current = true;
3208
3079
  hideDragTooltips();
3209
3080
  document.documentElement.classList.add("rvg-is-dragging");
3210
3081
  canvas.style.cursor = "move";
3211
- if (source.data.type === "table-row") {
3212
- const sourceIndex = Number(source.data.sourceIndex);
3213
- setRowDragPreview({ sourceIndex, targetIndex: sourceIndex });
3214
- }
3082
+ setRowDragPreview({ sourceIndex, targetIndex: sourceIndex });
3215
3083
  },
3216
3084
  onDrag: ({ source, location }) => {
3217
3085
  const target = location.current.dropTargets[0]?.data;
3218
3086
  const sourceIndex = Number(source.data.sourceIndex);
3219
- if (source.data.type === "table-row") {
3220
- const rawTargetIndex = Number(target?.targetIndex);
3221
- if (!Number.isInteger(rawTargetIndex)) {
3222
- setRowDragPreview(null);
3223
- return setRowDragGuide(null);
3224
- }
3225
- const edge2 = target?.rowEdge;
3226
- let targetIndex2 = rawTargetIndex + (edge2 === "bottom" ? 1 : 0);
3227
- if (sourceIndex < targetIndex2) targetIndex2 -= 1;
3228
- targetIndex2 = Math.max(0, Math.min(rows.length - 1, targetIndex2));
3229
- setRowDragPreview((current) => current?.sourceIndex === sourceIndex && current.targetIndex === targetIndex2 ? current : { sourceIndex, targetIndex: targetIndex2 });
3230
- setRowDragGuide(bodyTop + rawTargetIndex * rowHeight - scrollRef.current.top + (edge2 === "bottom" ? rowHeight : 0));
3231
- return;
3232
- }
3233
- const targetIndex = Number(target?.targetIndex);
3234
- if (!Number.isInteger(targetIndex) || target?.headerKind !== source.data.headerKind || target?.parentKey !== source.data.parentKey || target?.fixed !== source.data.fixed) {
3235
- validColumnDropRef.current = null;
3236
- setColumnDropTarget(null);
3237
- setDragGuide(null);
3238
- return;
3239
- }
3240
- const edge = target?.columnEdge;
3241
- const destinationIndex = getColumnDropIndex(sourceIndex, targetIndex, edge);
3242
- columnDragPreviewRef.current = { sourceIndex, targetIndex: destinationIndex };
3243
- if (destinationIndex === sourceIndex) {
3244
- validColumnDropRef.current = null;
3245
- setColumnDropTarget(null);
3246
- setDragGuide(null);
3247
- return;
3248
- }
3249
- validColumnDropRef.current = {
3250
- sourceIndex,
3251
- targetIndex: destinationIndex,
3252
- rawTargetIndex: targetIndex,
3253
- targetKey: String(target.targetKey),
3254
- headerKind: source.data.headerKind === "group" ? "group" : "column",
3255
- parentKey: typeof source.data.parentKey === "string" ? source.data.parentKey : void 0,
3256
- fixed: source.data.fixed === "left" || source.data.fixed === "right" ? source.data.fixed : void 0,
3257
- columnEdge: edge === "right" ? "right" : "left"
3258
- };
3259
- 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);
3260
- const targetEndIndex = Number.isInteger(target?.targetEndIndex) ? Number(target.targetEndIndex) : targetIndex;
3261
- const hoveredTargetCell = siblingCells.find((cell) => cell.startIndex === targetIndex && cell.endIndex === targetEndIndex);
3262
- if (!hoveredTargetCell) {
3263
- validColumnDropRef.current = null;
3264
- setColumnDropTarget(null);
3265
- setDragGuide(null);
3266
- return;
3267
- }
3268
- const highlightedCell = edge === "right" ? hoveredTargetCell : siblingCells.filter((cell) => cell.endIndex < hoveredTargetCell.startIndex).sort((left, right) => right.endIndex - left.endIndex)[0] ?? hoveredTargetCell;
3269
- setColumnDropTarget({ startIndex: highlightedCell.startIndex, endIndex: highlightedCell.endIndex });
3270
- const targetLeft = Number(target?.targetLeft);
3271
- const targetWidth = Number(target?.targetWidth);
3272
- if (!Number.isFinite(targetLeft) || !Number.isFinite(targetWidth)) {
3273
- validColumnDropRef.current = null;
3274
- setColumnDropTarget(null);
3275
- setDragGuide(null);
3087
+ const rawTargetIndex = Number(target?.targetIndex);
3088
+ if (!Number.isInteger(rawTargetIndex)) {
3089
+ setRowDragPreview(null);
3090
+ setRowDragGuide(null);
3276
3091
  return;
3277
3092
  }
3278
- const guideTop = headerRowOffsets[Number(source.data.headerLevel)] ?? 0;
3279
- 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));
3280
3099
  },
3281
3100
  onDrop: ({ source, location }) => {
3282
- document.documentElement.classList.remove("rvg-is-dragging");
3283
3101
  const target = location.current.dropTargets[0]?.data;
3284
3102
  const sourceIndex = Number(source.data.sourceIndex);
3285
- if (source.data.type === "table-row") {
3286
- const rawTargetIndex = Number(target?.targetIndex);
3287
- let targetIndex = rawTargetIndex + (target?.rowEdge === "bottom" ? 1 : 0);
3288
- if (sourceIndex < targetIndex) targetIndex -= 1;
3289
- targetIndex = Math.max(0, Math.min(rows.length - 1, targetIndex));
3290
- scrollerRef.current?.classList.add("rvg-row-drop-settling");
3291
- setRowDragPreview(null);
3292
- setRowDragGuide(null);
3293
- canvas.style.cursor = "default";
3294
- if (Number.isInteger(rawTargetIndex) && sourceIndex !== targetIndex) applyRowOrder(sourceIndex, targetIndex);
3295
- requestAnimationFrame(() => {
3296
- requestAnimationFrame(() => scrollerRef.current?.classList.remove("rvg-row-drop-settling"));
3297
- });
3298
- window.setTimeout(() => {
3299
- suppressClickRef.current = false;
3300
- }, 0);
3301
- return;
3302
- }
3303
- 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");
3304
3111
  canvas.style.cursor = "default";
3305
- setDragGuide(null);
3306
- setColumnDropTarget(null);
3307
- columnDragPreviewRef.current = null;
3308
- validColumnDropRef.current = null;
3309
- if (validDrop) {
3310
- applyColumnOrder(
3311
- validDrop.sourceIndex - utilityColumnCount,
3312
- validDrop.targetIndex - utilityColumnCount,
3313
- {
3314
- type: validDrop.headerKind,
3315
- sourceKey: String(source.data.sourceKey),
3316
- targetKey: validDrop.targetKey,
3317
- parentKey: validDrop.parentKey,
3318
- placement: getColumnDropPlacement(validDrop.sourceIndex, validDrop.rawTargetIndex, validDrop.columnEdge)
3319
- }
3320
- );
3321
- }
3112
+ if (Number.isInteger(rawTargetIndex) && sourceIndex !== targetIndex) applyRowOrder(sourceIndex, targetIndex);
3113
+ requestAnimationFrame(() => {
3114
+ requestAnimationFrame(() => scrollerRef.current?.classList.remove("rvg-row-drop-settling"));
3115
+ });
3322
3116
  window.setTimeout(() => {
3323
3117
  suppressClickRef.current = false;
3324
3118
  }, 0);
@@ -3326,43 +3120,14 @@ function TableInner({
3326
3120
  });
3327
3121
  const cleanupDrop = (0, import_adapter.dropTargetForElements)({
3328
3122
  element: canvas,
3329
- canDrop: ({ source }) => source.data.type === "table-column" || source.data.type === "table-row",
3123
+ canDrop: ({ source }) => source.data.type === "table-row",
3330
3124
  getDropEffect: () => "move",
3331
- getData: ({ input, element, source }) => {
3332
- if (source.data.type === "table-row") {
3333
- const targetIndex2 = locateRow(input.clientY);
3334
- if (targetIndex2 < 0) return { targetIndex: -1 };
3335
- const rowTop = bodyTop + targetIndex2 * rowHeight - scrollRef.current.top;
3336
- const rowEdge = input.clientY - canvas.getBoundingClientRect().top < rowTop + rowHeight / 2 ? "top" : "bottom";
3337
- return (0, import_closest_edge.attachClosestEdge)({ targetIndex: targetIndex2, rowEdge }, { element, input, allowedEdges: ["top", "bottom"] });
3338
- }
3339
- const hoveredColumnIndex = locateColumn(input.clientX);
3340
- 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);
3341
- if (!targetCell) return { targetIndex: -1 };
3342
- let targetIndex = targetCell.startIndex;
3343
- const targetFixed = columns[targetCell.startIndex]?.fixed;
3344
- const headerKind = targetCell.leaf ? "column" : "group";
3345
- if (source.data.headerKind !== headerKind || source.data.parentKey !== targetCell.parentKey || source.data.fixed !== targetFixed) return { targetIndex: -1 };
3346
- if (columns[targetIndex].rowSelection || columns[targetIndex].rowDragHandle || columns[targetIndex].rowNumber) {
3347
- const fixedSide = columns[Number(source.data.sourceIndex)]?.fixed;
3348
- targetIndex = columns.findIndex((column, index) => index > targetIndex && column.fixed === fixedSide && !column.rowSelection && !column.rowDragHandle && !column.rowNumber);
3349
- if (targetIndex < 0) return { targetIndex: -1 };
3350
- return { targetIndex, columnEdge: "left" };
3351
- }
3352
- const left = getHeaderCellLeft(targetCell);
3353
- const targetWidth = targetCell.leaf ? metrics[targetIndex].width : getHeaderCellWidth(targetCell);
3354
- const columnEdge = input.clientX - canvas.getBoundingClientRect().left < left + targetWidth / 2 ? "left" : "right";
3355
- return (0, import_closest_edge.attachClosestEdge)({
3356
- targetIndex,
3357
- targetEndIndex: targetCell.endIndex,
3358
- targetKey: targetCell.key,
3359
- parentKey: targetCell.parentKey,
3360
- headerKind,
3361
- fixed: targetFixed,
3362
- targetLeft: left,
3363
- targetWidth,
3364
- columnEdge
3365
- }, { 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"] });
3366
3131
  }
3367
3132
  });
3368
3133
  return () => {
@@ -3370,7 +3135,7 @@ function TableInner({
3370
3135
  cleanupDrag();
3371
3136
  cleanupDrop();
3372
3137
  };
3373
- }, [applyColumnOrder, applyRowOrder, bodyTop, columnDraggable, columns, filterValues, fixedHeader, getCellLabel, getDisplayedColumnLeft, getHeaderCellWidth, getRowKey, headerActionSize, headerActionSlotWidth, headerCells, headerHeight, hideDragTooltips, locateColumn, locateHeaderCell, locateHeaderCellDragHandle, 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]);
3374
3139
  const locateCell = (0, import_react5.useCallback)((clientX, clientY) => {
3375
3140
  const canvas = canvasRef.current;
3376
3141
  if (!canvas) return null;
@@ -3817,6 +3582,113 @@ function TableInner({
3817
3582
  setResizeGuideX(null);
3818
3583
  setResizeGuideTop(0);
3819
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]);
3820
3692
  const queueSortStateChange = (0, import_react5.useCallback)((next) => {
3821
3693
  setSortState(next);
3822
3694
  }, []);
@@ -3826,7 +3698,7 @@ function TableInner({
3826
3698
  const isAxisSelected = selectedColumnKeySet.has(column.key);
3827
3699
  const selectedClassName = isAxisSelected ? " is-axis-selected" : "";
3828
3700
  const hoveredColumnClassName = hoveredHeaderColumnIndex === columnIndex ? " is-header-hovered" : "";
3829
- const top = headerLeafTop + (headerLeafHeight - headerActionSize) / 2;
3701
+ const top = column.renderHeader ? headerLeafTop + 8 + Math.max(0, (16 - headerActionSize) / 2) : headerLeafTop + (headerLeafHeight - headerActionSize) / 2;
3830
3702
  const visibleActions = getVisibleHeaderActions(column, metrics[columnIndex].width, columnDraggable, measureHeaderTitleWidth(columnIndex), headerActionSlotWidth);
3831
3703
  let right = left + metrics[columnIndex].width - (visibleActions.drag ? headerActionSlotWidth : 2);
3832
3704
  const icons = [];
@@ -4630,7 +4502,7 @@ function TableInner({
4630
4502
  hideDragTooltips();
4631
4503
  return;
4632
4504
  }
4633
- if (columnDragRef.current) return;
4505
+ if (columnDragRef.current || columnOrderDragRef.current?.active) return;
4634
4506
  const rect = event.currentTarget.getBoundingClientRect();
4635
4507
  const localY = event.clientY - rect.top;
4636
4508
  const headerY = fixedHeader ? 0 : -scrollRef.current.top;
@@ -4747,20 +4619,22 @@ function TableInner({
4747
4619
  event.currentTarget.style.cursor = "move";
4748
4620
  }
4749
4621
  handleColumnPointerDown(event);
4622
+ if (!columnDragRef.current) handleColumnOrderPointerDown(event);
4750
4623
  beginRangeDrag(event);
4751
4624
  },
4752
4625
  onPointerMove: (event) => {
4753
4626
  handleColumnPointerMove(event);
4627
+ handleColumnOrderPointerMove(event);
4754
4628
  updateRangeDrag(event);
4755
4629
  },
4756
4630
  onPointerUp: (event) => {
4757
- document.documentElement.classList.remove("rvg-is-dragging");
4758
4631
  handleColumnPointerUp(event);
4632
+ finishColumnOrderPointerDrag(event, true);
4759
4633
  endRangeDrag(event);
4760
4634
  },
4761
4635
  onPointerCancel: (event) => {
4762
- document.documentElement.classList.remove("rvg-is-dragging");
4763
4636
  handleColumnPointerUp(event);
4637
+ finishColumnOrderPointerDrag(event, false);
4764
4638
  endRangeDrag(event);
4765
4639
  },
4766
4640
  onClick: (event) => {