@toolbox-web/grid 1.1.2 → 1.3.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 (84) hide show
  1. package/README.md +80 -22
  2. package/all.d.ts +1 -0
  3. package/all.d.ts.map +1 -1
  4. package/all.js +557 -365
  5. package/all.js.map +1 -1
  6. package/index.d.ts +1 -1
  7. package/index.d.ts.map +1 -1
  8. package/index.js +903 -769
  9. package/index.js.map +1 -1
  10. package/lib/core/grid.d.ts +102 -3
  11. package/lib/core/grid.d.ts.map +1 -1
  12. package/lib/core/internal/row-animation.d.ts +37 -0
  13. package/lib/core/internal/row-animation.d.ts.map +1 -0
  14. package/lib/core/internal/rows.d.ts.map +1 -1
  15. package/lib/core/internal/shell.d.ts.map +1 -1
  16. package/lib/core/plugin/base-plugin.d.ts +65 -3
  17. package/lib/core/plugin/base-plugin.d.ts.map +1 -1
  18. package/lib/core/plugin/index.d.ts +1 -1
  19. package/lib/core/plugin/index.d.ts.map +1 -1
  20. package/lib/core/plugin/plugin-manager.d.ts +25 -1
  21. package/lib/core/plugin/plugin-manager.d.ts.map +1 -1
  22. package/lib/core/plugin/types.d.ts +62 -0
  23. package/lib/core/plugin/types.d.ts.map +1 -1
  24. package/lib/core/types.d.ts +64 -1
  25. package/lib/core/types.d.ts.map +1 -1
  26. package/lib/plugins/clipboard/index.js +73 -69
  27. package/lib/plugins/clipboard/index.js.map +1 -1
  28. package/lib/plugins/clipboard/types.d.ts +1 -0
  29. package/lib/plugins/clipboard/types.d.ts.map +1 -1
  30. package/lib/plugins/column-virtualization/index.js.map +1 -1
  31. package/lib/plugins/context-menu/index.js.map +1 -1
  32. package/lib/plugins/editing/EditingPlugin.d.ts.map +1 -1
  33. package/lib/plugins/editing/index.js +69 -40
  34. package/lib/plugins/editing/index.js.map +1 -1
  35. package/lib/plugins/export/index.js.map +1 -1
  36. package/lib/plugins/filtering/index.js.map +1 -1
  37. package/lib/plugins/grouping-columns/index.js.map +1 -1
  38. package/lib/plugins/grouping-rows/index.js.map +1 -1
  39. package/lib/plugins/master-detail/MasterDetailPlugin.d.ts.map +1 -1
  40. package/lib/plugins/master-detail/index.js +14 -12
  41. package/lib/plugins/master-detail/index.js.map +1 -1
  42. package/lib/plugins/multi-sort/index.js.map +1 -1
  43. package/lib/plugins/pinned-columns/index.js.map +1 -1
  44. package/lib/plugins/pinned-rows/index.js.map +1 -1
  45. package/lib/plugins/pivot/index.js.map +1 -1
  46. package/lib/plugins/reorder/index.js.map +1 -1
  47. package/lib/plugins/responsive/index.js.map +1 -1
  48. package/lib/plugins/row-reorder/RowReorderPlugin.d.ts +155 -0
  49. package/lib/plugins/row-reorder/RowReorderPlugin.d.ts.map +1 -0
  50. package/lib/plugins/row-reorder/index.d.ts +9 -0
  51. package/lib/plugins/row-reorder/index.d.ts.map +1 -0
  52. package/lib/plugins/row-reorder/index.js +597 -0
  53. package/lib/plugins/row-reorder/index.js.map +1 -0
  54. package/lib/plugins/row-reorder/types.d.ts +80 -0
  55. package/lib/plugins/row-reorder/types.d.ts.map +1 -0
  56. package/lib/plugins/selection/SelectionPlugin.d.ts +13 -0
  57. package/lib/plugins/selection/SelectionPlugin.d.ts.map +1 -1
  58. package/lib/plugins/selection/index.d.ts +1 -1
  59. package/lib/plugins/selection/index.d.ts.map +1 -1
  60. package/lib/plugins/selection/index.js +95 -64
  61. package/lib/plugins/selection/index.js.map +1 -1
  62. package/lib/plugins/selection/types.d.ts +50 -6
  63. package/lib/plugins/selection/types.d.ts.map +1 -1
  64. package/lib/plugins/server-side/index.js.map +1 -1
  65. package/lib/plugins/tree/index.js.map +1 -1
  66. package/lib/plugins/undo-redo/index.js.map +1 -1
  67. package/lib/plugins/visibility/index.js.map +1 -1
  68. package/package.json +21 -4
  69. package/public.d.ts +15 -2
  70. package/public.d.ts.map +1 -1
  71. package/umd/grid.all.umd.js +23 -23
  72. package/umd/grid.all.umd.js.map +1 -1
  73. package/umd/grid.umd.js +15 -15
  74. package/umd/grid.umd.js.map +1 -1
  75. package/umd/plugins/clipboard.umd.js +5 -5
  76. package/umd/plugins/clipboard.umd.js.map +1 -1
  77. package/umd/plugins/editing.umd.js +1 -1
  78. package/umd/plugins/editing.umd.js.map +1 -1
  79. package/umd/plugins/master-detail.umd.js +1 -1
  80. package/umd/plugins/master-detail.umd.js.map +1 -1
  81. package/umd/plugins/row-reorder.umd.js +2 -0
  82. package/umd/plugins/row-reorder.umd.js.map +1 -0
  83. package/umd/plugins/selection.umd.js +2 -2
  84. package/umd/plugins/selection.umd.js.map +1 -1
