@lensui/lens-table 0.1.79 → 0.1.81

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
@@ -1280,6 +1280,7 @@ function paintGrid(options) {
1280
1280
  const annotation = cellAnnotations.get(`${typeof rowKey}:${String(rowKey)}\0${column.key}`);
1281
1281
  const rawValue = column.dataIndex === void 0 ? void 0 : row[column.dataIndex];
1282
1282
  const cellStyle = column.cellStyle?.(rawValue, row, rowIndex);
1283
+ const cellGridColor = cellStyle?.gridColor ? resolveColor(cellStyle.gridColor) : void 0;
1283
1284
  if (!isSelectedCell && !isRangeCell && cellStyle?.backgroundColor) {
1284
1285
  const cellBackground = resolveColor(cellStyle.backgroundColor);
1285
1286
  if (cellBackground) {
@@ -1306,7 +1307,7 @@ function paintGrid(options) {
1306
1307
  ctx.fillStyle = isAxisSelected ? getAxisSelectionFill(rowIndex, column.key) : colors.columnDropTargetFill;
1307
1308
  ctx.fillRect(x, y, cellWidth, cellHeight);
1308
1309
  }
1309
- ctx.fillStyle = selectedRowKeys.has(rowKey) ? getAxisSelectionFill(rowIndex, column.key) : isRangeCell ? colors.selectionFill : colors.grid;
1310
+ ctx.fillStyle = selectedRowKeys.has(rowKey) ? getAxisSelectionFill(rowIndex, column.key) : isRangeCell ? colors.selectionFill : cellGridColor ?? colors.grid;
1310
1311
  if (!verticalBorderless && !(frameBorderless && columnIndex + colSpan >= columns.length)) {
1311
1312
  ctx.fillRect(x + cellWidth - 1, y, 1, cellHeight);
1312
1313
  }
@@ -1928,6 +1929,9 @@ function TableInner({
1928
1929
  defaultSelectedCell,
1929
1930
  onSelectedCellChange,
1930
1931
  rangeSelection = false,
1932
+ selectedRange,
1933
+ defaultSelectedRange,
1934
+ onSelectedRangeChange,
1931
1935
  rowSelection,
1932
1936
  selectedRowKeys,
1933
1937
  defaultSelectedRowKeys,
@@ -2337,6 +2341,20 @@ function TableInner({
2337
2341
  }, [columns, getDataRowKey, rows]);
2338
2342
  const resolvedSelectedCell = (0, import_react8.useMemo)(() => resolveSelectionTarget(selectedCell), [resolveSelectionTarget, selectedCell]);
2339
2343
  const resolvedDefaultSelectedCell = (0, import_react8.useMemo)(() => resolveSelectionTarget(defaultSelectedCell), [defaultSelectedCell, resolveSelectionTarget]);
2344
+ const resolveSelectionRangeTarget = (0, import_react8.useCallback)((target) => {
2345
+ if (target == null) return target;
2346
+ const anchor = resolveSelectionTarget(target.anchor);
2347
+ const focus = resolveSelectionTarget(target.focus);
2348
+ return anchor && focus ? { anchor, focus } : null;
2349
+ }, [resolveSelectionTarget]);
2350
+ const resolvedSelectedRange = (0, import_react8.useMemo)(
2351
+ () => resolveSelectionRangeTarget(selectedRange),
2352
+ [resolveSelectionRangeTarget, selectedRange]
2353
+ );
2354
+ const resolvedDefaultSelectedRange = (0, import_react8.useMemo)(
2355
+ () => resolveSelectionRangeTarget(defaultSelectedRange),
2356
+ [defaultSelectedRange, resolveSelectionRangeTarget]
2357
+ );
2340
2358
  const handleSelectedCellChange = (0, import_react8.useCallback)((next) => {
2341
2359
  if (!onSelectedCellChange) return;
2342
2360
  if (!next) {
@@ -2349,7 +2367,11 @@ function TableInner({
2349
2367
  onSelectedCellChange({ ...next, value });
2350
2368
  }, [columns, onSelectedCellChange, rows]);
2351
2369
  const [selection, setSelection] = useControllableValue(resolvedSelectedCell, resolvedDefaultSelectedCell, handleSelectedCellChange);
2352
- const [selectionRange, setSelectionRange] = (0, import_react8.useState)(null);
2370
+ const [selectionRange, setSelectionRange] = useControllableValue(
2371
+ resolvedSelectedRange,
2372
+ resolvedDefaultSelectedRange,
2373
+ onSelectedRangeChange
2374
+ );
2353
2375
  const rangeDragRef = (0, import_react8.useRef)(null);
2354
2376
  (0, import_react8.useEffect)(() => {
2355
2377
  if (!selection) return void 0;
@@ -3475,8 +3497,10 @@ function TableInner({
3475
3497
  if (focus.rowIndex === drag.anchor.rowIndex && focus.columnIndex === drag.anchor.columnIndex) return;
3476
3498
  drag.moved = true;
3477
3499
  event.preventDefault();
3478
- setSelectionRange((current) => current?.focus.rowIndex === focus.rowIndex && current.focus.columnIndex === focus.columnIndex ? current : { anchor: drag.anchor, focus });
3479
- }, [columns, locateCell]);
3500
+ if (selectionRange?.focus.rowIndex === focus.rowIndex && selectionRange.focus.columnIndex === focus.columnIndex)
3501
+ return;
3502
+ setSelectionRange({ anchor: drag.anchor, focus });
3503
+ }, [columns, locateCell, selectionRange, setSelectionRange]);
3480
3504
  const endRangeDrag = (0, import_react8.useCallback)((event) => {
3481
3505
  const drag = rangeDragRef.current;
3482
3506
  if (!drag) return;
@@ -4875,6 +4899,23 @@ function TableInner({
4875
4899
  setSelection(cell);
4876
4900
  return true;
4877
4901
  },
4902
+ getSelectedRange: () => selectionRange ? { anchor: { ...selectionRange.anchor }, focus: { ...selectionRange.focus } } : null,
4903
+ setSelectedRange: (target) => {
4904
+ if (target === null) {
4905
+ rangeDragRef.current = null;
4906
+ setSelectionRange(null);
4907
+ return true;
4908
+ }
4909
+ if (!rangeSelection) return false;
4910
+ const anchor = resolveDataCell(target.anchor);
4911
+ const focus = resolveDataCell(target.focus);
4912
+ if (!anchor || !focus) return false;
4913
+ rangeDragRef.current = null;
4914
+ setEditing(null);
4915
+ setSelection(null);
4916
+ setSelectionRange({ anchor, focus });
4917
+ return true;
4918
+ },
4878
4919
  getSelectedRowKeys: () => [...rowKeys],
4879
4920
  getSelectedRows: () => rows.filter((row, index) => selectedRowKeySet.has(getRowKey(row, index))),
4880
4921
  setSelectedRowKeys: (keys) => {
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. */
@@ -258,6 +260,16 @@ type GridSelectionTarget = {
258
260
  rowKey?: GridKey;
259
261
  columnIndex?: number;
260
262
  };
263
+ /** Fully resolved rectangular cell selection. */
264
+ interface GridSelectionRange {
265
+ anchor: GridSelection;
266
+ focus: GridSelection;
267
+ }
268
+ /** Stable locators accepted when restoring a rectangular cell selection. */
269
+ interface GridSelectionRangeTarget {
270
+ anchor: GridSelectionTarget;
271
+ focus: GridSelectionTarget;
272
+ }
261
273
  /** Fully resolved selected cell returned by onSelectedCellChange. */
262
274
  interface SelectedCellChange extends GridSelection {
263
275
  value: unknown;
@@ -281,6 +293,9 @@ interface TableRef<Row extends object> {
281
293
  scrollToCell: (target: GridSelectionTarget) => boolean;
282
294
  getSelectedCell: () => TableCellContext<Row> | null;
283
295
  setSelectedCell: (target: GridSelectionTarget | null) => boolean;
296
+ getSelectedRange: () => GridSelectionRange | null;
297
+ /** Restore or clear the native range outline; false if range selection is disabled or a target is unavailable. */
298
+ setSelectedRange: (target: GridSelectionRangeTarget | null) => boolean;
284
299
  getSelectedRowKeys: () => GridKey[];
285
300
  getSelectedRows: () => Row[];
286
301
  setSelectedRowKeys: (keys: GridKey[]) => void;
@@ -400,6 +415,11 @@ interface TableProps<Row extends object> {
400
415
  onSelectedCellChange?: (selection: SelectedCellChange | null) => void;
401
416
  /** Enable spreadsheet-style mouse drag selection across multiple body cells. Defaults to false. */
402
417
  rangeSelection?: boolean;
418
+ /** Controlled rectangular cell selection. */
419
+ selectedRange?: GridSelectionRangeTarget | null;
420
+ /** Initial rectangular cell selection for uncontrolled usage. */
421
+ defaultSelectedRange?: GridSelectionRangeTarget | null;
422
+ onSelectedRangeChange?: (range: GridSelectionRange | null) => void;
403
423
  rowSelection?: boolean | RowSelectionConfig;
404
424
  selectedRowKeys?: GridKey[];
405
425
  defaultSelectedRowKeys?: GridKey[];
@@ -511,4 +531,4 @@ declare function hitTestColumn(metrics: ColumnMetric[], contentX: number): numbe
511
531
 
512
532
  type TableFilterValues = Record<string, string>;
513
533
 
514
- export { type AxisSelectionConfig, type CellChange, type ContextMenuEvent, type GridCellPosition, type GridColumn, type GridKey, type GridSelection, type GridSelectionTarget, type GridSortState, type RowSelectionConfig, type SelectedCellChange, type SelectionMode, type SortDirection, Table, type CellChange as TableCellChange, type TableCellContext, type GridCellPosition as TableCellPosition, type TableCellSpan, type TableCellSpanRule, type TableCellSpanRuleContext, type TableCellSpans, type GridColumn as TableColumn, type TableContextMenu, type TableContextMenuConfig, type ContextMenuEvent as TableContextMenuEvent, type GridSelection as TableEditingCell, type TableFilterValues, type TableHighlightConfig, type GridKey as TableKey, type TableLabels, type TableLayoutConfig, type TableLocaleCode, type TableLocaleConfig, type TableProps, type TableRef, type TableResolvedCellSpan, type TableRowNumberConfig, type GridSortState as TableSorter, type TableSummaryConfig, type TableTooltipConfig, type ViewportRange as TableViewportRange, type TableVirtualizedConfig, Table as VelocityGrid, type TableCellSpan as VelocityGridCellSpan, type TableCellSpanRule as VelocityGridCellSpanRule, type TableCellSpanRuleContext as VelocityGridCellSpanRuleContext, type TableCellSpans as VelocityGridCellSpans, type TableContextMenu as VelocityGridContextMenu, type TableContextMenuConfig as VelocityGridContextMenuConfig, type TableHighlightConfig as VelocityGridHighlightConfig, type TableLabels as VelocityGridLabels, type TableLayoutConfig as VelocityGridLayoutConfig, type TableLocaleCode as VelocityGridLocaleCode, type TableLocaleConfig as VelocityGridLocaleConfig, type TableProps as VelocityGridProps, type TableRef as VelocityGridRef, type TableResolvedCellSpan as VelocityGridResolvedCellSpan, type TableSummaryConfig as VelocityGridSummaryConfig, type TableTooltipConfig as VelocityGridTooltipConfig, type TableVirtualizedConfig as VelocityGridVirtualizedConfig, type ViewportRange, buildColumnMetrics, getViewportRange, hitTestColumn };
534
+ export { type AxisSelectionConfig, type CellChange, type ContextMenuEvent, type GridCellPosition, type GridColumn, type GridKey, type GridSelection, type GridSelectionRange, type GridSelectionRangeTarget, type GridSelectionTarget, type GridSortState, type RowSelectionConfig, type SelectedCellChange, type SelectionMode, type SortDirection, Table, type CellChange as TableCellChange, type TableCellContext, type GridCellPosition as TableCellPosition, type TableCellSpan, type TableCellSpanRule, type TableCellSpanRuleContext, type TableCellSpans, type GridColumn as TableColumn, type TableContextMenu, type TableContextMenuConfig, type ContextMenuEvent as TableContextMenuEvent, type GridSelection as TableEditingCell, type TableFilterValues, type TableHighlightConfig, type GridKey as TableKey, type TableLabels, type TableLayoutConfig, type TableLocaleCode, type TableLocaleConfig, type TableProps, type TableRef, type TableResolvedCellSpan, type TableRowNumberConfig, type GridSortState as TableSorter, type TableSummaryConfig, type TableTooltipConfig, type ViewportRange as TableViewportRange, type TableVirtualizedConfig, Table as VelocityGrid, type TableCellSpan as VelocityGridCellSpan, type TableCellSpanRule as VelocityGridCellSpanRule, type TableCellSpanRuleContext as VelocityGridCellSpanRuleContext, type TableCellSpans as VelocityGridCellSpans, type TableContextMenu as VelocityGridContextMenu, type TableContextMenuConfig as VelocityGridContextMenuConfig, type TableHighlightConfig as VelocityGridHighlightConfig, type TableLabels as VelocityGridLabels, type TableLayoutConfig as VelocityGridLayoutConfig, type TableLocaleCode as VelocityGridLocaleCode, type TableLocaleConfig as VelocityGridLocaleConfig, type TableProps as VelocityGridProps, type TableRef as VelocityGridRef, type TableResolvedCellSpan as VelocityGridResolvedCellSpan, type TableSummaryConfig as VelocityGridSummaryConfig, type TableTooltipConfig as VelocityGridTooltipConfig, type TableVirtualizedConfig as VelocityGridVirtualizedConfig, type ViewportRange, buildColumnMetrics, getViewportRange, hitTestColumn };
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. */
@@ -258,6 +260,16 @@ type GridSelectionTarget = {
258
260
  rowKey?: GridKey;
259
261
  columnIndex?: number;
260
262
  };
263
+ /** Fully resolved rectangular cell selection. */
264
+ interface GridSelectionRange {
265
+ anchor: GridSelection;
266
+ focus: GridSelection;
267
+ }
268
+ /** Stable locators accepted when restoring a rectangular cell selection. */
269
+ interface GridSelectionRangeTarget {
270
+ anchor: GridSelectionTarget;
271
+ focus: GridSelectionTarget;
272
+ }
261
273
  /** Fully resolved selected cell returned by onSelectedCellChange. */
262
274
  interface SelectedCellChange extends GridSelection {
263
275
  value: unknown;
@@ -281,6 +293,9 @@ interface TableRef<Row extends object> {
281
293
  scrollToCell: (target: GridSelectionTarget) => boolean;
282
294
  getSelectedCell: () => TableCellContext<Row> | null;
283
295
  setSelectedCell: (target: GridSelectionTarget | null) => boolean;
296
+ getSelectedRange: () => GridSelectionRange | null;
297
+ /** Restore or clear the native range outline; false if range selection is disabled or a target is unavailable. */
298
+ setSelectedRange: (target: GridSelectionRangeTarget | null) => boolean;
284
299
  getSelectedRowKeys: () => GridKey[];
285
300
  getSelectedRows: () => Row[];
286
301
  setSelectedRowKeys: (keys: GridKey[]) => void;
@@ -400,6 +415,11 @@ interface TableProps<Row extends object> {
400
415
  onSelectedCellChange?: (selection: SelectedCellChange | null) => void;
401
416
  /** Enable spreadsheet-style mouse drag selection across multiple body cells. Defaults to false. */
402
417
  rangeSelection?: boolean;
418
+ /** Controlled rectangular cell selection. */
419
+ selectedRange?: GridSelectionRangeTarget | null;
420
+ /** Initial rectangular cell selection for uncontrolled usage. */
421
+ defaultSelectedRange?: GridSelectionRangeTarget | null;
422
+ onSelectedRangeChange?: (range: GridSelectionRange | null) => void;
403
423
  rowSelection?: boolean | RowSelectionConfig;
404
424
  selectedRowKeys?: GridKey[];
405
425
  defaultSelectedRowKeys?: GridKey[];
@@ -511,4 +531,4 @@ declare function hitTestColumn(metrics: ColumnMetric[], contentX: number): numbe
511
531
 
512
532
  type TableFilterValues = Record<string, string>;
513
533
 
514
- export { type AxisSelectionConfig, type CellChange, type ContextMenuEvent, type GridCellPosition, type GridColumn, type GridKey, type GridSelection, type GridSelectionTarget, type GridSortState, type RowSelectionConfig, type SelectedCellChange, type SelectionMode, type SortDirection, Table, type CellChange as TableCellChange, type TableCellContext, type GridCellPosition as TableCellPosition, type TableCellSpan, type TableCellSpanRule, type TableCellSpanRuleContext, type TableCellSpans, type GridColumn as TableColumn, type TableContextMenu, type TableContextMenuConfig, type ContextMenuEvent as TableContextMenuEvent, type GridSelection as TableEditingCell, type TableFilterValues, type TableHighlightConfig, type GridKey as TableKey, type TableLabels, type TableLayoutConfig, type TableLocaleCode, type TableLocaleConfig, type TableProps, type TableRef, type TableResolvedCellSpan, type TableRowNumberConfig, type GridSortState as TableSorter, type TableSummaryConfig, type TableTooltipConfig, type ViewportRange as TableViewportRange, type TableVirtualizedConfig, Table as VelocityGrid, type TableCellSpan as VelocityGridCellSpan, type TableCellSpanRule as VelocityGridCellSpanRule, type TableCellSpanRuleContext as VelocityGridCellSpanRuleContext, type TableCellSpans as VelocityGridCellSpans, type TableContextMenu as VelocityGridContextMenu, type TableContextMenuConfig as VelocityGridContextMenuConfig, type TableHighlightConfig as VelocityGridHighlightConfig, type TableLabels as VelocityGridLabels, type TableLayoutConfig as VelocityGridLayoutConfig, type TableLocaleCode as VelocityGridLocaleCode, type TableLocaleConfig as VelocityGridLocaleConfig, type TableProps as VelocityGridProps, type TableRef as VelocityGridRef, type TableResolvedCellSpan as VelocityGridResolvedCellSpan, type TableSummaryConfig as VelocityGridSummaryConfig, type TableTooltipConfig as VelocityGridTooltipConfig, type TableVirtualizedConfig as VelocityGridVirtualizedConfig, type ViewportRange, buildColumnMetrics, getViewportRange, hitTestColumn };
534
+ export { type AxisSelectionConfig, type CellChange, type ContextMenuEvent, type GridCellPosition, type GridColumn, type GridKey, type GridSelection, type GridSelectionRange, type GridSelectionRangeTarget, type GridSelectionTarget, type GridSortState, type RowSelectionConfig, type SelectedCellChange, type SelectionMode, type SortDirection, Table, type CellChange as TableCellChange, type TableCellContext, type GridCellPosition as TableCellPosition, type TableCellSpan, type TableCellSpanRule, type TableCellSpanRuleContext, type TableCellSpans, type GridColumn as TableColumn, type TableContextMenu, type TableContextMenuConfig, type ContextMenuEvent as TableContextMenuEvent, type GridSelection as TableEditingCell, type TableFilterValues, type TableHighlightConfig, type GridKey as TableKey, type TableLabels, type TableLayoutConfig, type TableLocaleCode, type TableLocaleConfig, type TableProps, type TableRef, type TableResolvedCellSpan, type TableRowNumberConfig, type GridSortState as TableSorter, type TableSummaryConfig, type TableTooltipConfig, type ViewportRange as TableViewportRange, type TableVirtualizedConfig, Table as VelocityGrid, type TableCellSpan as VelocityGridCellSpan, type TableCellSpanRule as VelocityGridCellSpanRule, type TableCellSpanRuleContext as VelocityGridCellSpanRuleContext, type TableCellSpans as VelocityGridCellSpans, type TableContextMenu as VelocityGridContextMenu, type TableContextMenuConfig as VelocityGridContextMenuConfig, type TableHighlightConfig as VelocityGridHighlightConfig, type TableLabels as VelocityGridLabels, type TableLayoutConfig as VelocityGridLayoutConfig, type TableLocaleCode as VelocityGridLocaleCode, type TableLocaleConfig as VelocityGridLocaleConfig, type TableProps as VelocityGridProps, type TableRef as VelocityGridRef, type TableResolvedCellSpan as VelocityGridResolvedCellSpan, type TableSummaryConfig as VelocityGridSummaryConfig, type TableTooltipConfig as VelocityGridTooltipConfig, type TableVirtualizedConfig as VelocityGridVirtualizedConfig, type ViewportRange, buildColumnMetrics, getViewportRange, hitTestColumn };
package/dist/index.js CHANGED
@@ -1250,6 +1250,7 @@ function paintGrid(options) {
1250
1250
  const annotation = cellAnnotations.get(`${typeof rowKey}:${String(rowKey)}\0${column.key}`);
1251
1251
  const rawValue = column.dataIndex === void 0 ? void 0 : row[column.dataIndex];
1252
1252
  const cellStyle = column.cellStyle?.(rawValue, row, rowIndex);
1253
+ const cellGridColor = cellStyle?.gridColor ? resolveColor(cellStyle.gridColor) : void 0;
1253
1254
  if (!isSelectedCell && !isRangeCell && cellStyle?.backgroundColor) {
1254
1255
  const cellBackground = resolveColor(cellStyle.backgroundColor);
1255
1256
  if (cellBackground) {
@@ -1276,7 +1277,7 @@ function paintGrid(options) {
1276
1277
  ctx.fillStyle = isAxisSelected ? getAxisSelectionFill(rowIndex, column.key) : colors.columnDropTargetFill;
1277
1278
  ctx.fillRect(x, y, cellWidth, cellHeight);
1278
1279
  }
1279
- ctx.fillStyle = selectedRowKeys.has(rowKey) ? getAxisSelectionFill(rowIndex, column.key) : isRangeCell ? colors.selectionFill : colors.grid;
1280
+ ctx.fillStyle = selectedRowKeys.has(rowKey) ? getAxisSelectionFill(rowIndex, column.key) : isRangeCell ? colors.selectionFill : cellGridColor ?? colors.grid;
1280
1281
  if (!verticalBorderless && !(frameBorderless && columnIndex + colSpan >= columns.length)) {
1281
1282
  ctx.fillRect(x + cellWidth - 1, y, 1, cellHeight);
1282
1283
  }
@@ -1898,6 +1899,9 @@ function TableInner({
1898
1899
  defaultSelectedCell,
1899
1900
  onSelectedCellChange,
1900
1901
  rangeSelection = false,
1902
+ selectedRange,
1903
+ defaultSelectedRange,
1904
+ onSelectedRangeChange,
1901
1905
  rowSelection,
1902
1906
  selectedRowKeys,
1903
1907
  defaultSelectedRowKeys,
@@ -2307,6 +2311,20 @@ function TableInner({
2307
2311
  }, [columns, getDataRowKey, rows]);
2308
2312
  const resolvedSelectedCell = useMemo2(() => resolveSelectionTarget(selectedCell), [resolveSelectionTarget, selectedCell]);
2309
2313
  const resolvedDefaultSelectedCell = useMemo2(() => resolveSelectionTarget(defaultSelectedCell), [defaultSelectedCell, resolveSelectionTarget]);
2314
+ const resolveSelectionRangeTarget = useCallback2((target) => {
2315
+ if (target == null) return target;
2316
+ const anchor = resolveSelectionTarget(target.anchor);
2317
+ const focus = resolveSelectionTarget(target.focus);
2318
+ return anchor && focus ? { anchor, focus } : null;
2319
+ }, [resolveSelectionTarget]);
2320
+ const resolvedSelectedRange = useMemo2(
2321
+ () => resolveSelectionRangeTarget(selectedRange),
2322
+ [resolveSelectionRangeTarget, selectedRange]
2323
+ );
2324
+ const resolvedDefaultSelectedRange = useMemo2(
2325
+ () => resolveSelectionRangeTarget(defaultSelectedRange),
2326
+ [defaultSelectedRange, resolveSelectionRangeTarget]
2327
+ );
2310
2328
  const handleSelectedCellChange = useCallback2((next) => {
2311
2329
  if (!onSelectedCellChange) return;
2312
2330
  if (!next) {
@@ -2319,7 +2337,11 @@ function TableInner({
2319
2337
  onSelectedCellChange({ ...next, value });
2320
2338
  }, [columns, onSelectedCellChange, rows]);
2321
2339
  const [selection, setSelection] = useControllableValue(resolvedSelectedCell, resolvedDefaultSelectedCell, handleSelectedCellChange);
2322
- const [selectionRange, setSelectionRange] = useState6(null);
2340
+ const [selectionRange, setSelectionRange] = useControllableValue(
2341
+ resolvedSelectedRange,
2342
+ resolvedDefaultSelectedRange,
2343
+ onSelectedRangeChange
2344
+ );
2323
2345
  const rangeDragRef = useRef4(null);
2324
2346
  useEffect3(() => {
2325
2347
  if (!selection) return void 0;
@@ -3445,8 +3467,10 @@ function TableInner({
3445
3467
  if (focus.rowIndex === drag.anchor.rowIndex && focus.columnIndex === drag.anchor.columnIndex) return;
3446
3468
  drag.moved = true;
3447
3469
  event.preventDefault();
3448
- setSelectionRange((current) => current?.focus.rowIndex === focus.rowIndex && current.focus.columnIndex === focus.columnIndex ? current : { anchor: drag.anchor, focus });
3449
- }, [columns, locateCell]);
3470
+ if (selectionRange?.focus.rowIndex === focus.rowIndex && selectionRange.focus.columnIndex === focus.columnIndex)
3471
+ return;
3472
+ setSelectionRange({ anchor: drag.anchor, focus });
3473
+ }, [columns, locateCell, selectionRange, setSelectionRange]);
3450
3474
  const endRangeDrag = useCallback2((event) => {
3451
3475
  const drag = rangeDragRef.current;
3452
3476
  if (!drag) return;
@@ -4845,6 +4869,23 @@ function TableInner({
4845
4869
  setSelection(cell);
4846
4870
  return true;
4847
4871
  },
4872
+ getSelectedRange: () => selectionRange ? { anchor: { ...selectionRange.anchor }, focus: { ...selectionRange.focus } } : null,
4873
+ setSelectedRange: (target) => {
4874
+ if (target === null) {
4875
+ rangeDragRef.current = null;
4876
+ setSelectionRange(null);
4877
+ return true;
4878
+ }
4879
+ if (!rangeSelection) return false;
4880
+ const anchor = resolveDataCell(target.anchor);
4881
+ const focus = resolveDataCell(target.focus);
4882
+ if (!anchor || !focus) return false;
4883
+ rangeDragRef.current = null;
4884
+ setEditing(null);
4885
+ setSelection(null);
4886
+ setSelectionRange({ anchor, focus });
4887
+ return true;
4888
+ },
4848
4889
  getSelectedRowKeys: () => [...rowKeys],
4849
4890
  getSelectedRows: () => rows.filter((row, index) => selectedRowKeySet.has(getRowKey(row, index))),
4850
4891
  setSelectedRowKeys: (keys) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lensui/lens-table",
3
- "version": "0.1.79",
3
+ "version": "0.1.81",
4
4
  "description": "A lightweight, canvas-rendered React table component for LensUI.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",