@toolbox-web/grid 1.14.1 → 1.15.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 (70) hide show
  1. package/README.md +5 -1
  2. package/all.js +1985 -1558
  3. package/all.js.map +1 -1
  4. package/index.js +46 -20
  5. package/index.js.map +1 -1
  6. package/lib/core/grid.d.ts.map +1 -1
  7. package/lib/core/internal/validate-config.d.ts.map +1 -1
  8. package/lib/plugins/column-virtualization/ColumnVirtualizationPlugin.d.ts.map +1 -1
  9. package/lib/plugins/column-virtualization/index.js +1 -1
  10. package/lib/plugins/column-virtualization/index.js.map +1 -1
  11. package/lib/plugins/context-menu/ContextMenuPlugin.d.ts +20 -1
  12. package/lib/plugins/context-menu/ContextMenuPlugin.d.ts.map +1 -1
  13. package/lib/plugins/context-menu/index.d.ts +1 -1
  14. package/lib/plugins/context-menu/index.d.ts.map +1 -1
  15. package/lib/plugins/context-menu/index.js +153 -70
  16. package/lib/plugins/context-menu/index.js.map +1 -1
  17. package/lib/plugins/context-menu/menu.d.ts +7 -0
  18. package/lib/plugins/context-menu/menu.d.ts.map +1 -1
  19. package/lib/plugins/context-menu/types.d.ts +46 -0
  20. package/lib/plugins/context-menu/types.d.ts.map +1 -1
  21. package/lib/plugins/editing/EditingPlugin.d.ts.map +1 -1
  22. package/lib/plugins/editing/index.js +214 -197
  23. package/lib/plugins/editing/index.js.map +1 -1
  24. package/lib/plugins/filtering/FilteringPlugin.d.ts +7 -1
  25. package/lib/plugins/filtering/FilteringPlugin.d.ts.map +1 -1
  26. package/lib/plugins/filtering/index.js +169 -133
  27. package/lib/plugins/filtering/index.js.map +1 -1
  28. package/lib/plugins/grouping-columns/GroupingColumnsPlugin.d.ts +5 -1
  29. package/lib/plugins/grouping-columns/GroupingColumnsPlugin.d.ts.map +1 -1
  30. package/lib/plugins/grouping-columns/index.js +242 -109
  31. package/lib/plugins/grouping-columns/index.js.map +1 -1
  32. package/lib/plugins/grouping-columns/types.d.ts +7 -0
  33. package/lib/plugins/grouping-columns/types.d.ts.map +1 -1
  34. package/lib/plugins/pinned-columns/PinnedColumnsPlugin.d.ts +11 -1
  35. package/lib/plugins/pinned-columns/PinnedColumnsPlugin.d.ts.map +1 -1
  36. package/lib/plugins/pinned-columns/index.d.ts +1 -1
  37. package/lib/plugins/pinned-columns/index.d.ts.map +1 -1
  38. package/lib/plugins/pinned-columns/index.js +174 -79
  39. package/lib/plugins/pinned-columns/index.js.map +1 -1
  40. package/lib/plugins/pinned-columns/pinned-columns.d.ts +23 -4
  41. package/lib/plugins/pinned-columns/pinned-columns.d.ts.map +1 -1
  42. package/lib/plugins/pinned-columns/types.d.ts +21 -9
  43. package/lib/plugins/pinned-columns/types.d.ts.map +1 -1
  44. package/lib/plugins/visibility/VisibilityPlugin.d.ts +42 -2
  45. package/lib/plugins/visibility/VisibilityPlugin.d.ts.map +1 -1
  46. package/lib/plugins/visibility/index.d.ts +1 -1
  47. package/lib/plugins/visibility/index.d.ts.map +1 -1
  48. package/lib/plugins/visibility/index.js +219 -59
  49. package/lib/plugins/visibility/index.js.map +1 -1
  50. package/lib/plugins/visibility/types.d.ts +25 -0
  51. package/lib/plugins/visibility/types.d.ts.map +1 -1
  52. package/package.json +1 -1
  53. package/umd/grid.all.umd.js +25 -25
  54. package/umd/grid.all.umd.js.map +1 -1
  55. package/umd/grid.umd.js +2 -2
  56. package/umd/grid.umd.js.map +1 -1
  57. package/umd/plugins/column-virtualization.umd.js +1 -1
  58. package/umd/plugins/column-virtualization.umd.js.map +1 -1
  59. package/umd/plugins/context-menu.umd.js +1 -1
  60. package/umd/plugins/context-menu.umd.js.map +1 -1
  61. package/umd/plugins/editing.umd.js +1 -1
  62. package/umd/plugins/editing.umd.js.map +1 -1
  63. package/umd/plugins/filtering.umd.js +1 -1
  64. package/umd/plugins/filtering.umd.js.map +1 -1
  65. package/umd/plugins/grouping-columns.umd.js +1 -1
  66. package/umd/plugins/grouping-columns.umd.js.map +1 -1
  67. package/umd/plugins/pinned-columns.umd.js +1 -1
  68. package/umd/plugins/pinned-columns.umd.js.map +1 -1
  69. package/umd/plugins/visibility.umd.js +1 -1
  70. package/umd/plugins/visibility.umd.js.map +1 -1
