@lensui/lens-table 0.1.80 → 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
@@ -1929,6 +1929,9 @@ function TableInner({
1929
1929
  defaultSelectedCell,
1930
1930
  onSelectedCellChange,
1931
1931
  rangeSelection = false,
1932
+ selectedRange,
1933
+ defaultSelectedRange,
1934
+ onSelectedRangeChange,
1932
1935
  rowSelection,
1933
1936
  selectedRowKeys,
1934
1937
  defaultSelectedRowKeys,
@@ -2338,6 +2341,20 @@ function TableInner({
2338
2341
  }, [columns, getDataRowKey, rows]);
2339
2342
  const resolvedSelectedCell = (0, import_react8.useMemo)(() => resolveSelectionTarget(selectedCell), [resolveSelectionTarget, selectedCell]);
2340
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
+ );
2341
2358
  const handleSelectedCellChange = (0, import_react8.useCallback)((next) => {
2342
2359
  if (!onSelectedCellChange) return;
2343
2360
  if (!next) {
@@ -2350,7 +2367,11 @@ function TableInner({
2350
2367
  onSelectedCellChange({ ...next, value });
2351
2368
  }, [columns, onSelectedCellChange, rows]);
2352
2369
  const [selection, setSelection] = useControllableValue(resolvedSelectedCell, resolvedDefaultSelectedCell, handleSelectedCellChange);
2353
- const [selectionRange, setSelectionRange] = (0, import_react8.useState)(null);
2370
+ const [selectionRange, setSelectionRange] = useControllableValue(
2371
+ resolvedSelectedRange,
2372
+ resolvedDefaultSelectedRange,
2373
+ onSelectedRangeChange
2374
+ );
2354
2375
  const rangeDragRef = (0, import_react8.useRef)(null);
2355
2376
  (0, import_react8.useEffect)(() => {
2356
2377
  if (!selection) return void 0;
@@ -3476,8 +3497,10 @@ function TableInner({
3476
3497
  if (focus.rowIndex === drag.anchor.rowIndex && focus.columnIndex === drag.anchor.columnIndex) return;
3477
3498
  drag.moved = true;
3478
3499
  event.preventDefault();
3479
- setSelectionRange((current) => current?.focus.rowIndex === focus.rowIndex && current.focus.columnIndex === focus.columnIndex ? current : { anchor: drag.anchor, focus });
3480
- }, [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]);
3481
3504
  const endRangeDrag = (0, import_react8.useCallback)((event) => {
3482
3505
  const drag = rangeDragRef.current;
3483
3506
  if (!drag) return;
@@ -4876,6 +4899,23 @@ function TableInner({
4876
4899
  setSelection(cell);
4877
4900
  return true;
4878
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
+ },
4879
4919
  getSelectedRowKeys: () => [...rowKeys],
4880
4920
  getSelectedRows: () => rows.filter((row, index) => selectedRowKeySet.has(getRowKey(row, index))),
4881
4921
  setSelectedRowKeys: (keys) => {
package/dist/index.d.cts CHANGED
@@ -260,6 +260,16 @@ type GridSelectionTarget = {
260
260
  rowKey?: GridKey;
261
261
  columnIndex?: number;
262
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
+ }
263
273
  /** Fully resolved selected cell returned by onSelectedCellChange. */
264
274
  interface SelectedCellChange extends GridSelection {
265
275
  value: unknown;
@@ -283,6 +293,9 @@ interface TableRef<Row extends object> {
283
293
  scrollToCell: (target: GridSelectionTarget) => boolean;
284
294
  getSelectedCell: () => TableCellContext<Row> | null;
285
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;
286
299
  getSelectedRowKeys: () => GridKey[];
287
300
  getSelectedRows: () => Row[];
288
301
  setSelectedRowKeys: (keys: GridKey[]) => void;
@@ -402,6 +415,11 @@ interface TableProps<Row extends object> {
402
415
  onSelectedCellChange?: (selection: SelectedCellChange | null) => void;
403
416
  /** Enable spreadsheet-style mouse drag selection across multiple body cells. Defaults to false. */
404
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;
405
423
  rowSelection?: boolean | RowSelectionConfig;
406
424
  selectedRowKeys?: GridKey[];
407
425
  defaultSelectedRowKeys?: GridKey[];
@@ -513,4 +531,4 @@ declare function hitTestColumn(metrics: ColumnMetric[], contentX: number): numbe
513
531
 
514
532
  type TableFilterValues = Record<string, string>;
515
533
 
516
- 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
@@ -260,6 +260,16 @@ type GridSelectionTarget = {
260
260
  rowKey?: GridKey;
261
261
  columnIndex?: number;
262
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
+ }
263
273
  /** Fully resolved selected cell returned by onSelectedCellChange. */
264
274
  interface SelectedCellChange extends GridSelection {
265
275
  value: unknown;
@@ -283,6 +293,9 @@ interface TableRef<Row extends object> {
283
293
  scrollToCell: (target: GridSelectionTarget) => boolean;
284
294
  getSelectedCell: () => TableCellContext<Row> | null;
285
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;
286
299
  getSelectedRowKeys: () => GridKey[];
287
300
  getSelectedRows: () => Row[];
288
301
  setSelectedRowKeys: (keys: GridKey[]) => void;
@@ -402,6 +415,11 @@ interface TableProps<Row extends object> {
402
415
  onSelectedCellChange?: (selection: SelectedCellChange | null) => void;
403
416
  /** Enable spreadsheet-style mouse drag selection across multiple body cells. Defaults to false. */
404
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;
405
423
  rowSelection?: boolean | RowSelectionConfig;
406
424
  selectedRowKeys?: GridKey[];
407
425
  defaultSelectedRowKeys?: GridKey[];
@@ -513,4 +531,4 @@ declare function hitTestColumn(metrics: ColumnMetric[], contentX: number): numbe
513
531
 
514
532
  type TableFilterValues = Record<string, string>;
515
533
 
516
- 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
@@ -1899,6 +1899,9 @@ function TableInner({
1899
1899
  defaultSelectedCell,
1900
1900
  onSelectedCellChange,
1901
1901
  rangeSelection = false,
1902
+ selectedRange,
1903
+ defaultSelectedRange,
1904
+ onSelectedRangeChange,
1902
1905
  rowSelection,
1903
1906
  selectedRowKeys,
1904
1907
  defaultSelectedRowKeys,
@@ -2308,6 +2311,20 @@ function TableInner({
2308
2311
  }, [columns, getDataRowKey, rows]);
2309
2312
  const resolvedSelectedCell = useMemo2(() => resolveSelectionTarget(selectedCell), [resolveSelectionTarget, selectedCell]);
2310
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
+ );
2311
2328
  const handleSelectedCellChange = useCallback2((next) => {
2312
2329
  if (!onSelectedCellChange) return;
2313
2330
  if (!next) {
@@ -2320,7 +2337,11 @@ function TableInner({
2320
2337
  onSelectedCellChange({ ...next, value });
2321
2338
  }, [columns, onSelectedCellChange, rows]);
2322
2339
  const [selection, setSelection] = useControllableValue(resolvedSelectedCell, resolvedDefaultSelectedCell, handleSelectedCellChange);
2323
- const [selectionRange, setSelectionRange] = useState6(null);
2340
+ const [selectionRange, setSelectionRange] = useControllableValue(
2341
+ resolvedSelectedRange,
2342
+ resolvedDefaultSelectedRange,
2343
+ onSelectedRangeChange
2344
+ );
2324
2345
  const rangeDragRef = useRef4(null);
2325
2346
  useEffect3(() => {
2326
2347
  if (!selection) return void 0;
@@ -3446,8 +3467,10 @@ function TableInner({
3446
3467
  if (focus.rowIndex === drag.anchor.rowIndex && focus.columnIndex === drag.anchor.columnIndex) return;
3447
3468
  drag.moved = true;
3448
3469
  event.preventDefault();
3449
- setSelectionRange((current) => current?.focus.rowIndex === focus.rowIndex && current.focus.columnIndex === focus.columnIndex ? current : { anchor: drag.anchor, focus });
3450
- }, [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]);
3451
3474
  const endRangeDrag = useCallback2((event) => {
3452
3475
  const drag = rangeDragRef.current;
3453
3476
  if (!drag) return;
@@ -4846,6 +4869,23 @@ function TableInner({
4846
4869
  setSelection(cell);
4847
4870
  return true;
4848
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
+ },
4849
4889
  getSelectedRowKeys: () => [...rowKeys],
4850
4890
  getSelectedRows: () => rows.filter((row, index) => selectedRowKeySet.has(getRowKey(row, index))),
4851
4891
  setSelectedRowKeys: (keys) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lensui/lens-table",
3
- "version": "0.1.80",
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",