@toolbox-web/grid 1.13.0 → 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 (81) hide show
  1. package/all.js +1483 -1403
  2. package/all.js.map +1 -1
  3. package/index.js +11 -4
  4. package/index.js.map +1 -1
  5. package/lib/core/internal/row-animation.d.ts.map +1 -1
  6. package/lib/core/plugin/types.d.ts +1 -1
  7. package/lib/core/plugin/types.d.ts.map +1 -1
  8. package/lib/core/types.d.ts +44 -1
  9. package/lib/core/types.d.ts.map +1 -1
  10. package/lib/plugins/clipboard/ClipboardPlugin.d.ts +69 -8
  11. package/lib/plugins/clipboard/ClipboardPlugin.d.ts.map +1 -1
  12. package/lib/plugins/clipboard/index.d.ts +1 -1
  13. package/lib/plugins/clipboard/index.d.ts.map +1 -1
  14. package/lib/plugins/clipboard/index.js +257 -192
  15. package/lib/plugins/clipboard/index.js.map +1 -1
  16. package/lib/plugins/clipboard/types.d.ts +31 -0
  17. package/lib/plugins/clipboard/types.d.ts.map +1 -1
  18. package/lib/plugins/column-virtualization/index.js.map +1 -1
  19. package/lib/plugins/context-menu/ContextMenuPlugin.d.ts +8 -0
  20. package/lib/plugins/context-menu/ContextMenuPlugin.d.ts.map +1 -1
  21. package/lib/plugins/context-menu/index.js +75 -60
  22. package/lib/plugins/context-menu/index.js.map +1 -1
  23. package/lib/plugins/context-menu/types.d.ts +7 -0
  24. package/lib/plugins/context-menu/types.d.ts.map +1 -1
  25. package/lib/plugins/editing/EditingPlugin.d.ts.map +1 -1
  26. package/lib/plugins/editing/editors.d.ts +2 -2
  27. package/lib/plugins/editing/editors.d.ts.map +1 -1
  28. package/lib/plugins/editing/index.js +420 -381
  29. package/lib/plugins/editing/index.js.map +1 -1
  30. package/lib/plugins/editing/types.d.ts +6 -23
  31. package/lib/plugins/editing/types.d.ts.map +1 -1
  32. package/lib/plugins/export/ExportPlugin.d.ts.map +1 -1
  33. package/lib/plugins/export/index.js +75 -66
  34. package/lib/plugins/export/index.js.map +1 -1
  35. package/lib/plugins/filtering/index.d.ts +1 -1
  36. package/lib/plugins/filtering/index.d.ts.map +1 -1
  37. package/lib/plugins/filtering/index.js.map +1 -1
  38. package/lib/plugins/grouping-columns/index.js.map +1 -1
  39. package/lib/plugins/grouping-rows/index.js.map +1 -1
  40. package/lib/plugins/master-detail/index.js.map +1 -1
  41. package/lib/plugins/multi-sort/index.js.map +1 -1
  42. package/lib/plugins/pinned-columns/index.js.map +1 -1
  43. package/lib/plugins/pinned-rows/PinnedRowsPlugin.d.ts +1 -0
  44. package/lib/plugins/pinned-rows/PinnedRowsPlugin.d.ts.map +1 -1
  45. package/lib/plugins/pinned-rows/index.js +118 -87
  46. package/lib/plugins/pinned-rows/index.js.map +1 -1
  47. package/lib/plugins/pinned-rows/pinned-rows.d.ts +2 -1
  48. package/lib/plugins/pinned-rows/pinned-rows.d.ts.map +1 -1
  49. package/lib/plugins/pinned-rows/types.d.ts +23 -2
  50. package/lib/plugins/pinned-rows/types.d.ts.map +1 -1
  51. package/lib/plugins/pivot/index.js.map +1 -1
  52. package/lib/plugins/print/index.js.map +1 -1
  53. package/lib/plugins/reorder/index.js.map +1 -1
  54. package/lib/plugins/responsive/index.js.map +1 -1
  55. package/lib/plugins/row-reorder/index.js.map +1 -1
  56. package/lib/plugins/selection/SelectionPlugin.d.ts.map +1 -1
  57. package/lib/plugins/selection/index.js +147 -139
  58. package/lib/plugins/selection/index.js.map +1 -1
  59. package/lib/plugins/server-side/index.js.map +1 -1
  60. package/lib/plugins/shared/data-collection.d.ts +33 -0
  61. package/lib/plugins/shared/data-collection.d.ts.map +1 -0
  62. package/lib/plugins/tree/index.js.map +1 -1
  63. package/lib/plugins/undo-redo/index.js.map +1 -1
  64. package/lib/plugins/visibility/index.js.map +1 -1
  65. package/package.json +1 -1
  66. package/umd/grid.all.umd.js +23 -23
  67. package/umd/grid.all.umd.js.map +1 -1
  68. package/umd/grid.umd.js +2 -2
  69. package/umd/grid.umd.js.map +1 -1
  70. package/umd/plugins/clipboard.umd.js +5 -5
  71. package/umd/plugins/clipboard.umd.js.map +1 -1
  72. package/umd/plugins/context-menu.umd.js +1 -1
  73. package/umd/plugins/context-menu.umd.js.map +1 -1
  74. package/umd/plugins/editing.umd.js +1 -1
  75. package/umd/plugins/editing.umd.js.map +1 -1
  76. package/umd/plugins/export.umd.js +7 -7
  77. package/umd/plugins/export.umd.js.map +1 -1
  78. package/umd/plugins/pinned-rows.umd.js +1 -1
  79. package/umd/plugins/pinned-rows.umd.js.map +1 -1
  80. package/umd/plugins/selection.umd.js +2 -2
  81. package/umd/plugins/selection.umd.js.map +1 -1