@@ -1,59 +1,59 @@
1
- function P(r) {
2
- r && r.querySelectorAll(".cell-focus").forEach((e) => e.classList.remove("cell-focus"));
1
+ function P(o) {
2
+ o && o.querySelectorAll(".cell-focus").forEach((e) => e.classList.remove("cell-focus"));
3
3
  }
4
4
  const w = 'input,select,textarea,[contenteditable="true"],[contenteditable=""],[tabindex]:not([tabindex="-1"])', M = document.createElement("template");
5
5
  M.innerHTML = '<div class="cell" role="gridcell" part="cell"></div>';
6
6
  const H = document.createElement("template");
7
7
  H.innerHTML = '<div class="data-grid-row" role="row" part="row"></div>';
8
- function L(r, e) {
9
- if (r._virtualization?.enabled) {
10
- const { rowHeight: l, container: o, viewportEl: c } = r._virtualization, a = o, d = c?.clientHeight ?? a?.clientHeight ?? 0;
8
+ function L(o, e) {
9
+ if (o._virtualization?.enabled) {
10
+ const { rowHeight: r, container: l, viewportEl: c } = o._virtualization, a = l, d = c?.clientHeight ?? a?.clientHeight ?? 0;
11
11
  if (a && d > 0) {
12
- const g = r._focusRow * l;
13
- g < a.scrollTop ? a.scrollTop = g : g + l > a.scrollTop + d && (a.scrollTop = g - d + l);
12
+ const g = o._focusRow * r;
13
+ g < a.scrollTop ? a.scrollTop = g : g + r > a.scrollTop + d && (a.scrollTop = g - d + r);
14
14
  }
15
15
  }
16
- const t = r._activeEditRows !== void 0 && r._activeEditRows !== -1;
17
- t || r.refreshVirtualWindow(!1), P(r._bodyEl), Array.from(r._bodyEl.querySelectorAll('[aria-selected="true"]')).forEach((l) => {
18
- l.setAttribute("aria-selected", "false");
16
+ const t = o._activeEditRows !== void 0 && o._activeEditRows !== -1;
17
+ t || o.refreshVirtualWindow(!1), P(o._bodyEl), Array.from(o._bodyEl.querySelectorAll('[aria-selected="true"]')).forEach((r) => {
18
+ r.setAttribute("aria-selected", "false");
19
19
  });
20
- const i = r._focusRow, n = r._virtualization.start ?? 0, s = r._virtualization.end ?? r._rows.length;
20
+ const i = o._focusRow, n = o._virtualization.start ?? 0, s = o._virtualization.end ?? o._rows.length;
21
21
  if (i >= n && i < s) {
22
- const l = r._bodyEl.querySelectorAll(".data-grid-row")[i - n];
23
- let o = l?.children[r._focusCol];
24
- if ((!o || !o.classList?.contains("cell")) && (o = l?.querySelector(`.cell[data-col="${r._focusCol}"]`) ?? l?.querySelector(".cell[data-col]")), o) {
25
- o.classList.add("cell-focus"), o.setAttribute("aria-selected", "true");
26
- const c = r.querySelector(".tbw-scroll-area");
27
- if (c && o && (!t || e?.forceHorizontalScroll))
22
+ const r = o._bodyEl.querySelectorAll(".data-grid-row")[i - n];
23
+ let l = r?.children[o._focusCol];
24
+ if ((!l || !l.classList?.contains("cell")) && (l = r?.querySelector(`.cell[data-col="${o._focusCol}"]`) ?? r?.querySelector(".cell[data-col]")), l) {
25
+ l.classList.add("cell-focus"), l.setAttribute("aria-selected", "true");
26
+ const c = o.querySelector(".tbw-scroll-area");
27
+ if (c && l && (!t || e?.forceHorizontalScroll))
28
28
  if (e?.forceScrollLeft)
29
29
  c.scrollLeft = 0;
30
30
  else if (e?.forceScrollRight)
31
31
  c.scrollLeft = c.scrollWidth - c.clientWidth;
32
32
  else {
33
- const a = r._getHorizontalScrollOffsets?.(l ?? void 0, o) ?? { left: 0, right: 0 };
33
+ const a = o._getHorizontalScrollOffsets?.(r ?? void 0, l) ?? { left: 0, right: 0 };
34
34
  if (!a.skipScroll) {
35
- const d = o.getBoundingClientRect(), g = c.getBoundingClientRect(), f = d.left - g.left + c.scrollLeft, E = f + d.width, p = c.scrollLeft + a.left, m = c.scrollLeft + c.clientWidth - a.right;
35
+ const d = l.getBoundingClientRect(), g = c.getBoundingClientRect(), f = d.left - g.left + c.scrollLeft, E = f + d.width, p = c.scrollLeft + a.left, m = c.scrollLeft + c.clientWidth - a.right;
36
36
  f < p ? c.scrollLeft = f - a.left : E > m && (c.scrollLeft = E - c.clientWidth + a.right);
37
37
  }
38
38
  }
39
- if (r._activeEditRows !== void 0 && r._activeEditRows !== -1 && o.classList.contains("editing")) {
40
- const a = o.querySelector(w);
39
+ if (o._activeEditRows !== void 0 && o._activeEditRows !== -1 && l.classList.contains("editing")) {
40
+ const a = l.querySelector(w);
41
41
  if (a && document.activeElement !== a)
42
42
  try {
43
43
  a.focus({ preventScroll: !0 });
44
44
  } catch {
45
45
  }
46
- } else if (!o.contains(document.activeElement)) {
47
- o.hasAttribute("tabindex") || o.setAttribute("tabindex", "-1");
46
+ } else if (!l.contains(document.activeElement)) {
47
+ l.hasAttribute("tabindex") || l.setAttribute("tabindex", "-1");
48
48
  try {
49
- o.focus({ preventScroll: !0 });
49
+ l.focus({ preventScroll: !0 });
50
50
  } catch {
51
51
  }
52
52
  }
53
53
  }
54
54
  }
55
55
  }
56
- const I = '<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>', D = {
56
+ const I = '<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>', O = {
57
57
  expand: "▶",
58
58
  collapse: "▼",
59
59
  sortAsc: "▲",
@@ -66,7 +66,7 @@ const I = '<svg viewBox="0 0 16 16" width="12" height="12"><path fill="currentCo
66
66
  filterActive: I,
67
67
  print: "🖨️"
68
68
  };
69
- class O {
69
+ class D {
70
70
  /**
71
71
  * Plugin dependencies - declare other plugins this one requires.
72
72
  *
@@ -356,7 +356,7 @@ class O {
356
356
  */
357
357
  get gridIcons() {
358
358
  const e = this.grid?.gridConfig?.icons ?? {};
359
- return { ...D, ...e };
359
+ return { ...O, ...e };
360
360
  }
361
361
  // #region Animation Helpers
362
362
  /**
@@ -433,13 +433,13 @@ class O {
433
433
  // #endregion
434
434
  }
435
435
  const x = "@layer tbw-plugins{tbw-grid{--tbw-editing-bg: var(--tbw-color-selection);--tbw-editing-row-bg: var(--tbw-editing-bg);--tbw-editing-border: var(--tbw-border-input, 1px solid var(--tbw-color-border-strong));--tbw-padding-editing-input: var(--tbw-cell-padding-input, 2px 6px);--tbw-font-size-editor: inherit;--tbw-editing-row-outline-color: var(--tbw-color-accent);--tbw-editing-row-outline-width: 1px;--tbw-invalid-bg: light-dark(#fef2f2, #450a0a);--tbw-invalid-border-color: light-dark(#ef4444, #f87171)}tbw-grid:not(.tbw-grid-mode) .data-grid-row:has(.editing){background:var(--tbw-editing-row-bg);outline:var(--tbw-editing-row-outline-width) solid var(--tbw-editing-row-outline-color);outline-offset:calc(-1 * var(--tbw-editing-row-outline-width))}tbw-grid .data-grid-row>.cell.editing{overflow:hidden;padding:0;display:flex;min-height:calc(var(--tbw-row-height) + 2px);align-items:center;justify-content:center}tbw-grid .data-grid-row>.cell.editing input:not([type=checkbox]),tbw-grid .data-grid-row>.cell.editing select,tbw-grid .data-grid-row>.cell.editing textarea{width:100%;height:100%;flex:1 1 auto;min-width:0;border:var(--tbw-editing-border);padding:var(--tbw-padding-editing-input);font-size:var(--tbw-font-size-editor)}tbw-grid .tbw-editor-host{display:contents}tbw-grid .data-grid-row>.cell[data-invalid=true]{background:var(--tbw-invalid-bg);outline:1px solid var(--tbw-invalid-border-color);outline-offset:-1px}}";
436
- function B(r) {
437
- const e = r.options;
436
+ function B(o) {
437
+ const e = o.options;
438
438
  return e ? typeof e == "function" ? e() : e : [];
439
439
  }
440
- function N(r) {
440
+ function N(o) {
441
441
  return (e) => {
442
- const t = r.editorParams, i = document.createElement("input");
442
+ const t = o.editorParams, i = document.createElement("input");
443
443
  i.type = "number", i.value = e.value != null ? String(e.value) : "", t?.min !== void 0 && (i.min = String(t.min)), t?.max !== void 0 && (i.max = String(t.max)), t?.step !== void 0 && (i.step = String(t.step)), t?.placeholder && (i.placeholder = t.placeholder);
444
444
  const n = () => e.commit(i.value === "" ? null : Number(i.value));
445
445
  return i.addEventListener("blur", n), i.addEventListener("keydown", (s) => {
@@ -448,14 +448,14 @@ function N(r) {
448
448
  };
449
449
  }
450
450
  function $() {
451
- return (r) => {
451
+ return (o) => {
452
452
  const e = document.createElement("input");
453
- return e.type = "checkbox", e.checked = !!r.value, e.addEventListener("change", () => r.commit(e.checked)), e;
453
+ return e.type = "checkbox", e.checked = !!o.value, e.addEventListener("change", () => o.commit(e.checked)), e;
454
454
  };
455
455
  }
456
- function z(r) {
456
+ function z(o) {
457
457
  return (e) => {
458
- const t = r.editorParams, i = document.createElement("input");
458
+ const t = o.editorParams, i = document.createElement("input");
459
459
  i.type = "date", e.value instanceof Date ? i.valueAsDate = e.value : typeof e.value == "string" && e.value && (i.value = e.value.split("T")[0]), t?.min && (i.min = t.min), t?.max && (i.max = t.max), t?.placeholder && (i.placeholder = t.placeholder);
460
460
  const n = () => {
461
461
  typeof e.value == "string" ? e.commit(i.value) : e.commit(i.valueAsDate);
@@ -465,32 +465,32 @@ function z(r) {
465
465
  }), i;
466
466
  };
467
467
  }
468
- function G(r) {
468
+ function G(o) {
469
469
  return (e) => {
470
- const t = r.editorParams, i = document.createElement("select");
471
- if (r.multi && (i.multiple = !0), t?.includeEmpty) {
472
- const l = document.createElement("option");
473
- l.value = "", l.textContent = t.emptyLabel ?? "", i.appendChild(l);
470
+ const t = o.editorParams, i = document.createElement("select");
471
+ if (o.multi && (i.multiple = !0), t?.includeEmpty) {
472
+ const r = document.createElement("option");
473
+ r.value = "", r.textContent = t.emptyLabel ?? "", i.appendChild(r);
474
474
  }
475
- B(r).forEach((l) => {
476
- const o = document.createElement("option");
477
- o.value = String(l.value), o.textContent = l.label, (r.multi && Array.isArray(e.value) && e.value.includes(l.value) || !r.multi && e.value === l.value) && (o.selected = !0), i.appendChild(o);
475
+ B(o).forEach((r) => {
476
+ const l = document.createElement("option");
477
+ l.value = String(r.value), l.textContent = r.label, (o.multi && Array.isArray(e.value) && e.value.includes(r.value) || !o.multi && e.value === r.value) && (l.selected = !0), i.appendChild(l);
478
478
  });
479
479
  const s = () => {
480
- if (r.multi) {
481
- const l = Array.from(i.selectedOptions).map((o) => o.value);
482
- e.commit(l);
480
+ if (o.multi) {
481
+ const r = Array.from(i.selectedOptions).map((l) => l.value);
482
+ e.commit(r);
483
483
  } else
484
484
  e.commit(i.value);
485
485
  };
486
- return i.addEventListener("change", s), i.addEventListener("blur", s), i.addEventListener("keydown", (l) => {
487
- l.key === "Escape" && e.cancel();
486
+ return i.addEventListener("change", s), i.addEventListener("blur", s), i.addEventListener("keydown", (r) => {
487
+ r.key === "Escape" && e.cancel();
488
488
  }), i;
489
489
  };
490
490
  }
491
- function F(r) {
491
+ function F(o) {
492
492
  return (e) => {
493
- const t = r.editorParams, i = document.createElement("input");
493
+ const t = o.editorParams, i = document.createElement("input");
494
494
  i.type = "text", i.value = e.value != null ? String(e.value) : "", t?.maxLength !== void 0 && (i.maxLength = t.maxLength), t?.pattern && (i.pattern = t.pattern), t?.placeholder && (i.placeholder = t.placeholder);
495
495
  const n = () => {
496
496
  const s = i.value;
@@ -501,56 +501,56 @@ function F(r) {
501
501
  }), i;
502
502
  };
503
503
  }
504
- function j(r) {
505
- switch (r.type) {
504
+ function j(o) {
505
+ switch (o.type) {
506
506
  case "number":
507
- return N(r);
507
+ return N(o);
508
508
  case "boolean":
509
509
  return $();
510
510
  case "date":
511
- return z(r);
511
+ return z(o);
512
512
  case "select":
513
- return G(r);
513
+ return G(o);
514
514
  default:
515
- return F(r);
515
+ return F(o);
516
516
  }
517
517
  }
518
- function W(r, e) {
518
+ function W(o, e) {
519
519
  if (e.editor) return e.editor;
520
520
  if (e.__editorTemplate) return "template";
521
521
  if (!e.type) return;
522
- const i = r.effectiveConfig?.typeDefaults;
522
+ const i = o.effectiveConfig?.typeDefaults;
523
523
  if (i?.[e.type]?.editor)
524
524
  return i[e.type].editor;
525
- const n = r.__frameworkAdapter;
525
+ const n = o.__frameworkAdapter;
526
526
  if (n?.getTypeDefault) {
527
527
  const s = n.getTypeDefault(e.type);
528
528
  if (s?.editor)
529
529
  return s.editor;
530
530
  }
531
531
  }
532
- function S(r) {
533
- return !(typeof r != "string" || r === "__proto__" || r === "constructor" || r === "prototype");
532
+ function S(o) {
533
+ return !(typeof o != "string" || o === "__proto__" || o === "constructor" || o === "prototype");
534
534
  }
535
- function K(r) {
536
- const e = (r.__editingCellCount ?? 0) + 1;
537
- r.__editingCellCount = e, r.setAttribute("data-has-editing", "");
535
+ function K(o) {
536
+ const e = (o.__editingCellCount ?? 0) + 1;
537
+ o.__editingCellCount = e, o.setAttribute("data-has-editing", "");
538
538
  }
539
- function U(r) {
540
- r.__editingCellCount = 0, r.removeAttribute("data-has-editing");
539
+ function U(o) {
540
+ o.__editingCellCount = 0, o.removeAttribute("data-has-editing");
541
541
  }
542
- function _(r, e, t) {
543
- return r instanceof HTMLInputElement ? r.type === "checkbox" ? r.checked : r.type === "number" ? r.value === "" ? null : Number(r.value) : r.type === "date" ? typeof t == "string" ? r.value : r.valueAsDate : typeof t == "number" ? r.value === "" ? null : Number(r.value) : t == null && r.value === "" || typeof t == "string" && r.value === t.replace(/[\n\r]/g, "") ? t : r.value : e?.type === "number" && r.value !== "" || typeof t == "number" && r.value !== "" ? Number(r.value) : t == null && r.value === "" ? t : r.value;
542
+ function _(o, e, t) {
543
+ return o instanceof HTMLInputElement ? o.type === "checkbox" ? o.checked : o.type === "number" ? o.value === "" ? null : Number(o.value) : o.type === "date" ? typeof t == "string" ? o.value : o.valueAsDate : typeof t == "number" ? o.value === "" ? null : Number(o.value) : t == null && o.value === "" || typeof t == "string" && o.value === t.replace(/[\n\r]/g, "") ? t : o.value : e?.type === "number" && o.value !== "" || typeof t == "number" && o.value !== "" ? Number(o.value) : t == null && o.value === "" ? t : o.value;
544
544
  }
545
- function T(r) {
545
+ function T(o) {
546
546
  }
547
- function Q(r, e, t, i) {
548
- const n = r.querySelector("input,textarea,select");
547
+ function Q(o, e, t, i) {
548
+ const n = o.querySelector("input,textarea,select");
549
549
  n && (n.addEventListener("blur", () => {
550
550
  t(_(n, e, i));
551
551
  }), n instanceof HTMLInputElement && n.type === "checkbox" ? n.addEventListener("change", () => t(n.checked)) : n instanceof HTMLSelectElement && n.addEventListener("change", () => t(_(n, e, i))));
552
552
  }
553
- class X extends O {
553
+ class X extends D {
554
554
  /**
555
555
  * Plugin manifest - declares owned properties for configuration validation.
556
556
  * @internal
@@ -608,11 +608,11 @@ class X extends O {
608
608
  /** Currently active edit row index, or -1 if not editing */
609
609
  #e = -1;
610
610
  /** Currently active edit column index, or -1 if not editing */
611
- #d = -1;
611
+ #u = -1;
612
612
  /** Snapshots of row data before editing started */
613
613
  #l = /* @__PURE__ */ new Map();
614
614
  /** Set of row IDs that have been modified (ID-based for stability) */
615
- #s = /* @__PURE__ */ new Set();
615
+ #n = /* @__PURE__ */ new Set();
616
616
  /** Set of cells currently in edit mode: "rowIndex:colIndex" */
617
617
  #o = /* @__PURE__ */ new Set();
618
618
  /**
@@ -622,9 +622,9 @@ class X extends O {
622
622
  */
623
623
  #c = /* @__PURE__ */ new Map();
624
624
  /** Flag to restore focus after next render (used when exiting edit mode) */
625
- #u = !1;
625
+ #f = !1;
626
626
  /** Row index pending animation after render, or -1 if none */
627
- #f = -1;
627
+ #h = -1;
628
628
  /**
629
629
  * Invalid cell tracking: Map<rowId, Map<field, message>>
630
630
  * Used for validation feedback without canceling edits.
@@ -643,6 +643,11 @@ class X extends O {
643
643
  * when Enter is pressed or user explicitly clicks an input.
644
644
  */
645
645
  #a = !1;
646
+ /**
647
+ * When true, only a single cell is being edited (triggered by F2 or `beginCellEdit`).
648
+ * Tab and Arrow keys commit and close the editor instead of navigating to adjacent cells.
649
+ */
650
+ #d = !1;
646
651
  // #endregion
647
652
  // #region Lifecycle
648
653
  /** @internal */
@@ -663,7 +668,7 @@ class X extends O {
663
668
  if (!this.#t && n.key === "Escape" && this.#e !== -1) {
664
669
  if (this.config.onBeforeEditClose && this.config.onBeforeEditClose(n) === !1)
665
670
  return;
666
- this.#n(this.#e, !0);
671
+ this.#s(this.#e, !0);
667
672
  }
668
673
  },
669
674
  { capture: !0, signal: t }
@@ -673,7 +678,7 @@ class X extends O {
673
678
  if (this.#t || this.#e === -1) return;
674
679
  const s = i.findRenderedRowElement?.(this.#e);
675
680
  !s || (n.composedPath && n.composedPath() || []).includes(s) || this.config.onBeforeEditClose && this.config.onBeforeEditClose(n) === !1 || queueMicrotask(() => {
676
- this.#e !== -1 && this.#n(this.#e, !1);
681
+ this.#e !== -1 && this.#s(this.#e, !1);
677
682
  });
678
683
  },
679
684
  { signal: t }
@@ -682,8 +687,8 @@ class X extends O {
682
687
  (n) => {
683
688
  const s = n.detail;
684
689
  if (s.source === "user") return;
685
- const l = `${s.rowIndex}:${s.field}`, o = this.#c.get(l);
686
- o && o(s.newValue);
690
+ const r = `${s.rowIndex}:${s.field}`, l = this.#c.get(r);
691
+ l && l(s.newValue);
687
692
  },
688
693
  { signal: t }
689
694
  ), this.#t && (this.gridElement.classList.add("tbw-grid-mode"), this.requestRender(), this.gridElement.addEventListener(
@@ -725,7 +730,7 @@ class X extends O {
725
730
  }
726
731
  /** @internal */
727
732
  detach() {
728
- this.gridElement.classList.remove("tbw-grid-mode"), this.#e = -1, this.#d = -1, this.#l.clear(), this.#s.clear(), this.#o.clear(), this.#c.clear(), this.#r = !1, this.#a = !1, super.detach();
733
+ this.gridElement.classList.remove("tbw-grid-mode"), this.#e = -1, this.#u = -1, this.#l.clear(), this.#n.clear(), this.#o.clear(), this.#c.clear(), this.#r = !1, this.#a = !1, this.#d = !1, super.detach();
729
734
  }
730
735
  /**
731
736
  * Handle plugin queries.
@@ -750,7 +755,7 @@ class X extends O {
750
755
  const n = e.originalEvent.type === "dblclick";
751
756
  if (i === "click" && n || i === "dblclick" && !n) return !1;
752
757
  const { rowIndex: s } = e;
753
- return t._columns?.some((o) => o.editable) ? (e.originalEvent.stopPropagation(), this.beginBulkEdit(s), !0) : !1;
758
+ return t._columns?.some((l) => l.editable) ? (e.originalEvent.stopPropagation(), this.beginBulkEdit(s), !0) : !1;
754
759
  }
755
760
  /**
756
761
  * Handle keyboard events for edit lifecycle.
@@ -764,7 +769,7 @@ class X extends O {
764
769
  return i && this.gridElement.contains(i) && i.blur(), this.#r = !1, this.requestAfterRender(), !0;
765
770
  }
766
771
  if (this.#e !== -1 && !this.#t)
767
- return this.config.onBeforeEditClose && this.config.onBeforeEditClose(e) === !1 || this.#n(this.#e, !0), !0;
772
+ return this.config.onBeforeEditClose && this.config.onBeforeEditClose(e) === !1 || this.#s(this.#e, !0), !0;
768
773
  }
769
774
  if (this.#t && !this.#r && (e.key === "ArrowUp" || e.key === "ArrowDown" || e.key === "ArrowLeft" || e.key === "ArrowRight"))
770
775
  return !1;
@@ -772,24 +777,25 @@ class X extends O {
772
777
  if (this.config.onBeforeEditClose && this.config.onBeforeEditClose(e) === !1)
773
778
  return !0;
774
779
  const i = t._rows.length - 1, n = this.#e;
775
- return this.#n(n, !1), e.key === "ArrowDown" ? t._focusRow = Math.min(i, t._focusRow + 1) : t._focusRow = Math.max(0, t._focusRow - 1), e.preventDefault(), L(t), this.requestAfterRender(), !0;
780
+ return this.#s(n, !1), e.key === "ArrowDown" ? t._focusRow = Math.min(i, t._focusRow + 1) : t._focusRow = Math.max(0, t._focusRow - 1), e.preventDefault(), L(t), this.requestAfterRender(), !0;
776
781
  }
777
782
  if (e.key === "Tab" && (this.#e !== -1 || this.#t)) {
778
- e.preventDefault();
783
+ if (e.preventDefault(), this.#d)
784
+ return this.#s(this.#e, !1), !0;
779
785
  const i = !e.shiftKey;
780
- return this.#y(i), !0;
786
+ return this.#C(i), !0;
781
787
  }
782
788
  if (e.key === " " || e.key === "Spacebar") {
783
789
  if (this.#e !== -1)
784
790
  return !1;
785
791
  const i = t._focusRow, n = t._focusCol;
786
792
  if (i >= 0 && n >= 0) {
787
- const s = t._visibleColumns[n], l = t._rows[i];
788
- if (s?.editable && s.type === "boolean" && l) {
789
- const o = s.field;
790
- if (S(o)) {
791
- const a = !l[o];
792
- return this.#m(i, s, a, l), e.preventDefault(), this.requestRender(), !0;
793
+ const s = t._visibleColumns[n], r = t._rows[i];
794
+ if (s?.editable && s.type === "boolean" && r) {
795
+ const l = s.field;
796
+ if (S(l)) {
797
+ const a = !r[l];
798
+ return this.#E(i, s, a, r), e.preventDefault(), this.requestRender(), !0;
793
799
  }
794
800
  }
795
801
  }
@@ -797,14 +803,14 @@ class X extends O {
797
803
  }
798
804
  if (e.key === "Enter" && !e.shiftKey) {
799
805
  if (this.#t && !this.#r)
800
- return this.#b(), !0;
806
+ return this.#y(), !0;
801
807
  if (this.#e !== -1)
802
808
  return !!(this.config.onBeforeEditClose && this.config.onBeforeEditClose(e) === !1);
803
809
  const i = this.config.editOn ?? t.effectiveConfig?.editOn;
804
810
  if (i === !1 || i === "manual") return !1;
805
811
  const n = t._focusRow, s = t._focusCol;
806
- if (n >= 0 && t._columns?.some((o) => o.editable)) {
807
- const o = t._visibleColumns[s], c = t._rows[n], a = o?.field ?? "", d = a && c ? c[a] : void 0, g = this.gridElement.querySelector(`[data-row="${n}"][data-col="${s}"]`), f = new CustomEvent("cell-activate", {
812
+ if (n >= 0 && t._columns?.some((l) => l.editable)) {
813
+ const l = t._visibleColumns[s], c = t._rows[n], a = l?.field ?? "", d = a && c ? c[a] : void 0, g = this.gridElement.querySelector(`[data-row="${n}"][data-col="${s}"]`), f = new CustomEvent("cell-activate", {
808
814
  cancelable: !0,
809
815
  bubbles: !0,
810
816
  detail: {
@@ -828,6 +834,16 @@ class X extends O {
828
834
  }
829
835
  return !1;
830
836
  }
837
+ if (e.key === "F2") {
838
+ if (this.#e !== -1 || this.#t || (this.config.editOn ?? t.effectiveConfig?.editOn) === !1) return !1;
839
+ const n = t._focusRow, s = t._focusCol;
840
+ if (n >= 0 && s >= 0) {
841
+ const r = t._visibleColumns[s];
842
+ if (r?.editable && r.field)
843
+ return e.preventDefault(), this.beginCellEdit(n, r.field), !0;
844
+ }
845
+ return !1;
846
+ }
831
847
  return !1;
832
848
  }
833
849
  // #endregion
@@ -841,14 +857,14 @@ class X extends O {
841
857
  const t = this.grid, i = t.effectiveConfig?.typeDefaults, n = t.__frameworkAdapter;
842
858
  return !i && !n?.getTypeDefault ? e : e.map((s) => {
843
859
  if (!s.type) return s;
844
- let l;
845
- if (i?.[s.type]?.editorParams && (l = i[s.type].editorParams), !l && n?.getTypeDefault) {
846
- const o = n.getTypeDefault(s.type);
847
- o?.editorParams && (l = o.editorParams);
860
+ let r;
861
+ if (i?.[s.type]?.editorParams && (r = i[s.type].editorParams), !r && n?.getTypeDefault) {
862
+ const l = n.getTypeDefault(s.type);
863
+ l?.editorParams && (r = l.editorParams);
848
864
  }
849
- return l ? {
865
+ return r ? {
850
866
  ...s,
851
- editorParams: { ...l, ...s.editorParams }
867
+ editorParams: { ...r, ...s.editorParams }
852
868
  } : s;
853
869
  });
854
870
  }
@@ -860,18 +876,18 @@ class X extends O {
860
876
  */
861
877
  afterRender() {
862
878
  const e = this.grid;
863
- if (this.#u && (this.#u = !1, this.#v(e)), this.#f !== -1) {
864
- const t = this.#f;
865
- this.#f = -1, e.animateRow?.(t, "change");
879
+ if (this.#f && (this.#f = !1, this.#w(e)), this.#h !== -1) {
880
+ const t = this.#h;
881
+ this.#h = -1, e.animateRow?.(t, "change");
866
882
  }
867
883
  if (!this.#t && this.#o.size !== 0)
868
884
  for (const t of this.#o) {
869
- const [i, n] = t.split(":"), s = parseInt(i, 10), l = parseInt(n, 10), o = e.findRenderedRowElement?.(s);
870
- if (!o) continue;
871
- const c = o.querySelector(`.cell[data-col="${l}"]`);
885
+ const [i, n] = t.split(":"), s = parseInt(i, 10), r = parseInt(n, 10), l = e.findRenderedRowElement?.(s);
886
+ if (!l) continue;
887
+ const c = l.querySelector(`.cell[data-col="${r}"]`);
872
888
  if (!c || c.classList.contains("editing")) continue;
873
- const a = e._rows[s], d = e._visibleColumns[l];
874
- a && d && this.#p(a, s, d, l, c, !0);
889
+ const a = e._rows[s], d = e._visibleColumns[r];
890
+ a && d && this.#m(a, s, d, r, c, !0);
875
891
  }
876
892
  }
877
893
  /**
@@ -881,8 +897,8 @@ class X extends O {
881
897
  */
882
898
  afterCellRender(e) {
883
899
  if (!this.#t) return;
884
- const { row: t, rowIndex: i, column: n, colIndex: s, cellElement: l } = e;
885
- n.editable && (l.classList.contains("editing") || this.#p(t, i, n, s, l, !0));
900
+ const { row: t, rowIndex: i, column: n, colIndex: s, cellElement: r } = e;
901
+ n.editable && (r.classList.contains("editing") || this.#m(t, i, n, s, r, !0));
886
902
  }
887
903
  /**
888
904
  * On scroll render, reapply editors to recycled cells.
@@ -899,7 +915,7 @@ class X extends O {
899
915
  */
900
916
  get changedRows() {
901
917
  const e = [];
902
- for (const t of this.#s) {
918
+ for (const t of this.#n) {
903
919
  const i = this.grid.getRow(t);
904
920
  i && e.push(i);
905
921
  }
@@ -909,7 +925,7 @@ class X extends O {
909
925
  * Get IDs of all modified rows.
910
926
  */
911
927
  get changedRowIds() {
912
- return Array.from(this.#s);
928
+ return Array.from(this.#n);
913
929
  }
914
930
  /**
915
931
  * Get the currently active edit row index, or -1 if not editing.
@@ -921,7 +937,7 @@ class X extends O {
921
937
  * Get the currently active edit column index, or -1 if not editing.
922
938
  */
923
939
  get activeEditCol() {
924
- return this.#d;
940
+ return this.#u;
925
941
  }
926
942
  /**
927
943
  * Check if a specific row is currently being edited.
@@ -944,7 +960,7 @@ class X extends O {
944
960
  if (!i) return !1;
945
961
  try {
946
962
  const n = t.getRowId?.(i);
947
- return n ? this.#s.has(n) : !1;
963
+ return n ? this.#n.has(n) : !1;
948
964
  } catch {
949
965
  return !1;
950
966
  }
@@ -954,7 +970,7 @@ class X extends O {
954
970
  * @param rowId - Row ID to check
955
971
  */
956
972
  isRowChangedById(e) {
957
- return this.#s.has(e);
973
+ return this.#n.has(e);
958
974
  }
959
975
  // #region Cell Validation
960
976
  /**
@@ -980,7 +996,7 @@ class X extends O {
980
996
  */
981
997
  setInvalid(e, t, i = "") {
982
998
  let n = this.#i.get(e);
983
- n || (n = /* @__PURE__ */ new Map(), this.#i.set(e, n)), n.set(t, i), this.#h(e, t, !0);
999
+ n || (n = /* @__PURE__ */ new Map(), this.#i.set(e, n)), n.set(t, i), this.#g(e, t, !0);
984
1000
  }
985
1001
  /**
986
1002
  * Clear the invalid state for a specific cell.
@@ -990,7 +1006,7 @@ class X extends O {
990
1006
  */
991
1007
  clearInvalid(e, t) {
992
1008
  const i = this.#i.get(e);
993
- i && (i.delete(t), i.size === 0 && this.#i.delete(e)), this.#h(e, t, !1);
1009
+ i && (i.delete(t), i.size === 0 && this.#i.delete(e)), this.#g(e, t, !1);
994
1010
  }
995
1011
  /**
996
1012
  * Clear all invalid cells for a specific row.
@@ -1001,7 +1017,7 @@ class X extends O {
1001
1017
  const t = this.#i.get(e);
1002
1018
  if (t) {
1003
1019
  const i = Array.from(t.keys());
1004
- this.#i.delete(e), i.forEach((n) => this.#h(e, n, !1));
1020
+ this.#i.delete(e), i.forEach((n) => this.#g(e, n, !1));
1005
1021
  }
1006
1022
  }
1007
1023
  /**
@@ -1010,7 +1026,7 @@ class X extends O {
1010
1026
  clearAllInvalid() {
1011
1027
  const e = Array.from(this.#i.entries());
1012
1028
  this.#i.clear(), e.forEach(([t, i]) => {
1013
- i.forEach((n, s) => this.#h(t, s, !1));
1029
+ i.forEach((n, s) => this.#g(t, s, !1));
1014
1030
  });
1015
1031
  }
1016
1032
  /**
@@ -1055,18 +1071,18 @@ class X extends O {
1055
1071
  /**
1056
1072
  * Sync the data-invalid attribute on a cell element.
1057
1073
  */
1058
- #h(e, t, i) {
1074
+ #g(e, t, i) {
1059
1075
  const n = this.grid, s = n._visibleColumns?.findIndex((d) => d.field === t);
1060
1076
  if (s === -1 || s === void 0) return;
1061
- const o = n._rows?.findIndex((d) => {
1077
+ const l = n._rows?.findIndex((d) => {
1062
1078
  try {
1063
1079
  return n.getRowId?.(d) === e;
1064
1080
  } catch {
1065
1081
  return !1;
1066
1082
  }
1067
1083
  });
1068
- if (o === -1 || o === void 0) return;
1069
- const a = n.findRenderedRowElement?.(o)?.querySelector(`.cell[data-col="${s}"]`);
1084
+ if (l === -1 || l === void 0) return;
1085
+ const a = n.findRenderedRowElement?.(l)?.querySelector(`.cell[data-col="${s}"]`);
1070
1086
  if (a)
1071
1087
  if (i) {
1072
1088
  a.setAttribute("data-invalid", "true");
@@ -1083,7 +1099,7 @@ class X extends O {
1083
1099
  */
1084
1100
  resetChangedRows(e) {
1085
1101
  const t = this.changedRows, i = this.changedRowIds;
1086
- this.#s.clear(), this.#g(), e || this.emit("changed-rows-reset", { rows: t, ids: i }), this.grid._rowPool?.forEach((s) => s.classList.remove("changed"));
1102
+ this.#n.clear(), this.#p(), e || this.emit("changed-rows-reset", { rows: t, ids: i }), this.grid._rowPool?.forEach((s) => s.classList.remove("changed"));
1087
1103
  }
1088
1104
  /**
1089
1105
  * Programmatically begin editing a cell.
@@ -1094,8 +1110,8 @@ class X extends O {
1094
1110
  beginCellEdit(e, t) {
1095
1111
  const i = this.grid, n = i._visibleColumns.findIndex((c) => c.field === t);
1096
1112
  if (n === -1 || !i._visibleColumns[n]?.editable) return;
1097
- const o = i.findRenderedRowElement?.(e)?.querySelector(`.cell[data-col="${n}"]`);
1098
- o && this.#w(e, n, o);
1113
+ const l = i.findRenderedRowElement?.(e)?.querySelector(`.cell[data-col="${n}"]`);
1114
+ l && (this.#d = !0, this.#b(e, n, l));
1099
1115
  }
1100
1116
  /**
1101
1117
  * Programmatically begin editing all editable cells in a row.
@@ -1105,20 +1121,21 @@ class X extends O {
1105
1121
  */
1106
1122
  beginBulkEdit(e) {
1107
1123
  const t = this.grid;
1108
- if ((this.config.editOn ?? t.effectiveConfig?.editOn) === !1 || !t._columns?.some((o) => o.editable)) return;
1124
+ if ((this.config.editOn ?? t.effectiveConfig?.editOn) === !1 || !t._columns?.some((l) => l.editable)) return;
1109
1125
  const s = t.findRenderedRowElement?.(e);
1110
1126
  if (!s) return;
1111
- const l = t._rows[e];
1112
- this.#E(e, l), Array.from(s.children).forEach((o, c) => {
1127
+ this.#d = !1;
1128
+ const r = t._rows[e];
1129
+ this.#v(e, r), Array.from(s.children).forEach((l, c) => {
1113
1130
  const a = t._visibleColumns[c];
1114
1131
  if (a?.editable) {
1115
- const d = o;
1116
- d.classList.contains("editing") || this.#p(l, e, a, c, d, !0);
1132
+ const d = l;
1133
+ d.classList.contains("editing") || this.#m(r, e, a, c, d, !0);
1117
1134
  }
1118
1135
  }), setTimeout(() => {
1119
- let o = s.querySelector(`.cell[data-col="${t._focusCol}"]`);
1120
- if (o?.classList.contains("editing") || (o = s.querySelector(".cell.editing")), o?.classList.contains("editing")) {
1121
- const c = o.querySelector(w);
1136
+ let l = s.querySelector(`.cell[data-col="${t._focusCol}"]`);
1137
+ if (l?.classList.contains("editing") || (l = s.querySelector(".cell.editing")), l?.classList.contains("editing")) {
1138
+ const c = l.querySelector(w);
1122
1139
  try {
1123
1140
  c?.focus({ preventScroll: !0 });
1124
1141
  } catch {
@@ -1131,34 +1148,34 @@ class X extends O {
1131
1148
  * @fires row-commit - Emitted after the row edit is committed
1132
1149
  */
1133
1150
  commitActiveRowEdit() {
1134
- this.#e !== -1 && this.#n(this.#e, !1);
1151
+ this.#e !== -1 && this.#s(this.#e, !1);
1135
1152
  }
1136
1153
  /**
1137
1154
  * Cancel the currently active row edit.
1138
1155
  */
1139
1156
  cancelActiveRowEdit() {
1140
- this.#e !== -1 && this.#n(this.#e, !0);
1157
+ this.#e !== -1 && this.#s(this.#e, !0);
1141
1158
  }
1142
1159
  // #endregion
1143
1160
  // #region Internal Methods
1144
1161
  /**
1145
1162
  * Begin editing a single cell.
1146
1163
  */
1147
- #w(e, t, i) {
1148
- const n = this.grid, s = n._rows[e], l = n._visibleColumns[t];
1149
- !s || !l?.editable || i.classList.contains("editing") || (this.#e !== e && this.#E(e, s), this.#d = t, this.#p(s, e, l, t, i, !1));
1164
+ #b(e, t, i) {
1165
+ const n = this.grid, s = n._rows[e], r = n._visibleColumns[t];
1166
+ !s || !r?.editable || i.classList.contains("editing") || (this.#e !== e && this.#v(e, s), this.#u = t, this.#m(s, e, r, t, i, !1));
1150
1167
  }
1151
1168
  /**
1152
1169
  * Focus the editor input in the currently focused cell (grid mode only).
1153
1170
  * Used when pressing Enter to enter edit mode from navigation mode.
1154
1171
  */
1155
- #b() {
1172
+ #y() {
1156
1173
  const e = this.grid, t = e._focusRow, i = e._focusCol;
1157
1174
  if (t < 0 || i < 0) return;
1158
1175
  const s = e.findRenderedRowElement?.(t)?.querySelector(`.cell[data-col="${i}"]`);
1159
1176
  if (s?.classList.contains("editing")) {
1160
- const l = s.querySelector(w);
1161
- l && (this.#a = !1, l.focus(), this.#r = !0, l instanceof HTMLInputElement && (l.type === "text" || l.type === "number") && l.select());
1177
+ const r = s.querySelector(w);
1178
+ r && (this.#a = !1, r.focus(), this.#r = !0, r instanceof HTMLInputElement && (r.type === "text" || r.type === "number") && r.select());
1162
1179
  }
1163
1180
  }
1164
1181
  /**
@@ -1166,13 +1183,13 @@ class X extends O {
1166
1183
  * Moves to next/previous editable cell, staying in edit mode.
1167
1184
  * Wraps to next/previous row when reaching row boundaries.
1168
1185
  */
1169
- #y(e) {
1186
+ #C(e) {
1170
1187
  const t = this.grid, i = t._rows, n = this.#t ? t._focusRow : this.#e, s = t._visibleColumns.map((a, d) => a.editable ? d : -1).filter((a) => a >= 0);
1171
1188
  if (s.length === 0) return;
1172
- const o = s.indexOf(t._focusCol) + (e ? 1 : -1);
1173
- if (o >= 0 && o < s.length) {
1174
- t._focusCol = s[o];
1175
- const d = t.findRenderedRowElement?.(n)?.querySelector(`.cell[data-col="${s[o]}"]`);
1189
+ const l = s.indexOf(t._focusCol) + (e ? 1 : -1);
1190
+ if (l >= 0 && l < s.length) {
1191
+ t._focusCol = s[l];
1192
+ const d = t.findRenderedRowElement?.(n)?.querySelector(`.cell[data-col="${s[l]}"]`);
1176
1193
  d?.classList.contains("editing") && d.querySelector(w)?.focus({ preventScroll: !0 }), L(t, { forceHorizontalScroll: !0 });
1177
1194
  return;
1178
1195
  }
@@ -1180,20 +1197,20 @@ class X extends O {
1180
1197
  c >= 0 && c < i.length && (this.#t ? (t._focusRow = c, t._focusCol = e ? s[0] : s[s.length - 1], L(t, { forceHorizontalScroll: !0 }), this.requestAfterRender(), setTimeout(() => {
1181
1198
  const d = t.findRenderedRowElement?.(c)?.querySelector(`.cell[data-col="${t._focusCol}"]`);
1182
1199
  d?.classList.contains("editing") && d.querySelector(w)?.focus({ preventScroll: !0 });
1183
- }, 0)) : (this.#n(n, !1), t._focusRow = c, t._focusCol = e ? s[0] : s[s.length - 1], this.beginBulkEdit(c), L(t, { forceHorizontalScroll: !0 })));
1200
+ }, 0)) : (this.#s(n, !1), t._focusRow = c, t._focusCol = e ? s[0] : s[s.length - 1], this.beginBulkEdit(c), L(t, { forceHorizontalScroll: !0 })));
1184
1201
  }
1185
1202
  /**
1186
1203
  * Sync the internal grid state with the plugin's editing state.
1187
1204
  */
1188
- #g() {
1205
+ #p() {
1189
1206
  const e = this.grid;
1190
1207
  e._activeEditRows = this.#e, e._rowEditSnapshots = this.#l;
1191
1208
  }
1192
1209
  /**
1193
1210
  * Snapshot original row data and mark as editing.
1194
1211
  */
1195
- #E(e, t) {
1196
- if (this.#e !== e && (this.#l.set(e, { ...t }), this.#e = e, this.#g(), !this.#t)) {
1212
+ #v(e, t) {
1213
+ if (this.#e !== e && (this.#l.set(e, { ...t }), this.#e = e, this.#p(), !this.#t)) {
1197
1214
  const i = this.grid;
1198
1215
  let n = "";
1199
1216
  try {
@@ -1210,16 +1227,16 @@ class X extends O {
1210
1227
  /**
1211
1228
  * Exit editing for a row.
1212
1229
  */
1213
- #n(e, t) {
1230
+ #s(e, t) {
1214
1231
  if (this.#e !== e) return;
1215
- const i = this.grid, n = this.#l.get(e), s = i._rows[e], l = i.findRenderedRowElement?.(e);
1216
- let o;
1232
+ const i = this.grid, n = this.#l.get(e), s = i._rows[e], r = i.findRenderedRowElement?.(e);
1233
+ let l;
1217
1234
  if (s)
1218
1235
  try {
1219
- o = i.getRowId?.(s);
1236
+ l = i.getRowId?.(s);
1220
1237
  } catch {
1221
1238
  }
1222
- if (!t && l && s && l.querySelectorAll(".cell.editing").forEach((a) => {
1239
+ if (!t && r && s && r.querySelectorAll(".cell.editing").forEach((a) => {
1223
1240
  const d = Number(a.getAttribute("data-col"));
1224
1241
  if (isNaN(d)) return;
1225
1242
  const g = i._visibleColumns[d];
@@ -1228,16 +1245,16 @@ class X extends O {
1228
1245
  const f = a.querySelector("input,textarea,select");
1229
1246
  if (f) {
1230
1247
  const E = g.field, p = s[E], m = _(f, g, p);
1231
- p !== m && this.#m(e, g, m, s);
1248
+ p !== m && this.#E(e, g, m, s);
1232
1249
  }
1233
1250
  }), t && n && s)
1234
1251
  Object.keys(n).forEach((c) => {
1235
1252
  s[c] = n[c];
1236
- }), o && (this.#s.delete(o), this.clearRowInvalid(o));
1253
+ }), l && (this.#n.delete(l), this.clearRowInvalid(l));
1237
1254
  else if (!t && s) {
1238
- const c = this.#R(n, s), a = o ? this.#s.has(o) : c, d = this.emitCancelable("row-commit", {
1255
+ const c = this.#_(n, s), a = l ? this.#n.has(l) : c, d = this.emitCancelable("row-commit", {
1239
1256
  rowIndex: e,
1240
- rowId: o ?? "",
1257
+ rowId: l ?? "",
1241
1258
  row: s,
1242
1259
  oldValue: n,
1243
1260
  newValue: s,
@@ -1247,18 +1264,18 @@ class X extends O {
1247
1264
  });
1248
1265
  d && n ? (Object.keys(n).forEach((g) => {
1249
1266
  s[g] = n[g];
1250
- }), o && (this.#s.delete(o), this.clearRowInvalid(o))) : !d && c && this.isAnimationEnabled && (this.#f = e);
1267
+ }), l && (this.#n.delete(l), this.clearRowInvalid(l))) : !d && c && this.isAnimationEnabled && (this.#h = e);
1251
1268
  }
1252
- this.#l.delete(e), this.#e = -1, this.#d = -1, this.#g();
1269
+ this.#l.delete(e), this.#e = -1, this.#u = -1, this.#d = !1, this.#p();
1253
1270
  for (const c of this.#o)
1254
1271
  c.startsWith(`${e}:`) && this.#o.delete(c);
1255
1272
  for (const c of this.#c.keys())
1256
1273
  c.startsWith(`${e}:`) && this.#c.delete(c);
1257
- l && (l.querySelectorAll(".cell.editing").forEach((c) => {
1274
+ r && (r.querySelectorAll(".cell.editing").forEach((c) => {
1258
1275
  c.classList.remove("editing"), U(c.parentElement);
1259
- }), this.requestRender()), this.#u = !0, l || (this.#v(i), this.#u = !1), !this.#t && s && this.emit("edit-close", {
1276
+ }), this.requestRender()), this.#f = !0, r || (this.#w(i), this.#f = !1), !this.#t && s && this.emit("edit-close", {
1260
1277
  rowIndex: e,
1261
- rowId: o ?? "",
1278
+ rowId: l ?? "",
1262
1279
  row: s,
1263
1280
  reverted: t
1264
1281
  });
@@ -1267,18 +1284,18 @@ class X extends O {
1267
1284
  * Commit a single cell value change.
1268
1285
  * Uses ID-based change tracking for stability when rows are reordered.
1269
1286
  */
1270
- #m(e, t, i, n) {
1287
+ #E(e, t, i, n) {
1271
1288
  const s = t.field;
1272
1289
  if (!S(s)) return;
1273
- const l = n[s];
1274
- if (l === i) return;
1275
- const o = this.grid;
1290
+ const r = n[s];
1291
+ if (r === i) return;
1292
+ const l = this.grid;
1276
1293
  let c;
1277
1294
  try {
1278
1295
  c = this.grid.getRowId(n);
1279
1296
  } catch {
1280
1297
  }
1281
- const a = c ? !this.#s.has(c) : !0, d = c ? (m) => this.grid.updateRow(c, m, "cascade") : T;
1298
+ const a = c ? !this.#n.has(c) : !0, d = c ? (m) => this.grid.updateRow(c, m, "cascade") : T;
1282
1299
  let g = !1;
1283
1300
  const f = c ? (m) => {
1284
1301
  g = !0, this.setInvalid(c, s, m ?? "");
@@ -1288,7 +1305,7 @@ class X extends O {
1288
1305
  row: n,
1289
1306
  rowId: c ?? "",
1290
1307
  field: s,
1291
- oldValue: l,
1308
+ oldValue: r,
1292
1309
  value: i,
1293
1310
  rowIndex: e,
1294
1311
  changedRows: this.changedRows,
@@ -1297,32 +1314,32 @@ class X extends O {
1297
1314
  updateRow: d,
1298
1315
  setInvalid: f
1299
1316
  })) return;
1300
- c && !g && this.isCellInvalid(c, s) && this.clearInvalid(c, s), n[s] = i, c && this.#s.add(c), this.#g(), this.emitPluginEvent("cell-edit-committed", {
1317
+ c && !g && this.isCellInvalid(c, s) && this.clearInvalid(c, s), n[s] = i, c && this.#n.add(c), this.#p(), this.emitPluginEvent("cell-edit-committed", {
1301
1318
  rowIndex: e,
1302
1319
  field: s,
1303
- oldValue: l,
1320
+ oldValue: r,
1304
1321
  newValue: i
1305
1322
  });
1306
- const p = o.findRenderedRowElement?.(e);
1323
+ const p = l.findRenderedRowElement?.(e);
1307
1324
  p && p.classList.add("changed");
1308
1325
  }
1309
1326
  /**
1310
1327
  * Inject an editor into a cell.
1311
1328
  */
1312
- #p(e, t, i, n, s, l) {
1329
+ #m(e, t, i, n, s, r) {
1313
1330
  if (!i.editable || s.classList.contains("editing")) return;
1314
- let o;
1331
+ let l;
1315
1332
  try {
1316
- o = this.grid.getRowId(e);
1333
+ l = this.grid.getRowId(e);
1317
1334
  } catch {
1318
1335
  }
1319
- const c = o ? (u) => this.grid.updateRow(o, u, "cascade") : T, a = S(i.field) ? e[i.field] : void 0;
1336
+ const c = l ? (u) => this.grid.updateRow(l, u, "cascade") : T, a = S(i.field) ? e[i.field] : void 0;
1320
1337
  s.classList.add("editing"), this.#o.add(`${t}:${n}`);
1321
1338
  const d = s.parentElement;
1322
1339
  d && K(d);
1323
1340
  let g = !1;
1324
1341
  const f = (u) => {
1325
- g || !this.#t && this.#e === -1 || this.#m(t, i, u, e);
1342
+ g || !this.#t && this.#e === -1 || this.#E(t, i, u, e);
1326
1343
  }, E = () => {
1327
1344
  g = !0, S(i.field) && (e[i.field] = a);
1328
1345
  }, p = document.createElement("div");
@@ -1336,7 +1353,7 @@ class X extends O {
1336
1353
  }
1337
1354
  if (this.config.onBeforeEditClose && this.config.onBeforeEditClose(u) === !1)
1338
1355
  return;
1339
- u.stopPropagation(), u.preventDefault(), g = !0, this.#n(t, !1);
1356
+ u.stopPropagation(), u.preventDefault(), g = !0, this.#s(t, !1);
1340
1357
  }
1341
1358
  if (u.key === "Escape") {
1342
1359
  if (this.#t) {
@@ -1345,7 +1362,7 @@ class X extends O {
1345
1362
  }
1346
1363
  if (this.config.onBeforeEditClose && this.config.onBeforeEditClose(u) === !1)
1347
1364
  return;
1348
- u.stopPropagation(), u.preventDefault(), E(), this.#n(t, !0);
1365
+ u.stopPropagation(), u.preventDefault(), E(), this.#s(t, !0);
1349
1366
  }
1350
1367
  });
1351
1368
  const m = i, y = m.__editorTemplate, v = W(this.grid, m) ?? j(i), k = a, q = `${t}:${i.field}`, A = [];
@@ -1356,7 +1373,7 @@ class X extends O {
1356
1373
  A.push(u);
1357
1374
  };
1358
1375
  if (v === "template" && y)
1359
- this.#C(p, m, e, a, f, E, l, t), C((u) => {
1376
+ this.#R(p, m, e, a, f, E, r, t), C((u) => {
1360
1377
  const h = p.querySelector(
1361
1378
  "input,textarea,select"
1362
1379
  );
@@ -1366,13 +1383,13 @@ class X extends O {
1366
1383
  const u = document.createElement(v);
1367
1384
  u.value = k, u.addEventListener("change", () => f(u.value)), C((h) => {
1368
1385
  u.value = h;
1369
- }), p.appendChild(u), l || queueMicrotask(() => {
1386
+ }), p.appendChild(u), r || queueMicrotask(() => {
1370
1387
  p.querySelector(w)?.focus({ preventScroll: !0 });
1371
1388
  });
1372
1389
  } else if (typeof v == "function") {
1373
1390
  const u = {
1374
1391
  row: e,
1375
- rowId: o ?? "",
1392
+ rowId: l ?? "",
1376
1393
  value: k,
1377
1394
  field: i.field,
1378
1395
  column: i,
@@ -1388,7 +1405,7 @@ class X extends O {
1388
1405
  b && (b instanceof HTMLInputElement && b.type === "checkbox" ? b.checked = !!R : b.value = String(R ?? ""));
1389
1406
  })) : h instanceof Node && (p.appendChild(h), h instanceof HTMLInputElement || h instanceof HTMLSelectElement || h instanceof HTMLTextAreaElement ? C((b) => {
1390
1407
  h instanceof HTMLInputElement && h.type === "checkbox" ? h.checked = !!b : h.value = String(b ?? "");
1391
- }) : s.setAttribute("data-editor-managed", "")), l || queueMicrotask(() => {
1408
+ }) : s.setAttribute("data-editor-managed", "")), r || queueMicrotask(() => {
1392
1409
  p.querySelector(w)?.focus({ preventScroll: !0 });
1393
1410
  });
1394
1411
  } else if (v && typeof v == "object") {
@@ -1396,7 +1413,7 @@ class X extends O {
1396
1413
  u.setAttribute("data-external-editor", ""), u.setAttribute("data-field", i.field), p.appendChild(u), s.setAttribute("data-editor-managed", "");
1397
1414
  const h = {
1398
1415
  row: e,
1399
- rowId: o ?? "",
1416
+ rowId: l ?? "",
1400
1417
  value: k,
1401
1418
  field: i.field,
1402
1419
  column: i,
@@ -1420,7 +1437,7 @@ class X extends O {
1420
1437
  /**
1421
1438
  * Render a template-based editor.
1422
1439
  */
1423
- #C(e, t, i, n, s, l, o, c) {
1440
+ #R(e, t, i, n, s, r, l, c) {
1424
1441
  const a = t.__editorTemplate;
1425
1442
  if (!a) return;
1426
1443
  const d = a.cloneNode(!0), g = t.__compiledEditor;
@@ -1430,7 +1447,7 @@ class X extends O {
1430
1447
  field: t.field,
1431
1448
  column: t,
1432
1449
  commit: s,
1433
- cancel: l
1450
+ cancel: r
1434
1451
  }) : d.querySelectorAll("*").forEach((E) => {
1435
1452
  E.childNodes.length === 1 && E.firstChild?.nodeType === Node.TEXT_NODE && (E.textContent = E.textContent?.replace(/{{\s*value\s*}}/g, n == null ? "" : String(n)).replace(/{{\s*row\.([a-zA-Z0-9_]+)\s*}}/g, (p, m) => {
1436
1453
  if (!S(m)) return "";
@@ -1451,14 +1468,14 @@ class X extends O {
1451
1468
  if (m.key === "Enter") {
1452
1469
  if (this.config.onBeforeEditClose && this.config.onBeforeEditClose(m) === !1)
1453
1470
  return;
1454
- m.stopPropagation(), m.preventDefault(), E = !0, s(_(f, t, n)), this.#n(c, !1);
1471
+ m.stopPropagation(), m.preventDefault(), E = !0, s(_(f, t, n)), this.#s(c, !1);
1455
1472
  }
1456
1473
  if (m.key === "Escape") {
1457
1474
  if (this.config.onBeforeEditClose && this.config.onBeforeEditClose(m) === !1)
1458
1475
  return;
1459
- m.stopPropagation(), m.preventDefault(), l(), this.#n(c, !0);
1476
+ m.stopPropagation(), m.preventDefault(), r(), this.#s(c, !0);
1460
1477
  }
1461
- }), f instanceof HTMLInputElement && f.type === "checkbox" && f.addEventListener("change", () => s(f.checked)), o || setTimeout(() => f.focus({ preventScroll: !0 }), 0);
1478
+ }), f instanceof HTMLInputElement && f.type === "checkbox" && f.addEventListener("change", () => s(f.checked)), l || setTimeout(() => f.focus({ preventScroll: !0 }), 0);
1462
1479
  }
1463
1480
  e.appendChild(d);
1464
1481
  }
@@ -1466,24 +1483,24 @@ class X extends O {
1466
1483
  * Compare snapshot vs current row to detect if any values changed during this edit session.
1467
1484
  * Uses shallow comparison of all properties.
1468
1485
  */
1469
- #R(e, t) {
1486
+ #_(e, t) {
1470
1487
  if (!e) return !1;
1471
1488
  const i = e, n = t, s = /* @__PURE__ */ new Set([...Object.keys(i), ...Object.keys(n)]);
1472
- for (const l of s)
1473
- if (i[l] !== n[l])
1489
+ for (const r of s)
1490
+ if (i[r] !== n[r])
1474
1491
  return !0;
1475
1492
  return !1;
1476
1493
  }
1477
1494
  /**
1478
1495
  * Restore focus to cell after exiting edit mode.
1479
1496
  */
1480
- #v(e) {
1497
+ #w(e) {
1481
1498
  queueMicrotask(() => {
1482
1499
  try {
1483
1500
  const t = e._focusRow, i = e._focusCol, n = e.findRenderedRowElement?.(t);
1484
1501
  if (n) {
1485
1502
  Array.from(e._bodyEl.querySelectorAll(".cell-focus")).forEach(
1486
- (l) => l.classList.remove("cell-focus")
1503
+ (r) => r.classList.remove("cell-focus")
1487
1504
  );
1488
1505
  const s = n.querySelector(`.cell[data-row="${t}"][data-col="${i}"]`);
1489
1506
  s && (s.classList.add("cell-focus"), s.setAttribute("aria-selected", "true"), s.hasAttribute("tabindex") || s.setAttribute("tabindex", "-1"), s.focus({ preventScroll: !0 }));