@lensui/lens-table 0.1.42 → 0.1.44

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
@@ -879,6 +879,7 @@ var COLORS = {
879
879
  selection: "#1677ff",
880
880
  selectionFill: "#edf4ff",
881
881
  axisSelectionFill: "#e8f2ff",
882
+ axisSelectionStripeFill: "#dfeeff",
882
883
  axisSelectionText: "#202124",
883
884
  rowHoverFill: "#f6f9fc",
884
885
  editedFill: "#fff1b8",
@@ -907,6 +908,7 @@ function paintGrid(options) {
907
908
  const headerLeafTop = options.headerLeafTop ?? 0;
908
909
  const headerLeafHeight = options.headerLeafHeight ?? headerHeight;
909
910
  const colors = { ...COLORS, ...options.colors };
911
+ const getAxisSelectionFill = (rowIndex, columnKey) => selectedColumnKeys.has(columnKey) && striped && rowIndex % 2 === 1 ? colors.axisSelectionStripeFill : colors.axisSelectionFill;
910
912
  const bodyTop = options.bodyTop ?? headerHeight;
911
913
  const getCellSpan = (rowIndex, columnIndex) => options.cellSpans.get(getCellCoordKey(rowIndex, columnIndex));
912
914
  const getCellWidth = (columnIndex, colSpan) => {
@@ -1017,7 +1019,7 @@ function paintGrid(options) {
1017
1019
  ctx.fillRect(x, y, cellWidth, cellHeight);
1018
1020
  }
1019
1021
  if (isAxisSelected) {
1020
- ctx.fillStyle = colors.axisSelectionFill;
1022
+ ctx.fillStyle = getAxisSelectionFill(rowIndex, column.key);
1021
1023
  ctx.fillRect(x, y, cellWidth, cellHeight);
1022
1024
  }
1023
1025
  if (hoveredRowIndex === rowIndex) {
@@ -1049,7 +1051,7 @@ function paintGrid(options) {
1049
1051
  ctx.fillRect(x, y, cellWidth, cellHeight);
1050
1052
  }
1051
1053
  if (isColumnDropTarget) {
1052
- ctx.fillStyle = isAxisSelected ? colors.axisSelectionFill : colors.columnDropTargetFill;
1054
+ ctx.fillStyle = isAxisSelected ? getAxisSelectionFill(rowIndex, column.key) : colors.columnDropTargetFill;
1053
1055
  ctx.fillRect(x, y, cellWidth, cellHeight);
1054
1056
  }
1055
1057
  ctx.fillStyle = colors.grid;
@@ -1061,14 +1063,14 @@ function paintGrid(options) {
1061
1063
  ctx.fillRect(x, y + cellHeight - 1, cellWidth, 1);
1062
1064
  }
1063
1065
  if (rowSpan > 1) {
1064
- const mergedFill = isColumnDropTarget ? isAxisSelected ? colors.axisSelectionFill : colors.columnDropTargetFill : annotation?.type === "background" ? annotation.color : isSelectedCell || isRangeCell ? colors.selectionFill : highlightEditedCells && !insertedRowKeys.has(rowKey) && editedCellKeys.has(`${typeof rowKey}:${String(rowKey)}\0${column.key}`) ? colors.editedFill : highlightInsertedRows && insertedRowKeys.has(rowKey) ? colors.insertedFill : hoveredRowIndex === rowIndex ? colors.rowHoverFill : isAxisSelected ? colors.axisSelectionFill : cellStyle?.backgroundColor ?? rowStyle?.backgroundColor ?? (striped && rowIndex % 2 === 1 ? colors.stripe : colors.background);
1066
+ const mergedFill = isColumnDropTarget ? isAxisSelected ? getAxisSelectionFill(rowIndex, column.key) : colors.columnDropTargetFill : annotation?.type === "background" ? annotation.color : isSelectedCell || isRangeCell ? colors.selectionFill : highlightEditedCells && !insertedRowKeys.has(rowKey) && editedCellKeys.has(`${typeof rowKey}:${String(rowKey)}\0${column.key}`) ? colors.editedFill : highlightInsertedRows && insertedRowKeys.has(rowKey) ? colors.insertedFill : hoveredRowIndex === rowIndex ? colors.rowHoverFill : isAxisSelected ? getAxisSelectionFill(rowIndex, column.key) : cellStyle?.backgroundColor ?? rowStyle?.backgroundColor ?? (striped && rowIndex % 2 === 1 ? colors.stripe : colors.background);
1065
1067
  ctx.fillStyle = mergedFill;
1066
1068
  for (let offset = 1; offset < rowSpan; offset += 1) {
1067
1069
  ctx.fillRect(x, y + offset * rowHeight - 1, cellWidth, 2);
1068
1070
  }
1069
1071
  }
1070
1072
  if (colSpan > 1 && !verticalBorderless) {
1071
- const mergedFill = isColumnDropTarget ? isAxisSelected ? colors.axisSelectionFill : colors.columnDropTargetFill : annotation?.type === "background" ? annotation.color : isSelectedCell || isRangeCell ? colors.selectionFill : highlightEditedCells && !insertedRowKeys.has(rowKey) && editedCellKeys.has(`${typeof rowKey}:${String(rowKey)}\0${column.key}`) ? colors.editedFill : highlightInsertedRows && insertedRowKeys.has(rowKey) ? colors.insertedFill : hoveredRowIndex === rowIndex ? colors.rowHoverFill : isAxisSelected ? colors.axisSelectionFill : cellStyle?.backgroundColor ?? rowStyle?.backgroundColor ?? (striped && rowIndex % 2 === 1 ? colors.stripe : colors.background);
1073
+ const mergedFill = isColumnDropTarget ? isAxisSelected ? getAxisSelectionFill(rowIndex, column.key) : colors.columnDropTargetFill : annotation?.type === "background" ? annotation.color : isSelectedCell || isRangeCell ? colors.selectionFill : highlightEditedCells && !insertedRowKeys.has(rowKey) && editedCellKeys.has(`${typeof rowKey}:${String(rowKey)}\0${column.key}`) ? colors.editedFill : highlightInsertedRows && insertedRowKeys.has(rowKey) ? colors.insertedFill : hoveredRowIndex === rowIndex ? colors.rowHoverFill : isAxisSelected ? getAxisSelectionFill(rowIndex, column.key) : cellStyle?.backgroundColor ?? rowStyle?.backgroundColor ?? (striped && rowIndex % 2 === 1 ? colors.stripe : colors.background);
1072
1074
  ctx.fillStyle = mergedFill;
1073
1075
  let offsetLeft = 0;
1074
1076
  for (let offset = 1; offset < colSpan; offset += 1) {
@@ -2347,6 +2349,7 @@ function TableInner({
2347
2349
  selection: readThemeColor(themeStyles, "--rvg-color-primary", "#1677ff"),
2348
2350
  selectionFill: readThemeColor(themeStyles, "--rvg-color-selection-fill", "#edf4ff"),
2349
2351
  axisSelectionFill: isSelectedColumnDrag || isSelectedColumnDropTarget ? readThemeColor(themeStyles, "--rvg-color-axis-selection-drag-fill", "#d8e8f8") : readThemeColor(themeStyles, "--rvg-color-axis-selection-fill", "#e8f2ff"),
2352
+ axisSelectionStripeFill: isSelectedColumnDrag || isSelectedColumnDropTarget ? readThemeColor(themeStyles, "--rvg-color-axis-selection-drag-fill", "#d8e8f8") : readThemeColor(themeStyles, "--rvg-color-axis-selection-stripe-fill", "#dfeeff"),
2350
2353
  axisSelectionText: isSelectedColumnDrag || isSelectedColumnDropTarget ? readThemeColor(themeStyles, "--rvg-color-axis-selection-drag-text", "#325b88") : readThemeColor(themeStyles, "--rvg-color-axis-selection-text", readThemeColor(themeStyles, "--rvg-color-text", "#202124")),
2351
2354
  rowHoverFill: readThemeColor(themeStyles, "--rvg-color-row-hover-fill", "#f6f9fc"),
2352
2355
  editedFill: editedCellHighlightColor ?? readThemeColor(themeStyles, "--rvg-color-edited-fill", "#fff1b8"),
@@ -2922,11 +2925,16 @@ function TableInner({
2922
2925
  setResizedColumnWidths((current) => current[columnKey] === width2 ? current : { ...current, [columnKey]: width2 });
2923
2926
  onColumnResize?.(columnKey, width2);
2924
2927
  }, [onColumnResize]);
2925
- const locateHeaderAction = (0, import_react5.useCallback)((clientX, columnIndex) => {
2928
+ const locateHeaderAction = (0, import_react5.useCallback)((clientX, clientY, columnIndex) => {
2926
2929
  if (columnIndex < 0 || !canvasRef.current) return null;
2927
2930
  const column = columns[columnIndex];
2928
2931
  if (column.rowSelection || column.rowDragHandle || column.rowNumber) return null;
2929
- const localX = clientX - canvasRef.current.getBoundingClientRect().left;
2932
+ const rect = canvasRef.current.getBoundingClientRect();
2933
+ const localX = clientX - rect.left;
2934
+ const localY = clientY - rect.top;
2935
+ const headerY = fixedHeader ? 0 : -scrollRef.current.top;
2936
+ const actionTop = headerY + headerLeafTop + (column.renderHeader ? 8 + Math.max(0, (16 - headerActionSize) / 2) : (headerLeafHeight - headerActionSize) / 2);
2937
+ if (localY < actionTop - 4 || localY > actionTop + headerActionSize + 4) return null;
2930
2938
  const columnRight = getDisplayedColumnLeft(columnIndex) + metrics[columnIndex].width;
2931
2939
  const visibleActions = getVisibleHeaderActions(column, metrics[columnIndex].width, columnDraggable, measureHeaderTitleWidth(columnIndex), headerActionSlotWidth);
2932
2940
  let right = columnRight - (visibleActions.drag ? headerActionSlotWidth : 2);
@@ -2936,7 +2944,7 @@ function TableInner({
2936
2944
  }
2937
2945
  if (visibleActions.filter && localX >= right - headerActionSlotWidth && localX < right) return "filter";
2938
2946
  return null;
2939
- }, [columnDraggable, columns, getDisplayedColumnLeft, headerActionSlotWidth, measureHeaderTitleWidth, metrics]);
2947
+ }, [columnDraggable, columns, fixedHeader, getDisplayedColumnLeft, headerActionSize, headerActionSlotWidth, headerLeafHeight, headerLeafTop, measureHeaderTitleWidth, metrics]);
2940
2948
  const isHeaderTitleTruncated = (0, import_react5.useCallback)((columnIndex) => {
2941
2949
  const canvas = canvasRef.current;
2942
2950
  if (columnIndex < 0 || !canvas) return false;
@@ -2947,15 +2955,20 @@ function TableInner({
2947
2955
  const actionWidth = (Number(visibleActions.drag) + Number(visibleActions.filter) + Number(visibleActions.sort)) * headerActionSlotWidth;
2948
2956
  return getHeaderTitleRequiredWidth(column, titleWidth) > Math.max(0, metric.width - actionWidth);
2949
2957
  }, [columnDraggable, columns, headerActionSlotWidth, measureHeaderTitleWidth, metrics]);
2950
- const locateHeaderDragHandle = (0, import_react5.useCallback)((clientX, columnIndex) => {
2958
+ const locateHeaderDragHandle = (0, import_react5.useCallback)((clientX, clientY, columnIndex) => {
2951
2959
  if (!columnDraggable || columnIndex < 0 || !canvasRef.current) return false;
2952
2960
  const column = columns[columnIndex];
2953
2961
  if (column.rowSelection || column.rowDragHandle || column.rowNumber) return false;
2954
2962
  if (!getVisibleHeaderActions(column, metrics[columnIndex].width, columnDraggable, measureHeaderTitleWidth(columnIndex), headerActionSlotWidth).drag) return false;
2955
- const localX = clientX - canvasRef.current.getBoundingClientRect().left;
2963
+ const rect = canvasRef.current.getBoundingClientRect();
2964
+ const localX = clientX - rect.left;
2965
+ const localY = clientY - rect.top;
2966
+ const headerY = fixedHeader ? 0 : -scrollRef.current.top;
2967
+ const actionTop = headerY + headerLeafTop + (column.renderHeader ? 8 + Math.max(0, (16 - headerActionSize) / 2) : (headerLeafHeight - headerActionSize) / 2);
2968
+ if (localY < actionTop - 4 || localY > actionTop + headerActionSize + 4) return false;
2956
2969
  const columnRight = getDisplayedColumnLeft(columnIndex) + metrics[columnIndex].width;
2957
2970
  return localX >= columnRight - headerActionSlotWidth && localX < columnRight - 2;
2958
- }, [columnDraggable, columns, getDisplayedColumnLeft, headerActionSlotWidth, measureHeaderTitleWidth, metrics]);
2971
+ }, [columnDraggable, columns, fixedHeader, getDisplayedColumnLeft, headerActionSize, headerActionSlotWidth, headerLeafHeight, headerLeafTop, measureHeaderTitleWidth, metrics]);
2959
2972
  const getHeaderCellLeft = (0, import_react5.useCallback)((cell) => {
2960
2973
  const startMetric = metrics[cell.startIndex];
2961
2974
  const fixedSide = columns[cell.startIndex]?.fixed;
@@ -3015,9 +3028,9 @@ function TableInner({
3015
3028
  return closest;
3016
3029
  }, [columnResizable, columns, fixedHeader, getHeaderCellLeft, getHeaderCellWidth, getHeaderLevelAtY, headerCells, headerHeight]);
3017
3030
  const locateHeaderResizeCell = (0, import_react5.useCallback)((clientX, clientY) => locateHeaderResizeHit(clientX, clientY)?.cell ?? null, [locateHeaderResizeHit]);
3018
- const locateHeaderCellDragHandle = (0, import_react5.useCallback)((clientX, cell) => {
3031
+ const locateHeaderCellDragHandle = (0, import_react5.useCallback)((clientX, clientY, cell) => {
3019
3032
  if (!columnDraggable || !canvasRef.current) return false;
3020
- if (cell.leaf) return locateHeaderDragHandle(clientX, cell.startIndex);
3033
+ if (cell.leaf) return locateHeaderDragHandle(clientX, clientY, cell.startIndex);
3021
3034
  const localX = clientX - canvasRef.current.getBoundingClientRect().left;
3022
3035
  const right = getHeaderCellLeft(cell) + getHeaderCellWidth(cell);
3023
3036
  return localX >= right - headerActionSlotWidth && localX < right - 2;
@@ -3652,9 +3665,11 @@ function TableInner({
3652
3665
  setColumnDragPreview({
3653
3666
  sourceIndex: sourceCell.startIndex,
3654
3667
  left: Math.max(4, Math.min(viewport.width - previewWidth - 4, clientX - rootRect.left - previewWidth / 2)),
3655
- width: previewWidth
3668
+ width: previewWidth,
3669
+ snapshot: canvas.toDataURL(),
3670
+ sourceLeft: getDisplayedColumnLeft(sourceCell.startIndex)
3656
3671
  });
3657
- }, [metrics, viewport.width]);
3672
+ }, [getDisplayedColumnLeft, metrics, viewport.width]);
3658
3673
  const activateColumnOrderPointerDrag = (0, import_react5.useCallback)((canvas, clientX) => {
3659
3674
  const drag = columnOrderDragRef.current;
3660
3675
  if (!drag || drag.active) return;
@@ -3673,7 +3688,7 @@ function TableInner({
3673
3688
  if (!columnDraggable || event.button !== 0 || columnDragRef.current) return;
3674
3689
  const sourceCell = locateHeaderCell(event.clientX, event.clientY);
3675
3690
  if (!sourceCell || locateHeaderResizeCell(event.clientX, event.clientY)) return;
3676
- if (sourceCell.leaf && locateHeaderAction(event.clientX, sourceCell.startIndex)) return;
3691
+ if (sourceCell.leaf && locateHeaderAction(event.clientX, event.clientY, sourceCell.startIndex)) return;
3677
3692
  const sourceColumn = columns[sourceCell.startIndex];
3678
3693
  if (!sourceColumn || sourceColumn.rowSelection || sourceColumn.rowDragHandle || sourceColumn.rowNumber) return;
3679
3694
  event.currentTarget.setPointerCapture(event.pointerId);
@@ -4648,8 +4663,8 @@ function TableInner({
4648
4663
  const nextHoveredHeaderColumnIndex = inLeafHeader && columnIndex >= 0 ? columnIndex : null;
4649
4664
  setHoveredHeaderColumnIndex((current) => current === nextHoveredHeaderColumnIndex ? current : nextHoveredHeaderColumnIndex);
4650
4665
  const hoveredHeaderCell = inHeader ? locateHeaderCell(event.clientX, event.clientY) : null;
4651
- const hoveredAction = inLeafHeader ? locateHeaderAction(event.clientX, columnIndex) : null;
4652
- const hoveredDragHandle = Boolean(hoveredHeaderCell && locateHeaderCellDragHandle(event.clientX, hoveredHeaderCell));
4666
+ const hoveredAction = inLeafHeader ? locateHeaderAction(event.clientX, event.clientY, columnIndex) : null;
4667
+ const hoveredDragHandle = Boolean(hoveredHeaderCell && locateHeaderCellDragHandle(event.clientX, event.clientY, hoveredHeaderCell));
4653
4668
  const hoveredDragColumnIndex = hoveredHeaderCell?.startIndex ?? columnIndex;
4654
4669
  const customHeaderTooltipMatch = inHeader && !hoveredAction && !hoveredDragHandle ? locateCustomHeaderTooltip(event.clientX, event.clientY, columnIndex) : null;
4655
4670
  const hoveredContentTooltip = customHeaderTooltipMatch || null;
@@ -4754,7 +4769,7 @@ function TableInner({
4754
4769
  const headerDragCell = columnDraggable ? locateHeaderCell(event.clientX, event.clientY) : null;
4755
4770
  const columnIndex = locateColumn(event.clientX);
4756
4771
  const rowDragHandle = rowDraggable && columnIndex >= 0 && Boolean(columns[columnIndex].rowDragHandle) && locateRow(event.clientY) >= 0;
4757
- if (headerDragCell && locateHeaderCellDragHandle(event.clientX, headerDragCell) || rowDragHandle) {
4772
+ if (headerDragCell && locateHeaderCellDragHandle(event.clientX, event.clientY, headerDragCell) || rowDragHandle) {
4758
4773
  hideDragTooltips();
4759
4774
  document.documentElement.classList.add("rvg-is-dragging");
4760
4775
  event.currentTarget.style.cursor = "move";
@@ -4789,7 +4804,7 @@ function TableInner({
4789
4804
  clickedCellRef.current = null;
4790
4805
  if (localY < headerY + headerLeafTop) return;
4791
4806
  const columnIndex = locateColumn(event.clientX);
4792
- const action = locateHeaderAction(event.clientX, columnIndex);
4807
+ const action = locateHeaderAction(event.clientX, event.clientY, columnIndex);
4793
4808
  if (action === "sort") {
4794
4809
  const columnKey = columns[columnIndex].key;
4795
4810
  const next = sortState?.columnKey !== columnKey ? { columnKey, direction: "asc" } : sortState.direction === "asc" ? { columnKey, direction: "desc" } : null;
@@ -4801,7 +4816,7 @@ function TableInner({
4801
4816
  setFilterEditor({ columnIndex, left, top: Math.max(0, headerY + headerHeight), draft: filterValues[columns[columnIndex].key] ?? "" });
4802
4817
  return;
4803
4818
  }
4804
- if (locateHeaderDragHandle(event.clientX, columnIndex)) return;
4819
+ if (locateHeaderDragHandle(event.clientX, event.clientY, columnIndex)) return;
4805
4820
  if (columnIndex >= 0 && columns[columnIndex].rowSelection && rowSelection) {
4806
4821
  if (columns[columnIndex].rowSelectionIndicator === "arrow" || columns[columnIndex].rowSelectionIndicator === "none") return;
4807
4822
  setSelectionRange(null);
@@ -5290,7 +5305,11 @@ function TableInner({
5290
5305
  left: columnDragPreview.left,
5291
5306
  top: 0,
5292
5307
  width: columnDragPreview.width,
5293
- height: renderHeight
5308
+ height: renderHeight,
5309
+ backgroundImage: `url(${columnDragPreview.snapshot})`,
5310
+ backgroundRepeat: "no-repeat",
5311
+ backgroundPosition: `-${columnDragPreview.sourceLeft}px 0`,
5312
+ backgroundSize: `${viewport.width}px ${renderHeight}px`
5294
5313
  },
5295
5314
  children: [
5296
5315
  /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
package/dist/index.css CHANGED
@@ -16,6 +16,7 @@
16
16
  --rvg-color-primary-soft: #edf4ff;
17
17
  --rvg-color-selection-fill: #edf4ff;
18
18
  --rvg-color-axis-selection-fill: #e8f2ff;
19
+ --rvg-color-axis-selection-stripe-fill: #dfeeff;
19
20
  --rvg-color-axis-selection-text: var(--rvg-color-text);
20
21
  --rvg-color-axis-selection-drag-fill: #d8e8f8;
21
22
  --rvg-color-axis-selection-drag-text: #325b88;
@@ -1552,6 +1553,9 @@
1552
1553
  .rvg-column-drag-preview-cell.is-striped {
1553
1554
  background: var(--rvg-color-stripe);
1554
1555
  }
1556
+ .rvg-column-drag-preview-cell {
1557
+ visibility: hidden;
1558
+ }
1555
1559
  .rvg-column-drag-preview.is-axis-selected {
1556
1560
  background: var(--rvg-color-axis-selection-fill);
1557
1561
  }
package/dist/index.js CHANGED
@@ -849,6 +849,7 @@ var COLORS = {
849
849
  selection: "#1677ff",
850
850
  selectionFill: "#edf4ff",
851
851
  axisSelectionFill: "#e8f2ff",
852
+ axisSelectionStripeFill: "#dfeeff",
852
853
  axisSelectionText: "#202124",
853
854
  rowHoverFill: "#f6f9fc",
854
855
  editedFill: "#fff1b8",
@@ -877,6 +878,7 @@ function paintGrid(options) {
877
878
  const headerLeafTop = options.headerLeafTop ?? 0;
878
879
  const headerLeafHeight = options.headerLeafHeight ?? headerHeight;
879
880
  const colors = { ...COLORS, ...options.colors };
881
+ const getAxisSelectionFill = (rowIndex, columnKey) => selectedColumnKeys.has(columnKey) && striped && rowIndex % 2 === 1 ? colors.axisSelectionStripeFill : colors.axisSelectionFill;
880
882
  const bodyTop = options.bodyTop ?? headerHeight;
881
883
  const getCellSpan = (rowIndex, columnIndex) => options.cellSpans.get(getCellCoordKey(rowIndex, columnIndex));
882
884
  const getCellWidth = (columnIndex, colSpan) => {
@@ -987,7 +989,7 @@ function paintGrid(options) {
987
989
  ctx.fillRect(x, y, cellWidth, cellHeight);
988
990
  }
989
991
  if (isAxisSelected) {
990
- ctx.fillStyle = colors.axisSelectionFill;
992
+ ctx.fillStyle = getAxisSelectionFill(rowIndex, column.key);
991
993
  ctx.fillRect(x, y, cellWidth, cellHeight);
992
994
  }
993
995
  if (hoveredRowIndex === rowIndex) {
@@ -1019,7 +1021,7 @@ function paintGrid(options) {
1019
1021
  ctx.fillRect(x, y, cellWidth, cellHeight);
1020
1022
  }
1021
1023
  if (isColumnDropTarget) {
1022
- ctx.fillStyle = isAxisSelected ? colors.axisSelectionFill : colors.columnDropTargetFill;
1024
+ ctx.fillStyle = isAxisSelected ? getAxisSelectionFill(rowIndex, column.key) : colors.columnDropTargetFill;
1023
1025
  ctx.fillRect(x, y, cellWidth, cellHeight);
1024
1026
  }
1025
1027
  ctx.fillStyle = colors.grid;
@@ -1031,14 +1033,14 @@ function paintGrid(options) {
1031
1033
  ctx.fillRect(x, y + cellHeight - 1, cellWidth, 1);
1032
1034
  }
1033
1035
  if (rowSpan > 1) {
1034
- const mergedFill = isColumnDropTarget ? isAxisSelected ? colors.axisSelectionFill : colors.columnDropTargetFill : annotation?.type === "background" ? annotation.color : isSelectedCell || isRangeCell ? colors.selectionFill : highlightEditedCells && !insertedRowKeys.has(rowKey) && editedCellKeys.has(`${typeof rowKey}:${String(rowKey)}\0${column.key}`) ? colors.editedFill : highlightInsertedRows && insertedRowKeys.has(rowKey) ? colors.insertedFill : hoveredRowIndex === rowIndex ? colors.rowHoverFill : isAxisSelected ? colors.axisSelectionFill : cellStyle?.backgroundColor ?? rowStyle?.backgroundColor ?? (striped && rowIndex % 2 === 1 ? colors.stripe : colors.background);
1036
+ const mergedFill = isColumnDropTarget ? isAxisSelected ? getAxisSelectionFill(rowIndex, column.key) : colors.columnDropTargetFill : annotation?.type === "background" ? annotation.color : isSelectedCell || isRangeCell ? colors.selectionFill : highlightEditedCells && !insertedRowKeys.has(rowKey) && editedCellKeys.has(`${typeof rowKey}:${String(rowKey)}\0${column.key}`) ? colors.editedFill : highlightInsertedRows && insertedRowKeys.has(rowKey) ? colors.insertedFill : hoveredRowIndex === rowIndex ? colors.rowHoverFill : isAxisSelected ? getAxisSelectionFill(rowIndex, column.key) : cellStyle?.backgroundColor ?? rowStyle?.backgroundColor ?? (striped && rowIndex % 2 === 1 ? colors.stripe : colors.background);
1035
1037
  ctx.fillStyle = mergedFill;
1036
1038
  for (let offset = 1; offset < rowSpan; offset += 1) {
1037
1039
  ctx.fillRect(x, y + offset * rowHeight - 1, cellWidth, 2);
1038
1040
  }
1039
1041
  }
1040
1042
  if (colSpan > 1 && !verticalBorderless) {
1041
- const mergedFill = isColumnDropTarget ? isAxisSelected ? colors.axisSelectionFill : colors.columnDropTargetFill : annotation?.type === "background" ? annotation.color : isSelectedCell || isRangeCell ? colors.selectionFill : highlightEditedCells && !insertedRowKeys.has(rowKey) && editedCellKeys.has(`${typeof rowKey}:${String(rowKey)}\0${column.key}`) ? colors.editedFill : highlightInsertedRows && insertedRowKeys.has(rowKey) ? colors.insertedFill : hoveredRowIndex === rowIndex ? colors.rowHoverFill : isAxisSelected ? colors.axisSelectionFill : cellStyle?.backgroundColor ?? rowStyle?.backgroundColor ?? (striped && rowIndex % 2 === 1 ? colors.stripe : colors.background);
1043
+ const mergedFill = isColumnDropTarget ? isAxisSelected ? getAxisSelectionFill(rowIndex, column.key) : colors.columnDropTargetFill : annotation?.type === "background" ? annotation.color : isSelectedCell || isRangeCell ? colors.selectionFill : highlightEditedCells && !insertedRowKeys.has(rowKey) && editedCellKeys.has(`${typeof rowKey}:${String(rowKey)}\0${column.key}`) ? colors.editedFill : highlightInsertedRows && insertedRowKeys.has(rowKey) ? colors.insertedFill : hoveredRowIndex === rowIndex ? colors.rowHoverFill : isAxisSelected ? getAxisSelectionFill(rowIndex, column.key) : cellStyle?.backgroundColor ?? rowStyle?.backgroundColor ?? (striped && rowIndex % 2 === 1 ? colors.stripe : colors.background);
1042
1044
  ctx.fillStyle = mergedFill;
1043
1045
  let offsetLeft = 0;
1044
1046
  for (let offset = 1; offset < colSpan; offset += 1) {
@@ -2317,6 +2319,7 @@ function TableInner({
2317
2319
  selection: readThemeColor(themeStyles, "--rvg-color-primary", "#1677ff"),
2318
2320
  selectionFill: readThemeColor(themeStyles, "--rvg-color-selection-fill", "#edf4ff"),
2319
2321
  axisSelectionFill: isSelectedColumnDrag || isSelectedColumnDropTarget ? readThemeColor(themeStyles, "--rvg-color-axis-selection-drag-fill", "#d8e8f8") : readThemeColor(themeStyles, "--rvg-color-axis-selection-fill", "#e8f2ff"),
2322
+ axisSelectionStripeFill: isSelectedColumnDrag || isSelectedColumnDropTarget ? readThemeColor(themeStyles, "--rvg-color-axis-selection-drag-fill", "#d8e8f8") : readThemeColor(themeStyles, "--rvg-color-axis-selection-stripe-fill", "#dfeeff"),
2320
2323
  axisSelectionText: isSelectedColumnDrag || isSelectedColumnDropTarget ? readThemeColor(themeStyles, "--rvg-color-axis-selection-drag-text", "#325b88") : readThemeColor(themeStyles, "--rvg-color-axis-selection-text", readThemeColor(themeStyles, "--rvg-color-text", "#202124")),
2321
2324
  rowHoverFill: readThemeColor(themeStyles, "--rvg-color-row-hover-fill", "#f6f9fc"),
2322
2325
  editedFill: editedCellHighlightColor ?? readThemeColor(themeStyles, "--rvg-color-edited-fill", "#fff1b8"),
@@ -2892,11 +2895,16 @@ function TableInner({
2892
2895
  setResizedColumnWidths((current) => current[columnKey] === width2 ? current : { ...current, [columnKey]: width2 });
2893
2896
  onColumnResize?.(columnKey, width2);
2894
2897
  }, [onColumnResize]);
2895
- const locateHeaderAction = useCallback2((clientX, columnIndex) => {
2898
+ const locateHeaderAction = useCallback2((clientX, clientY, columnIndex) => {
2896
2899
  if (columnIndex < 0 || !canvasRef.current) return null;
2897
2900
  const column = columns[columnIndex];
2898
2901
  if (column.rowSelection || column.rowDragHandle || column.rowNumber) return null;
2899
- const localX = clientX - canvasRef.current.getBoundingClientRect().left;
2902
+ const rect = canvasRef.current.getBoundingClientRect();
2903
+ const localX = clientX - rect.left;
2904
+ const localY = clientY - rect.top;
2905
+ const headerY = fixedHeader ? 0 : -scrollRef.current.top;
2906
+ const actionTop = headerY + headerLeafTop + (column.renderHeader ? 8 + Math.max(0, (16 - headerActionSize) / 2) : (headerLeafHeight - headerActionSize) / 2);
2907
+ if (localY < actionTop - 4 || localY > actionTop + headerActionSize + 4) return null;
2900
2908
  const columnRight = getDisplayedColumnLeft(columnIndex) + metrics[columnIndex].width;
2901
2909
  const visibleActions = getVisibleHeaderActions(column, metrics[columnIndex].width, columnDraggable, measureHeaderTitleWidth(columnIndex), headerActionSlotWidth);
2902
2910
  let right = columnRight - (visibleActions.drag ? headerActionSlotWidth : 2);
@@ -2906,7 +2914,7 @@ function TableInner({
2906
2914
  }
2907
2915
  if (visibleActions.filter && localX >= right - headerActionSlotWidth && localX < right) return "filter";
2908
2916
  return null;
2909
- }, [columnDraggable, columns, getDisplayedColumnLeft, headerActionSlotWidth, measureHeaderTitleWidth, metrics]);
2917
+ }, [columnDraggable, columns, fixedHeader, getDisplayedColumnLeft, headerActionSize, headerActionSlotWidth, headerLeafHeight, headerLeafTop, measureHeaderTitleWidth, metrics]);
2910
2918
  const isHeaderTitleTruncated = useCallback2((columnIndex) => {
2911
2919
  const canvas = canvasRef.current;
2912
2920
  if (columnIndex < 0 || !canvas) return false;
@@ -2917,15 +2925,20 @@ function TableInner({
2917
2925
  const actionWidth = (Number(visibleActions.drag) + Number(visibleActions.filter) + Number(visibleActions.sort)) * headerActionSlotWidth;
2918
2926
  return getHeaderTitleRequiredWidth(column, titleWidth) > Math.max(0, metric.width - actionWidth);
2919
2927
  }, [columnDraggable, columns, headerActionSlotWidth, measureHeaderTitleWidth, metrics]);
2920
- const locateHeaderDragHandle = useCallback2((clientX, columnIndex) => {
2928
+ const locateHeaderDragHandle = useCallback2((clientX, clientY, columnIndex) => {
2921
2929
  if (!columnDraggable || columnIndex < 0 || !canvasRef.current) return false;
2922
2930
  const column = columns[columnIndex];
2923
2931
  if (column.rowSelection || column.rowDragHandle || column.rowNumber) return false;
2924
2932
  if (!getVisibleHeaderActions(column, metrics[columnIndex].width, columnDraggable, measureHeaderTitleWidth(columnIndex), headerActionSlotWidth).drag) return false;
2925
- const localX = clientX - canvasRef.current.getBoundingClientRect().left;
2933
+ const rect = canvasRef.current.getBoundingClientRect();
2934
+ const localX = clientX - rect.left;
2935
+ const localY = clientY - rect.top;
2936
+ const headerY = fixedHeader ? 0 : -scrollRef.current.top;
2937
+ const actionTop = headerY + headerLeafTop + (column.renderHeader ? 8 + Math.max(0, (16 - headerActionSize) / 2) : (headerLeafHeight - headerActionSize) / 2);
2938
+ if (localY < actionTop - 4 || localY > actionTop + headerActionSize + 4) return false;
2926
2939
  const columnRight = getDisplayedColumnLeft(columnIndex) + metrics[columnIndex].width;
2927
2940
  return localX >= columnRight - headerActionSlotWidth && localX < columnRight - 2;
2928
- }, [columnDraggable, columns, getDisplayedColumnLeft, headerActionSlotWidth, measureHeaderTitleWidth, metrics]);
2941
+ }, [columnDraggable, columns, fixedHeader, getDisplayedColumnLeft, headerActionSize, headerActionSlotWidth, headerLeafHeight, headerLeafTop, measureHeaderTitleWidth, metrics]);
2929
2942
  const getHeaderCellLeft = useCallback2((cell) => {
2930
2943
  const startMetric = metrics[cell.startIndex];
2931
2944
  const fixedSide = columns[cell.startIndex]?.fixed;
@@ -2985,9 +2998,9 @@ function TableInner({
2985
2998
  return closest;
2986
2999
  }, [columnResizable, columns, fixedHeader, getHeaderCellLeft, getHeaderCellWidth, getHeaderLevelAtY, headerCells, headerHeight]);
2987
3000
  const locateHeaderResizeCell = useCallback2((clientX, clientY) => locateHeaderResizeHit(clientX, clientY)?.cell ?? null, [locateHeaderResizeHit]);
2988
- const locateHeaderCellDragHandle = useCallback2((clientX, cell) => {
3001
+ const locateHeaderCellDragHandle = useCallback2((clientX, clientY, cell) => {
2989
3002
  if (!columnDraggable || !canvasRef.current) return false;
2990
- if (cell.leaf) return locateHeaderDragHandle(clientX, cell.startIndex);
3003
+ if (cell.leaf) return locateHeaderDragHandle(clientX, clientY, cell.startIndex);
2991
3004
  const localX = clientX - canvasRef.current.getBoundingClientRect().left;
2992
3005
  const right = getHeaderCellLeft(cell) + getHeaderCellWidth(cell);
2993
3006
  return localX >= right - headerActionSlotWidth && localX < right - 2;
@@ -3622,9 +3635,11 @@ function TableInner({
3622
3635
  setColumnDragPreview({
3623
3636
  sourceIndex: sourceCell.startIndex,
3624
3637
  left: Math.max(4, Math.min(viewport.width - previewWidth - 4, clientX - rootRect.left - previewWidth / 2)),
3625
- width: previewWidth
3638
+ width: previewWidth,
3639
+ snapshot: canvas.toDataURL(),
3640
+ sourceLeft: getDisplayedColumnLeft(sourceCell.startIndex)
3626
3641
  });
3627
- }, [metrics, viewport.width]);
3642
+ }, [getDisplayedColumnLeft, metrics, viewport.width]);
3628
3643
  const activateColumnOrderPointerDrag = useCallback2((canvas, clientX) => {
3629
3644
  const drag = columnOrderDragRef.current;
3630
3645
  if (!drag || drag.active) return;
@@ -3643,7 +3658,7 @@ function TableInner({
3643
3658
  if (!columnDraggable || event.button !== 0 || columnDragRef.current) return;
3644
3659
  const sourceCell = locateHeaderCell(event.clientX, event.clientY);
3645
3660
  if (!sourceCell || locateHeaderResizeCell(event.clientX, event.clientY)) return;
3646
- if (sourceCell.leaf && locateHeaderAction(event.clientX, sourceCell.startIndex)) return;
3661
+ if (sourceCell.leaf && locateHeaderAction(event.clientX, event.clientY, sourceCell.startIndex)) return;
3647
3662
  const sourceColumn = columns[sourceCell.startIndex];
3648
3663
  if (!sourceColumn || sourceColumn.rowSelection || sourceColumn.rowDragHandle || sourceColumn.rowNumber) return;
3649
3664
  event.currentTarget.setPointerCapture(event.pointerId);
@@ -4618,8 +4633,8 @@ function TableInner({
4618
4633
  const nextHoveredHeaderColumnIndex = inLeafHeader && columnIndex >= 0 ? columnIndex : null;
4619
4634
  setHoveredHeaderColumnIndex((current) => current === nextHoveredHeaderColumnIndex ? current : nextHoveredHeaderColumnIndex);
4620
4635
  const hoveredHeaderCell = inHeader ? locateHeaderCell(event.clientX, event.clientY) : null;
4621
- const hoveredAction = inLeafHeader ? locateHeaderAction(event.clientX, columnIndex) : null;
4622
- const hoveredDragHandle = Boolean(hoveredHeaderCell && locateHeaderCellDragHandle(event.clientX, hoveredHeaderCell));
4636
+ const hoveredAction = inLeafHeader ? locateHeaderAction(event.clientX, event.clientY, columnIndex) : null;
4637
+ const hoveredDragHandle = Boolean(hoveredHeaderCell && locateHeaderCellDragHandle(event.clientX, event.clientY, hoveredHeaderCell));
4623
4638
  const hoveredDragColumnIndex = hoveredHeaderCell?.startIndex ?? columnIndex;
4624
4639
  const customHeaderTooltipMatch = inHeader && !hoveredAction && !hoveredDragHandle ? locateCustomHeaderTooltip(event.clientX, event.clientY, columnIndex) : null;
4625
4640
  const hoveredContentTooltip = customHeaderTooltipMatch || null;
@@ -4724,7 +4739,7 @@ function TableInner({
4724
4739
  const headerDragCell = columnDraggable ? locateHeaderCell(event.clientX, event.clientY) : null;
4725
4740
  const columnIndex = locateColumn(event.clientX);
4726
4741
  const rowDragHandle = rowDraggable && columnIndex >= 0 && Boolean(columns[columnIndex].rowDragHandle) && locateRow(event.clientY) >= 0;
4727
- if (headerDragCell && locateHeaderCellDragHandle(event.clientX, headerDragCell) || rowDragHandle) {
4742
+ if (headerDragCell && locateHeaderCellDragHandle(event.clientX, event.clientY, headerDragCell) || rowDragHandle) {
4728
4743
  hideDragTooltips();
4729
4744
  document.documentElement.classList.add("rvg-is-dragging");
4730
4745
  event.currentTarget.style.cursor = "move";
@@ -4759,7 +4774,7 @@ function TableInner({
4759
4774
  clickedCellRef.current = null;
4760
4775
  if (localY < headerY + headerLeafTop) return;
4761
4776
  const columnIndex = locateColumn(event.clientX);
4762
- const action = locateHeaderAction(event.clientX, columnIndex);
4777
+ const action = locateHeaderAction(event.clientX, event.clientY, columnIndex);
4763
4778
  if (action === "sort") {
4764
4779
  const columnKey = columns[columnIndex].key;
4765
4780
  const next = sortState?.columnKey !== columnKey ? { columnKey, direction: "asc" } : sortState.direction === "asc" ? { columnKey, direction: "desc" } : null;
@@ -4771,7 +4786,7 @@ function TableInner({
4771
4786
  setFilterEditor({ columnIndex, left, top: Math.max(0, headerY + headerHeight), draft: filterValues[columns[columnIndex].key] ?? "" });
4772
4787
  return;
4773
4788
  }
4774
- if (locateHeaderDragHandle(event.clientX, columnIndex)) return;
4789
+ if (locateHeaderDragHandle(event.clientX, event.clientY, columnIndex)) return;
4775
4790
  if (columnIndex >= 0 && columns[columnIndex].rowSelection && rowSelection) {
4776
4791
  if (columns[columnIndex].rowSelectionIndicator === "arrow" || columns[columnIndex].rowSelectionIndicator === "none") return;
4777
4792
  setSelectionRange(null);
@@ -5260,7 +5275,11 @@ function TableInner({
5260
5275
  left: columnDragPreview.left,
5261
5276
  top: 0,
5262
5277
  width: columnDragPreview.width,
5263
- height: renderHeight
5278
+ height: renderHeight,
5279
+ backgroundImage: `url(${columnDragPreview.snapshot})`,
5280
+ backgroundRepeat: "no-repeat",
5281
+ backgroundPosition: `-${columnDragPreview.sourceLeft}px 0`,
5282
+ backgroundSize: `${viewport.width}px ${renderHeight}px`
5264
5283
  },
5265
5284
  children: [
5266
5285
  /* @__PURE__ */ jsxs7(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lensui/lens-table",
3
- "version": "0.1.42",
3
+ "version": "0.1.44",
4
4
  "description": "A lightweight, canvas-rendered React table component for LensUI.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",