@lensui/lens-table 0.1.25 → 0.1.27

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
@@ -882,7 +882,7 @@ var COLORS = {
882
882
  rowHoverFill: "#f6f9fc",
883
883
  editedFill: "#fff1b8",
884
884
  insertedFill: "#c8ead4",
885
- columnDropTargetFill: "#eeeeee",
885
+ columnDropTargetFill: "#e2edf9",
886
886
  stripe: "#fafbfc"
887
887
  };
888
888
  function ellipsizeText(context, text, maxWidth) {
@@ -966,15 +966,17 @@ function paintGrid(options) {
966
966
  const row = rows[rowIndex];
967
967
  const rowKey = getRowKey(row, rowIndex);
968
968
  const trailingRowStyle = options.rowStyle?.(row, rowIndex);
969
- let fill = striped && rowIndex % 2 === 1 ? colors.stripe : null;
970
- if (trailingRowStyle?.backgroundColor) fill = trailingRowStyle.backgroundColor;
971
- if (selectedRowKeys.has(rowKey)) fill = colors.axisSelectionFill;
972
- if (hoveredRowIndex === rowIndex) fill = colors.rowHoverFill;
973
- if (highlightInsertedRows && insertedRowKeys.has(rowKey)) fill = colors.insertedFill;
974
- if (!fill) continue;
975
969
  const y = bodyTop + rowIndex * rowHeight - scrollTop + getRowDragOffset(rowIndex);
976
- ctx.fillStyle = fill;
977
- ctx.fillRect(trailingBlankStart, y, width - trailingBlankStart, rowHeight);
970
+ const paintTrailingLayer = (fill) => {
971
+ if (!fill) return;
972
+ ctx.fillStyle = fill;
973
+ ctx.fillRect(trailingBlankStart, y, width - trailingBlankStart, rowHeight);
974
+ };
975
+ if (striped && rowIndex % 2 === 1) paintTrailingLayer(colors.stripe);
976
+ paintTrailingLayer(trailingRowStyle?.backgroundColor);
977
+ if (selectedRowKeys.has(rowKey)) paintTrailingLayer(colors.axisSelectionFill);
978
+ if (hoveredRowIndex === rowIndex) paintTrailingLayer(colors.rowHoverFill);
979
+ if (highlightInsertedRows && insertedRowKeys.has(rowKey)) paintTrailingLayer(colors.insertedFill);
978
980
  }
979
981
  }