@@ -1,4 +1,4 @@
1
- function b(r) {
1
+ function p(r) {
2
2
  if (!r) return -1;
3
3
  const e = r.getAttribute("data-row");
4
4
  if (e) return parseInt(e, 10);
@@ -7,14 +7,14 @@ function b(r) {
7
7
  const s = t.parentElement;
8
8
  if (!s) return -1;
9
9
  const i = s.querySelectorAll(":scope > .data-grid-row");
10
- for (let n = 0; n < i.length; n++)
11
- if (i[n] === t) return n;
10
+ for (let l = 0; l < i.length; l++)
11
+ if (i[l] === t) return l;
12
12
  return -1;
13
13
  }
14
- function w(r) {
14
+ function b(r) {
15
15
  r && r.querySelectorAll(".cell-focus").forEach((e) => e.classList.remove("cell-focus"));
16
16
  }
17
- const p = {
17
+ const A = {
18
18
  expand: "▶",
19
19
  collapse: "▼",
20
20
  sortAsc: "▲",
@@ -248,7 +248,7 @@ class y {
248
248
  */
249
249
  get gridIcons() {
250
250
  const e = this.grid?.gridConfig?.icons ?? {};
251
- return { ...p, ...e };
251
+ return { ...A, ...e };
252
252
  }
253
253
  // #region Animation Helpers
254
254
  /**
@@ -335,7 +335,7 @@ function u(r) {
335
335
  endCol: Math.max(r.startCol, r.endCol)
336
336
  };
337
337
  }
338
- function A(r) {
338
+ function v(r) {
339
339
  const e = u(r);
340
340
  return {
341
341
  from: { row: e.startRow, col: e.startCol },
@@ -343,14 +343,14 @@ function A(r) {
343
343
  };
344
344
  }
345
345
  function R(r) {
346
- return r.map(A);
346
+ return r.map(v);
347
347
  }
348
- function v(r, e, t) {
348
+ function S(r, e, t) {
349
349
  const s = u(t);
350
350
  return r >= s.startRow && r <= s.endRow && e >= s.startCol && e <= s.endCol;
351
351
  }
352
352
  function m(r, e, t) {
353
- return t.some((s) => v(r, e, s));
353
+ return t.some((s) => S(r, e, s));
354
354
  }
355
355
  function I(r) {
356
356
  const e = [], t = u(r);
@@ -374,7 +374,7 @@ function f(r, e) {
374
374
  endCol: e.col
375
375
  };
376
376
  }
377
- const x = "@layer tbw-plugins{tbw-grid.selecting .data-grid-row>.cell{-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)}tbw-grid .data-grid-row>.cell.selected.bottom{border-bottom:2px solid var(--tbw-range-border-color)}tbw-grid .data-grid-row>.cell.selected.first{border-left:2px solid var(--tbw-range-border-color)}tbw-grid .data-grid-row>.cell.selected.last{border-right:2px solid var(--tbw-range-border-color)}tbw-grid .tbw-selection-summary{font-size:var(--tbw-font-size-sm, .8125rem);color:var(--tbw-color-fg-muted);white-space:nowrap}}";
377
+ const x = "@layer tbw-plugins{tbw-grid.selecting .data-grid-row>.cell{-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)}tbw-grid .data-grid-row>.cell.selected.bottom{border-bottom:2px solid var(--tbw-range-border-color)}tbw-grid .data-grid-row>.cell.selected.first{border-left:2px solid var(--tbw-range-border-color)}tbw-grid .data-grid-row>.cell.selected.last{border-right:2px solid var(--tbw-range-border-color)}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-color-warning-bg, rgba(255, 243, 205, .5))}tbw-grid .tbw-selection-summary{font-size:var(--tbw-font-size-sm, .8125rem);color:var(--tbw-color-fg-muted);white-space:nowrap}}";
378
378
  function q(r, e, t) {
379
379
  if (r === "cell" && e.selectedCell)
380
380
  return {
@@ -438,6 +438,32 @@ class K extends y {
438
438
  /** Cell selection state (cell mode) */
439
439
  selectedCell = null;
440
440
  // #endregion
441
+ // #region Private Helpers - Selectability
442
+ /**
443
+ * Check if a row/cell is selectable.
444
+ * Returns true if selectable, false if not.
445
+ */
446
+ checkSelectable(e, t) {
447
+ const { isSelectable: s } = this.config;
448
+ if (!s) return !0;
449
+ const i = this.rows[e];
450
+ if (!i) return !1;
451
+ const l = t !== void 0 ? this.columns[t] : void 0;
452
+ return s(i, e, l, t);
453
+ }
454
+ /**
455
+ * Check if an entire row is selectable (for row mode).
456
+ */
457
+ isRowSelectable(e) {
458
+ return this.checkSelectable(e);
459
+ }
460
+ /**
461
+ * Check if a cell is selectable (for cell/range modes).
462
+ */
463
+ isCellSelectable(e, t) {
464
+ return this.checkSelectable(e, t);
465
+ }
466
+ // #endregion
441
467
  // #region Lifecycle
442
468
  /** @internal */
443
469
  detach() {
@@ -447,37 +473,37 @@ class K extends y {
447
473
  // #region Event Handlers
448
474
  /** @internal */
449
475
  onCellClick(e) {
450
- const { rowIndex: t, colIndex: s, originalEvent: i } = e, { mode: n, triggerOn: o = "click" } = this.config;
451
- if (i.type !== o)
476
+ const { rowIndex: t, colIndex: s, originalEvent: i } = e, { mode: l, triggerOn: n = "click" } = this.config;
477
+ if (i.type !== n)
452
478
  return !1;
453
- const c = this.columns[s], a = c && h(c);
454
- if (n === "cell")
455
- return a || (this.selectedCell = { row: t, col: s }, this.emit("selection-change", this.#e()), this.requestAfterRender()), !1;
456
- if (n === "row")
457
- return this.selected.clear(), this.selected.add(t), this.lastSelected = t, this.emit("selection-change", this.#e()), this.requestAfterRender(), !1;
458
- if (n === "range") {
459
- if (a)
479
+ const o = this.columns[s], d = o && h(o);
480
+ if (l === "cell")
481
+ return d || !this.isCellSelectable(t, s) || (this.selectedCell = { row: t, col: s }, this.emit("selection-change", this.#e()), this.requestAfterRender()), !1;
482
+ if (l === "row")
483
+ return this.isRowSelectable(t) && (this.selected.clear(), this.selected.add(t), this.lastSelected = t, this.emit("selection-change", this.#e()), this.requestAfterRender()), !1;
484
+ if (l === "range") {
485
+ if (d || !this.isCellSelectable(t, s))
460
486
  return !1;
461
- const g = i.shiftKey, d = i.ctrlKey || i.metaKey;
462
- if (g && this.cellAnchor) {
463
- const l = f(this.cellAnchor, { row: t, col: s });
464
- d ? this.ranges.length > 0 ? this.ranges[this.ranges.length - 1] = l : this.ranges.push(l) : this.ranges = [l], this.activeRange = l;
465
- } else if (d) {
466
- const l = {
487
+ const a = i.shiftKey, g = i.ctrlKey || i.metaKey;
488
+ if (a && this.cellAnchor) {
489
+ const c = f(this.cellAnchor, { row: t, col: s });
490
+ g ? this.ranges.length > 0 ? this.ranges[this.ranges.length - 1] = c : this.ranges.push(c) : this.ranges = [c], this.activeRange = c;
491
+ } else if (g) {
492
+ const c = {
467
493
  startRow: t,
468
494
  startCol: s,
469
495
  endRow: t,
470
496
  endCol: s
471
497
  };
472
- this.ranges.push(l), this.activeRange = l, this.cellAnchor = { row: t, col: s };
498
+ this.ranges.push(c), this.activeRange = c, this.cellAnchor = { row: t, col: s };
473
499
  } else {
474
- const l = {
500
+ const c = {
475
501
  startRow: t,
476
502
  startCol: s,
477
503
  endRow: t,
478
504
  endCol: s
479
505
  };
480
- this.ranges = [l], this.activeRange = l, this.cellAnchor = { row: t, col: s };
506
+ this.ranges = [c], this.activeRange = c, this.cellAnchor = { row: t, col: s };
481
507
  }
482
508
  return this.emit("selection-change", this.#e()), this.requestAfterRender(), !1;
483
509
  }
@@ -490,26 +516,28 @@ class K extends y {
490
516
  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;
491
517
  if (t === "cell" && i)
492
518
  return queueMicrotask(() => {
493
- this.selectedCell = { row: this.grid._focusRow, col: this.grid._focusCol }, this.emit("selection-change", this.#e()), this.requestAfterRender();
519
+ const l = this.grid._focusRow, n = this.grid._focusCol;
520
+ this.isCellSelectable(l, n) ? this.selectedCell = { row: l, col: n } : this.selectedCell = null, this.emit("selection-change", this.#e()), this.requestAfterRender();
494
521
  }), !1;
495
522
  if (t === "row" && (e.key === "ArrowUp" || e.key === "ArrowDown"))
496
523
  return queueMicrotask(() => {
497
- this.selected.clear(), this.selected.add(this.grid._focusRow), this.lastSelected = this.grid._focusRow, this.emit("selection-change", this.#e()), this.requestAfterRender();
524
+ const l = this.grid._focusRow;
525
+ this.isRowSelectable(l) ? (this.selected.clear(), this.selected.add(l), this.lastSelected = l) : this.selected.clear(), this.emit("selection-change", this.#e()), this.requestAfterRender();
498
526
  }), !1;
499
527
  if (t === "range" && i) {
500
- const n = e.key === "Tab", o = e.shiftKey && !n;
501
- return o && !this.cellAnchor && (this.cellAnchor = { row: this.grid._focusRow, col: this.grid._focusCol }), this.pendingKeyboardUpdate = { shiftKey: o }, queueMicrotask(() => this.requestAfterRender()), !1;
528
+ const l = e.key === "Tab", n = e.shiftKey && !l;
529
+ return n && !this.cellAnchor && (this.cellAnchor = { row: this.grid._focusRow, col: this.grid._focusCol }), this.pendingKeyboardUpdate = { shiftKey: n }, queueMicrotask(() => this.requestAfterRender()), !1;
502
530
  }
503
531
  if (t === "range" && e.key === "a" && (e.ctrlKey || e.metaKey)) {
504
- const n = this.rows.length, o = this.columns.length;
505
- if (n > 0 && o > 0) {
506
- const c = {
532
+ const l = this.rows.length, n = this.columns.length;
533
+ if (l > 0 && n > 0) {
534
+ const o = {
507
535
  startRow: 0,
508
536
  startCol: 0,
509
- endRow: n - 1,
510
- endCol: o - 1
537
+ endRow: l - 1,
538
+ endCol: n - 1
511
539
  };
512
- return this.ranges = [c], this.activeRange = c, this.emit("selection-change", this.#e()), this.requestAfterRender(), !0;
540
+ return this.ranges = [o], this.activeRange = o, this.emit("selection-change", this.#e()), this.requestAfterRender(), !0;
513
541
  }
514
542
  }
515
543
  return !1;
@@ -518,18 +546,18 @@ class K extends y {
518
546
  onCellMouseDown(e) {
519
547
  if (this.config.mode !== "range" || e.rowIndex === void 0 || e.colIndex === void 0 || e.rowIndex < 0) return;
520
548
  const t = this.columns[e.colIndex];
521
- if (t && h(t) || e.originalEvent.shiftKey && this.cellAnchor)
549
+ if (t && h(t) || !this.isCellSelectable(e.rowIndex, e.colIndex) || e.originalEvent.shiftKey && this.cellAnchor)
522
550
  return;
523
551
  this.isDragging = !0;
524
552
  const s = e.rowIndex, i = e.colIndex;
525
553
  this.cellAnchor = { row: s, col: i }, e.originalEvent.ctrlKey || e.originalEvent.metaKey || (this.ranges = []);
526
- const o = {
554
+ const n = {
527
555
  startRow: s,
528
556
  startCol: i,
529
557
  endRow: s,
530
558
  endCol: i
531
559
  };
532
- return this.ranges.push(o), this.activeRange = o, this.emit("selection-change", this.#e()), this.requestAfterRender(), !0;
560
+ return this.ranges.push(n), this.activeRange = n, this.emit("selection-change", this.#e()), this.requestAfterRender(), !0;
533
561
  }
534
562
  /** @internal */
535
563
  onCellMouseMove(e) {
@@ -537,8 +565,8 @@ class K extends y {
537
565
  let t = e.colIndex;
538
566
  const s = this.columns[t];
539
567
  if (s && h(s)) {
540
- const n = this.columns.findIndex((o) => !h(o));
541
- n >= 0 && (t = n);
568
+ const l = this.columns.findIndex((n) => !h(n));
569
+ l >= 0 && (t = l);
542
570
  }
543
571
  const i = f(this.cellAnchor, { row: e.rowIndex, col: t });
544
572
  return 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;
@@ -555,29 +583,32 @@ class K extends y {
555
583
  #t() {
556
584
  const e = this.gridElement;
557
585
  if (!e) return;
558
- const { mode: t } = this.config;
586
+ const { mode: t } = this.config, s = !!this.config.isSelectable;
559
587
  e.querySelectorAll(".cell").forEach((n) => {
560
- n.classList.remove("selected", "top", "bottom", "first", "last");
588
+ n.classList.remove("selected", "top", "bottom", "first", "last"), s && n.removeAttribute("data-selectable");
561
589
  });
562
- const i = e.querySelectorAll(".data-grid-row");
563
- if (i.forEach((n) => {
564
- n.classList.remove("selected", "row-focus");
565
- }), t === "row" && (w(e), i.forEach((n) => {
566
- const o = n.querySelector(".cell[data-row]"), c = b(o);
567
- c >= 0 && this.selected.has(c) && n.classList.add("selected", "row-focus");
568
- })), t === "range" && this.ranges.length > 0) {
569
- w(e);
590
+ const l = e.querySelectorAll(".data-grid-row");
591
+ if (l.forEach((n) => {
592
+ n.classList.remove("selected", "row-focus"), s && n.removeAttribute("data-selectable");
593
+ }), t === "row" && (b(e), l.forEach((n) => {
594
+ const o = n.querySelector(".cell[data-row]"), d = p(o);
595
+ d >= 0 && (s && !this.isRowSelectable(d) && n.setAttribute("data-selectable", "false"), this.selected.has(d) && n.classList.add("selected", "row-focus"));
596
+ })), (t === "cell" || t === "range") && s && e.querySelectorAll(".cell[data-row][data-col]").forEach((o) => {
597
+ const d = parseInt(o.getAttribute("data-row") ?? "-1", 10), a = parseInt(o.getAttribute("data-col") ?? "-1", 10);
598
+ d >= 0 && a >= 0 && (this.isCellSelectable(d, a) || o.setAttribute("data-selectable", "false"));
599
+ }), t === "range" && this.ranges.length > 0) {
600
+ b(e);
570
601
  const n = this.activeRange ? u(this.activeRange) : null, o = this.columns.findIndex((a) => !h(a));
571
602
  this.columns.length - 1, e.querySelectorAll(".cell[data-row][data-col]").forEach((a) => {
572
- const g = parseInt(a.getAttribute("data-row") ?? "-1", 10), d = parseInt(a.getAttribute("data-col") ?? "-1", 10);
573
- if (g >= 0 && d >= 0) {
574
- const l = this.columns[d];
575
- if (l && h(l))
603
+ const g = parseInt(a.getAttribute("data-row") ?? "-1", 10), c = parseInt(a.getAttribute("data-col") ?? "-1", 10);
604
+ if (g >= 0 && c >= 0) {
605
+ const w = this.columns[c];
606
+ if (w && h(w))
576
607
  return;
577
- if (m(g, d, this.ranges) && (a.classList.add("selected"), n)) {
608
+ if (m(g, c, this.ranges) && (a.classList.add("selected"), n)) {
578
609
  g === n.startRow && a.classList.add("top"), g === n.endRow && a.classList.add("bottom");
579
610
  const C = Math.max(n.startCol, o);
580
- d === C && a.classList.add("first"), d === n.endCol && a.classList.add("last");
611
+ c === C && a.classList.add("first"), c === n.endCol && a.classList.add("last");
581
612
  }
582
613
  }
583
614
  });
@@ -591,11 +622,11 @@ class K extends y {
591
622
  if (this.pendingKeyboardUpdate && s === "range") {
592
623
  const { shiftKey: i } = this.pendingKeyboardUpdate;
593
624
  this.pendingKeyboardUpdate = null;
594
- const n = this.grid._focusRow, o = this.grid._focusCol;
625
+ const l = this.grid._focusRow, n = this.grid._focusCol;
595
626
  if (i && this.cellAnchor) {
596
- const c = f(this.cellAnchor, { row: n, col: o });
597
- this.ranges = [c], this.activeRange = c;
598
- } else i || (this.ranges = [], this.activeRange = null, this.cellAnchor = { row: n, col: o });
627
+ const o = f(this.cellAnchor, { row: l, col: n });
628
+ this.ranges = [o], this.activeRange = o;
629
+ } else i || (this.ranges = [], this.activeRange = null, this.cellAnchor = { row: l, col: n });
599
630
  this.emit("selection-change", this.#e());
600
631
  }
601
632
  this.grid.setAttribute("data-selection-mode", s), t && t.classList.toggle("selecting", this.isDragging), this.#t();