@@ -1,46 +1,46 @@
1
- function k(n) {
2
- n && n.querySelectorAll(".cell-focus").forEach((e) => e.classList.remove("cell-focus"));
1
+ function P(r) {
2
+ r && r.querySelectorAll(".cell-focus").forEach((e) => e.classList.remove("cell-focus"));
3
3
  }
4
- const v = 'input,select,textarea,[contenteditable="true"],[contenteditable=""],[tabindex]:not([tabindex="-1"])', I = document.createElement("template");
5
- I.innerHTML = '<div class="cell" role="gridcell" part="cell"></div>';
6
- const T = document.createElement("template");
7
- T.innerHTML = '<div class="data-grid-row" role="row" part="row"></div>';
8
- function R(n, e) {
9
- if (n._virtualization?.enabled) {
10
- const { rowHeight: l, container: o, viewportEl: a } = n._virtualization, c = o, d = a?.clientHeight ?? c?.clientHeight ?? 0;
11
- if (c && d > 0) {
12
- const h = n._focusRow * l;
13
- h < c.scrollTop ? c.scrollTop = h : h + l > c.scrollTop + d && (c.scrollTop = h - d + l);
4
+ const w = 'input,select,textarea,[contenteditable="true"],[contenteditable=""],[tabindex]:not([tabindex="-1"])', M = document.createElement("template");
5
+ M.innerHTML = '<div class="cell" role="gridcell" part="cell"></div>';
6
+ const H = document.createElement("template");
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;
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);
14
14
  }
15
15
  }
16
- const t = n._activeEditRows !== void 0 && n._activeEditRows !== -1;
17
- t || n.refreshVirtualWindow(!1), k(n._bodyEl), Array.from(n._bodyEl.querySelectorAll('[aria-selected="true"]')).forEach((l) => {
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
18
  l.setAttribute("aria-selected", "false");
19
19
  });
20
- const i = n._focusRow, s = n._virtualization.start ?? 0, r = n._virtualization.end ?? n._rows.length;
21
- if (i >= s && i < r) {
22
- const l = n._bodyEl.querySelectorAll(".data-grid-row")[i - s];
23
- let o = l?.children[n._focusCol];
24
- if ((!o || !o.classList?.contains("cell")) && (o = l?.querySelector(`.cell[data-col="${n._focusCol}"]`) ?? l?.querySelector(".cell[data-col]")), o) {
20
+ const i = r._focusRow, n = r._virtualization.start ?? 0, s = r._virtualization.end ?? r._rows.length;
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
25
  o.classList.add("cell-focus"), o.setAttribute("aria-selected", "true");
26
- const a = n.querySelector(".tbw-scroll-area");
27
- if (a && o && (!t || e?.forceHorizontalScroll))
26
+ const c = r.querySelector(".tbw-scroll-area");
27
+ if (c && o && (!t || e?.forceHorizontalScroll))
28
28
  if (e?.forceScrollLeft)
29
- a.scrollLeft = 0;
29
+ c.scrollLeft = 0;
30
30
  else if (e?.forceScrollRight)
31
- a.scrollLeft = a.scrollWidth - a.clientWidth;
31
+ c.scrollLeft = c.scrollWidth - c.clientWidth;
32
32
  else {
33
- const c = n._getHorizontalScrollOffsets?.(l ?? void 0, o) ?? { left: 0, right: 0 };
34
- if (!c.skipScroll) {
35
- const d = o.getBoundingClientRect(), h = a.getBoundingClientRect(), u = d.left - h.left + a.scrollLeft, m = u + d.width, p = a.scrollLeft + c.left, g = a.scrollLeft + a.clientWidth - c.right;
36
- u < p ? a.scrollLeft = u - c.left : m > g && (a.scrollLeft = m - a.clientWidth + c.right);
33
+ const a = r._getHorizontalScrollOffsets?.(l ?? void 0, o) ?? { left: 0, right: 0 };
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;
36
+ f < p ? c.scrollLeft = f - a.left : E > m && (c.scrollLeft = E - c.clientWidth + a.right);
37
37
  }
38
38
  }
39
- if (n._activeEditRows !== void 0 && n._activeEditRows !== -1 && o.classList.contains("editing")) {
40
- const c = o.querySelector(v);
41
- if (c && document.activeElement !== c)
39
+ if (r._activeEditRows !== void 0 && r._activeEditRows !== -1 && o.classList.contains("editing")) {
40
+ const a = o.querySelector(w);
41
+ if (a && document.activeElement !== a)
42
42
  try {
43
- c.focus({ preventScroll: !0 });
43
+ a.focus({ preventScroll: !0 });
44
44
  } catch {
45
45
  }
46
46
  } else if (!o.contains(document.activeElement)) {
@@ -53,7 +53,7 @@ function R(n, e) {
53
53
  }
54
54
  }
55
55
  }
56
- const L = '<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>', q = {
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 = {
57
57
  expand: "▶",
58
58
  collapse: "▼",
59
59
  sortAsc: "▲",
@@ -62,11 +62,11 @@ const L = '<svg viewBox="0 0 16 16" width="12" height="12"><path fill="currentCo
62
62
  submenuArrow: "▶",
63
63
  dragHandle: "⋮⋮",
64
64
  toolPanel: "☰",
65
- filter: L,
66
- filterActive: L,
65
+ filter: I,
66
+ filterActive: I,
67
67
  print: "🖨️"
68
68
  };
69
- class P {
69
+ class O {
70
70
  /**
71
71
  * Plugin dependencies - declare other plugins this one requires.
72
72
  *
@@ -356,7 +356,7 @@ class P {
356
356
  */
357
357
  get gridIcons() {
358
358
  const e = this.grid?.gridConfig?.icons ?? {};
359
- return { ...q, ...e };
359
+ return { ...D, ...e };
360
360
  }
361
361
  // #region Animation Helpers
362
362
  /**
@@ -432,125 +432,125 @@ class P {
432
432
  }
433
433
  // #endregion
434
434
  }
435
- const M = "@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 D(n) {
437
- const e = n.options;
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;
438
438
  return e ? typeof e == "function" ? e() : e : [];
439
439
  }
440
- function H(n) {
440
+ function N(r) {
441
441
  return (e) => {
442
- const t = n.editorParams, i = document.createElement("input");
442
+ const t = r.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
- const s = () => e.commit(i.value === "" ? null : Number(i.value));
445
- return i.addEventListener("blur", s), i.addEventListener("keydown", (r) => {
446
- r.key === "Enter" && s(), r.key === "Escape" && e.cancel();
444
+ const n = () => e.commit(i.value === "" ? null : Number(i.value));
445
+ return i.addEventListener("blur", n), i.addEventListener("keydown", (s) => {
446
+ s.key === "Enter" && n(), s.key === "Escape" && e.cancel();
447
447
  }), i;
448
448
  };
449
449
  }
450
- function O() {
451
- return (n) => {
450
+ function $() {
451
+ return (r) => {
452
452
  const e = document.createElement("input");
453
- return e.type = "checkbox", e.checked = !!n.value, e.addEventListener("change", () => n.commit(e.checked)), e;
453
+ return e.type = "checkbox", e.checked = !!r.value, e.addEventListener("change", () => r.commit(e.checked)), e;
454
454
  };
455
455
  }
456
- function B(n) {
456
+ function z(r) {
457
457
  return (e) => {
458
- const t = n.editorParams, i = document.createElement("input");
458
+ const t = r.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
- const s = () => {
460
+ const n = () => {
461
461
  typeof e.value == "string" ? e.commit(i.value) : e.commit(i.valueAsDate);
462
462
  };
463
- return i.addEventListener("change", s), i.addEventListener("keydown", (r) => {
464
- r.key === "Escape" && e.cancel();
463
+ return i.addEventListener("change", n), i.addEventListener("keydown", (s) => {
464
+ s.key === "Escape" && e.cancel();
465
465
  }), i;
466
466
  };
467
467
  }
468
- function x(n) {
468
+ function G(r) {
469
469
  return (e) => {
470
- const t = n.editorParams, i = document.createElement("select");
471
- if (n.multi && (i.multiple = !0), t?.includeEmpty) {
470
+ const t = r.editorParams, i = document.createElement("select");
471
+ if (r.multi && (i.multiple = !0), t?.includeEmpty) {
472
472
  const l = document.createElement("option");
473
473
  l.value = "", l.textContent = t.emptyLabel ?? "", i.appendChild(l);
474
474
  }
475
- D(n).forEach((l) => {
475
+ B(r).forEach((l) => {
476
476
  const o = document.createElement("option");
477
- o.value = String(l.value), o.textContent = l.label, (n.multi && Array.isArray(e.value) && e.value.includes(l.value) || !n.multi && e.value === l.value) && (o.selected = !0), i.appendChild(o);
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);
478
478
  });
479
- const r = () => {
480
- if (n.multi) {
479
+ const s = () => {
480
+ if (r.multi) {
481
481
  const l = Array.from(i.selectedOptions).map((o) => o.value);
482
482
  e.commit(l);
483
483
  } else
484
484
  e.commit(i.value);
485
485
  };
486
- return i.addEventListener("change", r), i.addEventListener("blur", r), i.addEventListener("keydown", (l) => {
486
+ return i.addEventListener("change", s), i.addEventListener("blur", s), i.addEventListener("keydown", (l) => {
487
487
  l.key === "Escape" && e.cancel();
488
488
  }), i;
489
489
  };
490
490
  }
491
- function N(n) {
491
+ function F(r) {
492
492
  return (e) => {
493
- const t = n.editorParams, i = document.createElement("input");
493
+ const t = r.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
- const s = () => {
496
- const r = i.value;
497
- (e.value === null || e.value === void 0) && r === "" || typeof e.value == "string" && r === e.value.replace(/[\n\r]/g, "") || (typeof e.value == "number" && r !== "" ? e.commit(Number(r)) : e.commit(r));
495
+ const n = () => {
496
+ const s = i.value;
497
+ (e.value === null || e.value === void 0) && s === "" || typeof e.value == "string" && s === e.value.replace(/[\n\r]/g, "") || (typeof e.value == "number" && s !== "" ? e.commit(Number(s)) : e.commit(s));
498
498
  };
499
- return i.addEventListener("blur", s), i.addEventListener("keydown", (r) => {
500
- r.key === "Enter" && s(), r.key === "Escape" && e.cancel();
499
+ return i.addEventListener("blur", n), i.addEventListener("keydown", (s) => {
500
+ s.key === "Enter" && n(), s.key === "Escape" && e.cancel();
501
501
  }), i;
502
502
  };
503
503
  }
504
- function z(n) {
505
- switch (n.type) {
504
+ function j(r) {
505
+ switch (r.type) {
506
506
  case "number":
507
- return H(n);
507
+ return N(r);
508
508
  case "boolean":
509
- return O();
509
+ return $();
510
510
  case "date":
511
- return B(n);
511
+ return z(r);
512
512
  case "select":
513
- return x(n);
513
+ return G(r);
514
514
  default:
515
- return N(n);
515
+ return F(r);
516
516
  }
517
517
  }
518
- function G(n, e) {
518
+ function W(r, 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 = n.effectiveConfig?.typeDefaults;
522
+ const i = r.effectiveConfig?.typeDefaults;
523
523
  if (i?.[e.type]?.editor)
524
524
  return i[e.type].editor;
525
- const s = n.__frameworkAdapter;
526
- if (s?.getTypeDefault) {
527
- const r = s.getTypeDefault(e.type);
528
- if (r?.editor)
529
- return r.editor;
525
+ const n = r.__frameworkAdapter;
526
+ if (n?.getTypeDefault) {
527
+ const s = n.getTypeDefault(e.type);
528
+ if (s?.editor)
529
+ return s.editor;
530
530
  }
531
531
  }
532
- function C(n) {
533
- return !(typeof n != "string" || n === "__proto__" || n === "constructor" || n === "prototype");
532
+ function S(r) {
533
+ return !(typeof r != "string" || r === "__proto__" || r === "constructor" || r === "prototype");
534
534
  }
535
- function $(n) {
536
- const e = (n.__editingCellCount ?? 0) + 1;
537
- n.__editingCellCount = e, n.setAttribute("data-has-editing", "");
535
+ function K(r) {
536
+ const e = (r.__editingCellCount ?? 0) + 1;
537
+ r.__editingCellCount = e, r.setAttribute("data-has-editing", "");
538
538
  }
539
- function F(n) {
540
- n.__editingCellCount = 0, n.removeAttribute("data-has-editing");
539
+ function U(r) {
540
+ r.__editingCellCount = 0, r.removeAttribute("data-has-editing");
541
541
  }
542
- function y(n, e, t) {
543
- return n instanceof HTMLInputElement ? n.type === "checkbox" ? n.checked : n.type === "number" ? n.value === "" ? null : Number(n.value) : n.type === "date" ? typeof t == "string" ? n.value : n.valueAsDate : typeof t == "number" ? n.value === "" ? null : Number(n.value) : t == null && n.value === "" || typeof t == "string" && n.value === t.replace(/[\n\r]/g, "") ? t : n.value : e?.type === "number" && n.value !== "" || typeof t == "number" && n.value !== "" ? Number(n.value) : t == null && n.value === "" ? t : n.value;
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;
544
544
  }
545
- function A(n) {
545
+ function T(r) {
546
546
  }
547
- function j(n, e, t, i) {
548
- const s = n.querySelector("input,textarea,select");
549
- s && (s.addEventListener("blur", () => {
550
- t(y(s, e, i));
551
- }), s instanceof HTMLInputElement && s.type === "checkbox" ? s.addEventListener("change", () => t(s.checked)) : s instanceof HTMLSelectElement && s.addEventListener("change", () => t(y(s, e, i))));
547
+ function Q(r, e, t, i) {
548
+ const n = r.querySelector("input,textarea,select");
549
+ n && (n.addEventListener("blur", () => {
550
+ t(_(n, e, i));
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 W extends P {
553
+ class X extends O {
554
554
  /**
555
555
  * Plugin manifest - declares owned properties for configuration validation.
556
556
  * @internal
@@ -590,7 +590,7 @@ class W extends P {
590
590
  /** @internal */
591
591
  name = "editing";
592
592
  /** @internal */
593
- styles = M;
593
+ styles = x;
594
594
  /** @internal */
595
595
  get defaultConfig() {
596
596
  return {
@@ -608,17 +608,23 @@ class W extends P {
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
- #c = -1;
611
+ #d = -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
- #r = /* @__PURE__ */ new Set();
615
+ #s = /* @__PURE__ */ new Set();
616
616
  /** Set of cells currently in edit mode: "rowIndex:colIndex" */
617
617
  #o = /* @__PURE__ */ new Set();
618
+ /**
619
+ * Value-change callbacks for active editors.
620
+ * Keyed by "rowIndex:field" → callback that pushes updated values to the editor.
621
+ * Populated during #injectEditor, cleaned up when editors are removed.
622
+ */
623
+ #c = /* @__PURE__ */ new Map();
618
624
  /** Flag to restore focus after next render (used when exiting edit mode) */
619
- #d = !1;
625
+ #u = !1;
620
626
  /** Row index pending animation after render, or -1 if none */
621
- #u = -1;
627
+ #f = -1;
622
628
  /**
623
629
  * Invalid cell tracking: Map<rowId, Map<field, message>>
624
630
  * Used for validation feedback without canceling edits.
@@ -630,7 +636,7 @@ class W extends P {
630
636
  * When false: arrow keys navigate between cells (navigation mode).
631
637
  * Escape switches to navigation mode, Enter switches to edit mode.
632
638
  */
633
- #n = !1;
639
+ #r = !1;
634
640
  /**
635
641
  * In grid mode, when true, prevents inputs from auto-focusing.
636
642
  * This is set when Escape is pressed (navigation mode) and cleared
@@ -649,68 +655,77 @@ class W extends P {
649
655
  }), Object.defineProperty(e, "changedRowIds", {
650
656
  get: () => this.changedRowIds,
651
657
  configurable: !0
652
- }), e.resetChangedRows = (s) => this.resetChangedRows(s), e.beginBulkEdit = (s, r) => {
653
- r && this.beginCellEdit(s, r);
658
+ }), e.resetChangedRows = (n) => this.resetChangedRows(n), e.beginBulkEdit = (n, s) => {
659
+ s && this.beginCellEdit(n, s);
654
660
  }, document.addEventListener(
655
661
  "keydown",
656
- (s) => {
657
- if (!this.#t && s.key === "Escape" && this.#e !== -1) {
658
- if (this.config.onBeforeEditClose && this.config.onBeforeEditClose(s) === !1)
662
+ (n) => {
663
+ if (!this.#t && n.key === "Escape" && this.#e !== -1) {
664
+ if (this.config.onBeforeEditClose && this.config.onBeforeEditClose(n) === !1)
659
665
  return;
660
- this.#s(this.#e, !0);
666
+ this.#n(this.#e, !0);
661
667
  }
662
668
  },
663
669
  { capture: !0, signal: t }
664
670
  ), document.addEventListener(
665
671
  "mousedown",
666
- (s) => {
672
+ (n) => {
667
673
  if (this.#t || this.#e === -1) return;
668
- const r = i.findRenderedRowElement?.(this.#e);
669
- !r || (s.composedPath && s.composedPath() || []).includes(r) || this.config.onBeforeEditClose && this.config.onBeforeEditClose(s) === !1 || queueMicrotask(() => {
670
- this.#e !== -1 && this.#s(this.#e, !1);
674
+ const s = i.findRenderedRowElement?.(this.#e);
675
+ !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);
671
677
  });
672
678
  },
673
679
  { signal: t }
680
+ ), this.gridElement.addEventListener(
681
+ "cell-change",
682
+ (n) => {
683
+ const s = n.detail;
684
+ if (s.source === "user") return;
685
+ const l = `${s.rowIndex}:${s.field}`, o = this.#c.get(l);
686
+ o && o(s.newValue);
687
+ },
688
+ { signal: t }
674
689
  ), this.#t && (this.gridElement.classList.add("tbw-grid-mode"), this.requestRender(), this.gridElement.addEventListener(
675
690
  "focusin",
676
- (s) => {
677
- const r = s.target;
678
- if (r.matches(v)) {
691
+ (n) => {
692
+ const s = n.target;
693
+ if (s.matches(w)) {
679
694
  if (this.#a) {
680
- r.blur(), this.gridElement.focus();
695
+ s.blur(), this.gridElement.focus();
681
696
  return;
682
697
  }
683
- this.#n = !0;
698
+ this.#r = !0;
684
699
  }
685
700
  },
686
701
  { signal: t }
687
702
  ), this.gridElement.addEventListener(
688
703
  "focusout",
689
- (s) => {
690
- const r = s.relatedTarget;
691
- (!r || !this.gridElement.contains(r) || !r.matches(v)) && (this.#n = !1);
704
+ (n) => {
705
+ const s = n.relatedTarget;
706
+ (!s || !this.gridElement.contains(s) || !s.matches(w)) && (this.#r = !1);
692
707
  },
693
708
  { signal: t }
694
709
  ), this.gridElement.addEventListener(
695
710
  "keydown",
696
- (s) => {
697
- if (s.key === "Escape" && this.#n) {
698
- const r = document.activeElement;
699
- r && this.gridElement.contains(r) && (r.blur(), this.gridElement.focus()), this.#n = !1, this.#a = !0, s.preventDefault(), s.stopPropagation();
711
+ (n) => {
712
+ if (n.key === "Escape" && this.#r) {
713
+ const s = document.activeElement;
714
+ s && this.gridElement.contains(s) && (s.blur(), this.gridElement.focus()), this.#r = !1, this.#a = !0, n.preventDefault(), n.stopPropagation();
700
715
  }
701
716
  },
702
717
  { capture: !0, signal: t }
703
718
  ), this.gridElement.addEventListener(
704
719
  "mousedown",
705
- (s) => {
706
- s.target.matches(v) && (this.#a = !1);
720
+ (n) => {
721
+ n.target.matches(w) && (this.#a = !1);
707
722
  },
708
723
  { signal: t }
709
724
  ));
710
725
  }
711
726
  /** @internal */
712
727
  detach() {
713
- this.gridElement.classList.remove("tbw-grid-mode"), this.#e = -1, this.#c = -1, this.#l.clear(), this.#r.clear(), this.#o.clear(), this.#n = !1, this.#a = !1, super.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();
714
729
  }
715
730
  /**
716
731
  * Handle plugin queries.
@@ -732,10 +747,10 @@ class W extends P {
732
747
  if (this.#t) return !1;
733
748
  const t = this.grid, i = this.config.editOn ?? t.effectiveConfig?.editOn;
734
749
  if (i === !1 || i === "manual" || i !== "click" && i !== "dblclick") return !1;
735
- const s = e.originalEvent.type === "dblclick";
736
- if (i === "click" && s || i === "dblclick" && !s) return !1;
737
- const { rowIndex: r } = e;
738
- return t._columns?.some((o) => o.editable) ? (e.originalEvent.stopPropagation(), this.beginBulkEdit(r), !0) : !1;
750
+ const n = e.originalEvent.type === "dblclick";
751
+ if (i === "click" && n || i === "dblclick" && !n) return !1;
752
+ const { rowIndex: s } = e;
753
+ return t._columns?.some((o) => o.editable) ? (e.originalEvent.stopPropagation(), this.beginBulkEdit(s), !0) : !1;
739
754
  }
740
755
  /**
741
756
  * Handle keyboard events for edit lifecycle.
@@ -744,72 +759,72 @@ class W extends P {
744
759
  onKeyDown(e) {
745
760
  const t = this.grid;
746
761
  if (e.key === "Escape") {
747
- if (this.#t && this.#n) {
762
+ if (this.#t && this.#r) {
748
763
  const i = document.activeElement;
749
- return i && this.gridElement.contains(i) && i.blur(), this.#n = !1, this.requestAfterRender(), !0;
764
+ return i && this.gridElement.contains(i) && i.blur(), this.#r = !1, this.requestAfterRender(), !0;
750
765
  }
751
766
  if (this.#e !== -1 && !this.#t)
752
- return this.config.onBeforeEditClose && this.config.onBeforeEditClose(e) === !1 || this.#s(this.#e, !0), !0;
767
+ return this.config.onBeforeEditClose && this.config.onBeforeEditClose(e) === !1 || this.#n(this.#e, !0), !0;
753
768
  }
754
- if (this.#t && !this.#n && (e.key === "ArrowUp" || e.key === "ArrowDown" || e.key === "ArrowLeft" || e.key === "ArrowRight"))
769
+ if (this.#t && !this.#r && (e.key === "ArrowUp" || e.key === "ArrowDown" || e.key === "ArrowLeft" || e.key === "ArrowRight"))
755
770
  return !1;
756
771
  if ((e.key === "ArrowUp" || e.key === "ArrowDown") && this.#e !== -1 && !this.#t) {
757
772
  if (this.config.onBeforeEditClose && this.config.onBeforeEditClose(e) === !1)
758
773
  return !0;
759
- const i = t._rows.length - 1, s = this.#e;
760
- return this.#s(s, !1), e.key === "ArrowDown" ? t._focusRow = Math.min(i, t._focusRow + 1) : t._focusRow = Math.max(0, t._focusRow - 1), e.preventDefault(), R(t), this.requestAfterRender(), !0;
774
+ 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;
761
776
  }
762
777
  if (e.key === "Tab" && (this.#e !== -1 || this.#t)) {
763
778
  e.preventDefault();
764
779
  const i = !e.shiftKey;
765
- return this.#b(i), !0;
780
+ return this.#y(i), !0;
766
781
  }
767
782
  if (e.key === " " || e.key === "Spacebar") {
768
783
  if (this.#e !== -1)
769
784
  return !1;
770
- const i = t._focusRow, s = t._focusCol;
771
- if (i >= 0 && s >= 0) {
772
- const r = t._visibleColumns[s], l = t._rows[i];
773
- if (r?.editable && r.type === "boolean" && l) {
774
- const o = r.field;
775
- if (C(o)) {
776
- const c = !l[o];
777
- return this.#p(i, r, c, l), e.preventDefault(), this.requestRender(), !0;
785
+ const i = t._focusRow, n = t._focusCol;
786
+ 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;
778
793
  }
779
794
  }
780
795
  }
781
796
  return !1;
782
797
  }
783
798
  if (e.key === "Enter" && !e.shiftKey) {
784
- if (this.#t && !this.#n)
785
- return this.#v(), !0;
799
+ if (this.#t && !this.#r)
800
+ return this.#b(), !0;
786
801
  if (this.#e !== -1)
787
802
  return !!(this.config.onBeforeEditClose && this.config.onBeforeEditClose(e) === !1);
788
803
  const i = this.config.editOn ?? t.effectiveConfig?.editOn;
789
804
  if (i === !1 || i === "manual") return !1;
790
- const s = t._focusRow, r = t._focusCol;
791
- if (s >= 0 && t._columns?.some((o) => o.editable)) {
792
- const o = t._visibleColumns[r], a = t._rows[s], c = o?.field ?? "", d = c && a ? a[c] : void 0, h = this.gridElement.querySelector(`[data-row="${s}"][data-col="${r}"]`), u = new CustomEvent("cell-activate", {
805
+ 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", {
793
808
  cancelable: !0,
794
809
  bubbles: !0,
795
810
  detail: {
796
- rowIndex: s,
797
- colIndex: r,
798
- field: c,
811
+ rowIndex: n,
812
+ colIndex: s,
813
+ field: a,
799
814
  value: d,
800
- row: a,
801
- cellEl: h,
815
+ row: c,
816
+ cellEl: g,
802
817
  trigger: "keyboard",
803
818
  originalEvent: e
804
819
  }
805
820
  });
806
- this.gridElement.dispatchEvent(u);
807
- const m = new CustomEvent("activate-cell", {
821
+ this.gridElement.dispatchEvent(f);
822
+ const E = new CustomEvent("activate-cell", {
808
823
  cancelable: !0,
809
824
  bubbles: !0,
810
- detail: { row: s, col: r }
825
+ detail: { row: n, col: s }
811
826
  });
812
- return this.gridElement.dispatchEvent(m), u.defaultPrevented || m.defaultPrevented ? (e.preventDefault(), !0) : (this.beginBulkEdit(s), !0);
827
+ return this.gridElement.dispatchEvent(E), f.defaultPrevented || E.defaultPrevented ? (e.preventDefault(), !0) : (this.beginBulkEdit(n), !0);
813
828
  }
814
829
  return !1;
815
830
  }
@@ -823,18 +838,18 @@ class W extends P {
823
838
  * @internal
824
839
  */
825
840
  processColumns(e) {
826
- const t = this.grid, i = t.effectiveConfig?.typeDefaults, s = t.__frameworkAdapter;
827
- return !i && !s?.getTypeDefault ? e : e.map((r) => {
828
- if (!r.type) return r;
841
+ const t = this.grid, i = t.effectiveConfig?.typeDefaults, n = t.__frameworkAdapter;
842
+ return !i && !n?.getTypeDefault ? e : e.map((s) => {
843
+ if (!s.type) return s;
829
844
  let l;
830
- if (i?.[r.type]?.editorParams && (l = i[r.type].editorParams), !l && s?.getTypeDefault) {
831
- const o = s.getTypeDefault(r.type);
845
+ if (i?.[s.type]?.editorParams && (l = i[s.type].editorParams), !l && n?.getTypeDefault) {
846
+ const o = n.getTypeDefault(s.type);
832
847
  o?.editorParams && (l = o.editorParams);
833
848
  }
834
849
  return l ? {
835
- ...r,
836
- editorParams: { ...l, ...r.editorParams }
837
- } : r;
850
+ ...s,
851
+ editorParams: { ...l, ...s.editorParams }
852
+ } : s;
838
853
  });
839
854
  }
840
855
  /**
@@ -845,18 +860,18 @@ class W extends P {
845
860
  */
846
861
  afterRender() {
847
862
  const e = this.grid;
848
- if (this.#d && (this.#d = !1, this.#E(e)), this.#u !== -1) {
849
- const t = this.#u;
850
- this.#u = -1, e.animateRow?.(t, "change");
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");
851
866
  }
852
867
  if (!this.#t && this.#o.size !== 0)
853
868
  for (const t of this.#o) {
854
- const [i, s] = t.split(":"), r = parseInt(i, 10), l = parseInt(s, 10), o = e.findRenderedRowElement?.(r);
869
+ const [i, n] = t.split(":"), s = parseInt(i, 10), l = parseInt(n, 10), o = e.findRenderedRowElement?.(s);
855
870
  if (!o) continue;
856
- const a = o.querySelector(`.cell[data-col="${l}"]`);
857
- if (!a || a.classList.contains("editing")) continue;
858
- const c = e._rows[r], d = e._visibleColumns[l];
859
- c && d && this.#g(c, r, d, l, a, !0);
871
+ const c = o.querySelector(`.cell[data-col="${l}"]`);
872
+ 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);
860
875
  }
861
876
  }
862
877
  /**
@@ -866,8 +881,8 @@ class W extends P {
866
881
  */
867
882
  afterCellRender(e) {
868
883
  if (!this.#t) return;
869
- const { row: t, rowIndex: i, column: s, colIndex: r, cellElement: l } = e;
870
- s.editable && (l.classList.contains("editing") || this.#g(t, i, s, r, l, !0));
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));
871
886
  }
872
887
  /**
873
888
  * On scroll render, reapply editors to recycled cells.
@@ -884,7 +899,7 @@ class W extends P {
884
899
  */
885
900
  get changedRows() {
886
901
  const e = [];
887
- for (const t of this.#r) {
902
+ for (const t of this.#s) {
888
903
  const i = this.grid.getRow(t);
889
904
  i && e.push(i);
890
905
  }
@@ -894,7 +909,7 @@ class W extends P {
894
909
  * Get IDs of all modified rows.
895
910
  */
896
911
  get changedRowIds() {
897
- return Array.from(this.#r);
912
+ return Array.from(this.#s);
898
913
  }
899
914
  /**
900
915
  * Get the currently active edit row index, or -1 if not editing.
@@ -906,7 +921,7 @@ class W extends P {
906
921
  * Get the currently active edit column index, or -1 if not editing.
907
922
  */
908
923
  get activeEditCol() {
909
- return this.#c;
924
+ return this.#d;
910
925
  }
911
926
  /**
912
927
  * Check if a specific row is currently being edited.
@@ -928,8 +943,8 @@ class W extends P {
928
943
  const t = this.grid, i = t._rows[e];
929
944
  if (!i) return !1;
930
945
  try {
931
- const s = t.getRowId?.(i);
932
- return s ? this.#r.has(s) : !1;
946
+ const n = t.getRowId?.(i);
947
+ return n ? this.#s.has(n) : !1;
933
948
  } catch {
934
949
  return !1;
935
950
  }
@@ -939,7 +954,7 @@ class W extends P {
939
954
  * @param rowId - Row ID to check
940
955
  */
941
956
  isRowChangedById(e) {
942
- return this.#r.has(e);
957
+ return this.#s.has(e);
943
958
  }
944
959
  // #region Cell Validation
945
960
  /**
@@ -964,8 +979,8 @@ class W extends P {
964
979
  * ```
965
980
  */
966
981
  setInvalid(e, t, i = "") {
967
- let s = this.#i.get(e);
968
- s || (s = /* @__PURE__ */ new Map(), this.#i.set(e, s)), s.set(t, i), this.#f(e, t, !0);
982
+ 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);
969
984
  }
970
985
  /**
971
986
  * Clear the invalid state for a specific cell.
@@ -975,7 +990,7 @@ class W extends P {
975
990
  */
976
991
  clearInvalid(e, t) {
977
992
  const i = this.#i.get(e);
978
- i && (i.delete(t), i.size === 0 && this.#i.delete(e)), this.#f(e, t, !1);
993
+ i && (i.delete(t), i.size === 0 && this.#i.delete(e)), this.#h(e, t, !1);
979
994
  }
980
995
  /**
981
996
  * Clear all invalid cells for a specific row.
@@ -986,7 +1001,7 @@ class W extends P {
986
1001
  const t = this.#i.get(e);
987
1002
  if (t) {
988
1003
  const i = Array.from(t.keys());
989
- this.#i.delete(e), i.forEach((s) => this.#f(e, s, !1));
1004
+ this.#i.delete(e), i.forEach((n) => this.#h(e, n, !1));
990
1005
  }
991
1006
  }
992
1007
  /**
@@ -995,7 +1010,7 @@ class W extends P {
995
1010
  clearAllInvalid() {
996
1011
  const e = Array.from(this.#i.entries());
997
1012
  this.#i.clear(), e.forEach(([t, i]) => {
998
- i.forEach((s, r) => this.#f(t, r, !1));
1013
+ i.forEach((n, s) => this.#h(t, s, !1));
999
1014
  });
1000
1015
  }
1001
1016
  /**
@@ -1040,25 +1055,25 @@ class W extends P {
1040
1055
  /**
1041
1056
  * Sync the data-invalid attribute on a cell element.
1042
1057
  */
1043
- #f(e, t, i) {
1044
- const s = this.grid, r = s._visibleColumns?.findIndex((d) => d.field === t);
1045
- if (r === -1 || r === void 0) return;
1046
- const o = s._rows?.findIndex((d) => {
1058
+ #h(e, t, i) {
1059
+ const n = this.grid, s = n._visibleColumns?.findIndex((d) => d.field === t);
1060
+ if (s === -1 || s === void 0) return;
1061
+ const o = n._rows?.findIndex((d) => {
1047
1062
  try {
1048
- return s.getRowId?.(d) === e;
1063
+ return n.getRowId?.(d) === e;
1049
1064
  } catch {
1050
1065
  return !1;
1051
1066
  }
1052
1067
  });
1053
1068
  if (o === -1 || o === void 0) return;
1054
- const c = s.findRenderedRowElement?.(o)?.querySelector(`.cell[data-col="${r}"]`);
1055
- if (c)
1069
+ const a = n.findRenderedRowElement?.(o)?.querySelector(`.cell[data-col="${s}"]`);
1070
+ if (a)
1056
1071
  if (i) {
1057
- c.setAttribute("data-invalid", "true");
1072
+ a.setAttribute("data-invalid", "true");
1058
1073
  const d = this.#i.get(e)?.get(t);
1059
- d && c.setAttribute("title", d);
1074
+ d && a.setAttribute("title", d);
1060
1075
  } else
1061
- c.removeAttribute("data-invalid"), c.removeAttribute("title");
1076
+ a.removeAttribute("data-invalid"), a.removeAttribute("title");
1062
1077
  }
1063
1078
  // #endregion
1064
1079
  /**
@@ -1068,7 +1083,7 @@ class W extends P {
1068
1083
  */
1069
1084
  resetChangedRows(e) {
1070
1085
  const t = this.changedRows, i = this.changedRowIds;
1071
- this.#r.clear(), this.#h(), e || this.emit("changed-rows-reset", { rows: t, ids: i }), this.grid._rowPool?.forEach((r) => r.classList.remove("changed"));
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"));
1072
1087
  }
1073
1088
  /**
1074
1089
  * Programmatically begin editing a cell.
@@ -1077,10 +1092,10 @@ class W extends P {
1077
1092
  * @fires cell-commit - Emitted when the cell value is committed (on blur or Enter)
1078
1093
  */
1079
1094
  beginCellEdit(e, t) {
1080
- const i = this.grid, s = i._visibleColumns.findIndex((a) => a.field === t);
1081
- if (s === -1 || !i._visibleColumns[s]?.editable) return;
1082
- const o = i.findRenderedRowElement?.(e)?.querySelector(`.cell[data-col="${s}"]`);
1083
- o && this.#w(e, s, o);
1095
+ const i = this.grid, n = i._visibleColumns.findIndex((c) => c.field === t);
1096
+ 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);
1084
1099
  }
1085
1100
  /**
1086
1101
  * Programmatically begin editing all editable cells in a row.
@@ -1091,21 +1106,21 @@ class W extends P {
1091
1106
  beginBulkEdit(e) {
1092
1107
  const t = this.grid;
1093
1108
  if ((this.config.editOn ?? t.effectiveConfig?.editOn) === !1 || !t._columns?.some((o) => o.editable)) return;
1094
- const r = t.findRenderedRowElement?.(e);
1095
- if (!r) return;
1109
+ const s = t.findRenderedRowElement?.(e);
1110
+ if (!s) return;
1096
1111
  const l = t._rows[e];
1097
- this.#m(e, l), Array.from(r.children).forEach((o, a) => {
1098
- const c = t._visibleColumns[a];
1099
- if (c?.editable) {
1112
+ this.#E(e, l), Array.from(s.children).forEach((o, c) => {
1113
+ const a = t._visibleColumns[c];
1114
+ if (a?.editable) {
1100
1115
  const d = o;
1101
- d.classList.contains("editing") || this.#g(l, e, c, a, d, !0);
1116
+ d.classList.contains("editing") || this.#p(l, e, a, c, d, !0);
1102
1117
  }
1103
1118
  }), setTimeout(() => {
1104
- let o = r.querySelector(`.cell[data-col="${t._focusCol}"]`);
1105
- if (o?.classList.contains("editing") || (o = r.querySelector(".cell.editing")), o?.classList.contains("editing")) {
1106
- const a = o.querySelector(v);
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);
1107
1122
  try {
1108
- a?.focus({ preventScroll: !0 });
1123
+ c?.focus({ preventScroll: !0 });
1109
1124
  } catch {
1110
1125
  }
1111
1126
  }
@@ -1116,13 +1131,13 @@ class W extends P {
1116
1131
  * @fires row-commit - Emitted after the row edit is committed
1117
1132
  */
1118
1133
  commitActiveRowEdit() {
1119
- this.#e !== -1 && this.#s(this.#e, !1);
1134
+ this.#e !== -1 && this.#n(this.#e, !1);
1120
1135
  }
1121
1136
  /**
1122
1137
  * Cancel the currently active row edit.
1123
1138
  */
1124
1139
  cancelActiveRowEdit() {
1125
- this.#e !== -1 && this.#s(this.#e, !0);
1140
+ this.#e !== -1 && this.#n(this.#e, !0);
1126
1141
  }
1127
1142
  // #endregion
1128
1143
  // #region Internal Methods
@@ -1130,20 +1145,20 @@ class W extends P {
1130
1145
  * Begin editing a single cell.
1131
1146
  */
1132
1147
  #w(e, t, i) {
1133
- const s = this.grid, r = s._rows[e], l = s._visibleColumns[t];
1134
- !r || !l?.editable || i.classList.contains("editing") || (this.#e !== e && this.#m(e, r), this.#c = t, this.#g(r, e, l, t, i, !1));
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));
1135
1150
  }
1136
1151
  /**
1137
1152
  * Focus the editor input in the currently focused cell (grid mode only).
1138
1153
  * Used when pressing Enter to enter edit mode from navigation mode.
1139
1154
  */
1140
- #v() {
1155
+ #b() {
1141
1156
  const e = this.grid, t = e._focusRow, i = e._focusCol;
1142
1157
  if (t < 0 || i < 0) return;
1143
- const r = e.findRenderedRowElement?.(t)?.querySelector(`.cell[data-col="${i}"]`);
1144
- if (r?.classList.contains("editing")) {
1145
- const l = r.querySelector(v);
1146
- l && (this.#a = !1, l.focus(), this.#n = !0, l instanceof HTMLInputElement && (l.type === "text" || l.type === "number") && l.select());
1158
+ const s = e.findRenderedRowElement?.(t)?.querySelector(`.cell[data-col="${i}"]`);
1159
+ 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());
1147
1162
  }
1148
1163
  }
1149
1164
  /**
@@ -1151,43 +1166,43 @@ class W extends P {
1151
1166
  * Moves to next/previous editable cell, staying in edit mode.
1152
1167
  * Wraps to next/previous row when reaching row boundaries.
1153
1168
  */
1154
- #b(e) {
1155
- const t = this.grid, i = t._rows, s = this.#t ? t._focusRow : this.#e, r = t._visibleColumns.map((c, d) => c.editable ? d : -1).filter((c) => c >= 0);
1156
- if (r.length === 0) return;
1157
- const o = r.indexOf(t._focusCol) + (e ? 1 : -1);
1158
- if (o >= 0 && o < r.length) {
1159
- t._focusCol = r[o];
1160
- const d = t.findRenderedRowElement?.(s)?.querySelector(`.cell[data-col="${r[o]}"]`);
1161
- d?.classList.contains("editing") && d.querySelector(v)?.focus({ preventScroll: !0 }), R(t, { forceHorizontalScroll: !0 });
1169
+ #y(e) {
1170
+ 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
+ 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]}"]`);
1176
+ d?.classList.contains("editing") && d.querySelector(w)?.focus({ preventScroll: !0 }), L(t, { forceHorizontalScroll: !0 });
1162
1177
  return;
1163
1178
  }
1164
- const a = s + (e ? 1 : -1);
1165
- a >= 0 && a < i.length && (this.#t ? (t._focusRow = a, t._focusCol = e ? r[0] : r[r.length - 1], R(t, { forceHorizontalScroll: !0 }), this.requestAfterRender(), setTimeout(() => {
1166
- const d = t.findRenderedRowElement?.(a)?.querySelector(`.cell[data-col="${t._focusCol}"]`);
1167
- d?.classList.contains("editing") && d.querySelector(v)?.focus({ preventScroll: !0 });
1168
- }, 0)) : (this.#s(s, !1), t._focusRow = a, t._focusCol = e ? r[0] : r[r.length - 1], this.beginBulkEdit(a), R(t, { forceHorizontalScroll: !0 })));
1179
+ const c = n + (e ? 1 : -1);
1180
+ 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
+ const d = t.findRenderedRowElement?.(c)?.querySelector(`.cell[data-col="${t._focusCol}"]`);
1182
+ 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 })));
1169
1184
  }
1170
1185
  /**
1171
1186
  * Sync the internal grid state with the plugin's editing state.
1172
1187
  */
1173
- #h() {
1188
+ #g() {
1174
1189
  const e = this.grid;
1175
1190
  e._activeEditRows = this.#e, e._rowEditSnapshots = this.#l;
1176
1191
  }
1177
1192
  /**
1178
1193
  * Snapshot original row data and mark as editing.
1179
1194
  */
1180
- #m(e, t) {
1181
- if (this.#e !== e && (this.#l.set(e, { ...t }), this.#e = e, this.#h(), !this.#t)) {
1195
+ #E(e, t) {
1196
+ if (this.#e !== e && (this.#l.set(e, { ...t }), this.#e = e, this.#g(), !this.#t)) {
1182
1197
  const i = this.grid;
1183
- let s = "";
1198
+ let n = "";
1184
1199
  try {
1185
- s = i.getRowId?.(t) ?? "";
1200
+ n = i.getRowId?.(t) ?? "";
1186
1201
  } catch {
1187
1202
  }
1188
1203
  this.emit("edit-open", {
1189
1204
  rowIndex: e,
1190
- rowId: s,
1205
+ rowId: n,
1191
1206
  row: t
1192
1207
  });
1193
1208
  }
@@ -1195,54 +1210,56 @@ class W extends P {
1195
1210
  /**
1196
1211
  * Exit editing for a row.
1197
1212
  */
1198
- #s(e, t) {
1213
+ #n(e, t) {
1199
1214
  if (this.#e !== e) return;
1200
- const i = this.grid, s = this.#l.get(e), r = i._rows[e], l = i.findRenderedRowElement?.(e);
1215
+ const i = this.grid, n = this.#l.get(e), s = i._rows[e], l = i.findRenderedRowElement?.(e);
1201
1216
  let o;
1202
- if (r)
1217
+ if (s)
1203
1218
  try {
1204
- o = i.getRowId?.(r);
1219
+ o = i.getRowId?.(s);
1205
1220
  } catch {
1206
1221
  }
1207
- if (!t && l && r && l.querySelectorAll(".cell.editing").forEach((c) => {
1208
- const d = Number(c.getAttribute("data-col"));
1222
+ if (!t && l && s && l.querySelectorAll(".cell.editing").forEach((a) => {
1223
+ const d = Number(a.getAttribute("data-col"));
1209
1224
  if (isNaN(d)) return;
1210
- const h = i._visibleColumns[d];
1211
- if (!h || c.hasAttribute("data-editor-managed"))
1225
+ const g = i._visibleColumns[d];
1226
+ if (!g || a.hasAttribute("data-editor-managed"))
1212
1227
  return;
1213
- const u = c.querySelector("input,textarea,select");
1214
- if (u) {
1215
- const m = h.field, p = r[m], g = y(u, h, p);
1216
- p !== g && this.#p(e, h, g, r);
1228
+ const f = a.querySelector("input,textarea,select");
1229
+ if (f) {
1230
+ const E = g.field, p = s[E], m = _(f, g, p);
1231
+ p !== m && this.#m(e, g, m, s);
1217
1232
  }
1218
- }), t && s && r)
1219
- Object.keys(s).forEach((a) => {
1220
- r[a] = s[a];
1221
- }), o && (this.#r.delete(o), this.clearRowInvalid(o));
1222
- else if (!t && r) {
1223
- const a = this.#C(s, r), c = o ? this.#r.has(o) : a, d = this.emitCancelable("row-commit", {
1233
+ }), t && n && s)
1234
+ Object.keys(n).forEach((c) => {
1235
+ s[c] = n[c];
1236
+ }), o && (this.#s.delete(o), this.clearRowInvalid(o));
1237
+ else if (!t && s) {
1238
+ const c = this.#R(n, s), a = o ? this.#s.has(o) : c, d = this.emitCancelable("row-commit", {
1224
1239
  rowIndex: e,
1225
1240
  rowId: o ?? "",
1226
- row: r,
1227
- oldValue: s,
1228
- newValue: r,
1229
- changed: c,
1241
+ row: s,
1242
+ oldValue: n,
1243
+ newValue: s,
1244
+ changed: a,
1230
1245
  changedRows: this.changedRows,
1231
1246
  changedRowIds: this.changedRowIds
1232
1247
  });
1233
- d && s ? (Object.keys(s).forEach((h) => {
1234
- r[h] = s[h];
1235
- }), o && (this.#r.delete(o), this.clearRowInvalid(o))) : !d && a && this.isAnimationEnabled && (this.#u = e);
1248
+ d && n ? (Object.keys(n).forEach((g) => {
1249
+ s[g] = n[g];
1250
+ }), o && (this.#s.delete(o), this.clearRowInvalid(o))) : !d && c && this.isAnimationEnabled && (this.#f = e);
1236
1251
  }
1237
- this.#l.delete(e), this.#e = -1, this.#c = -1, this.#h();
1238
- for (const a of this.#o)
1239
- a.startsWith(`${e}:`) && this.#o.delete(a);
1240
- l && (l.querySelectorAll(".cell.editing").forEach((a) => {
1241
- a.classList.remove("editing"), F(a.parentElement);
1242
- }), this.requestRender()), this.#d = !0, l || (this.#E(i), this.#d = !1), !this.#t && r && this.emit("edit-close", {
1252
+ this.#l.delete(e), this.#e = -1, this.#d = -1, this.#g();
1253
+ for (const c of this.#o)
1254
+ c.startsWith(`${e}:`) && this.#o.delete(c);
1255
+ for (const c of this.#c.keys())
1256
+ c.startsWith(`${e}:`) && this.#c.delete(c);
1257
+ l && (l.querySelectorAll(".cell.editing").forEach((c) => {
1258
+ 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", {
1243
1260
  rowIndex: e,
1244
1261
  rowId: o ?? "",
1245
- row: r,
1262
+ row: s,
1246
1263
  reverted: t
1247
1264
  });
1248
1265
  }
@@ -1250,39 +1267,39 @@ class W extends P {
1250
1267
  * Commit a single cell value change.
1251
1268
  * Uses ID-based change tracking for stability when rows are reordered.
1252
1269
  */
1253
- #p(e, t, i, s) {
1254
- const r = t.field;
1255
- if (!C(r)) return;
1256
- const l = s[r];
1270
+ #m(e, t, i, n) {
1271
+ const s = t.field;
1272
+ if (!S(s)) return;
1273
+ const l = n[s];
1257
1274
  if (l === i) return;
1258
1275
  const o = this.grid;
1259
- let a;
1276
+ let c;
1260
1277
  try {
1261
- a = this.grid.getRowId(s);
1278
+ c = this.grid.getRowId(n);
1262
1279
  } catch {
1263
1280
  }
1264
- const c = a ? !this.#r.has(a) : !0, d = a ? (g) => this.grid.updateRow(a, g, "cascade") : A;
1265
- let h = !1;
1266
- const u = a ? (g) => {
1267
- h = !0, this.setInvalid(a, r, g ?? "");
1281
+ const a = c ? !this.#s.has(c) : !0, d = c ? (m) => this.grid.updateRow(c, m, "cascade") : T;
1282
+ let g = !1;
1283
+ const f = c ? (m) => {
1284
+ g = !0, this.setInvalid(c, s, m ?? "");
1268
1285
  } : () => {
1269
1286
  };
1270
1287
  if (this.emitCancelable("cell-commit", {
1271
- row: s,
1272
- rowId: a ?? "",
1273
- field: r,
1288
+ row: n,
1289
+ rowId: c ?? "",
1290
+ field: s,
1274
1291
  oldValue: l,
1275
1292
  value: i,
1276
1293
  rowIndex: e,
1277
1294
  changedRows: this.changedRows,
1278
1295
  changedRowIds: this.changedRowIds,
1279
- firstTimeForRow: c,
1296
+ firstTimeForRow: a,
1280
1297
  updateRow: d,
1281
- setInvalid: u
1298
+ setInvalid: f
1282
1299
  })) return;
1283
- a && !h && this.isCellInvalid(a, r) && this.clearInvalid(a, r), s[r] = i, a && this.#r.add(a), this.#h(), this.emitPluginEvent("cell-edit-committed", {
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", {
1284
1301
  rowIndex: e,
1285
- field: r,
1302
+ field: s,
1286
1303
  oldValue: l,
1287
1304
  newValue: i
1288
1305
  });
@@ -1292,134 +1309,156 @@ class W extends P {
1292
1309
  /**
1293
1310
  * Inject an editor into a cell.
1294
1311
  */
1295
- #g(e, t, i, s, r, l) {
1296
- if (!i.editable || r.classList.contains("editing")) return;
1312
+ #p(e, t, i, n, s, l) {
1313
+ if (!i.editable || s.classList.contains("editing")) return;
1297
1314
  let o;
1298
1315
  try {
1299
1316
  o = this.grid.getRowId(e);
1300
1317
  } catch {
1301
1318
  }
1302
- const a = o ? (f) => this.grid.updateRow(o, f, "cascade") : A, c = C(i.field) ? e[i.field] : void 0;
1303
- r.classList.add("editing"), this.#o.add(`${t}:${s}`);
1304
- const d = r.parentElement;
1305
- d && $(d);
1306
- let h = !1;
1307
- const u = (f) => {
1308
- h || !this.#t && this.#e === -1 || this.#p(t, i, f, e);
1309
- }, m = () => {
1310
- h = !0, C(i.field) && (e[i.field] = c);
1319
+ const c = o ? (u) => this.grid.updateRow(o, u, "cascade") : T, a = S(i.field) ? e[i.field] : void 0;
1320
+ s.classList.add("editing"), this.#o.add(`${t}:${n}`);
1321
+ const d = s.parentElement;
1322
+ d && K(d);
1323
+ let g = !1;
1324
+ const f = (u) => {
1325
+ g || !this.#t && this.#e === -1 || this.#m(t, i, u, e);
1326
+ }, E = () => {
1327
+ g = !0, S(i.field) && (e[i.field] = a);
1311
1328
  }, p = document.createElement("div");
1312
- p.className = "tbw-editor-host", r.innerHTML = "", r.appendChild(p), p.addEventListener("keydown", (f) => {
1313
- if (f.key === "Enter") {
1329
+ p.className = "tbw-editor-host", s.innerHTML = "", s.appendChild(p), p.addEventListener("keydown", (u) => {
1330
+ if (u.key === "Enter") {
1314
1331
  if (this.#t) {
1315
- f.stopPropagation(), f.preventDefault();
1316
- const E = p.querySelector("input,textarea,select");
1317
- E && u(y(E, i, c));
1332
+ u.stopPropagation(), u.preventDefault();
1333
+ const h = p.querySelector("input,textarea,select");
1334
+ h && f(_(h, i, a));
1318
1335
  return;
1319
1336
  }
1320
- if (this.config.onBeforeEditClose && this.config.onBeforeEditClose(f) === !1)
1337
+ if (this.config.onBeforeEditClose && this.config.onBeforeEditClose(u) === !1)
1321
1338
  return;
1322
- f.stopPropagation(), f.preventDefault(), h = !0, this.#s(t, !1);
1339
+ u.stopPropagation(), u.preventDefault(), g = !0, this.#n(t, !1);
1323
1340
  }
1324
- if (f.key === "Escape") {
1341
+ if (u.key === "Escape") {
1325
1342
  if (this.#t) {
1326
- f.stopPropagation(), f.preventDefault();
1343
+ u.stopPropagation(), u.preventDefault();
1327
1344
  return;
1328
1345
  }
1329
- if (this.config.onBeforeEditClose && this.config.onBeforeEditClose(f) === !1)
1346
+ if (this.config.onBeforeEditClose && this.config.onBeforeEditClose(u) === !1)
1330
1347
  return;
1331
- f.stopPropagation(), f.preventDefault(), m(), this.#s(t, !0);
1348
+ u.stopPropagation(), u.preventDefault(), E(), this.#n(t, !0);
1332
1349
  }
1333
1350
  });
1334
- const g = i, b = g.__editorTemplate, w = G(this.grid, g) ?? z(i), _ = c;
1335
- if (w === "template" && b)
1336
- this.#y(p, g, e, c, u, m, l, t);
1337
- else if (typeof w == "string") {
1338
- const f = document.createElement(w);
1339
- f.value = _, f.addEventListener("change", () => u(f.value)), p.appendChild(f), l || queueMicrotask(() => {
1340
- p.querySelector(v)?.focus({ preventScroll: !0 });
1351
+ const m = i, y = m.__editorTemplate, v = W(this.grid, m) ?? j(i), k = a, q = `${t}:${i.field}`, A = [];
1352
+ this.#c.set(q, (u) => {
1353
+ for (const h of A) h(u);
1354
+ });
1355
+ const C = (u) => {
1356
+ A.push(u);
1357
+ };
1358
+ if (v === "template" && y)
1359
+ this.#C(p, m, e, a, f, E, l, t), C((u) => {
1360
+ const h = p.querySelector(
1361
+ "input,textarea,select"
1362
+ );
1363
+ h && (h instanceof HTMLInputElement && h.type === "checkbox" ? h.checked = !!u : h.value = String(u ?? ""));
1364
+ });
1365
+ else if (typeof v == "string") {
1366
+ const u = document.createElement(v);
1367
+ u.value = k, u.addEventListener("change", () => f(u.value)), C((h) => {
1368
+ u.value = h;
1369
+ }), p.appendChild(u), l || queueMicrotask(() => {
1370
+ p.querySelector(w)?.focus({ preventScroll: !0 });
1341
1371
  });
1342
- } else if (typeof w == "function") {
1343
- const f = {
1372
+ } else if (typeof v == "function") {
1373
+ const u = {
1344
1374
  row: e,
1345
1375
  rowId: o ?? "",
1346
- value: _,
1376
+ value: k,
1347
1377
  field: i.field,
1348
1378
  column: i,
1349
- commit: u,
1350
- cancel: m,
1351
- updateRow: a
1352
- }, E = w(f);
1353
- typeof E == "string" ? (p.innerHTML = E, j(p, i, u, c)) : E instanceof Node && (p.appendChild(E), E instanceof HTMLInputElement || E instanceof HTMLSelectElement || E instanceof HTMLTextAreaElement || r.setAttribute("data-editor-managed", "")), l || queueMicrotask(() => {
1354
- p.querySelector(v)?.focus({ preventScroll: !0 });
1379
+ commit: f,
1380
+ cancel: E,
1381
+ updateRow: c,
1382
+ onValueChange: C
1383
+ }, h = v(u);
1384
+ typeof h == "string" ? (p.innerHTML = h, Q(p, i, f, a), C((R) => {
1385
+ const b = p.querySelector(
1386
+ "input,textarea,select"
1387
+ );
1388
+ b && (b instanceof HTMLInputElement && b.type === "checkbox" ? b.checked = !!R : b.value = String(R ?? ""));
1389
+ })) : h instanceof Node && (p.appendChild(h), h instanceof HTMLInputElement || h instanceof HTMLSelectElement || h instanceof HTMLTextAreaElement ? C((b) => {
1390
+ h instanceof HTMLInputElement && h.type === "checkbox" ? h.checked = !!b : h.value = String(b ?? "");
1391
+ }) : s.setAttribute("data-editor-managed", "")), l || queueMicrotask(() => {
1392
+ p.querySelector(w)?.focus({ preventScroll: !0 });
1355
1393
  });
1356
- } else if (w && typeof w == "object") {
1357
- const f = document.createElement("div");
1358
- f.setAttribute("data-external-editor", ""), f.setAttribute("data-field", i.field), p.appendChild(f), r.setAttribute("data-editor-managed", "");
1359
- const E = {
1394
+ } else if (v && typeof v == "object") {
1395
+ const u = document.createElement("div");
1396
+ u.setAttribute("data-external-editor", ""), u.setAttribute("data-field", i.field), p.appendChild(u), s.setAttribute("data-editor-managed", "");
1397
+ const h = {
1360
1398
  row: e,
1361
1399
  rowId: o ?? "",
1362
- value: _,
1400
+ value: k,
1363
1401
  field: i.field,
1364
1402
  column: i,
1365
- commit: u,
1366
- cancel: m,
1367
- updateRow: a
1403
+ commit: f,
1404
+ cancel: E,
1405
+ updateRow: c,
1406
+ onValueChange: C
1368
1407
  };
1369
- if (w.mount)
1408
+ if (v.mount)
1370
1409
  try {
1371
- w.mount({ placeholder: f, context: E, spec: w });
1372
- } catch (S) {
1373
- console.warn(`[tbw-grid] External editor mount error for column '${i.field}':`, S);
1410
+ v.mount({ placeholder: u, context: h, spec: v });
1411
+ } catch (R) {
1412
+ console.warn(`[tbw-grid] External editor mount error for column '${i.field}':`, R);
1374
1413
  }
1375
1414
  else
1376
1415
  this.grid.dispatchEvent(
1377
- new CustomEvent("mount-external-editor", { detail: { placeholder: f, spec: w, context: E } })
1416
+ new CustomEvent("mount-external-editor", { detail: { placeholder: u, spec: v, context: h } })
1378
1417
  );
1379
1418
  }
1380
1419
  }
1381
1420
  /**
1382
1421
  * Render a template-based editor.
1383
1422
  */
1384
- #y(e, t, i, s, r, l, o, a) {
1385
- const c = t.__editorTemplate;
1386
- if (!c) return;
1387
- const d = c.cloneNode(!0), h = t.__compiledEditor;
1388
- h ? d.innerHTML = h({
1423
+ #C(e, t, i, n, s, l, o, c) {
1424
+ const a = t.__editorTemplate;
1425
+ if (!a) return;
1426
+ const d = a.cloneNode(!0), g = t.__compiledEditor;
1427
+ g ? d.innerHTML = g({
1389
1428
  row: i,
1390
- value: s,
1429
+ value: n,
1391
1430
  field: t.field,
1392
1431
  column: t,
1393
- commit: r,
1432
+ commit: s,
1394
1433
  cancel: l
1395
- }) : d.querySelectorAll("*").forEach((m) => {
1396
- m.childNodes.length === 1 && m.firstChild?.nodeType === Node.TEXT_NODE && (m.textContent = m.textContent?.replace(/{{\s*value\s*}}/g, s == null ? "" : String(s)).replace(/{{\s*row\.([a-zA-Z0-9_]+)\s*}}/g, (p, g) => {
1397
- if (!C(g)) return "";
1398
- const b = i[g];
1399
- return b == null ? "" : String(b);
1434
+ }) : d.querySelectorAll("*").forEach((E) => {
1435
+ 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
+ if (!S(m)) return "";
1437
+ const y = i[m];
1438
+ return y == null ? "" : String(y);
1400
1439
  }) || "");
1401
1440
  });
1402
- const u = d.querySelector(
1441
+ const f = d.querySelector(
1403
1442
  "input,textarea,select"
1404
1443
  );
1405
- if (u) {
1406
- u instanceof HTMLInputElement && u.type === "checkbox" ? u.checked = !!s : u.value = String(s ?? "");
1407
- let m = !1;
1408
- u.addEventListener("blur", () => {
1409
- m || r(y(u, t, s));
1410
- }), u.addEventListener("keydown", (p) => {
1411
- const g = p;
1412
- if (g.key === "Enter") {
1413
- if (this.config.onBeforeEditClose && this.config.onBeforeEditClose(g) === !1)
1444
+ if (f) {
1445
+ f instanceof HTMLInputElement && f.type === "checkbox" ? f.checked = !!n : f.value = String(n ?? "");
1446
+ let E = !1;
1447
+ f.addEventListener("blur", () => {
1448
+ E || s(_(f, t, n));
1449
+ }), f.addEventListener("keydown", (p) => {
1450
+ const m = p;
1451
+ if (m.key === "Enter") {
1452
+ if (this.config.onBeforeEditClose && this.config.onBeforeEditClose(m) === !1)
1414
1453
  return;
1415
- g.stopPropagation(), g.preventDefault(), m = !0, r(y(u, t, s)), this.#s(a, !1);
1454
+ m.stopPropagation(), m.preventDefault(), E = !0, s(_(f, t, n)), this.#n(c, !1);
1416
1455
  }
1417
- if (g.key === "Escape") {
1418
- if (this.config.onBeforeEditClose && this.config.onBeforeEditClose(g) === !1)
1456
+ if (m.key === "Escape") {
1457
+ if (this.config.onBeforeEditClose && this.config.onBeforeEditClose(m) === !1)
1419
1458
  return;
1420
- g.stopPropagation(), g.preventDefault(), l(), this.#s(a, !0);
1459
+ m.stopPropagation(), m.preventDefault(), l(), this.#n(c, !0);
1421
1460
  }
1422
- }), u instanceof HTMLInputElement && u.type === "checkbox" && u.addEventListener("change", () => r(u.checked)), o || setTimeout(() => u.focus({ preventScroll: !0 }), 0);
1461
+ }), f instanceof HTMLInputElement && f.type === "checkbox" && f.addEventListener("change", () => s(f.checked)), o || setTimeout(() => f.focus({ preventScroll: !0 }), 0);
1423
1462
  }
1424
1463
  e.appendChild(d);
1425
1464
  }
@@ -1427,27 +1466,27 @@ class W extends P {
1427
1466
  * Compare snapshot vs current row to detect if any values changed during this edit session.
1428
1467
  * Uses shallow comparison of all properties.
1429
1468
  */
1430
- #C(e, t) {
1469
+ #R(e, t) {
1431
1470
  if (!e) return !1;
1432
- const i = e, s = t, r = /* @__PURE__ */ new Set([...Object.keys(i), ...Object.keys(s)]);
1433
- for (const l of r)
1434
- if (i[l] !== s[l])
1471
+ 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])
1435
1474
  return !0;
1436
1475
  return !1;
1437
1476
  }
1438
1477
  /**
1439
1478
  * Restore focus to cell after exiting edit mode.
1440
1479
  */
1441
- #E(e) {
1480
+ #v(e) {
1442
1481
  queueMicrotask(() => {
1443
1482
  try {
1444
- const t = e._focusRow, i = e._focusCol, s = e.findRenderedRowElement?.(t);
1445
- if (s) {
1483
+ const t = e._focusRow, i = e._focusCol, n = e.findRenderedRowElement?.(t);
1484
+ if (n) {
1446
1485
  Array.from(e._bodyEl.querySelectorAll(".cell-focus")).forEach(
1447
1486
  (l) => l.classList.remove("cell-focus")
1448
1487
  );
1449
- const r = s.querySelector(`.cell[data-row="${t}"][data-col="${i}"]`);
1450
- r && (r.classList.add("cell-focus"), r.setAttribute("aria-selected", "true"), r.hasAttribute("tabindex") || r.setAttribute("tabindex", "-1"), r.focus({ preventScroll: !0 }));
1488
+ const s = n.querySelector(`.cell[data-row="${t}"][data-col="${i}"]`);
1489
+ s && (s.classList.add("cell-focus"), s.setAttribute("aria-selected", "true"), s.hasAttribute("tabindex") || s.setAttribute("tabindex", "-1"), s.focus({ preventScroll: !0 }));
1451
1490
  }
1452
1491
  } catch {
1453
1492
  }
@@ -1456,7 +1495,7 @@ class W extends P {
1456
1495
  // #endregion
1457
1496
  }
1458
1497
  export {
1459
- W as EditingPlugin,
1460
- z as defaultEditorFor
1498
+ X as EditingPlugin,
1499
+ j as defaultEditorFor
1461
1500
  };
1462
1501
  //# sourceMappingURL=index.js.map