980
982
  const paintBodyColumns = (layer) => {
@@ -999,6 +1001,7 @@ function paintGrid(options) {
999
1001
  const cellWidth = getCellWidth(columnIndex, colSpan);
1000
1002
  const cellHeight = rowHeight * rowSpan;
1001
1003
  const isAxisSelected = selectedRowKeys.has(rowKey) || selectedColumnKeys.has(column.key);
1004
+ const isColumnDropTarget = Boolean(columnDropTarget && columnIndex >= columnDropTarget.startIndex && columnIndex <= columnDropTarget.endIndex);
1002
1005
  const rangeRowStart = selectionRange ? Math.min(selectionRange.anchor.rowIndex, selectionRange.focus.rowIndex) : -1;
1003
1006
  const rangeRowEnd = selectionRange ? Math.max(selectionRange.anchor.rowIndex, selectionRange.focus.rowIndex) : -1;
1004
1007
  const rangeColumnStart = selectionRange ? Math.min(selectionRange.anchor.columnIndex, selectionRange.focus.columnIndex) : -1;
@@ -1020,10 +1023,6 @@ function paintGrid(options) {
1020
1023
  ctx.fillStyle = colors.rowHoverFill;
1021
1024
  ctx.fillRect(x, y, cellWidth, cellHeight);
1022
1025
  }
1023
- if (columnDropTarget && columnIndex >= columnDropTarget.startIndex && columnIndex <= columnDropTarget.endIndex) {
1024
- ctx.fillStyle = colors.columnDropTargetFill;
1025
- ctx.fillRect(x, y, cellWidth, cellHeight);
1026
- }
1027
1026
  if (highlightInsertedRows && insertedRowKeys.has(rowKey)) {
1028
1027
  ctx.fillStyle = colors.insertedFill;
1029
1028
  ctx.fillRect(x, y, cellWidth, cellHeight);
@@ -1048,6 +1047,10 @@ function paintGrid(options) {
1048
1047
  ctx.fillStyle = annotation.color;
1049
1048
  ctx.fillRect(x, y, cellWidth, cellHeight);
1050
1049
  }
1050
+ if (isColumnDropTarget) {
1051
+ ctx.fillStyle = colors.columnDropTargetFill;
1052
+ ctx.fillRect(x, y, cellWidth, cellHeight);
1053
+ }
1051
1054
  ctx.fillStyle = colors.grid;
1052
1055
  if (!verticalBorderless && !(frameBorderless && columnIndex + colSpan >= columns.length)) {
1053
1056
  ctx.fillRect(x + cellWidth - 1, y, 1, cellHeight);
@@ -1057,14 +1060,14 @@ function paintGrid(options) {
1057
1060
  ctx.fillRect(x, y + cellHeight - 1, cellWidth, 1);
1058
1061
  }
1059
1062
  if (rowSpan > 1) {
1060
- const mergedFill = 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);
1063
+ const mergedFill = isColumnDropTarget ? 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);
1061
1064
  ctx.fillStyle = mergedFill;
1062
1065
  for (let offset = 1; offset < rowSpan; offset += 1) {
1063
1066
  ctx.fillRect(x, y + offset * rowHeight - 1, cellWidth, 2);
1064
1067
  }
1065
1068
  }
1066
1069
  if (colSpan > 1 && !verticalBorderless) {
1067
- const mergedFill = 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);
1070
+ const mergedFill = isColumnDropTarget ? 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);
1068
1071
  ctx.fillStyle = mergedFill;
1069
1072
  let offsetLeft = 0;
1070
1073
  for (let offset = 1; offset < colSpan; offset += 1) {
@@ -1161,7 +1164,7 @@ function paintGrid(options) {
1161
1164
  ctx.beginPath();
1162
1165
  ctx.rect(x + 2, y + 1, Math.max(0, cellWidth - 4), cellHeight - 2);
1163
1166
  ctx.clip();
1164
- ctx.fillStyle = isAxisSelected && !isSelectedCell && !isRangeCell ? colors.axisSelectionText : cellStyle?.color ?? rowStyle?.color ?? colors.text;
1167
+ ctx.fillStyle = isColumnDropTarget ? colors.text : isAxisSelected && !isSelectedCell && !isRangeCell ? colors.axisSelectionText : cellStyle?.color ?? rowStyle?.color ?? colors.text;
1165
1168
  ctx.font = createCellFont(bodyFontSize);
1166
1169
  ctx.textBaseline = "alphabetic";
1167
1170
  ctx.textAlign = column.align === "right" ? "right" : column.align === "center" ? "center" : "left";
@@ -1224,6 +1227,25 @@ function paintGrid(options) {
1224
1227
  paintExtendedColumnSelection("scroll");
1225
1228
  paintExtendedColumnSelection("left");
1226
1229
  paintExtendedColumnSelection("right");
1230
+ const paintExtendedColumnDropTarget = (layer) => {
1231
+ if (!columnDropTarget) return;
1232
+ ctx.save();
1233
+ if (layer === "scroll") {
1234
+ ctx.beginPath();
1235
+ ctx.rect(leftFixedWidth, extensionTop, Math.max(0, rightFixedLeft - leftFixedWidth), extensionHeight);
1236
+ ctx.clip();
1237
+ }
1238
+ ctx.fillStyle = colors.columnDropTargetFill;
1239
+ for (let columnIndex = columnDropTarget.startIndex; columnIndex <= columnDropTarget.endIndex; columnIndex += 1) {
1240
+ if (layer === "scroll" ? columns[columnIndex]?.fixed !== void 0 : columns[columnIndex]?.fixed !== layer) continue;
1241
+ if (layer === "scroll" && (columnIndex < range.columnStart || columnIndex >= range.columnEnd)) continue;
1242
+ ctx.fillRect(getColumnX(columnIndex), extensionTop, metrics[columnIndex].width, extensionHeight);
1243
+ }
1244
+ ctx.restore();
1245
+ };
1246
+ paintExtendedColumnDropTarget("scroll");
1247
+ paintExtendedColumnDropTarget("left");
1248
+ paintExtendedColumnDropTarget("right");
1227
1249
  if (!verticalBorderless) {
1228
1250
  paintExtendedColumnLines("scroll");
1229
1251
  paintExtendedColumnLines("left");
@@ -1245,11 +1267,12 @@ function paintGrid(options) {
1245
1267
  ctx.fillRect(x, headerY, metric.width, headerHeight);
1246
1268
  }
1247
1269
  const isAxisSelected = selectedColumnKeys.has(columns[columnIndex].key);
1270
+ const isColumnDropTarget = Boolean(columnDropTarget && columnIndex >= columnDropTarget.startIndex && columnIndex <= columnDropTarget.endIndex);
1248
1271
  if (isAxisSelected) {
1249
1272
  ctx.fillStyle = colors.axisSelectionFill;
1250
1273
  ctx.fillRect(x, headerY, metric.width, headerHeight);
1251
1274
  }
1252
- if (columnDropTarget && columnIndex >= columnDropTarget.startIndex && columnIndex <= columnDropTarget.endIndex) {
1275
+ if (isColumnDropTarget) {
1253
1276
  ctx.fillStyle = colors.columnDropTargetFill;
1254
1277
  ctx.fillRect(x, headerY, metric.width, headerHeight);
1255
1278
  }
@@ -1278,7 +1301,7 @@ function paintGrid(options) {
1278
1301
  ctx.beginPath();
1279
1302
  ctx.rect(x + 2, headerY + headerLeafTop + 1, Math.max(0, clipWidth - 4), headerLeafHeight - 2);
1280
1303
  ctx.clip();
1281
- ctx.fillStyle = isAxisSelected ? colors.axisSelectionText : colors.muted;
1304
+ ctx.fillStyle = isColumnDropTarget ? colors.muted : isAxisSelected ? colors.axisSelectionText : colors.muted;
1282
1305
  ctx.textAlign = titleAlign === "right" ? "right" : titleAlign === "center" ? "center" : "left";
1283
1306
  ctx.fillText(title, textX, headerY + headerLeafTop + headerLeafHeight / 2);
1284
1307
  ctx.restore();
@@ -1437,6 +1460,11 @@ function resolveColumnDropIndex(sourceIndex, targetIndex, edge, columnCount) {
1437
1460
  function resolveColumnDropPlacement(edge) {
1438
1461
  return edge === "right" ? "after" : "before";
1439
1462
  }
1463
+ function resolveColumnDropHighlightRange(target, edge, cells) {
1464
+ if (edge === "right") return { startIndex: target.startIndex, endIndex: target.endIndex };
1465
+ const previous = cells.find((cell) => cell.endIndex === target.startIndex - 1 && cell.level === target.level && cell.parentKey === target.parentKey);
1466
+ return previous ? { startIndex: previous.startIndex, endIndex: previous.endIndex } : { startIndex: target.startIndex, endIndex: target.endIndex };
1467
+ }
1440
1468
  var ANNOTATION_COLORS = ["#f44336", "#ff7a45", "#f5a623", "#f2c94c", "#52c41a", "#13a8a8", "#1677ff", "#597ef7", "#9254de", "#eb2f96"];
1441
1469
  var FALLBACK_HEIGHT = 480;
1442
1470
  var EMPTY_BODY_HEIGHT = 240;
@@ -2316,7 +2344,7 @@ function TableInner({
2316
2344
  rowHoverFill: readThemeColor(themeStyles, "--rvg-color-row-hover-fill", "#f6f9fc"),
2317
2345
  editedFill: editedCellHighlightColor ?? readThemeColor(themeStyles, "--rvg-color-edited-fill", "#fff1b8"),
2318
2346
  insertedFill: insertedRowHighlightColor ?? readThemeColor(themeStyles, "--rvg-color-inserted-fill", "#c8ead4"),
2319
- columnDropTargetFill: readThemeColor(themeStyles, "--rvg-color-column-drop-target-fill", "#eeeeee"),
2347
+ columnDropTargetFill: readThemeColor(themeStyles, "--rvg-color-column-drop-target-fill", "#e2edf9"),
2320
2348
  stripe: stripedColor ?? readThemeColor(themeStyles, "--rvg-color-stripe", "#fafbfc")
2321
2349
  };
2322
2350
  const scroll = scrollRef.current;
@@ -3677,7 +3705,11 @@ function TableInner({
3677
3705
  fixed: targetColumn.fixed,
3678
3706
  columnEdge
3679
3707
  };
3680
- setColumnDropTarget({ startIndex: targetCell.startIndex, endIndex: targetCell.endIndex });
3708
+ const compatibleHighlightCells = headerCells.filter((cell) => {
3709
+ const cellColumn = columns[cell.startIndex];
3710
+ return cellColumn && !cellColumn.rowSelection && !cellColumn.rowDragHandle && !cellColumn.rowNumber && cellColumn.fixed === targetColumn.fixed;
3711
+ });
3712
+ setColumnDropTarget(resolveColumnDropHighlightRange(targetCell, columnEdge, compatibleHighlightCells));
3681
3713
  setDragGuide(columnEdge === "right" ? targetLeft + targetWidth : targetLeft, headerRowOffsets[sourceCell.level] ?? 0);
3682
3714
  }, [columns, getHeaderCellLeft, getHeaderCellWidth, headerCells, headerRowOffsets, hideDragTooltips, locateColumn, locateHeaderCell, setDragGuide]);
3683
3715
  const finishColumnOrderPointerDrag = (0, import_react5.useCallback)((event, apply) => {
@@ -3832,7 +3864,11 @@ function TableInner({
3832
3864
  const rect = target.getBoundingClientRect();
3833
3865
  if (clientX < rect.left || clientX > rect.right || clientY < rect.top || clientY > rect.bottom) continue;
3834
3866
  const label = target.dataset.rvgTooltip?.trim();
3835
- if (!label) return null;
3867
+ if (!label) return false;
3868
+ const visibleText = target.textContent?.replace(/\s+/g, " ").trim() ?? "";
3869
+ const candidates = [target, ...target.querySelectorAll("*")];
3870
+ const truncated = candidates.some((candidate) => candidate.scrollWidth > candidate.clientWidth + 1 || candidate.scrollHeight > candidate.clientHeight + 1);
3871
+ if (!truncated && label.replace(/\s+/g, " ").trim() === visibleText) return false;
3836
3872
  const rawLeft = rect.left - canvasRect.left;
3837
3873
  return {
3838
3874
  key: `content:${columnIndex}:${label}:${Math.round(rawLeft)}:${Math.round(rect.top - canvasRect.top)}`,
@@ -4190,6 +4226,7 @@ function TableInner({
4190
4226
  children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4191
4227
  "span",
4192
4228
  {
4229
+ style: { width: "100%" },
4193
4230
  ref: (node) => {
4194
4231
  if (node) {
4195
4232
  customHeaderContentRefs.current.set(column.key, node);
@@ -4556,8 +4593,10 @@ function TableInner({
4556
4593
  const hoveredAction = inLeafHeader ? locateHeaderAction(event.clientX, columnIndex) : null;
4557
4594
  const hoveredDragHandle = Boolean(hoveredHeaderCell && locateHeaderCellDragHandle(event.clientX, hoveredHeaderCell));
4558
4595
  const hoveredDragColumnIndex = hoveredHeaderCell?.startIndex ?? columnIndex;
4559
- const hoveredContentTooltip = inHeader && !hoveredAction && !hoveredDragHandle ? locateCustomHeaderTooltip(event.clientX, event.clientY, columnIndex) : null;
4560
- const hoveredTitle = inHeader && !hoveredAction && !hoveredDragHandle && !hoveredContentTooltip && hoveredHeaderCell && Boolean(hoveredHeaderCell.column.title) && isPointerOnHeaderTitle(event.clientX, event.clientY, hoveredHeaderCell) && (tooltipConfig.header || hoveredHeaderCell.leaf && isHeaderTitleTruncated(hoveredHeaderCell.startIndex));
4596
+ const customHeaderTooltipMatch = inHeader && !hoveredAction && !hoveredDragHandle ? locateCustomHeaderTooltip(event.clientX, event.clientY, columnIndex) : null;
4597
+ const hoveredContentTooltip = customHeaderTooltipMatch || null;
4598
+ const hoveredCustomContent = customHeaderTooltipMatch !== null;
4599
+ const hoveredTitle = inHeader && !hoveredAction && !hoveredDragHandle && !hoveredCustomContent && hoveredHeaderCell && Boolean(hoveredHeaderCell.column.title) && isPointerOnHeaderTitle(event.clientX, event.clientY, hoveredHeaderCell) && (tooltipConfig.header || hoveredHeaderCell.leaf && isHeaderTitleTruncated(hoveredHeaderCell.startIndex));
4561
4600
  const nextHover = hoveredAction ? { columnIndex, action: hoveredAction } : hoveredDragHandle ? { columnIndex: hoveredDragColumnIndex, action: "drag" } : hoveredContentTooltip ? { columnIndex, action: "content" } : hoveredTitle ? { columnIndex: hoveredHeaderCell.startIndex, action: "title" } : null;
4562
4601
  const nextTooltip = hoveredAction && hoveredHeaderCell ? createHeaderTooltip(hoveredAction, columnIndex, hoveredHeaderCell) : hoveredDragHandle && hoveredHeaderCell ? createHeaderTooltip("drag", hoveredDragColumnIndex, hoveredHeaderCell) : hoveredContentTooltip ? hoveredContentTooltip : hoveredTitle && hoveredHeaderCell ? createHeaderTooltip("title", hoveredHeaderCell.startIndex, hoveredHeaderCell) : null;
4563
4602
  const previousHover = hoveredHeaderActionRef.current;
package/dist/index.css CHANGED
@@ -17,7 +17,7 @@
17
17
  --rvg-color-selection-fill: #edf4ff;
18
18
  --rvg-color-axis-selection-fill: #e8f2ff;
19
19
  --rvg-color-axis-selection-text: var(--rvg-color-text);
20
- --rvg-color-column-drop-target-fill: #eeeeee;
20
+ --rvg-color-column-drop-target-fill: #e2edf9;
21
21
  --rvg-color-range-fill: #e8f1ff;
22
22
  --rvg-color-row-hover-fill: #f6f9fc;
23
23
  --rvg-color-hover: #f1f4f8;
package/dist/index.js CHANGED
@@ -852,7 +852,7 @@ var COLORS = {
852
852
  rowHoverFill: "#f6f9fc",
853
853
  editedFill: "#fff1b8",
854
854
  insertedFill: "#c8ead4",
855
- columnDropTargetFill: "#eeeeee",
855
+ columnDropTargetFill: "#e2edf9",
856
856
  stripe: "#fafbfc"
857
857
  };
858
858
  function ellipsizeText(context, text, maxWidth) {
@@ -936,15 +936,17 @@ function paintGrid(options) {
936
936
  const row = rows[rowIndex];
937
937
  const rowKey = getRowKey(row, rowIndex);
938
938
  const trailingRowStyle = options.rowStyle?.(row, rowIndex);
939
- let fill = striped && rowIndex % 2 === 1 ? colors.stripe : null;
940
- if (trailingRowStyle?.backgroundColor) fill = trailingRowStyle.backgroundColor;
941
- if (selectedRowKeys.has(rowKey)) fill = colors.axisSelectionFill;
942
- if (hoveredRowIndex === rowIndex) fill = colors.rowHoverFill;
943
- if (highlightInsertedRows && insertedRowKeys.has(rowKey)) fill = colors.insertedFill;
944
- if (!fill) continue;
945
939
  const y = bodyTop + rowIndex * rowHeight - scrollTop + getRowDragOffset(rowIndex);
946
- ctx.fillStyle = fill;
947
- ctx.fillRect(trailingBlankStart, y, width - trailingBlankStart, rowHeight);
940
+ const paintTrailingLayer = (fill) => {
941
+ if (!fill) return;
942
+ ctx.fillStyle = fill;
943
+ ctx.fillRect(trailingBlankStart, y, width - trailingBlankStart, rowHeight);
944
+ };
945
+ if (striped && rowIndex % 2 === 1) paintTrailingLayer(colors.stripe);
946
+ paintTrailingLayer(trailingRowStyle?.backgroundColor);
947
+ if (selectedRowKeys.has(rowKey)) paintTrailingLayer(colors.axisSelectionFill);
948
+ if (hoveredRowIndex === rowIndex) paintTrailingLayer(colors.rowHoverFill);
949
+ if (highlightInsertedRows && insertedRowKeys.has(rowKey)) paintTrailingLayer(colors.insertedFill);
948
950
  }
949
951
  }
950
952
  const paintBodyColumns = (layer) => {
@@ -969,6 +971,7 @@ function paintGrid(options) {
969
971
  const cellWidth = getCellWidth(columnIndex, colSpan);
970
972
  const cellHeight = rowHeight * rowSpan;
971
973
  const isAxisSelected = selectedRowKeys.has(rowKey) || selectedColumnKeys.has(column.key);
974
+ const isColumnDropTarget = Boolean(columnDropTarget && columnIndex >= columnDropTarget.startIndex && columnIndex <= columnDropTarget.endIndex);
972
975
  const rangeRowStart = selectionRange ? Math.min(selectionRange.anchor.rowIndex, selectionRange.focus.rowIndex) : -1;
973
976
  const rangeRowEnd = selectionRange ? Math.max(selectionRange.anchor.rowIndex, selectionRange.focus.rowIndex) : -1;
974
977
  const rangeColumnStart = selectionRange ? Math.min(selectionRange.anchor.columnIndex, selectionRange.focus.columnIndex) : -1;
@@ -990,10 +993,6 @@ function paintGrid(options) {
990
993
  ctx.fillStyle = colors.rowHoverFill;
991
994
  ctx.fillRect(x, y, cellWidth, cellHeight);
992
995
  }
993
- if (columnDropTarget && columnIndex >= columnDropTarget.startIndex && columnIndex <= columnDropTarget.endIndex) {
994
- ctx.fillStyle = colors.columnDropTargetFill;
995
- ctx.fillRect(x, y, cellWidth, cellHeight);
996
- }
997
996
  if (highlightInsertedRows && insertedRowKeys.has(rowKey)) {
998
997
  ctx.fillStyle = colors.insertedFill;
999
998
  ctx.fillRect(x, y, cellWidth, cellHeight);
@@ -1018,6 +1017,10 @@ function paintGrid(options) {
1018
1017
  ctx.fillStyle = annotation.color;
1019
1018
  ctx.fillRect(x, y, cellWidth, cellHeight);
1020
1019
  }
1020
+ if (isColumnDropTarget) {
1021
+ ctx.fillStyle = colors.columnDropTargetFill;
1022
+ ctx.fillRect(x, y, cellWidth, cellHeight);
1023
+ }
1021
1024
  ctx.fillStyle = colors.grid;
1022
1025
  if (!verticalBorderless && !(frameBorderless && columnIndex + colSpan >= columns.length)) {
1023
1026
  ctx.fillRect(x + cellWidth - 1, y, 1, cellHeight);
@@ -1027,14 +1030,14 @@ function paintGrid(options) {
1027
1030
  ctx.fillRect(x, y + cellHeight - 1, cellWidth, 1);
1028
1031
  }
1029
1032
  if (rowSpan > 1) {
1030
- const mergedFill = 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);
1033
+ const mergedFill = isColumnDropTarget ? 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);
1031
1034
  ctx.fillStyle = mergedFill;
1032
1035
  for (let offset = 1; offset < rowSpan; offset += 1) {
1033
1036
  ctx.fillRect(x, y + offset * rowHeight - 1, cellWidth, 2);
1034
1037
  }
1035
1038
  }
1036
1039
  if (colSpan > 1 && !verticalBorderless) {
1037
- const mergedFill = 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);
1040
+ const mergedFill = isColumnDropTarget ? 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);
1038
1041
  ctx.fillStyle = mergedFill;
1039
1042
  let offsetLeft = 0;
1040
1043
  for (let offset = 1; offset < colSpan; offset += 1) {
@@ -1131,7 +1134,7 @@ function paintGrid(options) {
1131
1134
  ctx.beginPath();
1132
1135
  ctx.rect(x + 2, y + 1, Math.max(0, cellWidth - 4), cellHeight - 2);
1133
1136
  ctx.clip();
1134
- ctx.fillStyle = isAxisSelected && !isSelectedCell && !isRangeCell ? colors.axisSelectionText : cellStyle?.color ?? rowStyle?.color ?? colors.text;
1137
+ ctx.fillStyle = isColumnDropTarget ? colors.text : isAxisSelected && !isSelectedCell && !isRangeCell ? colors.axisSelectionText : cellStyle?.color ?? rowStyle?.color ?? colors.text;
1135
1138
  ctx.font = createCellFont(bodyFontSize);
1136
1139
  ctx.textBaseline = "alphabetic";
1137
1140
  ctx.textAlign = column.align === "right" ? "right" : column.align === "center" ? "center" : "left";
@@ -1194,6 +1197,25 @@ function paintGrid(options) {
1194
1197
  paintExtendedColumnSelection("scroll");
1195
1198
  paintExtendedColumnSelection("left");
1196
1199
  paintExtendedColumnSelection("right");
1200
+ const paintExtendedColumnDropTarget = (layer) => {
1201
+ if (!columnDropTarget) return;
1202
+ ctx.save();
1203
+ if (layer === "scroll") {
1204
+ ctx.beginPath();
1205
+ ctx.rect(leftFixedWidth, extensionTop, Math.max(0, rightFixedLeft - leftFixedWidth), extensionHeight);
1206
+ ctx.clip();
1207
+ }
1208
+ ctx.fillStyle = colors.columnDropTargetFill;
1209
+ for (let columnIndex = columnDropTarget.startIndex; columnIndex <= columnDropTarget.endIndex; columnIndex += 1) {
1210
+ if (layer === "scroll" ? columns[columnIndex]?.fixed !== void 0 : columns[columnIndex]?.fixed !== layer) continue;
1211
+ if (layer === "scroll" && (columnIndex < range.columnStart || columnIndex >= range.columnEnd)) continue;
1212
+ ctx.fillRect(getColumnX(columnIndex), extensionTop, metrics[columnIndex].width, extensionHeight);
1213
+ }
1214
+ ctx.restore();
1215
+ };
1216
+ paintExtendedColumnDropTarget("scroll");
1217
+ paintExtendedColumnDropTarget("left");
1218
+ paintExtendedColumnDropTarget("right");
1197
1219
  if (!verticalBorderless) {
1198
1220
  paintExtendedColumnLines("scroll");
1199
1221
  paintExtendedColumnLines("left");
@@ -1215,11 +1237,12 @@ function paintGrid(options) {
1215
1237
  ctx.fillRect(x, headerY, metric.width, headerHeight);
1216
1238
  }
1217
1239
  const isAxisSelected = selectedColumnKeys.has(columns[columnIndex].key);
1240
+ const isColumnDropTarget = Boolean(columnDropTarget && columnIndex >= columnDropTarget.startIndex && columnIndex <= columnDropTarget.endIndex);
1218
1241
  if (isAxisSelected) {
1219
1242
  ctx.fillStyle = colors.axisSelectionFill;
1220
1243
  ctx.fillRect(x, headerY, metric.width, headerHeight);
1221
1244
  }
1222
- if (columnDropTarget && columnIndex >= columnDropTarget.startIndex && columnIndex <= columnDropTarget.endIndex) {
1245
+ if (isColumnDropTarget) {
1223
1246
  ctx.fillStyle = colors.columnDropTargetFill;
1224
1247
  ctx.fillRect(x, headerY, metric.width, headerHeight);
1225
1248
  }
@@ -1248,7 +1271,7 @@ function paintGrid(options) {
1248
1271
  ctx.beginPath();
1249
1272
  ctx.rect(x + 2, headerY + headerLeafTop + 1, Math.max(0, clipWidth - 4), headerLeafHeight - 2);
1250
1273
  ctx.clip();
1251
- ctx.fillStyle = isAxisSelected ? colors.axisSelectionText : colors.muted;
1274
+ ctx.fillStyle = isColumnDropTarget ? colors.muted : isAxisSelected ? colors.axisSelectionText : colors.muted;
1252
1275
  ctx.textAlign = titleAlign === "right" ? "right" : titleAlign === "center" ? "center" : "left";
1253
1276
  ctx.fillText(title, textX, headerY + headerLeafTop + headerLeafHeight / 2);
1254
1277
  ctx.restore();
@@ -1407,6 +1430,11 @@ function resolveColumnDropIndex(sourceIndex, targetIndex, edge, columnCount) {
1407
1430
  function resolveColumnDropPlacement(edge) {
1408
1431
  return edge === "right" ? "after" : "before";
1409
1432
  }
1433
+ function resolveColumnDropHighlightRange(target, edge, cells) {
1434
+ if (edge === "right") return { startIndex: target.startIndex, endIndex: target.endIndex };
1435
+ const previous = cells.find((cell) => cell.endIndex === target.startIndex - 1 && cell.level === target.level && cell.parentKey === target.parentKey);
1436
+ return previous ? { startIndex: previous.startIndex, endIndex: previous.endIndex } : { startIndex: target.startIndex, endIndex: target.endIndex };
1437
+ }
1410
1438
  var ANNOTATION_COLORS = ["#f44336", "#ff7a45", "#f5a623", "#f2c94c", "#52c41a", "#13a8a8", "#1677ff", "#597ef7", "#9254de", "#eb2f96"];
1411
1439
  var FALLBACK_HEIGHT = 480;
1412
1440
  var EMPTY_BODY_HEIGHT = 240;
@@ -2286,7 +2314,7 @@ function TableInner({
2286
2314
  rowHoverFill: readThemeColor(themeStyles, "--rvg-color-row-hover-fill", "#f6f9fc"),
2287
2315
  editedFill: editedCellHighlightColor ?? readThemeColor(themeStyles, "--rvg-color-edited-fill", "#fff1b8"),
2288
2316
  insertedFill: insertedRowHighlightColor ?? readThemeColor(themeStyles, "--rvg-color-inserted-fill", "#c8ead4"),
2289
- columnDropTargetFill: readThemeColor(themeStyles, "--rvg-color-column-drop-target-fill", "#eeeeee"),
2317
+ columnDropTargetFill: readThemeColor(themeStyles, "--rvg-color-column-drop-target-fill", "#e2edf9"),
2290
2318
  stripe: stripedColor ?? readThemeColor(themeStyles, "--rvg-color-stripe", "#fafbfc")
2291
2319
  };
2292
2320
  const scroll = scrollRef.current;
@@ -3647,7 +3675,11 @@ function TableInner({
3647
3675
  fixed: targetColumn.fixed,
3648
3676
  columnEdge
3649
3677
  };
3650
- setColumnDropTarget({ startIndex: targetCell.startIndex, endIndex: targetCell.endIndex });
3678
+ const compatibleHighlightCells = headerCells.filter((cell) => {
3679
+ const cellColumn = columns[cell.startIndex];
3680
+ return cellColumn && !cellColumn.rowSelection && !cellColumn.rowDragHandle && !cellColumn.rowNumber && cellColumn.fixed === targetColumn.fixed;
3681
+ });
3682
+ setColumnDropTarget(resolveColumnDropHighlightRange(targetCell, columnEdge, compatibleHighlightCells));
3651
3683
  setDragGuide(columnEdge === "right" ? targetLeft + targetWidth : targetLeft, headerRowOffsets[sourceCell.level] ?? 0);
3652
3684
  }, [columns, getHeaderCellLeft, getHeaderCellWidth, headerCells, headerRowOffsets, hideDragTooltips, locateColumn, locateHeaderCell, setDragGuide]);
3653
3685
  const finishColumnOrderPointerDrag = useCallback2((event, apply) => {
@@ -3802,7 +3834,11 @@ function TableInner({
3802
3834
  const rect = target.getBoundingClientRect();
3803
3835
  if (clientX < rect.left || clientX > rect.right || clientY < rect.top || clientY > rect.bottom) continue;
3804
3836
  const label = target.dataset.rvgTooltip?.trim();
3805
- if (!label) return null;
3837
+ if (!label) return false;
3838
+ const visibleText = target.textContent?.replace(/\s+/g, " ").trim() ?? "";
3839
+ const candidates = [target, ...target.querySelectorAll("*")];
3840
+ const truncated = candidates.some((candidate) => candidate.scrollWidth > candidate.clientWidth + 1 || candidate.scrollHeight > candidate.clientHeight + 1);
3841
+ if (!truncated && label.replace(/\s+/g, " ").trim() === visibleText) return false;
3806
3842
  const rawLeft = rect.left - canvasRect.left;
3807
3843
  return {
3808
3844
  key: `content:${columnIndex}:${label}:${Math.round(rawLeft)}:${Math.round(rect.top - canvasRect.top)}`,
@@ -4160,6 +4196,7 @@ function TableInner({
4160
4196
  children: /* @__PURE__ */ jsx7(
4161
4197
  "span",
4162
4198
  {
4199
+ style: { width: "100%" },
4163
4200
  ref: (node) => {
4164
4201
  if (node) {
4165
4202
  customHeaderContentRefs.current.set(column.key, node);
@@ -4526,8 +4563,10 @@ function TableInner({
4526
4563
  const hoveredAction = inLeafHeader ? locateHeaderAction(event.clientX, columnIndex) : null;
4527
4564
  const hoveredDragHandle = Boolean(hoveredHeaderCell && locateHeaderCellDragHandle(event.clientX, hoveredHeaderCell));
4528
4565
  const hoveredDragColumnIndex = hoveredHeaderCell?.startIndex ?? columnIndex;
4529
- const hoveredContentTooltip = inHeader && !hoveredAction && !hoveredDragHandle ? locateCustomHeaderTooltip(event.clientX, event.clientY, columnIndex) : null;
4530
- const hoveredTitle = inHeader && !hoveredAction && !hoveredDragHandle && !hoveredContentTooltip && hoveredHeaderCell && Boolean(hoveredHeaderCell.column.title) && isPointerOnHeaderTitle(event.clientX, event.clientY, hoveredHeaderCell) && (tooltipConfig.header || hoveredHeaderCell.leaf && isHeaderTitleTruncated(hoveredHeaderCell.startIndex));
4566
+ const customHeaderTooltipMatch = inHeader && !hoveredAction && !hoveredDragHandle ? locateCustomHeaderTooltip(event.clientX, event.clientY, columnIndex) : null;
4567
+ const hoveredContentTooltip = customHeaderTooltipMatch || null;
4568
+ const hoveredCustomContent = customHeaderTooltipMatch !== null;
4569
+ const hoveredTitle = inHeader && !hoveredAction && !hoveredDragHandle && !hoveredCustomContent && hoveredHeaderCell && Boolean(hoveredHeaderCell.column.title) && isPointerOnHeaderTitle(event.clientX, event.clientY, hoveredHeaderCell) && (tooltipConfig.header || hoveredHeaderCell.leaf && isHeaderTitleTruncated(hoveredHeaderCell.startIndex));
4531
4570
  const nextHover = hoveredAction ? { columnIndex, action: hoveredAction } : hoveredDragHandle ? { columnIndex: hoveredDragColumnIndex, action: "drag" } : hoveredContentTooltip ? { columnIndex, action: "content" } : hoveredTitle ? { columnIndex: hoveredHeaderCell.startIndex, action: "title" } : null;
4532
4571
  const nextTooltip = hoveredAction && hoveredHeaderCell ? createHeaderTooltip(hoveredAction, columnIndex, hoveredHeaderCell) : hoveredDragHandle && hoveredHeaderCell ? createHeaderTooltip("drag", hoveredDragColumnIndex, hoveredHeaderCell) : hoveredContentTooltip ? hoveredContentTooltip : hoveredTitle && hoveredHeaderCell ? createHeaderTooltip("title", hoveredHeaderCell.startIndex, hoveredHeaderCell) : null;
4533
4572
  const previousHover = hoveredHeaderActionRef.current;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lensui/lens-table",
3
- "version": "0.1.25",
3
+ "version": "0.1.27",
4
4
  "description": "A lightweight, canvas-rendered React table component for LensUI.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",