@toolbox-web/grid 1.12.1 → 1.14.0

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.
Files changed (98) hide show
  1. package/all.js +1171 -943
  2. package/all.js.map +1 -1
  3. package/index.js +735 -737
  4. package/index.js.map +1 -1
  5. package/lib/core/grid.d.ts.map +1 -1
  6. package/lib/core/internal/row-animation.d.ts.map +1 -1
  7. package/lib/core/internal/sanitize.d.ts.map +1 -1
  8. package/lib/core/internal/validate-config.d.ts.map +1 -1
  9. package/lib/core/plugin/types.d.ts +1 -1
  10. package/lib/core/plugin/types.d.ts.map +1 -1
  11. package/lib/core/types.d.ts +48 -1
  12. package/lib/core/types.d.ts.map +1 -1
  13. package/lib/plugins/clipboard/ClipboardPlugin.d.ts +69 -8
  14. package/lib/plugins/clipboard/ClipboardPlugin.d.ts.map +1 -1
  15. package/lib/plugins/clipboard/index.d.ts +1 -1
  16. package/lib/plugins/clipboard/index.d.ts.map +1 -1
  17. package/lib/plugins/clipboard/index.js +257 -192
  18. package/lib/plugins/clipboard/index.js.map +1 -1
  19. package/lib/plugins/clipboard/types.d.ts +31 -0
  20. package/lib/plugins/clipboard/types.d.ts.map +1 -1
  21. package/lib/plugins/column-virtualization/index.js.map +1 -1
  22. package/lib/plugins/context-menu/ContextMenuPlugin.d.ts +8 -0
  23. package/lib/plugins/context-menu/ContextMenuPlugin.d.ts.map +1 -1
  24. package/lib/plugins/context-menu/index.js +75 -60
  25. package/lib/plugins/context-menu/index.js.map +1 -1
  26. package/lib/plugins/context-menu/types.d.ts +7 -0
  27. package/lib/plugins/context-menu/types.d.ts.map +1 -1
  28. package/lib/plugins/editing/EditingPlugin.d.ts.map +1 -1
  29. package/lib/plugins/editing/editors.d.ts +2 -2
  30. package/lib/plugins/editing/editors.d.ts.map +1 -1
  31. package/lib/plugins/editing/index.d.ts +1 -1
  32. package/lib/plugins/editing/index.d.ts.map +1 -1
  33. package/lib/plugins/editing/index.js +393 -337
  34. package/lib/plugins/editing/index.js.map +1 -1
  35. package/lib/plugins/editing/types.d.ts +50 -23
  36. package/lib/plugins/editing/types.d.ts.map +1 -1
  37. package/lib/plugins/export/ExportPlugin.d.ts.map +1 -1
  38. package/lib/plugins/export/index.js +75 -66
  39. package/lib/plugins/export/index.js.map +1 -1
  40. package/lib/plugins/filtering/index.d.ts +1 -1
  41. package/lib/plugins/filtering/index.d.ts.map +1 -1
  42. package/lib/plugins/filtering/index.js +9 -9
  43. package/lib/plugins/filtering/index.js.map +1 -1
  44. package/lib/plugins/grouping-columns/index.js.map +1 -1
  45. package/lib/plugins/grouping-rows/index.js.map +1 -1
  46. package/lib/plugins/master-detail/index.js +57 -56
  47. package/lib/plugins/master-detail/index.js.map +1 -1
  48. package/lib/plugins/multi-sort/index.js.map +1 -1
  49. package/lib/plugins/pinned-columns/index.js.map +1 -1
  50. package/lib/plugins/pinned-rows/PinnedRowsPlugin.d.ts +1 -0
  51. package/lib/plugins/pinned-rows/PinnedRowsPlugin.d.ts.map +1 -1
  52. package/lib/plugins/pinned-rows/index.js +118 -87
  53. package/lib/plugins/pinned-rows/index.js.map +1 -1
  54. package/lib/plugins/pinned-rows/pinned-rows.d.ts +2 -1
  55. package/lib/plugins/pinned-rows/pinned-rows.d.ts.map +1 -1
  56. package/lib/plugins/pinned-rows/types.d.ts +23 -2
  57. package/lib/plugins/pinned-rows/types.d.ts.map +1 -1
  58. package/lib/plugins/pivot/index.js.map +1 -1
  59. package/lib/plugins/print/index.js.map +1 -1
  60. package/lib/plugins/reorder/index.js.map +1 -1
  61. package/lib/plugins/responsive/index.js +40 -39
  62. package/lib/plugins/responsive/index.js.map +1 -1
  63. package/lib/plugins/row-reorder/index.js.map +1 -1
  64. package/lib/plugins/selection/SelectionPlugin.d.ts +51 -0
  65. package/lib/plugins/selection/SelectionPlugin.d.ts.map +1 -1
  66. package/lib/plugins/selection/index.js +347 -145
  67. package/lib/plugins/selection/index.js.map +1 -1
  68. package/lib/plugins/selection/types.d.ts +18 -0
  69. package/lib/plugins/selection/types.d.ts.map +1 -1
  70. package/lib/plugins/server-side/index.js.map +1 -1
  71. package/lib/plugins/shared/data-collection.d.ts +33 -0
  72. package/lib/plugins/shared/data-collection.d.ts.map +1 -0
  73. package/lib/plugins/tree/index.js.map +1 -1
  74. package/lib/plugins/undo-redo/index.js.map +1 -1
  75. package/lib/plugins/visibility/index.js.map +1 -1
  76. package/package.json +1 -1
  77. package/public.d.ts +2 -0
  78. package/public.d.ts.map +1 -1
  79. package/themes/dg-theme-bootstrap.css +192 -8
  80. package/themes/dg-theme-material.css +243 -0
  81. package/umd/grid.all.umd.js +42 -42
  82. package/umd/grid.all.umd.js.map +1 -1
  83. package/umd/grid.umd.js +19 -19
  84. package/umd/grid.umd.js.map +1 -1
  85. package/umd/plugins/clipboard.umd.js +5 -5
  86. package/umd/plugins/clipboard.umd.js.map +1 -1
  87. package/umd/plugins/context-menu.umd.js +1 -1
  88. package/umd/plugins/context-menu.umd.js.map +1 -1
  89. package/umd/plugins/editing.umd.js +1 -1
  90. package/umd/plugins/editing.umd.js.map +1 -1
  91. package/umd/plugins/export.umd.js +7 -7
  92. package/umd/plugins/export.umd.js.map +1 -1
  93. package/umd/plugins/filtering.umd.js +1 -1
  94. package/umd/plugins/filtering.umd.js.map +1 -1
  95. package/umd/plugins/pinned-rows.umd.js +1 -1
  96. package/umd/plugins/pinned-rows.umd.js.map +1 -1
  97. package/umd/plugins/selection.umd.js +2 -2
  98. package/umd/plugins/selection.umd.js.map +1 -1
