@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.
- package/README.md +5 -1
- package/all.js +1985 -1558
- package/all.js.map +1 -1
- package/index.js +46 -20
- package/index.js.map +1 -1
- package/lib/core/grid.d.ts.map +1 -1
- package/lib/core/internal/validate-config.d.ts.map +1 -1
- package/lib/plugins/column-virtualization/ColumnVirtualizationPlugin.d.ts.map +1 -1
- package/lib/plugins/column-virtualization/index.js +1 -1
- package/lib/plugins/column-virtualization/index.js.map +1 -1
- package/lib/plugins/context-menu/ContextMenuPlugin.d.ts +20 -1
- package/lib/plugins/context-menu/ContextMenuPlugin.d.ts.map +1 -1
- package/lib/plugins/context-menu/index.d.ts +1 -1
- package/lib/plugins/context-menu/index.d.ts.map +1 -1
- package/lib/plugins/context-menu/index.js +153 -70
- package/lib/plugins/context-menu/index.js.map +1 -1
- package/lib/plugins/context-menu/menu.d.ts +7 -0
- package/lib/plugins/context-menu/menu.d.ts.map +1 -1
- package/lib/plugins/context-menu/types.d.ts +46 -0
- package/lib/plugins/context-menu/types.d.ts.map +1 -1
- package/lib/plugins/editing/EditingPlugin.d.ts.map +1 -1
- package/lib/plugins/editing/index.js +214 -197
- package/lib/plugins/editing/index.js.map +1 -1
- package/lib/plugins/filtering/FilteringPlugin.d.ts +7 -1
- package/lib/plugins/filtering/FilteringPlugin.d.ts.map +1 -1
- package/lib/plugins/filtering/index.js +169 -133
- package/lib/plugins/filtering/index.js.map +1 -1
- package/lib/plugins/grouping-columns/GroupingColumnsPlugin.d.ts +5 -1
- package/lib/plugins/grouping-columns/GroupingColumnsPlugin.d.ts.map +1 -1
- package/lib/plugins/grouping-columns/index.js +242 -109
- package/lib/plugins/grouping-columns/index.js.map +1 -1
- package/lib/plugins/grouping-columns/types.d.ts +7 -0
- package/lib/plugins/grouping-columns/types.d.ts.map +1 -1
- package/lib/plugins/pinned-columns/PinnedColumnsPlugin.d.ts +11 -1
- package/lib/plugins/pinned-columns/PinnedColumnsPlugin.d.ts.map +1 -1
- package/lib/plugins/pinned-columns/index.d.ts +1 -1
- package/lib/plugins/pinned-columns/index.d.ts.map +1 -1
- package/lib/plugins/pinned-columns/index.js +174 -79
- package/lib/plugins/pinned-columns/index.js.map +1 -1
- package/lib/plugins/pinned-columns/pinned-columns.d.ts +23 -4
- package/lib/plugins/pinned-columns/pinned-columns.d.ts.map +1 -1
- package/lib/plugins/pinned-columns/types.d.ts +21 -9
- package/lib/plugins/pinned-columns/types.d.ts.map +1 -1
- package/lib/plugins/visibility/VisibilityPlugin.d.ts +42 -2
- package/lib/plugins/visibility/VisibilityPlugin.d.ts.map +1 -1
- package/lib/plugins/visibility/index.d.ts +1 -1
- package/lib/plugins/visibility/index.d.ts.map +1 -1
- package/lib/plugins/visibility/index.js +219 -59
- package/lib/plugins/visibility/index.js.map +1 -1
- package/lib/plugins/visibility/types.d.ts +25 -0
- package/lib/plugins/visibility/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/umd/grid.all.umd.js +25 -25
- package/umd/grid.all.umd.js.map +1 -1
- package/umd/grid.umd.js +2 -2
- package/umd/grid.umd.js.map +1 -1
- package/umd/plugins/column-virtualization.umd.js +1 -1
- package/umd/plugins/column-virtualization.umd.js.map +1 -1
- package/umd/plugins/context-menu.umd.js +1 -1
- package/umd/plugins/context-menu.umd.js.map +1 -1
- package/umd/plugins/editing.umd.js +1 -1
- package/umd/plugins/editing.umd.js.map +1 -1
- package/umd/plugins/filtering.umd.js +1 -1
- package/umd/plugins/filtering.umd.js.map +1 -1
- package/umd/plugins/grouping-columns.umd.js +1 -1
- package/umd/plugins/grouping-columns.umd.js.map +1 -1
- package/umd/plugins/pinned-columns.umd.js +1 -1
- package/umd/plugins/pinned-columns.umd.js.map +1 -1
- package/umd/plugins/visibility.umd.js +1 -1
- package/umd/plugins/visibility.umd.js.map +1 -1
|
@@ -1,59 +1,59 @@
|
|
|
1
|
-
function P(
|
|
2
|
-
|
|
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(
|
|
9
|
-
if (
|
|
10
|
-
const { rowHeight:
|
|
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 =
|
|
13
|
-
g < a.scrollTop ? a.scrollTop = g : g +
|
|
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 =
|
|
17
|
-
t ||
|
|
18
|
-
|
|
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 =
|
|
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
|
|
23
|
-
let
|
|
24
|
-
if ((!
|
|
25
|
-
|
|
26
|
-
const c =
|
|
27
|
-
if (c &&
|
|
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 =
|
|
33
|
+
const a = o._getHorizontalScrollOffsets?.(r ?? void 0, l) ?? { left: 0, right: 0 };
|
|
34
34
|
if (!a.skipScroll) {
|
|
35
|
-
const d =
|
|
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 (
|
|
40
|
-
const a =
|
|
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 (!
|
|
47
|
-
|
|
46
|
+
} else if (!l.contains(document.activeElement)) {
|
|
47
|
+
l.hasAttribute("tabindex") || l.setAttribute("tabindex", "-1");
|
|
48
48
|
try {
|
|
49
|
-
|
|
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>',
|
|
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
|
|
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 { ...
|
|
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(
|
|
437
|
-
const e =
|
|
436
|
+
function B(o) {
|
|
437
|
+
const e = o.options;
|
|
438
438
|
return e ? typeof e == "function" ? e() : e : [];
|
|
439
439
|
}
|
|
440
|
-
function N(
|
|
440
|
+
function N(o) {
|
|
441
441
|
return (e) => {
|
|
442
|
-
const t =
|
|
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 (
|
|
451
|
+
return (o) => {
|
|
452
452
|
const e = document.createElement("input");
|
|
453
|
-
return e.type = "checkbox", e.checked = !!
|
|
453
|
+
return e.type = "checkbox", e.checked = !!o.value, e.addEventListener("change", () => o.commit(e.checked)), e;
|
|
454
454
|
};
|
|
455
455
|
}
|
|
456
|
-
function z(
|
|
456
|
+
function z(o) {
|
|
457
457
|
return (e) => {
|
|
458
|
-
const t =
|
|
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(
|
|
468
|
+
function G(o) {
|
|
469
469
|
return (e) => {
|
|
470
|
-
const t =
|
|
471
|
-
if (
|
|
472
|
-
const
|
|
473
|
-
|
|
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(
|
|
476
|
-
const
|
|
477
|
-
|
|
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 (
|
|
481
|
-
const
|
|
482
|
-
e.commit(
|
|
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", (
|
|
487
|
-
|
|
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(
|
|
491
|
+
function F(o) {
|
|
492
492
|
return (e) => {
|
|
493
|
-
const t =
|
|
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(
|
|
505
|
-
switch (
|
|
504
|
+
function j(o) {
|
|
505
|
+
switch (o.type) {
|
|
506
506
|
case "number":
|
|
507
|
-
return N(
|
|
507
|
+
return N(o);
|
|
508
508
|
case "boolean":
|
|
509
509
|
return $();
|
|
510
510
|
case "date":
|
|
511
|
-
return z(
|
|
511
|
+
return z(o);
|
|
512
512
|
case "select":
|
|
513
|
-
return G(
|
|
513
|
+
return G(o);
|
|
514
514
|
default:
|
|
515
|
-
return F(
|
|
515
|
+
return F(o);
|
|
516
516
|
}
|
|
517
517
|
}
|
|
518
|
-
function W(
|
|
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 =
|
|
522
|
+
const i = o.effectiveConfig?.typeDefaults;
|
|
523
523
|
if (i?.[e.type]?.editor)
|
|
524
524
|
return i[e.type].editor;
|
|
525
|
-
const n =
|
|
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(
|
|
533
|
-
return !(typeof
|
|
532
|
+
function S(o) {
|
|
533
|
+
return !(typeof o != "string" || o === "__proto__" || o === "constructor" || o === "prototype");
|
|
534
534
|
}
|
|
535
|
-
function K(
|
|
536
|
-
const e = (
|
|
537
|
-
|
|
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(
|
|
540
|
-
|
|
539
|
+
function U(o) {
|
|
540
|
+
o.__editingCellCount = 0, o.removeAttribute("data-has-editing");
|
|
541
541
|
}
|
|
542
|
-
function _(
|
|
543
|
-
return
|
|
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(
|
|
545
|
+
function T(o) {
|
|
546
546
|
}
|
|
547
|
-
function Q(
|
|
548
|
-
const n =
|
|
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
|
|
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
|
-
#
|
|
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
|
-
#
|
|
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
|
-
#
|
|
625
|
+
#f = !1;
|
|
626
626
|
/** Row index pending animation after render, or -1 if none */
|
|
627
|
-
#
|
|
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.#
|
|
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.#
|
|
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
|
|
686
|
-
|
|
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.#
|
|
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((
|
|
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.#
|
|
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.#
|
|
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.#
|
|
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],
|
|
788
|
-
if (s?.editable && s.type === "boolean" &&
|
|
789
|
-
const
|
|
790
|
-
if (S(
|
|
791
|
-
const a = !l
|
|
792
|
-
return this.#
|
|
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.#
|
|
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((
|
|
807
|
-
const
|
|
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
|
|
845
|
-
if (i?.[s.type]?.editorParams && (
|
|
846
|
-
const
|
|
847
|
-
|
|
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
|
|
865
|
+
return r ? {
|
|
850
866
|
...s,
|
|
851
|
-
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.#
|
|
864
|
-
const t = this.#
|
|
865
|
-
this.#
|
|
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),
|
|
870
|
-
if (!
|
|
871
|
-
const c =
|
|
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[
|
|
874
|
-
a && d && this.#
|
|
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:
|
|
885
|
-
n.editable && (
|
|
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.#
|
|
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.#
|
|
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.#
|
|
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.#
|
|
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.#
|
|
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.#
|
|
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.#
|
|
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.#
|
|
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.#
|
|
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
|
-
#
|
|
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
|
|
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 (
|
|
1069
|
-
const a = n.findRenderedRowElement?.(
|
|
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.#
|
|
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
|
|
1098
|
-
|
|
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((
|
|
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
|
-
|
|
1112
|
-
|
|
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 =
|
|
1116
|
-
d.classList.contains("editing") || this.#
|
|
1132
|
+
const d = l;
|
|
1133
|
+
d.classList.contains("editing") || this.#m(r, e, a, c, d, !0);
|
|
1117
1134
|
}
|
|
1118
1135
|
}), setTimeout(() => {
|
|
1119
|
-
let
|
|
1120
|
-
if (
|
|
1121
|
-
const c =
|
|
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.#
|
|
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.#
|
|
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
|
-
#
|
|
1148
|
-
const n = this.grid, s = n._rows[e],
|
|
1149
|
-
!s || !
|
|
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
|
-
#
|
|
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
|
|
1161
|
-
|
|
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
|
-
#
|
|
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
|
|
1173
|
-
if (
|
|
1174
|
-
t._focusCol = s[
|
|
1175
|
-
const d = t.findRenderedRowElement?.(n)?.querySelector(`.cell[data-col="${s[
|
|
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.#
|
|
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
|
-
#
|
|
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
|
-
#
|
|
1196
|
-
if (this.#e !== e && (this.#l.set(e, { ...t }), this.#e = e, this.#
|
|
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
|
-
#
|
|
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],
|
|
1216
|
-
let
|
|
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
|
-
|
|
1236
|
+
l = i.getRowId?.(s);
|
|
1220
1237
|
} catch {
|
|
1221
1238
|
}
|
|
1222
|
-
if (!t &&
|
|
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.#
|
|
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
|
-
}),
|
|
1253
|
+
}), l && (this.#n.delete(l), this.clearRowInvalid(l));
|
|
1237
1254
|
else if (!t && s) {
|
|
1238
|
-
const c = this.#
|
|
1255
|
+
const c = this.#_(n, s), a = l ? this.#n.has(l) : c, d = this.emitCancelable("row-commit", {
|
|
1239
1256
|
rowIndex: e,
|
|
1240
|
-
rowId:
|
|
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
|
-
}),
|
|
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.#
|
|
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
|
-
|
|
1274
|
+
r && (r.querySelectorAll(".cell.editing").forEach((c) => {
|
|
1258
1275
|
c.classList.remove("editing"), U(c.parentElement);
|
|
1259
|
-
}), this.requestRender()), this.#
|
|
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:
|
|
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
|
-
#
|
|
1287
|
+
#E(e, t, i, n) {
|
|
1271
1288
|
const s = t.field;
|
|
1272
1289
|
if (!S(s)) return;
|
|
1273
|
-
const
|
|
1274
|
-
if (
|
|
1275
|
-
const
|
|
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.#
|
|
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:
|
|
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.#
|
|
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:
|
|
1320
|
+
oldValue: r,
|
|
1304
1321
|
newValue: i
|
|
1305
1322
|
});
|
|
1306
|
-
const p =
|
|
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
|
-
#
|
|
1329
|
+
#m(e, t, i, n, s, r) {
|
|
1313
1330
|
if (!i.editable || s.classList.contains("editing")) return;
|
|
1314
|
-
let
|
|
1331
|
+
let l;
|
|
1315
1332
|
try {
|
|
1316
|
-
|
|
1333
|
+
l = this.grid.getRowId(e);
|
|
1317
1334
|
} catch {
|
|
1318
1335
|
}
|
|
1319
|
-
const c =
|
|
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.#
|
|
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.#
|
|
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.#
|
|
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.#
|
|
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),
|
|
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:
|
|
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", "")),
|
|
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:
|
|
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
|
-
#
|
|
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:
|
|
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.#
|
|
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(),
|
|
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)),
|
|
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
|
-
#
|
|
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
|
|
1473
|
-
if (i[
|
|
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
|
-
#
|
|
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
|
-
(
|
|
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 }));
|