@lensui/lens-table 0.1.78 → 0.1.80

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
@@ -907,7 +907,11 @@ function TextEditor({ value, type, min, max, integer = false, style, labels, onC
907
907
  if (type === "number" && integer && next !== "" && !/^-?\d+$/.test(next)) return;
908
908
  onChange(next);
909
909
  },
910
- onBlur: commitValue,
910
+ onBlur: (event) => {
911
+ const nextTarget = event.relatedTarget;
912
+ if (nextTarget instanceof Element && nextTarget.closest("[data-rvg-preserve-edit]")) return;
913
+ commitValue();
914
+ },
911
915
  onKeyDown: handleKeyDown
912
916
  }
913
917
  ),
@@ -1276,6 +1280,7 @@ function paintGrid(options) {
1276
1280
  const annotation = cellAnnotations.get(`${typeof rowKey}:${String(rowKey)}\0${column.key}`);
1277
1281
  const rawValue = column.dataIndex === void 0 ? void 0 : row[column.dataIndex];
1278
1282
  const cellStyle = column.cellStyle?.(rawValue, row, rowIndex);
1283
+ const cellGridColor = cellStyle?.gridColor ? resolveColor(cellStyle.gridColor) : void 0;
1279
1284
  if (!isSelectedCell && !isRangeCell && cellStyle?.backgroundColor) {
1280
1285
  const cellBackground = resolveColor(cellStyle.backgroundColor);
1281
1286
  if (cellBackground) {
@@ -1302,7 +1307,7 @@ function paintGrid(options) {
1302
1307
  ctx.fillStyle = isAxisSelected ? getAxisSelectionFill(rowIndex, column.key) : colors.columnDropTargetFill;
1303
1308
  ctx.fillRect(x, y, cellWidth, cellHeight);
1304
1309
  }
1305
- ctx.fillStyle = selectedRowKeys.has(rowKey) ? getAxisSelectionFill(rowIndex, column.key) : colors.grid;
1310
+ ctx.fillStyle = selectedRowKeys.has(rowKey) ? getAxisSelectionFill(rowIndex, column.key) : isRangeCell ? colors.selectionFill : cellGridColor ?? colors.grid;
1306
1311
  if (!verticalBorderless && !(frameBorderless && columnIndex + colSpan >= columns.length)) {
1307
1312
  ctx.fillRect(x + cellWidth - 1, y, 1, cellHeight);
1308
1313
  }
@@ -2127,6 +2132,7 @@ function TableInner({
2127
2132
  const [editing, setEditing] = (0, import_react8.useState)(null);
2128
2133
  const [draft, setDraft] = (0, import_react8.useState)("");
2129
2134
  const [rowDragPreview, setRowDragPreview] = (0, import_react8.useState)(null);
2135
+ const [liftedRowPreview, setLiftedRowPreview] = (0, import_react8.useState)(null);
2130
2136
  const [columnDragPreview, setColumnDragPreview] = (0, import_react8.useState)(null);
2131
2137
  const [columnDropTarget, setColumnDropTarget] = (0, import_react8.useState)(null);
2132
2138
  (0, import_react8.useEffect)(() => {
@@ -3399,24 +3405,29 @@ function TableInner({
3399
3405
  event.currentTarget.style.cursor = "move";
3400
3406
  }
3401
3407
  event.preventDefault();
3408
+ const canvasTop = event.currentTarget.getBoundingClientRect().top;
3409
+ setLiftedRowPreview({
3410
+ sourceIndex: drag.sourceIndex,
3411
+ top: Math.max(bodyTop, Math.min(renderHeight - rowHeight, event.clientY - canvasTop - rowHeight / 2))
3412
+ });
3402
3413
  const rawTargetIndex = locateRow(event.clientY);
3403
3414
  if (rawTargetIndex < 0) return;
3404
- const canvasTop = event.currentTarget.getBoundingClientRect().top;
3405
3415
  const rowTop = bodyTop + rawTargetIndex * rowHeight - scrollRef.current.top;
3406
3416
  const edge = event.clientY - canvasTop < rowTop + rowHeight / 2 ? "top" : "bottom";
3407
3417
  let targetIndex = rawTargetIndex + (edge === "bottom" ? 1 : 0);
3408
3418
  if (drag.sourceIndex < targetIndex) targetIndex -= 1;
3409
3419
  targetIndex = Math.max(0, Math.min(rows.length - 1, targetIndex));
3410
3420
  drag.targetIndex = targetIndex;
3411
- setRowDragPreview((current) => current?.sourceIndex === drag.sourceIndex && current.targetIndex === targetIndex ? current : { sourceIndex: drag.sourceIndex, targetIndex });
3421
+ setRowDragPreview(null);
3412
3422
  setRowDragGuide(rowTop + (edge === "bottom" ? rowHeight : 0));
3413
- }, [bodyTop, hideDragTooltips, locateRow, rowHeight, rows.length, setRowDragGuide]);
3423
+ }, [bodyTop, hideDragTooltips, locateRow, renderHeight, rowHeight, rows.length, setRowDragGuide]);
3414
3424
  const finishRowOrderPointerDrag = (0, import_react8.useCallback)((event, apply) => {
3415
3425
  const drag = rowOrderDragRef.current;
3416
3426
  if (!drag || drag.pointerId !== event.pointerId) return;
3417
3427
  if (event.currentTarget.hasPointerCapture?.(event.pointerId)) event.currentTarget.releasePointerCapture?.(event.pointerId);
3418
3428
  rowOrderDragRef.current = null;
3419
3429
  setRowDragPreview(null);
3430
+ setLiftedRowPreview(null);
3420
3431
  setRowDragGuide(null);
3421
3432
  document.documentElement.classList.remove("rvg-is-dragging");
3422
3433
  event.currentTarget.style.cursor = "default";
@@ -5628,6 +5639,26 @@ function TableInner({
5628
5639
  ]
5629
5640
  }
5630
5641
  ),
5642
+ liftedRowPreview && rows[liftedRowPreview.sourceIndex] && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
5643
+ "div",
5644
+ {
5645
+ "aria-hidden": "true",
5646
+ className: `rvg-row-drag-preview${selectedRowKeySet.has(getRowKey(rows[liftedRowPreview.sourceIndex], liftedRowPreview.sourceIndex)) ? " is-selected" : ""}`,
5647
+ style: { top: liftedRowPreview.top, width: viewport.width, height: rowHeight },
5648
+ children: columns.map((column, columnIndex) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
5649
+ "div",
5650
+ {
5651
+ className: "rvg-row-drag-preview-cell",
5652
+ style: {
5653
+ left: getDisplayedColumnLeft(columnIndex),
5654
+ width: metrics[columnIndex]?.width ?? 0
5655
+ },
5656
+ children: getCellLabel(liftedRowPreview.sourceIndex, columnIndex)
5657
+ },
5658
+ `row-preview:${column.key}`
5659
+ ))
5660
+ }
5661
+ ),
5631
5662
  resizeGuideX !== null && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
5632
5663
  "div",
5633
5664
  {
package/dist/index.css CHANGED
@@ -1638,13 +1638,16 @@
1638
1638
  }
1639
1639
  .rvg-row-drag-preview {
1640
1640
  position: absolute;
1641
- top: 2px;
1642
- left: 2px;
1643
- overflow: visible;
1644
- border: 1px solid #a9c8f5;
1645
- background: #fff;
1646
- box-shadow: 0 2px 6px rgba(5, 5, 5, 0.08);
1641
+ z-index: 6;
1642
+ left: 0;
1643
+ overflow: hidden;
1644
+ border: 1px solid #8db8f3;
1645
+ background: var(--rvg-color-bg);
1646
+ box-shadow: 0 5px 14px rgba(32, 75, 135, 0.2);
1647
1647
  box-sizing: border-box;
1648
+ opacity: 0.94;
1649
+ pointer-events: none;
1650
+ transform: translateY(-1px);
1648
1651
  }
1649
1652
  .rvg-row-drag-preview-cell {
1650
1653
  position: absolute;
@@ -1665,6 +1668,14 @@
1665
1668
  text-overflow: ellipsis;
1666
1669
  box-sizing: border-box;
1667
1670
  }
1671
+ .rvg-row-drag-preview.is-selected {
1672
+ border-color: var(--rvg-color-primary);
1673
+ background: var(--rvg-color-selection-fill);
1674
+ }
1675
+ .rvg-row-drag-preview.is-selected .rvg-row-drag-preview-cell {
1676
+ border-right-color: color-mix(in srgb, var(--rvg-color-axis-selection-text) 34%, transparent);
1677
+ color: var(--rvg-color-axis-selection-text);
1678
+ }
1668
1679
  .rvg-row-drag-preview-cell svg {
1669
1680
  width: 16px;
1670
1681
  height: 16px;
package/dist/index.d.cts CHANGED
@@ -230,10 +230,12 @@ interface GridColumn<Row> {
230
230
  renderCell?: (value: unknown, row: Row, rowIndex: number) => ReactNode;
231
231
  /** Show this column in the summary row. true sums numeric values; a function can return custom content. */
232
232
  summary?: boolean | ((rows: Row[], column: GridColumn<Row>) => ReactNode);
233
- /** Custom cell paint style. Supports text color and background color in canvas rendering. */
233
+ /** Custom cell paint style used by canvas rendering. */
234
234
  cellStyle?: (value: unknown, row: Row, rowIndex: number) => {
235
235
  color?: string;
236
236
  backgroundColor?: string;
237
+ /** Override this cell's right and bottom grid separators without changing their geometry. */
238
+ gridColor?: string;
237
239
  };
238
240
  }
239
241
  /** Zero-based row/column coordinates inside the current row and column arrays. */
package/dist/index.d.ts CHANGED
@@ -230,10 +230,12 @@ interface GridColumn<Row> {
230
230
  renderCell?: (value: unknown, row: Row, rowIndex: number) => ReactNode;
231
231
  /** Show this column in the summary row. true sums numeric values; a function can return custom content. */
232
232
  summary?: boolean | ((rows: Row[], column: GridColumn<Row>) => ReactNode);
233
- /** Custom cell paint style. Supports text color and background color in canvas rendering. */
233
+ /** Custom cell paint style used by canvas rendering. */
234
234
  cellStyle?: (value: unknown, row: Row, rowIndex: number) => {
235
235
  color?: string;
236
236
  backgroundColor?: string;
237
+ /** Override this cell's right and bottom grid separators without changing their geometry. */
238
+ gridColor?: string;
237
239
  };
238
240
  }
239
241
  /** Zero-based row/column coordinates inside the current row and column arrays. */
package/dist/index.js CHANGED
@@ -877,7 +877,11 @@ function TextEditor({ value, type, min, max, integer = false, style, labels, onC
877
877
  if (type === "number" && integer && next !== "" && !/^-?\d+$/.test(next)) return;
878
878
  onChange(next);
879
879
  },
880
- onBlur: commitValue,
880
+ onBlur: (event) => {
881
+ const nextTarget = event.relatedTarget;
882
+ if (nextTarget instanceof Element && nextTarget.closest("[data-rvg-preserve-edit]")) return;
883
+ commitValue();
884
+ },
881
885
  onKeyDown: handleKeyDown
882
886
  }
883
887
  ),
@@ -1246,6 +1250,7 @@ function paintGrid(options) {
1246
1250
  const annotation = cellAnnotations.get(`${typeof rowKey}:${String(rowKey)}\0${column.key}`);
1247
1251
  const rawValue = column.dataIndex === void 0 ? void 0 : row[column.dataIndex];
1248
1252
  const cellStyle = column.cellStyle?.(rawValue, row, rowIndex);
1253
+ const cellGridColor = cellStyle?.gridColor ? resolveColor(cellStyle.gridColor) : void 0;
1249
1254
  if (!isSelectedCell && !isRangeCell && cellStyle?.backgroundColor) {
1250
1255
  const cellBackground = resolveColor(cellStyle.backgroundColor);
1251
1256
  if (cellBackground) {
@@ -1272,7 +1277,7 @@ function paintGrid(options) {
1272
1277
  ctx.fillStyle = isAxisSelected ? getAxisSelectionFill(rowIndex, column.key) : colors.columnDropTargetFill;
1273
1278
  ctx.fillRect(x, y, cellWidth, cellHeight);
1274
1279
  }
1275
- ctx.fillStyle = selectedRowKeys.has(rowKey) ? getAxisSelectionFill(rowIndex, column.key) : colors.grid;
1280
+ ctx.fillStyle = selectedRowKeys.has(rowKey) ? getAxisSelectionFill(rowIndex, column.key) : isRangeCell ? colors.selectionFill : cellGridColor ?? colors.grid;
1276
1281
  if (!verticalBorderless && !(frameBorderless && columnIndex + colSpan >= columns.length)) {
1277
1282
  ctx.fillRect(x + cellWidth - 1, y, 1, cellHeight);
1278
1283
  }
@@ -2097,6 +2102,7 @@ function TableInner({
2097
2102
  const [editing, setEditing] = useState6(null);
2098
2103
  const [draft, setDraft] = useState6("");
2099
2104
  const [rowDragPreview, setRowDragPreview] = useState6(null);
2105
+ const [liftedRowPreview, setLiftedRowPreview] = useState6(null);
2100
2106
  const [columnDragPreview, setColumnDragPreview] = useState6(null);
2101
2107
  const [columnDropTarget, setColumnDropTarget] = useState6(null);
2102
2108
  useEffect3(() => {
@@ -3369,24 +3375,29 @@ function TableInner({
3369
3375
  event.currentTarget.style.cursor = "move";
3370
3376
  }
3371
3377
  event.preventDefault();
3378
+ const canvasTop = event.currentTarget.getBoundingClientRect().top;
3379
+ setLiftedRowPreview({
3380
+ sourceIndex: drag.sourceIndex,
3381
+ top: Math.max(bodyTop, Math.min(renderHeight - rowHeight, event.clientY - canvasTop - rowHeight / 2))
3382
+ });
3372
3383
  const rawTargetIndex = locateRow(event.clientY);
3373
3384
  if (rawTargetIndex < 0) return;
3374
- const canvasTop = event.currentTarget.getBoundingClientRect().top;
3375
3385
  const rowTop = bodyTop + rawTargetIndex * rowHeight - scrollRef.current.top;
3376
3386
  const edge = event.clientY - canvasTop < rowTop + rowHeight / 2 ? "top" : "bottom";
3377
3387
  let targetIndex = rawTargetIndex + (edge === "bottom" ? 1 : 0);
3378
3388
  if (drag.sourceIndex < targetIndex) targetIndex -= 1;
3379
3389
  targetIndex = Math.max(0, Math.min(rows.length - 1, targetIndex));
3380
3390
  drag.targetIndex = targetIndex;
3381
- setRowDragPreview((current) => current?.sourceIndex === drag.sourceIndex && current.targetIndex === targetIndex ? current : { sourceIndex: drag.sourceIndex, targetIndex });
3391
+ setRowDragPreview(null);
3382
3392
  setRowDragGuide(rowTop + (edge === "bottom" ? rowHeight : 0));
3383
- }, [bodyTop, hideDragTooltips, locateRow, rowHeight, rows.length, setRowDragGuide]);
3393
+ }, [bodyTop, hideDragTooltips, locateRow, renderHeight, rowHeight, rows.length, setRowDragGuide]);
3384
3394
  const finishRowOrderPointerDrag = useCallback2((event, apply) => {
3385
3395
  const drag = rowOrderDragRef.current;
3386
3396
  if (!drag || drag.pointerId !== event.pointerId) return;
3387
3397
  if (event.currentTarget.hasPointerCapture?.(event.pointerId)) event.currentTarget.releasePointerCapture?.(event.pointerId);
3388
3398
  rowOrderDragRef.current = null;
3389
3399
  setRowDragPreview(null);
3400
+ setLiftedRowPreview(null);
3390
3401
  setRowDragGuide(null);
3391
3402
  document.documentElement.classList.remove("rvg-is-dragging");
3392
3403
  event.currentTarget.style.cursor = "default";
@@ -5598,6 +5609,26 @@ function TableInner({
5598
5609
  ]
5599
5610
  }
5600
5611
  ),
5612
+ liftedRowPreview && rows[liftedRowPreview.sourceIndex] && /* @__PURE__ */ jsx8(
5613
+ "div",
5614
+ {
5615
+ "aria-hidden": "true",
5616
+ className: `rvg-row-drag-preview${selectedRowKeySet.has(getRowKey(rows[liftedRowPreview.sourceIndex], liftedRowPreview.sourceIndex)) ? " is-selected" : ""}`,
5617
+ style: { top: liftedRowPreview.top, width: viewport.width, height: rowHeight },
5618
+ children: columns.map((column, columnIndex) => /* @__PURE__ */ jsx8(
5619
+ "div",
5620
+ {
5621
+ className: "rvg-row-drag-preview-cell",
5622
+ style: {
5623
+ left: getDisplayedColumnLeft(columnIndex),
5624
+ width: metrics[columnIndex]?.width ?? 0
5625
+ },
5626
+ children: getCellLabel(liftedRowPreview.sourceIndex, columnIndex)
5627
+ },
5628
+ `row-preview:${column.key}`
5629
+ ))
5630
+ }
5631
+ ),
5601
5632
  resizeGuideX !== null && /* @__PURE__ */ jsx8(
5602
5633
  "div",
5603
5634
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lensui/lens-table",
3
- "version": "0.1.78",
3
+ "version": "0.1.80",
4
4
  "description": "A lightweight, canvas-rendered React table component for LensUI.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",