@@ -1,20 +1,20 @@
1
- function S(r) {
2
- if (!r) return -1;
3
- const e = r.getAttribute("data-row");
1
+ function R(o) {
2
+ if (!o) return -1;
3
+ const e = o.getAttribute("data-row");
4
4
  if (e) return parseInt(e, 10);
5
- const t = r.closest(".data-grid-row");
5
+ const t = o.closest(".data-grid-row");
6
6
  if (!t) return -1;
7
7
  const s = t.parentElement;
8
8
  if (!s) return -1;
9
- const i = s.querySelectorAll(":scope > .data-grid-row");
10
- for (let l = 0; l < i.length; l++)
11
- if (i[l] === t) return l;
9
+ const r = s.querySelectorAll(":scope > .data-grid-row");
10
+ for (let n = 0; n < r.length; n++)
11
+ if (r[n] === t) return n;
12
12
  return -1;
13
13
  }
14
- function m(r) {
15
- r && r.querySelectorAll(".cell-focus").forEach((e) => e.classList.remove("cell-focus"));
14
+ function C(o) {
15
+ o && o.querySelectorAll(".cell-focus").forEach((e) => e.classList.remove("cell-focus"));
16
16
  }
17
- const R = '<svg viewBox="0 0 16 16" width="12" height="12"><path fill="currentColor" d="M6 10.5a.5.5 0 0 1 .5-.5h3a.5.5 0 0 1 0 1h-3a.5.5 0 0 1-.5-.5zm-2-3a.5.5 0 0 1 .5-.5h7a.5.5 0 0 1 0 1h-7a.5.5 0 0 1-.5-.5zm-2-3a.5.5 0 0 1 .5-.5h11a.5.5 0 0 1 0 1h-11a.5.5 0 0 1-.5-.5z"/></svg>', y = {
17
+ const p = '<svg viewBox="0 0 16 16" width="12" height="12"><path fill="currentColor" d="M6 10.5a.5.5 0 0 1 .5-.5h3a.5.5 0 0 1 0 1h-3a.5.5 0 0 1-.5-.5zm-2-3a.5.5 0 0 1 .5-.5h7a.5.5 0 0 1 0 1h-7a.5.5 0 0 1-.5-.5zm-2-3a.5.5 0 0 1 .5-.5h11a.5.5 0 0 1 0 1h-11a.5.5 0 0 1-.5-.5z"/></svg>', A = {
18
18
  expand: "▶",
19
19
  collapse: "▼",
20
20
  sortAsc: "▲",
@@ -23,8 +23,8 @@ const R = '<svg viewBox="0 0 16 16" width="12" height="12"><path fill="currentCo
23
23
  submenuArrow: "▶",
24
24
  dragHandle: "⋮⋮",
25
25
  toolPanel: "☰",
26
- filter: R,
27
- filterActive: R,
26
+ filter: p,
27
+ filterActive: p,
28
28
  print: "🖨️"
29
29
  };
30
30
  class v {
@@ -317,7 +317,7 @@ class v {
317
317
  */
318
318
  get gridIcons() {
319
319
  const e = this.grid?.gridConfig?.icons ?? {};
320
- return { ...y, ...e };
320
+ return { ...A, ...e };
321
321
  }
322
322
  // #region Animation Helpers
323
323
  /**
@@ -393,65 +393,69 @@ class v {
393
393
  }
394
394
  // #endregion
395
395
  }
396
- function g(r) {
397
- return r.meta?.utility === !0;
396
+ const E = "__tbw_expander";
397
+ function k(o) {
398
+ return o.field === E;
398
399
  }
399
- function u(r) {
400
+ function f(o) {
401
+ return o.meta?.utility === !0;
402
+ }
403
+ function g(o) {
400
404
  return {
401
- startRow: Math.min(r.startRow, r.endRow),
402
- startCol: Math.min(r.startCol, r.endCol),
403
- endRow: Math.max(r.startRow, r.endRow),
404
- endCol: Math.max(r.startCol, r.endCol)
405
+ startRow: Math.min(o.startRow, o.endRow),
406
+ startCol: Math.min(o.startCol, o.endCol),
407
+ endRow: Math.max(o.startRow, o.endRow),
408
+ endCol: Math.max(o.startCol, o.endCol)
405
409
  };
406
410
  }
407
- function E(r) {
408
- const e = u(r);
411
+ function I(o) {
412
+ const e = g(o);
409
413
  return {
410
414
  from: { row: e.startRow, col: e.startCol },
411
415
  to: { row: e.endRow, col: e.endCol }
412
416
  };
413
417
  }
414
- function p(r) {
415
- return r.map(E);
418
+ function y(o) {
419
+ return o.map(I);
416
420
  }
417
- function x(r, e, t) {
418
- const s = u(t);
419
- return r >= s.startRow && r <= s.endRow && e >= s.startCol && e <= s.endCol;
421
+ function _(o, e, t) {
422
+ const s = g(t);
423
+ return o >= s.startRow && o <= s.endRow && e >= s.startCol && e <= s.endCol;
420
424
  }
421
- function C(r, e, t) {
422
- return t.some((s) => x(r, e, s));
425
+ function q(o, e, t) {
426
+ return t.some((s) => _(o, e, s));
423
427
  }
424
- function I(r) {
425
- const e = [], t = u(r);
428
+ function K(o) {
429
+ const e = [], t = g(o);
426
430
  for (let s = t.startRow; s <= t.endRow; s++)
427
- for (let i = t.startCol; i <= t.endCol; i++)
428
- e.push({ row: s, col: i });
431
+ for (let r = t.startCol; r <= t.endCol; r++)
432
+ e.push({ row: s, col: r });
429
433
  return e;
430
434
  }
431
- function q(r) {
435
+ function M(o) {
432
436
  const e = /* @__PURE__ */ new Map();
433
- for (const t of r)
434
- for (const s of I(t))
437
+ for (const t of o)
438
+ for (const s of K(t))
435
439
  e.set(`${s.row},${s.col}`, s);
436
440
  return [...e.values()];
437
441
  }
438
- function b(r, e) {
442
+ function m(o, e) {
439
443
  return {
440
- startRow: r.row,
441
- startCol: r.col,
444
+ startRow: o.row,
445
+ startCol: o.col,
442
446
  endRow: e.row,
443
447
  endCol: e.col
444
448
  };
445
449
  }
446
- function w(r, e) {
447
- const t = u(r), s = u(e);
450
+ function b(o, e) {
451
+ const t = g(o), s = g(e);
448
452
  return t.startRow === s.startRow && t.startCol === s.startCol && t.endRow === s.endRow && t.endCol === s.endCol;
449
453
  }
450
- const k = "@layer tbw-plugins{tbw-grid.selecting .data-grid-row>.cell{-webkit-user-select:none;user-select:none}tbw-grid:has(.selection){-webkit-user-select:none;user-select:none}tbw-grid[data-has-focus] .data-grid-row.row-focus{background-color:var(--tbw-focus-background, rgba(from var(--tbw-color-accent) r g b / 12%))}tbw-grid[data-selection-mode=row] .cell-focus{outline:none}tbw-grid .data-grid-row>.cell.selected{background-color:var(--tbw-range-selection-bg)}tbw-grid .data-grid-row>.cell.selected.top{border-top:2px solid var(--tbw-range-border-color);padding-top:calc(var(--tbw-cell-padding, 2px 8px) - 2px)}tbw-grid .data-grid-row>.cell.selected.bottom{border-bottom:2px solid var(--tbw-range-border-color);padding-bottom:calc(var(--tbw-cell-padding, 2px 8px) - 2px)}tbw-grid .data-grid-row>.cell.selected.first{border-left:2px solid var(--tbw-range-border-color);padding-left:calc(var(--tbw-cell-padding, 2px 8px) - 2px)}tbw-grid .data-grid-row>.cell.selected.last{border-right:2px solid var(--tbw-range-border-color);padding-right:calc(var(--tbw-cell-padding, 2px 8px) - 2px)}tbw-grid .data-grid-row[data-selectable=false]{cursor:not-allowed;opacity:.6}tbw-grid .data-grid-row[data-selectable=false].row-focus{background-color:var(--tbw-color-row-alt)}tbw-grid .data-grid-row>.cell[data-selectable=false]{cursor:not-allowed;opacity:.6}tbw-grid .data-grid-row>.cell[data-selectable=false].selected{background-color:var(--tbw-selection-warning-bg, rgba(from var(--tbw-color-error) r g b / 50%))}tbw-grid .tbw-selection-summary{font-size:var(--tbw-font-size-sm, .8125rem);color:var(--tbw-color-fg-muted);white-space:nowrap}}";
451
- function _(r, e, t) {
452
- if (r === "cell" && e.selectedCell)
454
+ const F = '@layer tbw-plugins{tbw-grid.selecting .data-grid-row>.cell{-webkit-user-select:none;user-select:none}tbw-grid:has(.selection){-webkit-user-select:none;user-select:none}tbw-grid .data-grid-row.row-focus{background-color:var(--tbw-focus-background, rgba(from var(--tbw-color-accent) r g b / 12%));outline:none;position:relative}tbw-grid .data-grid-row.row-focus:after{content:"";position:absolute;inset:0;pointer-events:none;border-width:0;border-style:var(--tbw-selection-border-style, var(--tbw-border-style));border-color:var(--tbw-range-border-color, var(--tbw-color-accent));border-top-width:var(--tbw-selection-border-width, var(--tbw-border-width));border-bottom-width:var(--tbw-selection-border-width, var(--tbw-border-width));z-index:1}tbw-grid .data-grid-row.row-focus+.data-grid-row.row-focus:after{border-top-width:0}tbw-grid .data-grid-row.row-focus:has(+.data-grid-row.row-focus):after{border-bottom-width:0}tbw-grid[data-selection-mode=row] .cell-focus,tbw-grid[data-selection-mode=row] .row-focus,tbw-grid[data-selection-mode=range] .cell-focus{outline:none}tbw-grid .data-grid-row>.cell.selected{background-color:var(--tbw-range-selection-bg);position:relative}tbw-grid .data-grid-row>.cell.selected:after{content:"";position:absolute;inset:0;pointer-events:none;border:0 var(--tbw-selection-border-style, var(--tbw-border-style)) var(--tbw-range-border-color);z-index:1}tbw-grid .data-grid-row>.cell.selected.top:after{border-top-width:var(--tbw-selection-border-width, var(--tbw-border-width))}tbw-grid .data-grid-row>.cell.selected.bottom:after{border-bottom-width:var(--tbw-selection-border-width, var(--tbw-border-width))}tbw-grid .data-grid-row>.cell.selected.first:after{border-left-width:var(--tbw-selection-border-width, var(--tbw-border-width))}tbw-grid .data-grid-row>.cell.selected.last:after{border-right-width:var(--tbw-selection-border-width, var(--tbw-border-width))}tbw-grid .data-grid-row[data-selectable=false]{cursor:not-allowed;opacity:.6}tbw-grid .data-grid-row[data-selectable=false].row-focus{background-color:var(--tbw-color-row-alt)}tbw-grid .data-grid-row>.cell[data-selectable=false]{cursor:not-allowed;opacity:.6}tbw-grid .data-grid-row>.cell[data-selectable=false].selected{background-color:var(--tbw-selection-warning-bg, rgba(from var(--tbw-color-error) r g b / 50%))}tbw-grid .tbw-selection-summary{font-size:var(--tbw-font-size-sm, .8125rem);color:var(--tbw-color-fg-muted);white-space:nowrap}tbw-grid .data-grid-row>.cell[data-field=__tbw_checkbox],tbw-grid .header-row>.cell[data-field=__tbw_checkbox]{text-align:center;cursor:pointer;padding:0;display:flex;align-items:center;justify-content:center}tbw-grid .tbw-select-row-checkbox{pointer-events:none;margin:0;cursor:pointer}tbw-grid .tbw-checkbox-header{display:flex;justify-content:center;align-items:center;height:100%}tbw-grid .tbw-select-all-checkbox{margin:0;cursor:pointer}}', S = "__tbw_checkbox";
455
+ function D(o, e, t) {
456
+ if (o === "cell" && e.selectedCell)
453
457
  return {
454
- mode: r,
458
+ mode: o,
455
459
  ranges: [
456
460
  {
457
461
  from: { row: e.selectedCell.row, col: e.selectedCell.col },
@@ -459,22 +463,26 @@ function _(r, e, t) {
459
463
  }
460
464
  ]
461
465
  };
462
- if (r === "row" && e.selected.size > 0) {
463
- const s = [...e.selected].map((i) => ({
464
- from: { row: i, col: 0 },
465
- to: { row: i, col: t - 1 }
466
- }));
467
- return { mode: r, ranges: s };
468
- }
469
- return r === "range" && e.ranges.length > 0 ? { mode: r, ranges: p(e.ranges) } : { mode: r, ranges: [] };
466
+ if (o === "row" && e.selected.size > 0) {
467
+ const s = [...e.selected].sort((l, d) => l - d), r = [];
468
+ let n = s[0], i = n;
469
+ for (let l = 1; l < s.length; l++)
470
+ s[l] === i + 1 ? i = s[l] : (r.push({ from: { row: n, col: 0 }, to: { row: i, col: t - 1 } }), n = s[l], i = n);
471
+ return r.push({ from: { row: n, col: 0 }, to: { row: i, col: t - 1 } }), { mode: o, ranges: r };
472
+ }
473
+ return o === "range" && e.ranges.length > 0 ? { mode: o, ranges: y(e.ranges) } : { mode: o, ranges: [] };
470
474
  }
471
- class D extends v {
475
+ class L extends v {
472
476
  /**
473
477
  * Plugin manifest - declares queries and configuration validation rules.
474
478
  * @internal
475
479
  */
476
480
  static manifest = {
477
- queries: [{ type: "getSelection", description: "Get the current selection state" }],
481
+ queries: [
482
+ { type: "getSelection", description: "Get the current selection state" },
483
+ { type: "selectRows", description: "Select specific rows by index (row mode only)" },
484
+ { type: "getSelectedRowIndices", description: "Get sorted array of selected row indices" }
485
+ ],
478
486
  configRules: [
479
487
  {
480
488
  id: "selection/range-dblclick",
@@ -489,7 +497,7 @@ class D extends v {
489
497
  /** @internal */
490
498
  name = "selection";
491
499
  /** @internal */
492
- styles = k;
500
+ styles = F;
493
501
  /** @internal */
494
502
  get defaultConfig() {
495
503
  return {
@@ -512,6 +520,12 @@ class D extends v {
512
520
  pendingKeyboardUpdate = null;
513
521
  /** Cell selection state (cell mode) */
514
522
  selectedCell = null;
523
+ /** Last synced focus row — used to detect when grid focus moves so selection follows */
524
+ lastSyncedFocusRow = -1;
525
+ /** Last synced focus col (cell mode) */
526
+ lastSyncedFocusCol = -1;
527
+ /** True when selection was explicitly set (click/keyboard) — prevents #syncSelectionToFocus from overwriting */
528
+ explicitSelection = !1;
515
529
  // #endregion
516
530
  // #region Private Helpers - Selection Enabled Check
517
531
  /**
@@ -530,10 +544,10 @@ class D extends v {
530
544
  checkSelectable(e, t) {
531
545
  const { isSelectable: s } = this.config;
532
546
  if (!s) return !0;
533
- const i = this.rows[e];
534
- if (!i) return !1;
535
- const l = t !== void 0 ? this.columns[t] : void 0;
536
- return s(i, e, l, t);
547
+ const r = this.rows[e];
548
+ if (!r) return !1;
549
+ const n = t !== void 0 ? this.columns[t] : void 0;
550
+ return s(r, e, n, t);
537
551
  }
538
552
  /**
539
553
  * Check if an entire row is selectable (for row mode).
@@ -560,42 +574,62 @@ class D extends v {
560
574
  handleQuery(e) {
561
575
  if (e.type === "getSelection")
562
576
  return this.getSelection();
577
+ if (e.type === "getSelectedRowIndices")
578
+ return this.getSelectedRowIndices();
579
+ if (e.type === "selectRows")
580
+ return this.selectRows(e.context), !0;
563
581
  }
564
582
  /** @internal */
565
583
  detach() {
566
- this.selected.clear(), this.ranges = [], this.activeRange = null, this.cellAnchor = null, this.isDragging = !1, this.selectedCell = null, this.pendingKeyboardUpdate = null;
584
+ this.selected.clear(), this.ranges = [], this.activeRange = null, this.cellAnchor = null, this.isDragging = !1, this.selectedCell = null, this.pendingKeyboardUpdate = null, this.lastSyncedFocusRow = -1, this.lastSyncedFocusCol = -1;
567
585
  }
568
586
  /**
569
587
  * Clear selection without emitting an event.
570
588
  * Used when selection is invalidated by external changes (filtering, grouping, etc.)
571
589
  */
572
590
  clearSelectionSilent() {
573
- this.selected.clear(), this.ranges = [], this.activeRange = null, this.cellAnchor = null, this.selectedCell = null, this.lastSelected = null, this.anchor = null, this.requestAfterRender();
591
+ this.selected.clear(), this.ranges = [], this.activeRange = null, this.cellAnchor = null, this.selectedCell = null, this.lastSelected = null, this.anchor = null, this.lastSyncedFocusRow = -1, this.lastSyncedFocusCol = -1, this.requestAfterRender();
574
592
  }
575
593
  // #endregion
576
594
  // #region Event Handlers
577
595
  /** @internal */
578
596
  onCellClick(e) {
579
597
  if (!this.isSelectionEnabled()) return !1;
580
- const { rowIndex: t, colIndex: s, originalEvent: i } = e, { mode: l, triggerOn: n = "click" } = this.config;
581
- if (i.type !== n)
598
+ const { rowIndex: t, colIndex: s, originalEvent: r } = e, { mode: n, triggerOn: i = "click" } = this.config;
599
+ if (r.type !== i)
582
600
  return !1;
583
- const o = this.columns[s], d = o && g(o);
584
- if (l === "cell") {
601
+ const l = this.columns[s], d = l && f(l);
602
+ if (n === "cell") {
585
603
  if (d || !this.isCellSelectable(t, s))
586
604
  return !1;
587
605
  const a = this.selectedCell;
588
606
  return a && a.row === t && a.col === s || (this.selectedCell = { row: t, col: s }, this.emit("selection-change", this.#e()), this.requestAfterRender()), !1;
589
607
  }
590
- if (l === "row")
591
- return !this.isRowSelectable(t) || this.selected.size === 1 && this.selected.has(t) || (this.selected.clear(), this.selected.add(t), this.lastSelected = t, this.emit("selection-change", this.#e()), this.requestAfterRender()), !1;
592
- if (l === "range") {
608
+ if (n === "row") {
609
+ if (!this.isRowSelectable(t))
610
+ return !1;
611
+ const a = r.shiftKey, h = r.ctrlKey || r.metaKey, c = l?.meta?.checkboxColumn === !0;
612
+ if (a && this.anchor !== null) {
613
+ const u = Math.min(this.anchor, t), x = Math.max(this.anchor, t);
614
+ h || this.selected.clear();
615
+ for (let w = u; w <= x; w++)
616
+ this.isRowSelectable(w) && this.selected.add(w);
617
+ } else if (h || c)
618
+ this.selected.has(t) ? this.selected.delete(t) : this.selected.add(t), this.anchor = t;
619
+ else {
620
+ if (this.selected.size === 1 && this.selected.has(t))
621
+ return !1;
622
+ this.selected.clear(), this.selected.add(t), this.anchor = t;
623
+ }
624
+ return this.lastSelected = t, this.explicitSelection = !0, this.emit("selection-change", this.#e()), this.requestAfterRender(), !1;
625
+ }
626
+ if (n === "range") {
593
627
  if (d || !this.isCellSelectable(t, s))
594
628
  return !1;
595
- const a = i.shiftKey, h = i.ctrlKey || i.metaKey;
629
+ const a = r.shiftKey, h = r.ctrlKey || r.metaKey;
596
630
  if (a && this.cellAnchor) {
597
- const c = b(this.cellAnchor, { row: t, col: s }), f = this.ranges.length > 0 ? this.ranges[this.ranges.length - 1] : null;
598
- if (f && w(f, c))
631
+ const c = m(this.cellAnchor, { row: t, col: s }), u = this.ranges.length > 0 ? this.ranges[this.ranges.length - 1] : null;
632
+ if (u && b(u, c))
599
633
  return !1;
600
634
  h ? this.ranges.length > 0 ? this.ranges[this.ranges.length - 1] = c : this.ranges.push(c) : this.ranges = [c], this.activeRange = c;
601
635
  } else if (h) {
@@ -613,7 +647,7 @@ class D extends v {
613
647
  endRow: t,
614
648
  endCol: s
615
649
  };
616
- if (this.ranges.length === 1 && w(this.ranges[0], c))
650
+ if (this.ranges.length === 1 && b(this.ranges[0], c))
617
651
  return !1;
618
652
  this.ranges = [c], this.activeRange = c, this.cellAnchor = { row: t, col: s };
619
653
  }
@@ -624,104 +658,205 @@ class D extends v {
624
658
  /** @internal */
625
659
  onKeyDown(e) {
626
660
  if (!this.isSelectionEnabled()) return !1;
627
- const { mode: t } = this.config, i = ["ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight", "Tab", "Home", "End", "PageUp", "PageDown"].includes(e.key);
661
+ const { mode: t } = this.config, r = ["ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight", "Tab", "Home", "End", "PageUp", "PageDown"].includes(e.key);
628
662
  if (e.key === "Escape")
629
- return t === "cell" ? this.selectedCell = null : t === "row" ? (this.selected.clear(), this.anchor = null) : t === "range" && (this.ranges = [], this.activeRange = null, this.cellAnchor = null), this.emit("selection-change", this.#e()), this.requestAfterRender(), !0;
630
- if (t === "cell" && i)
631
- return queueMicrotask(() => {
632
- const l = this.grid._focusRow, n = this.grid._focusCol;
633
- this.isCellSelectable(l, n) ? this.selectedCell = { row: l, col: n } : this.selectedCell = null, this.emit("selection-change", this.#e()), this.requestAfterRender();
634
- }), !1;
635
- if (t === "row" && (e.key === "ArrowUp" || e.key === "ArrowDown"))
663
+ return this.grid.query("isEditing").some(Boolean) ? !1 : (t === "cell" ? this.selectedCell = null : t === "row" ? (this.selected.clear(), this.anchor = null) : t === "range" && (this.ranges = [], this.activeRange = null, this.cellAnchor = null), this.emit("selection-change", this.#e()), this.requestAfterRender(), !0);
664
+ if (t === "cell" && r)
636
665
  return queueMicrotask(() => {
637
- const l = this.grid._focusRow;
638
- this.isRowSelectable(l) ? (this.selected.clear(), this.selected.add(l), this.lastSelected = l) : this.selected.clear(), this.emit("selection-change", this.#e()), this.requestAfterRender();
666
+ const n = this.grid._focusRow, i = this.grid._focusCol;
667
+ this.isCellSelectable(n, i) ? this.selectedCell = { row: n, col: i } : this.selectedCell = null, this.emit("selection-change", this.#e()), this.requestAfterRender();
639
668
  }), !1;
640
- if (t === "range" && i) {
641
- const l = e.key === "Tab", n = e.shiftKey && !l;
642
- return n && !this.cellAnchor && (this.cellAnchor = { row: this.grid._focusRow, col: this.grid._focusCol }), this.pendingKeyboardUpdate = { shiftKey: n }, queueMicrotask(() => this.requestAfterRender()), !1;
643
- }
644
- if (t === "range" && e.key === "a" && (e.ctrlKey || e.metaKey)) {
645
- const l = this.rows.length, n = this.columns.length;
646
- if (l > 0 && n > 0) {
647
- e.preventDefault(), e.stopPropagation();
648
- const o = {
649
- startRow: 0,
650
- startCol: 0,
651
- endRow: l - 1,
652
- endCol: n - 1
653
- };
654
- return this.ranges = [o], this.activeRange = o, this.emit("selection-change", this.#e()), this.requestAfterRender(), !0;
669
+ if (t === "row") {
670
+ if (e.key === "ArrowUp" || e.key === "ArrowDown") {
671
+ const n = e.shiftKey;
672
+ return n && this.anchor === null && (this.anchor = this.grid._focusRow), queueMicrotask(() => {
673
+ const i = this.grid._focusRow;
674
+ if (n && this.anchor !== null) {
675
+ this.selected.clear();
676
+ const l = Math.min(this.anchor, i), d = Math.max(this.anchor, i);
677
+ for (let a = l; a <= d; a++)
678
+ this.isRowSelectable(a) && this.selected.add(a);
679
+ } else
680
+ this.isRowSelectable(i) ? (this.selected.clear(), this.selected.add(i), this.anchor = i) : this.selected.clear();
681
+ this.lastSelected = i, this.explicitSelection = !0, this.emit("selection-change", this.#e()), this.requestAfterRender();
682
+ }), !1;
655
683
  }
684
+ if (e.key === "a" && (e.ctrlKey || e.metaKey))
685
+ return e.preventDefault(), e.stopPropagation(), this.selectAll(), !0;
656
686
  }
657
- return !1;
687
+ if (t === "range" && r) {
688
+ const n = e.key === "Tab", i = e.shiftKey && !n;
689
+ return i && !this.cellAnchor && (this.cellAnchor = { row: this.grid._focusRow, col: this.grid._focusCol }), this.pendingKeyboardUpdate = { shiftKey: i }, queueMicrotask(() => this.requestAfterRender()), !1;
690
+ }
691
+ return t === "range" && e.key === "a" && (e.ctrlKey || e.metaKey) ? (e.preventDefault(), e.stopPropagation(), this.selectAll(), !0) : !1;
658
692
  }
659
693
  /** @internal */
660
694
  onCellMouseDown(e) {
661
695
  if (!this.isSelectionEnabled() || this.config.mode !== "range" || e.rowIndex === void 0 || e.colIndex === void 0 || e.rowIndex < 0) return;
662
696
  const t = this.columns[e.colIndex];
663
- if (t && g(t) || !this.isCellSelectable(e.rowIndex, e.colIndex) || e.originalEvent.shiftKey && this.cellAnchor)
697
+ if (t && f(t) || !this.isCellSelectable(e.rowIndex, e.colIndex) || e.originalEvent.shiftKey && this.cellAnchor)
664
698
  return;
665
699
  this.isDragging = !0;
666
- const s = e.rowIndex, i = e.colIndex, l = e.originalEvent.ctrlKey || e.originalEvent.metaKey, n = {
700
+ const s = e.rowIndex, r = e.colIndex, n = e.originalEvent.ctrlKey || e.originalEvent.metaKey, i = {
667
701
  startRow: s,
668
- startCol: i,
702
+ startCol: r,
669
703
  endRow: s,
670
- endCol: i
704
+ endCol: r
671
705
  };
672
- return !l && this.ranges.length === 1 && w(this.ranges[0], n) ? (this.cellAnchor = { row: s, col: i }, !0) : (this.cellAnchor = { row: s, col: i }, l || (this.ranges = []), this.ranges.push(n), this.activeRange = n, this.emit("selection-change", this.#e()), this.requestAfterRender(), !0);
706
+ return !n && this.ranges.length === 1 && b(this.ranges[0], i) ? (this.cellAnchor = { row: s, col: r }, !0) : (this.cellAnchor = { row: s, col: r }, n || (this.ranges = []), this.ranges.push(i), this.activeRange = i, this.emit("selection-change", this.#e()), this.requestAfterRender(), !0);
673
707
  }
674
708
  /** @internal */
675
709
  onCellMouseMove(e) {
676
710
  if (!this.isSelectionEnabled() || this.config.mode !== "range" || !this.isDragging || !this.cellAnchor || e.rowIndex === void 0 || e.colIndex === void 0 || e.rowIndex < 0) return;
677
711
  let t = e.colIndex;
678
712
  const s = this.columns[t];
679
- if (s && g(s)) {
680
- const n = this.columns.findIndex((o) => !g(o));
681
- n >= 0 && (t = n);
713
+ if (s && f(s)) {
714
+ const i = this.columns.findIndex((l) => !f(l));
715
+ i >= 0 && (t = i);
682
716
  }
683
- const i = b(this.cellAnchor, { row: e.rowIndex, col: t }), l = this.ranges.length > 0 ? this.ranges[this.ranges.length - 1] : null;
684
- return l && w(l, i) || (this.ranges.length > 0 ? this.ranges[this.ranges.length - 1] = i : this.ranges.push(i), this.activeRange = i, this.emit("selection-change", this.#e()), this.requestAfterRender()), !0;
717
+ const r = m(this.cellAnchor, { row: e.rowIndex, col: t }), n = this.ranges.length > 0 ? this.ranges[this.ranges.length - 1] : null;
718
+ return n && b(n, r) || (this.ranges.length > 0 ? this.ranges[this.ranges.length - 1] = r : this.ranges.push(r), this.activeRange = r, this.emit("selection-change", this.#e()), this.requestAfterRender()), !0;
685
719
  }
686
720
  /** @internal */
687
721
  onCellMouseUp(e) {
688
722
  if (this.isSelectionEnabled() && this.config.mode === "range" && this.isDragging)
689
723
  return this.isDragging = !1, !0;
690
724
  }
725
+ // #region Checkbox Column
691
726
  /**
692
- * Apply selection classes to visible cells/rows.
693
- * Shared by afterRender and onScrollRender.
727
+ * Inject checkbox column when `checkbox: true` and mode is `'row'`.
728
+ * @internal
729
+ */
730
+ processColumns(e) {
731
+ if (this.config.checkbox && this.config.mode === "row") {
732
+ if (e.some((n) => n.field === S))
733
+ return e;
734
+ const t = this.#t(), s = e.findIndex(k), r = s >= 0 ? s + 1 : 0;
735
+ return [...e.slice(0, r), t, ...e.slice(r)];
736
+ }
737
+ return e;
738
+ }
739
+ /**
740
+ * Create the checkbox utility column configuration.
694
741
  */
695
742
  #t() {
743
+ return {
744
+ field: S,
745
+ header: "",
746
+ width: 32,
747
+ resizable: !1,
748
+ sortable: !1,
749
+ meta: {
750
+ lockPosition: !0,
751
+ suppressMovable: !0,
752
+ utility: !0,
753
+ checkboxColumn: !0
754
+ },
755
+ headerRenderer: () => {
756
+ const e = document.createElement("div");
757
+ e.className = "tbw-checkbox-header";
758
+ const t = document.createElement("input");
759
+ return t.type = "checkbox", t.className = "tbw-select-all-checkbox", t.addEventListener("click", (s) => {
760
+ s.stopPropagation(), s.target.checked ? this.selectAll() : this.clearSelection();
761
+ }), e.appendChild(t), e;
762
+ },
763
+ renderer: (e) => {
764
+ const t = document.createElement("input");
765
+ t.type = "checkbox", t.className = "tbw-select-row-checkbox";
766
+ const s = e.cellEl;
767
+ if (s) {
768
+ const r = parseInt(s.getAttribute("data-row") ?? "-1", 10);
769
+ r >= 0 && (t.checked = this.selected.has(r));
770
+ }
771
+ return t;
772
+ }
773
+ };
774
+ }
775
+ /**
776
+ * Update checkbox checked states to reflect current selection.
777
+ * Called from #applySelectionClasses.
778
+ */
779
+ #r(e) {
780
+ e.querySelectorAll(".tbw-select-row-checkbox").forEach((r) => {
781
+ const n = r.closest(".cell"), i = n ? R(n) : -1;
782
+ i >= 0 && (r.checked = this.selected.has(i));
783
+ });
784
+ const s = e.querySelector(".tbw-select-all-checkbox");
785
+ if (s) {
786
+ const r = this.rows.length;
787
+ let n = 0;
788
+ if (this.config.isSelectable)
789
+ for (let d = 0; d < r; d++)
790
+ this.isRowSelectable(d) && n++;
791
+ else
792
+ n = r;
793
+ const i = n > 0 && this.selected.size >= n, l = this.selected.size > 0;
794
+ s.checked = i, s.indeterminate = l && !i;
795
+ }
796
+ }
797
+ // #endregion
798
+ /**
799
+ * Sync selection state to the grid's current focus position.
800
+ * In row mode, keeps `selected` in sync with `_focusRow`.
801
+ * In cell mode, keeps `selectedCell` in sync with `_focusRow`/`_focusCol`.
802
+ * Only updates when the focus has changed since the last sync.
803
+ * Skips when `explicitSelection` is set (click/keyboard set selection directly).
804
+ */
805
+ #i(e) {
806
+ const t = this.grid._focusRow, s = this.grid._focusCol;
807
+ if (e === "row") {
808
+ if (this.explicitSelection) {
809
+ this.explicitSelection = !1, this.lastSyncedFocusRow = t;
810
+ return;
811
+ }
812
+ t !== this.lastSyncedFocusRow && (this.lastSyncedFocusRow = t, this.isRowSelectable(t) && (!this.selected.has(t) || this.selected.size !== 1) && (this.selected.clear(), this.selected.add(t), this.lastSelected = t, this.anchor = t, this.emit("selection-change", this.#e())));
813
+ }
814
+ if (e === "cell") {
815
+ if (this.explicitSelection) {
816
+ this.explicitSelection = !1, this.lastSyncedFocusRow = t, this.lastSyncedFocusCol = s;
817
+ return;
818
+ }
819
+ if ((t !== this.lastSyncedFocusRow || s !== this.lastSyncedFocusCol) && (this.lastSyncedFocusRow = t, this.lastSyncedFocusCol = s, this.isCellSelectable(t, s))) {
820
+ const r = this.selectedCell;
821
+ (!r || r.row !== t || r.col !== s) && (this.selectedCell = { row: t, col: s }, this.emit("selection-change", this.#e()));
822
+ }
823
+ }
824
+ }
825
+ /**
826
+ * Apply CSS selection classes to row/cell elements.
827
+ * Shared by afterRender and onScrollRender.
828
+ */
829
+ #s() {
696
830
  const e = this.gridElement;
697
831
  if (!e) return;
698
832
  const { mode: t } = this.config, s = !!this.config.isSelectable;
699
- e.querySelectorAll(".cell").forEach((n) => {
700
- n.classList.remove("selected", "top", "bottom", "first", "last"), s && n.removeAttribute("data-selectable");
833
+ e.querySelectorAll(".cell").forEach((i) => {
834
+ i.classList.remove("selected", "top", "bottom", "first", "last"), s && i.removeAttribute("data-selectable");
701
835
  });
702
- const l = e.querySelectorAll(".data-grid-row");
703
- if (l.forEach((n) => {
704
- n.classList.remove("selected", "row-focus"), s && n.removeAttribute("data-selectable");
705
- }), t === "row" && (m(e), l.forEach((n) => {
706
- const o = n.querySelector(".cell[data-row]"), d = S(o);
707
- d >= 0 && (s && !this.isRowSelectable(d) && n.setAttribute("data-selectable", "false"), this.selected.has(d) && n.classList.add("selected", "row-focus"));
708
- })), (t === "cell" || t === "range") && s && e.querySelectorAll(".cell[data-row][data-col]").forEach((o) => {
709
- const d = parseInt(o.getAttribute("data-row") ?? "-1", 10), a = parseInt(o.getAttribute("data-col") ?? "-1", 10);
710
- d >= 0 && a >= 0 && (this.isCellSelectable(d, a) || o.setAttribute("data-selectable", "false"));
836
+ const n = e.querySelectorAll(".data-grid-row");
837
+ if (n.forEach((i) => {
838
+ i.classList.remove("selected", "row-focus"), s && i.removeAttribute("data-selectable");
839
+ }), t === "row" && (C(e), n.forEach((i) => {
840
+ const l = i.querySelector(".cell[data-row]"), d = R(l);
841
+ d >= 0 && (s && !this.isRowSelectable(d) && i.setAttribute("data-selectable", "false"), this.selected.has(d) && i.classList.add("selected", "row-focus"));
842
+ }), this.config.checkbox && this.#r(e)), (t === "cell" || t === "range") && s && e.querySelectorAll(".cell[data-row][data-col]").forEach((l) => {
843
+ const d = parseInt(l.getAttribute("data-row") ?? "-1", 10), a = parseInt(l.getAttribute("data-col") ?? "-1", 10);
844
+ d >= 0 && a >= 0 && (this.isCellSelectable(d, a) || l.setAttribute("data-selectable", "false"));
711
845
  }), t === "range" && this.ranges.length > 0) {
712
- m(e);
713
- const n = this.activeRange ? u(this.activeRange) : null, o = this.columns.findIndex((a) => !g(a));
714
- this.columns.length - 1, e.querySelectorAll(".cell[data-row][data-col]").forEach((a) => {
846
+ C(e);
847
+ const i = this.ranges.map(g), l = (a, h) => {
848
+ for (const c of i)
849
+ if (a >= c.startRow && a <= c.endRow && h >= c.startCol && h <= c.endCol)
850
+ return !0;
851
+ return !1;
852
+ };
853
+ e.querySelectorAll(".cell[data-row][data-col]").forEach((a) => {
715
854
  const h = parseInt(a.getAttribute("data-row") ?? "-1", 10), c = parseInt(a.getAttribute("data-col") ?? "-1", 10);
716
855
  if (h >= 0 && c >= 0) {
717
- const f = this.columns[c];
718
- if (f && g(f))
856
+ const u = this.columns[c];
857
+ if (u && f(u))
719
858
  return;
720
- if (C(h, c, this.ranges) && (a.classList.add("selected"), n)) {
721
- h === n.startRow && a.classList.add("top"), h === n.endRow && a.classList.add("bottom");
722
- const A = Math.max(n.startCol, o);
723
- c === A && a.classList.add("first"), c === n.endCol && a.classList.add("last");
724
- }
859
+ l(h, c) && (a.classList.add("selected"), l(h - 1, c) || a.classList.add("top"), l(h + 1, c) || a.classList.add("bottom"), l(h, c - 1) || a.classList.add("first"), l(h, c + 1) || a.classList.add("last"));
725
860
  }
726
861
  });
727
862
  }
@@ -733,16 +868,16 @@ class D extends v {
733
868
  if (!e) return;
734
869
  const t = e.children[0], { mode: s } = this.config;
735
870
  if (this.pendingKeyboardUpdate && s === "range") {
736
- const { shiftKey: i } = this.pendingKeyboardUpdate;
871
+ const { shiftKey: r } = this.pendingKeyboardUpdate;
737
872
  this.pendingKeyboardUpdate = null;
738
- const l = this.grid._focusRow, n = this.grid._focusCol;
739
- if (i && this.cellAnchor) {
740
- const o = b(this.cellAnchor, { row: l, col: n });
741
- this.ranges = [o], this.activeRange = o;
742
- } else i || (this.ranges = [], this.activeRange = null, this.cellAnchor = { row: l, col: n });
873
+ const n = this.grid._focusRow, i = this.grid._focusCol;
874
+ if (r && this.cellAnchor) {
875
+ const l = m(this.cellAnchor, { row: n, col: i });
876
+ this.ranges = [l], this.activeRange = l;
877
+ } else r || (this.ranges = [], this.activeRange = null, this.cellAnchor = { row: n, col: i });
743
878
  this.emit("selection-change", this.#e());
744
879
  }
745
- this.grid.setAttribute("data-selection-mode", s), t && t.classList.toggle("selecting", this.isDragging), this.#t();
880
+ this.#i(s), this.grid.setAttribute("data-selection-mode", s), t && t.classList.toggle("selecting", this.isDragging), this.#s();
746
881
  }
747
882
  /**
748
883
  * Called after scroll-triggered row rendering.
@@ -750,7 +885,7 @@ class D extends v {
750
885
  * @internal
751
886
  */
752
887
  onScrollRender() {
753
- this.isSelectionEnabled() && this.#t();
888
+ this.isSelectionEnabled() && this.#s();
754
889
  }
755
890
  // #endregion
756
891
  // #region Public API
@@ -780,13 +915,80 @@ class D extends v {
780
915
  * Get all selected cells across all ranges.
781
916
  */
782
917
  getSelectedCells() {
783
- return q(this.ranges);
918
+ return M(this.ranges);
784
919
  }
785
920
  /**
786
921
  * Check if a specific cell is in range selection.
787
922
  */
788
923
  isCellSelected(e, t) {
789
- return C(e, t, this.ranges);
924
+ return q(e, t, this.ranges);
925
+ }
926
+ /**
927
+ * Select all selectable rows (row mode) or all cells (range mode).
928
+ *
929
+ * In row mode, selects every row where `isSelectable` returns true (or all rows if no callback).
930
+ * In range mode, creates a single range spanning all rows and columns.
931
+ * Has no effect in cell mode.
932
+ *
933
+ * @example
934
+ * ```ts
935
+ * const plugin = grid.getPlugin(SelectionPlugin);
936
+ * plugin.selectAll(); // Selects everything in current mode
937
+ * ```
938
+ */
939
+ selectAll() {
940
+ const { mode: e } = this.config;
941
+ if (e === "row") {
942
+ this.selected.clear();
943
+ for (let t = 0; t < this.rows.length; t++)
944
+ this.isRowSelectable(t) && this.selected.add(t);
945
+ this.explicitSelection = !0, this.emit("selection-change", this.#e()), this.requestAfterRender();
946
+ } else if (e === "range") {
947
+ const t = this.rows.length, s = this.columns.length;
948
+ if (t > 0 && s > 0) {
949
+ const r = {
950
+ startRow: 0,
951
+ startCol: 0,
952
+ endRow: t - 1,
953
+ endCol: s - 1
954
+ };
955
+ this.ranges = [r], this.activeRange = r, this.emit("selection-change", this.#e()), this.requestAfterRender();
956
+ }
957
+ }
958
+ }
959
+ /**
960
+ * Select specific rows by index (row mode only).
961
+ * Replaces the current selection with the provided row indices.
962
+ * Indices that are out of bounds or fail the `isSelectable` check are ignored.
963
+ *
964
+ * @param indices - Array of row indices to select
965
+ *
966
+ * @example
967
+ * ```ts
968
+ * const plugin = grid.getPlugin(SelectionPlugin);
969
+ * plugin.selectRows([0, 2, 4]); // Select rows 0, 2, and 4
970
+ * ```
971
+ */
972
+ selectRows(e) {
973
+ if (this.config.mode === "row") {
974
+ this.selected.clear();
975
+ for (const t of e)
976
+ t >= 0 && t < this.rows.length && this.isRowSelectable(t) && this.selected.add(t);
977
+ this.anchor = e.length > 0 ? e[e.length - 1] : null, this.explicitSelection = !0, this.emit("selection-change", this.#e()), this.requestAfterRender();
978
+ }
979
+ }
980
+ /**
981
+ * Get the indices of all selected rows (convenience for row mode).
982
+ * Returns indices sorted in ascending order.
983
+ *
984
+ * @example
985
+ * ```ts
986
+ * const plugin = grid.getPlugin(SelectionPlugin);
987
+ * const rows = plugin.getSelectedRowIndices(); // [0, 2, 4]
988
+ * ```
989
+ */
990
+ getSelectedRowIndices() {
991
+ return [...this.selected].sort((e, t) => e - t);
790
992
  }
791
993
  /**
792
994
  * Clear all selection.
@@ -805,13 +1007,13 @@ class D extends v {
805
1007
  endCol: t.to.col
806
1008
  })), this.activeRange = this.ranges.length > 0 ? this.ranges[this.ranges.length - 1] : null, this.emit("selection-change", {
807
1009
  mode: this.config.mode,
808
- ranges: p(this.ranges)
1010
+ ranges: y(this.ranges)
809
1011
  }), this.requestAfterRender();
810
1012
  }
811
1013
  // #endregion
812
1014
  // #region Private Helpers
813
1015
  #e() {
814
- return _(
1016
+ return D(
815
1017
  this.config.mode,
816
1018
  {
817
1019
  selectedCell: this.selectedCell,
@@ -824,6 +1026,6 @@ class D extends v {
824
1026
  // #endregion
825
1027
  }
826
1028
  export {
827
- D as SelectionPlugin
1029
+ L as SelectionPlugin
828
1030
  };
829
1031
  //# sourceMappingURL=index.js.map