@toolbox-web/grid 1.11.0 → 1.12.1
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/all.js +1224 -1110
- package/all.js.map +1 -1
- package/index.js +2000 -1700
- package/index.js.map +1 -1
- package/lib/core/grid.d.ts +21 -1
- package/lib/core/grid.d.ts.map +1 -1
- package/lib/core/internal/aria.d.ts +52 -0
- package/lib/core/internal/aria.d.ts.map +1 -0
- package/lib/core/internal/config-manager.d.ts.map +1 -1
- package/lib/core/internal/idle-scheduler.d.ts +0 -27
- package/lib/core/internal/idle-scheduler.d.ts.map +1 -1
- package/lib/core/internal/loading.d.ts +0 -38
- package/lib/core/internal/loading.d.ts.map +1 -1
- package/lib/core/internal/row-animation.d.ts.map +1 -1
- package/lib/core/internal/shell.d.ts +6 -0
- package/lib/core/internal/shell.d.ts.map +1 -1
- package/lib/core/internal/style-injector.d.ts +0 -8
- package/lib/core/internal/style-injector.d.ts.map +1 -1
- package/lib/core/internal/utils.d.ts +6 -4
- package/lib/core/internal/utils.d.ts.map +1 -1
- package/lib/core/internal/validate-config.d.ts.map +1 -1
- package/lib/core/internal/virtualization.d.ts +177 -23
- package/lib/core/internal/virtualization.d.ts.map +1 -1
- package/lib/core/plugin/base-plugin.d.ts +50 -0
- package/lib/core/plugin/base-plugin.d.ts.map +1 -1
- package/lib/core/plugin/plugin-manager.d.ts +18 -0
- package/lib/core/plugin/plugin-manager.d.ts.map +1 -1
- package/lib/core/plugin/types.d.ts +16 -0
- package/lib/core/plugin/types.d.ts.map +1 -1
- package/lib/core/types.d.ts +56 -3
- package/lib/core/types.d.ts.map +1 -1
- package/lib/plugins/clipboard/index.js.map +1 -1
- package/lib/plugins/column-virtualization/index.js.map +1 -1
- package/lib/plugins/context-menu/ContextMenuPlugin.d.ts.map +1 -1
- package/lib/plugins/context-menu/index.js +1 -1
- package/lib/plugins/context-menu/index.js.map +1 -1
- package/lib/plugins/editing/EditingPlugin.d.ts +7 -5
- package/lib/plugins/editing/EditingPlugin.d.ts.map +1 -1
- package/lib/plugins/editing/index.js +379 -278
- package/lib/plugins/editing/index.js.map +1 -1
- package/lib/plugins/editing/types.d.ts +14 -1
- package/lib/plugins/editing/types.d.ts.map +1 -1
- package/lib/plugins/export/index.js.map +1 -1
- package/lib/plugins/filtering/index.js.map +1 -1
- package/lib/plugins/grouping-columns/GroupingColumnsPlugin.d.ts +8 -1
- package/lib/plugins/grouping-columns/GroupingColumnsPlugin.d.ts.map +1 -1
- package/lib/plugins/grouping-columns/index.js +59 -60
- package/lib/plugins/grouping-columns/index.js.map +1 -1
- package/lib/plugins/grouping-rows/GroupingRowsPlugin.d.ts +14 -0
- package/lib/plugins/grouping-rows/GroupingRowsPlugin.d.ts.map +1 -1
- package/lib/plugins/grouping-rows/index.js +88 -69
- package/lib/plugins/grouping-rows/index.js.map +1 -1
- package/lib/plugins/grouping-rows/types.d.ts +17 -0
- package/lib/plugins/grouping-rows/types.d.ts.map +1 -1
- package/lib/plugins/master-detail/MasterDetailPlugin.d.ts +24 -0
- package/lib/plugins/master-detail/MasterDetailPlugin.d.ts.map +1 -1
- package/lib/plugins/master-detail/index.js +203 -128
- package/lib/plugins/master-detail/index.js.map +1 -1
- package/lib/plugins/multi-sort/index.js.map +1 -1
- package/lib/plugins/pinned-columns/index.js.map +1 -1
- package/lib/plugins/pinned-rows/index.js +2 -2
- package/lib/plugins/pinned-rows/index.js.map +1 -1
- package/lib/plugins/pivot/index.js +2 -2
- package/lib/plugins/pivot/index.js.map +1 -1
- package/lib/plugins/print/index.js.map +1 -1
- package/lib/plugins/reorder/index.js.map +1 -1
- package/lib/plugins/responsive/ResponsivePlugin.d.ts +13 -0
- package/lib/plugins/responsive/ResponsivePlugin.d.ts.map +1 -1
- package/lib/plugins/responsive/index.js +65 -49
- package/lib/plugins/responsive/index.js.map +1 -1
- package/lib/plugins/row-reorder/index.js.map +1 -1
- package/lib/plugins/selection/index.js +5 -5
- package/lib/plugins/selection/index.js.map +1 -1
- package/lib/plugins/server-side/index.js.map +1 -1
- package/lib/plugins/tree/index.js.map +1 -1
- package/lib/plugins/undo-redo/index.js.map +1 -1
- package/lib/plugins/visibility/index.js.map +1 -1
- package/package.json +1 -1
- package/umd/grid.all.umd.js +27 -25
- package/umd/grid.all.umd.js.map +1 -1
- package/umd/grid.umd.js +18 -16
- package/umd/grid.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/grouping-columns.umd.js +1 -1
- package/umd/plugins/grouping-columns.umd.js.map +1 -1
- package/umd/plugins/grouping-rows.umd.js +2 -2
- package/umd/plugins/grouping-rows.umd.js.map +1 -1
- package/umd/plugins/master-detail.umd.js +1 -1
- package/umd/plugins/master-detail.umd.js.map +1 -1
- package/umd/plugins/responsive.umd.js +1 -1
- package/umd/plugins/responsive.umd.js.map +1 -1
- package/umd/plugins/selection.umd.js +2 -2
- package/umd/plugins/selection.umd.js.map +1 -1
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
function k(s) {
|
|
2
2
|
s && s.querySelectorAll(".cell-focus").forEach((e) => e.classList.remove("cell-focus"));
|
|
3
3
|
}
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
function
|
|
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(s, e) {
|
|
9
9
|
if (s._virtualization?.enabled) {
|
|
10
10
|
const { rowHeight: l, container: o, viewportEl: a } = s._virtualization, c = o, d = a?.clientHeight ?? c?.clientHeight ?? 0;
|
|
11
11
|
if (c && d > 0) {
|
|
12
|
-
const
|
|
13
|
-
|
|
12
|
+
const h = s._focusRow * l;
|
|
13
|
+
h < c.scrollTop ? c.scrollTop = h : h + l > c.scrollTop + d && (c.scrollTop = h - d + l);
|
|
14
14
|
}
|
|
15
15
|
}
|
|
16
16
|
const t = s._activeEditRows !== void 0 && s._activeEditRows !== -1;
|
|
17
17
|
t || s.refreshVirtualWindow(!1), k(s._bodyEl), Array.from(s._bodyEl.querySelectorAll('[aria-selected="true"]')).forEach((l) => {
|
|
18
18
|
l.setAttribute("aria-selected", "false");
|
|
19
19
|
});
|
|
20
|
-
const i = s._focusRow,
|
|
21
|
-
if (i >=
|
|
22
|
-
const l = s._bodyEl.querySelectorAll(".data-grid-row")[i -
|
|
20
|
+
const i = s._focusRow, n = s._virtualization.start ?? 0, r = s._virtualization.end ?? s._rows.length;
|
|
21
|
+
if (i >= n && i < r) {
|
|
22
|
+
const l = s._bodyEl.querySelectorAll(".data-grid-row")[i - n];
|
|
23
23
|
let o = l?.children[s._focusCol];
|
|
24
24
|
if ((!o || !o.classList?.contains("cell")) && (o = l?.querySelector(`.cell[data-col="${s._focusCol}"]`) ?? l?.querySelector(".cell[data-col]")), o) {
|
|
25
25
|
o.classList.add("cell-focus"), o.setAttribute("aria-selected", "true");
|
|
@@ -32,12 +32,12 @@ function S(s, e) {
|
|
|
32
32
|
else {
|
|
33
33
|
const c = s._getHorizontalScrollOffsets?.(l ?? void 0, o) ?? { left: 0, right: 0 };
|
|
34
34
|
if (!c.skipScroll) {
|
|
35
|
-
const d = o.getBoundingClientRect(),
|
|
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
36
|
u < p ? a.scrollLeft = u - c.left : m > g && (a.scrollLeft = m - a.clientWidth + c.right);
|
|
37
37
|
}
|
|
38
38
|
}
|
|
39
39
|
if (s._activeEditRows !== void 0 && s._activeEditRows !== -1 && o.classList.contains("editing")) {
|
|
40
|
-
const c = o.querySelector(
|
|
40
|
+
const c = o.querySelector(v);
|
|
41
41
|
if (c && document.activeElement !== c)
|
|
42
42
|
try {
|
|
43
43
|
c.focus({ preventScroll: !0 });
|
|
@@ -53,7 +53,7 @@ function S(s, 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>',
|
|
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 = {
|
|
57
57
|
expand: "▶",
|
|
58
58
|
collapse: "▼",
|
|
59
59
|
sortAsc: "▲",
|
|
@@ -66,7 +66,7 @@ const L = '<svg viewBox="0 0 16 16" width="12" height="12"><path fill="currentCo
|
|
|
66
66
|
filterActive: L,
|
|
67
67
|
print: "🖨️"
|
|
68
68
|
};
|
|
69
|
-
class
|
|
69
|
+
class P {
|
|
70
70
|
/**
|
|
71
71
|
* Plugin dependencies - declare other plugins this one requires.
|
|
72
72
|
*
|
|
@@ -129,7 +129,7 @@ class O {
|
|
|
129
129
|
* Created fresh in attach(), aborted in detach().
|
|
130
130
|
* This ensures event listeners are properly cleaned up when plugins are re-attached.
|
|
131
131
|
*/
|
|
132
|
-
#
|
|
132
|
+
#t;
|
|
133
133
|
/**
|
|
134
134
|
* Default configuration - subclasses should override this getter.
|
|
135
135
|
* Note: This must be a getter (not property initializer) for proper inheritance
|
|
@@ -157,7 +157,7 @@ class O {
|
|
|
157
157
|
* ```
|
|
158
158
|
*/
|
|
159
159
|
attach(e) {
|
|
160
|
-
this.#
|
|
160
|
+
this.#t?.abort(), this.#t = new AbortController(), this.grid = e, this.config = { ...this.defaultConfig, ...this.userConfig };
|
|
161
161
|
}
|
|
162
162
|
/**
|
|
163
163
|
* Called when the plugin is detached from a grid.
|
|
@@ -173,7 +173,7 @@ class O {
|
|
|
173
173
|
* ```
|
|
174
174
|
*/
|
|
175
175
|
detach() {
|
|
176
|
-
this.#
|
|
176
|
+
this.#t?.abort(), this.#t = void 0;
|
|
177
177
|
}
|
|
178
178
|
/**
|
|
179
179
|
* Get another plugin instance from the same grid.
|
|
@@ -348,7 +348,7 @@ class O {
|
|
|
348
348
|
* document.addEventListener('keydown', handler, { signal: this.disconnectSignal });
|
|
349
349
|
*/
|
|
350
350
|
get disconnectSignal() {
|
|
351
|
-
return this.#
|
|
351
|
+
return this.#t?.signal ?? this.grid?.disconnectSignal;
|
|
352
352
|
}
|
|
353
353
|
/**
|
|
354
354
|
* Get the grid-level icons configuration.
|
|
@@ -356,7 +356,7 @@ class O {
|
|
|
356
356
|
*/
|
|
357
357
|
get gridIcons() {
|
|
358
358
|
const e = this.grid?.gridConfig?.icons ?? {};
|
|
359
|
-
return { ...
|
|
359
|
+
return { ...q, ...e };
|
|
360
360
|
}
|
|
361
361
|
// #region Animation Helpers
|
|
362
362
|
/**
|
|
@@ -432,8 +432,8 @@ class O {
|
|
|
432
432
|
}
|
|
433
433
|
// #endregion
|
|
434
434
|
}
|
|
435
|
-
const
|
|
436
|
-
function
|
|
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(s) {
|
|
437
437
|
const e = s.options;
|
|
438
438
|
return e ? typeof e == "function" ? e() : e : [];
|
|
439
439
|
}
|
|
@@ -441,81 +441,80 @@ function x(s) {
|
|
|
441
441
|
return (e) => {
|
|
442
442
|
const t = s.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
|
|
445
|
-
return i.addEventListener("blur",
|
|
446
|
-
|
|
444
|
+
const n = () => e.commit(i.value === "" ? null : Number(i.value));
|
|
445
|
+
return i.addEventListener("blur", n), i.addEventListener("keydown", (r) => {
|
|
446
|
+
r.key === "Enter" && n(), r.key === "Escape" && e.cancel();
|
|
447
447
|
}), i;
|
|
448
448
|
};
|
|
449
449
|
}
|
|
450
|
-
function
|
|
450
|
+
function H() {
|
|
451
451
|
return (s) => {
|
|
452
452
|
const e = document.createElement("input");
|
|
453
453
|
return e.type = "checkbox", e.checked = !!s.value, e.addEventListener("change", () => s.commit(e.checked)), e;
|
|
454
454
|
};
|
|
455
455
|
}
|
|
456
|
-
function
|
|
456
|
+
function O(s) {
|
|
457
457
|
return (e) => {
|
|
458
458
|
const t = s.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
|
|
460
|
+
const n = () => {
|
|
461
461
|
typeof e.value == "string" ? e.commit(i.value) : e.commit(i.valueAsDate);
|
|
462
462
|
};
|
|
463
|
-
return i.addEventListener("change",
|
|
464
|
-
|
|
463
|
+
return i.addEventListener("change", n), i.addEventListener("keydown", (r) => {
|
|
464
|
+
r.key === "Escape" && e.cancel();
|
|
465
465
|
}), i;
|
|
466
466
|
};
|
|
467
467
|
}
|
|
468
|
-
function
|
|
468
|
+
function B(s) {
|
|
469
469
|
return (e) => {
|
|
470
470
|
const t = s.editorParams, i = document.createElement("select");
|
|
471
471
|
if (s.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
|
-
|
|
475
|
+
D(s).forEach((l) => {
|
|
476
476
|
const o = document.createElement("option");
|
|
477
477
|
o.value = String(l.value), o.textContent = l.label, (s.multi && Array.isArray(e.value) && e.value.includes(l.value) || !s.multi && e.value === l.value) && (o.selected = !0), i.appendChild(o);
|
|
478
478
|
});
|
|
479
|
-
const
|
|
479
|
+
const r = () => {
|
|
480
480
|
if (s.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",
|
|
486
|
+
return i.addEventListener("change", r), i.addEventListener("blur", r), i.addEventListener("keydown", (l) => {
|
|
487
487
|
l.key === "Escape" && e.cancel();
|
|
488
488
|
}), i;
|
|
489
489
|
};
|
|
490
490
|
}
|
|
491
|
-
function
|
|
491
|
+
function N(s) {
|
|
492
492
|
return (e) => {
|
|
493
493
|
const t = s.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
|
|
496
|
-
const
|
|
497
|
-
typeof e.value == "number" &&
|
|
495
|
+
const n = () => {
|
|
496
|
+
const r = i.value;
|
|
497
|
+
typeof e.value == "number" && r !== "" ? e.commit(Number(r)) : e.commit(r);
|
|
498
498
|
};
|
|
499
|
-
return i.addEventListener("blur",
|
|
500
|
-
|
|
499
|
+
return i.addEventListener("blur", n), i.addEventListener("keydown", (r) => {
|
|
500
|
+
r.key === "Enter" && n(), r.key === "Escape" && e.cancel();
|
|
501
501
|
}), i;
|
|
502
502
|
};
|
|
503
503
|
}
|
|
504
|
-
function
|
|
504
|
+
function z(s) {
|
|
505
505
|
switch (s.type) {
|
|
506
506
|
case "number":
|
|
507
507
|
return x(s);
|
|
508
508
|
case "boolean":
|
|
509
|
-
return
|
|
509
|
+
return H();
|
|
510
510
|
case "date":
|
|
511
|
-
return
|
|
511
|
+
return O(s);
|
|
512
512
|
case "select":
|
|
513
|
-
return
|
|
513
|
+
return B(s);
|
|
514
514
|
default:
|
|
515
|
-
return
|
|
515
|
+
return N(s);
|
|
516
516
|
}
|
|
517
517
|
}
|
|
518
|
-
const C = 'input,select,textarea,[contenteditable="true"],[contenteditable=""],[tabindex]:not([tabindex="-1"])';
|
|
519
518
|
function G(s, e) {
|
|
520
519
|
if (e.editor) return e.editor;
|
|
521
520
|
if (e.__editorTemplate) return "template";
|
|
@@ -523,21 +522,21 @@ function G(s, e) {
|
|
|
523
522
|
const i = s.effectiveConfig?.typeDefaults;
|
|
524
523
|
if (i?.[e.type]?.editor)
|
|
525
524
|
return i[e.type].editor;
|
|
526
|
-
const
|
|
527
|
-
if (
|
|
528
|
-
const
|
|
529
|
-
if (
|
|
530
|
-
return
|
|
525
|
+
const n = s.__frameworkAdapter;
|
|
526
|
+
if (n?.getTypeDefault) {
|
|
527
|
+
const r = n.getTypeDefault(e.type);
|
|
528
|
+
if (r?.editor)
|
|
529
|
+
return r.editor;
|
|
531
530
|
}
|
|
532
531
|
}
|
|
533
|
-
function
|
|
532
|
+
function C(s) {
|
|
534
533
|
return !(typeof s != "string" || s === "__proto__" || s === "constructor" || s === "prototype");
|
|
535
534
|
}
|
|
536
|
-
function
|
|
535
|
+
function $(s) {
|
|
537
536
|
const e = (s.__editingCellCount ?? 0) + 1;
|
|
538
537
|
s.__editingCellCount = e, s.setAttribute("data-has-editing", "");
|
|
539
538
|
}
|
|
540
|
-
function
|
|
539
|
+
function F(s) {
|
|
541
540
|
s.__editingCellCount = 0, s.removeAttribute("data-has-editing");
|
|
542
541
|
}
|
|
543
542
|
function y(s, e, t) {
|
|
@@ -545,13 +544,13 @@ function y(s, e, t) {
|
|
|
545
544
|
}
|
|
546
545
|
function A(s) {
|
|
547
546
|
}
|
|
548
|
-
function
|
|
549
|
-
const
|
|
550
|
-
|
|
551
|
-
t(y(
|
|
552
|
-
}),
|
|
547
|
+
function j(s, e, t, i) {
|
|
548
|
+
const n = s.querySelector("input,textarea,select");
|
|
549
|
+
n && (n.addEventListener("blur", () => {
|
|
550
|
+
t(y(n, e, i));
|
|
551
|
+
}), n instanceof HTMLInputElement && n.type === "checkbox" ? n.addEventListener("change", () => t(n.checked)) : n instanceof HTMLSelectElement && n.addEventListener("change", () => t(y(n, e, i))));
|
|
553
552
|
}
|
|
554
|
-
class
|
|
553
|
+
class W extends P {
|
|
555
554
|
/**
|
|
556
555
|
* Plugin manifest - declares owned properties for configuration validation.
|
|
557
556
|
* @internal
|
|
@@ -591,33 +590,53 @@ class K extends O {
|
|
|
591
590
|
/** @internal */
|
|
592
591
|
name = "editing";
|
|
593
592
|
/** @internal */
|
|
594
|
-
styles =
|
|
593
|
+
styles = M;
|
|
595
594
|
/** @internal */
|
|
596
595
|
get defaultConfig() {
|
|
597
596
|
return {
|
|
597
|
+
mode: "row",
|
|
598
598
|
editOn: "click"
|
|
599
599
|
};
|
|
600
600
|
}
|
|
601
|
+
/**
|
|
602
|
+
* Whether the grid is in 'grid' mode (all cells always editable).
|
|
603
|
+
*/
|
|
604
|
+
get #t() {
|
|
605
|
+
return this.config.mode === "grid";
|
|
606
|
+
}
|
|
601
607
|
// #region Editing State (fully owned by plugin)
|
|
602
608
|
/** Currently active edit row index, or -1 if not editing */
|
|
603
609
|
#e = -1;
|
|
604
610
|
/** Currently active edit column index, or -1 if not editing */
|
|
605
|
-
#
|
|
611
|
+
#c = -1;
|
|
606
612
|
/** Snapshots of row data before editing started */
|
|
607
|
-
#
|
|
613
|
+
#l = /* @__PURE__ */ new Map();
|
|
608
614
|
/** Set of row IDs that have been modified (ID-based for stability) */
|
|
609
|
-
#i = /* @__PURE__ */ new Set();
|
|
610
|
-
/** Set of cells currently in edit mode: "rowIndex:colIndex" */
|
|
611
615
|
#r = /* @__PURE__ */ new Set();
|
|
616
|
+
/** Set of cells currently in edit mode: "rowIndex:colIndex" */
|
|
617
|
+
#o = /* @__PURE__ */ new Set();
|
|
612
618
|
/** Flag to restore focus after next render (used when exiting edit mode) */
|
|
613
|
-
#
|
|
619
|
+
#d = !1;
|
|
614
620
|
/** Row index pending animation after render, or -1 if none */
|
|
615
|
-
#
|
|
621
|
+
#u = -1;
|
|
616
622
|
/**
|
|
617
623
|
* Invalid cell tracking: Map<rowId, Map<field, message>>
|
|
618
624
|
* Used for validation feedback without canceling edits.
|
|
619
625
|
*/
|
|
620
|
-
#
|
|
626
|
+
#i = /* @__PURE__ */ new Map();
|
|
627
|
+
/**
|
|
628
|
+
* In grid mode, tracks whether an input field is currently focused.
|
|
629
|
+
* When true: arrow keys work within input (edit mode).
|
|
630
|
+
* When false: arrow keys navigate between cells (navigation mode).
|
|
631
|
+
* Escape switches to navigation mode, Enter switches to edit mode.
|
|
632
|
+
*/
|
|
633
|
+
#s = !1;
|
|
634
|
+
/**
|
|
635
|
+
* In grid mode, when true, prevents inputs from auto-focusing.
|
|
636
|
+
* This is set when Escape is pressed (navigation mode) and cleared
|
|
637
|
+
* when Enter is pressed or user explicitly clicks an input.
|
|
638
|
+
*/
|
|
639
|
+
#a = !1;
|
|
621
640
|
// #endregion
|
|
622
641
|
// #region Lifecycle
|
|
623
642
|
/** @internal */
|
|
@@ -630,13 +649,13 @@ class K extends O {
|
|
|
630
649
|
}), Object.defineProperty(e, "changedRowIds", {
|
|
631
650
|
get: () => this.changedRowIds,
|
|
632
651
|
configurable: !0
|
|
633
|
-
}), e.resetChangedRows = (
|
|
634
|
-
|
|
652
|
+
}), e.resetChangedRows = (n) => this.resetChangedRows(n), e.beginBulkEdit = (n, r) => {
|
|
653
|
+
r && this.beginCellEdit(n, r);
|
|
635
654
|
}, document.addEventListener(
|
|
636
655
|
"keydown",
|
|
637
|
-
(
|
|
638
|
-
if (
|
|
639
|
-
if (this.config.onBeforeEditClose && this.config.onBeforeEditClose(
|
|
656
|
+
(n) => {
|
|
657
|
+
if (!this.#t && n.key === "Escape" && this.#e !== -1) {
|
|
658
|
+
if (this.config.onBeforeEditClose && this.config.onBeforeEditClose(n) === !1)
|
|
640
659
|
return;
|
|
641
660
|
this.#n(this.#e, !0);
|
|
642
661
|
}
|
|
@@ -644,19 +663,54 @@ class K extends O {
|
|
|
644
663
|
{ capture: !0, signal: t }
|
|
645
664
|
), document.addEventListener(
|
|
646
665
|
"mousedown",
|
|
647
|
-
(
|
|
648
|
-
if (this.#e === -1) return;
|
|
649
|
-
const
|
|
650
|
-
!
|
|
666
|
+
(n) => {
|
|
667
|
+
if (this.#t || this.#e === -1) return;
|
|
668
|
+
const r = i.findRenderedRowElement?.(this.#e);
|
|
669
|
+
!r || (n.composedPath && n.composedPath() || []).includes(r) || this.config.onBeforeEditClose && this.config.onBeforeEditClose(n) === !1 || queueMicrotask(() => {
|
|
651
670
|
this.#e !== -1 && this.#n(this.#e, !1);
|
|
652
671
|
});
|
|
653
672
|
},
|
|
654
673
|
{ signal: t }
|
|
655
|
-
)
|
|
674
|
+
), this.#t && (this.gridElement.classList.add("tbw-grid-mode"), this.requestRender(), this.gridElement.addEventListener(
|
|
675
|
+
"focusin",
|
|
676
|
+
(n) => {
|
|
677
|
+
const r = n.target;
|
|
678
|
+
if (r.matches(v)) {
|
|
679
|
+
if (this.#a) {
|
|
680
|
+
r.blur(), this.gridElement.focus();
|
|
681
|
+
return;
|
|
682
|
+
}
|
|
683
|
+
this.#s = !0;
|
|
684
|
+
}
|
|
685
|
+
},
|
|
686
|
+
{ signal: t }
|
|
687
|
+
), this.gridElement.addEventListener(
|
|
688
|
+
"focusout",
|
|
689
|
+
(n) => {
|
|
690
|
+
const r = n.relatedTarget;
|
|
691
|
+
(!r || !this.gridElement.contains(r) || !r.matches(v)) && (this.#s = !1);
|
|
692
|
+
},
|
|
693
|
+
{ signal: t }
|
|
694
|
+
), this.gridElement.addEventListener(
|
|
695
|
+
"keydown",
|
|
696
|
+
(n) => {
|
|
697
|
+
if (n.key === "Escape" && this.#s) {
|
|
698
|
+
const r = document.activeElement;
|
|
699
|
+
r && this.gridElement.contains(r) && (r.blur(), this.gridElement.focus()), this.#s = !1, this.#a = !0, n.preventDefault(), n.stopPropagation();
|
|
700
|
+
}
|
|
701
|
+
},
|
|
702
|
+
{ capture: !0, signal: t }
|
|
703
|
+
), this.gridElement.addEventListener(
|
|
704
|
+
"mousedown",
|
|
705
|
+
(n) => {
|
|
706
|
+
n.target.matches(v) && (this.#a = !1);
|
|
707
|
+
},
|
|
708
|
+
{ signal: t }
|
|
709
|
+
));
|
|
656
710
|
}
|
|
657
711
|
/** @internal */
|
|
658
712
|
detach() {
|
|
659
|
-
this.#e = -1, this.#
|
|
713
|
+
this.gridElement.classList.remove("tbw-grid-mode"), this.#e = -1, this.#c = -1, this.#l.clear(), this.#r.clear(), this.#o.clear(), this.#s = !1, this.#a = !1, super.detach();
|
|
660
714
|
}
|
|
661
715
|
/**
|
|
662
716
|
* Handle plugin queries.
|
|
@@ -664,7 +718,7 @@ class K extends O {
|
|
|
664
718
|
*/
|
|
665
719
|
handleQuery(e) {
|
|
666
720
|
if (e.type === "isEditing")
|
|
667
|
-
return this.#e !== -1;
|
|
721
|
+
return this.#t || this.#e !== -1;
|
|
668
722
|
}
|
|
669
723
|
// #endregion
|
|
670
724
|
// #region Event Handlers (event distribution)
|
|
@@ -675,12 +729,13 @@ class K extends O {
|
|
|
675
729
|
* @internal
|
|
676
730
|
*/
|
|
677
731
|
onCellClick(e) {
|
|
732
|
+
if (this.#t) return !1;
|
|
678
733
|
const t = this.grid, i = this.config.editOn ?? t.effectiveConfig?.editOn;
|
|
679
734
|
if (i === !1 || i === "manual" || i !== "click" && i !== "dblclick") return !1;
|
|
680
|
-
const
|
|
681
|
-
if (i === "click" &&
|
|
682
|
-
const { rowIndex:
|
|
683
|
-
return t._columns?.some((o) => o.editable) ? (e.originalEvent.stopPropagation(), this.beginBulkEdit(
|
|
735
|
+
const n = e.originalEvent.type === "dblclick";
|
|
736
|
+
if (i === "click" && n || i === "dblclick" && !n) return !1;
|
|
737
|
+
const { rowIndex: r } = e;
|
|
738
|
+
return t._columns?.some((o) => o.editable) ? (e.originalEvent.stopPropagation(), this.beginBulkEdit(r), !0) : !1;
|
|
684
739
|
}
|
|
685
740
|
/**
|
|
686
741
|
* Handle keyboard events for edit lifecycle.
|
|
@@ -688,52 +743,62 @@ class K extends O {
|
|
|
688
743
|
*/
|
|
689
744
|
onKeyDown(e) {
|
|
690
745
|
const t = this.grid;
|
|
691
|
-
if (e.key === "Escape"
|
|
692
|
-
|
|
693
|
-
|
|
746
|
+
if (e.key === "Escape") {
|
|
747
|
+
if (this.#t && this.#s) {
|
|
748
|
+
const i = document.activeElement;
|
|
749
|
+
return i && this.gridElement.contains(i) && i.blur(), this.#s = !1, this.requestAfterRender(), !0;
|
|
750
|
+
}
|
|
751
|
+
if (this.#e !== -1 && !this.#t)
|
|
752
|
+
return this.config.onBeforeEditClose && this.config.onBeforeEditClose(e) === !1 || this.#n(this.#e, !0), !0;
|
|
753
|
+
}
|
|
754
|
+
if (this.#t && !this.#s && (e.key === "ArrowUp" || e.key === "ArrowDown" || e.key === "ArrowLeft" || e.key === "ArrowRight"))
|
|
755
|
+
return !1;
|
|
756
|
+
if ((e.key === "ArrowUp" || e.key === "ArrowDown") && this.#e !== -1 && !this.#t) {
|
|
694
757
|
if (this.config.onBeforeEditClose && this.config.onBeforeEditClose(e) === !1)
|
|
695
758
|
return !0;
|
|
696
|
-
const i = t._rows.length - 1,
|
|
697
|
-
return this.#n(
|
|
759
|
+
const i = t._rows.length - 1, n = this.#e;
|
|
760
|
+
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(), R(t), this.requestAfterRender(), !0;
|
|
698
761
|
}
|
|
699
|
-
if (e.key === "Tab" && this.#e !== -1) {
|
|
762
|
+
if (e.key === "Tab" && (this.#e !== -1 || this.#t)) {
|
|
700
763
|
e.preventDefault();
|
|
701
764
|
const i = !e.shiftKey;
|
|
702
|
-
return this.#
|
|
765
|
+
return this.#b(i), !0;
|
|
703
766
|
}
|
|
704
767
|
if (e.key === " " || e.key === "Spacebar") {
|
|
705
768
|
if (this.#e !== -1)
|
|
706
769
|
return !1;
|
|
707
|
-
const i = t._focusRow,
|
|
708
|
-
if (i >= 0 &&
|
|
709
|
-
const
|
|
710
|
-
if (
|
|
711
|
-
const o =
|
|
712
|
-
if (
|
|
770
|
+
const i = t._focusRow, n = t._focusCol;
|
|
771
|
+
if (i >= 0 && n >= 0) {
|
|
772
|
+
const r = t._visibleColumns[n], l = t._rows[i];
|
|
773
|
+
if (r?.editable && r.type === "boolean" && l) {
|
|
774
|
+
const o = r.field;
|
|
775
|
+
if (C(o)) {
|
|
713
776
|
const c = !l[o];
|
|
714
|
-
return this.#
|
|
777
|
+
return this.#p(i, r, c, l), e.preventDefault(), this.requestRender(), !0;
|
|
715
778
|
}
|
|
716
779
|
}
|
|
717
780
|
}
|
|
718
781
|
return !1;
|
|
719
782
|
}
|
|
720
783
|
if (e.key === "Enter" && !e.shiftKey) {
|
|
784
|
+
if (this.#t && !this.#s)
|
|
785
|
+
return this.#v(), !0;
|
|
721
786
|
if (this.#e !== -1)
|
|
722
787
|
return !!(this.config.onBeforeEditClose && this.config.onBeforeEditClose(e) === !1);
|
|
723
788
|
const i = this.config.editOn ?? t.effectiveConfig?.editOn;
|
|
724
789
|
if (i === !1 || i === "manual") return !1;
|
|
725
|
-
const
|
|
726
|
-
if (
|
|
727
|
-
const o = t._visibleColumns[
|
|
790
|
+
const n = t._focusRow, r = t._focusCol;
|
|
791
|
+
if (n >= 0 && t._columns?.some((o) => o.editable)) {
|
|
792
|
+
const o = t._visibleColumns[r], a = t._rows[n], c = o?.field ?? "", d = c && a ? a[c] : void 0, h = this.gridElement.querySelector(`[data-row="${n}"][data-col="${r}"]`), u = new CustomEvent("cell-activate", {
|
|
728
793
|
cancelable: !0,
|
|
729
794
|
bubbles: !0,
|
|
730
795
|
detail: {
|
|
731
|
-
rowIndex:
|
|
732
|
-
colIndex:
|
|
796
|
+
rowIndex: n,
|
|
797
|
+
colIndex: r,
|
|
733
798
|
field: c,
|
|
734
799
|
value: d,
|
|
735
800
|
row: a,
|
|
736
|
-
cellEl:
|
|
801
|
+
cellEl: h,
|
|
737
802
|
trigger: "keyboard",
|
|
738
803
|
originalEvent: e
|
|
739
804
|
}
|
|
@@ -742,9 +807,9 @@ class K extends O {
|
|
|
742
807
|
const m = new CustomEvent("activate-cell", {
|
|
743
808
|
cancelable: !0,
|
|
744
809
|
bubbles: !0,
|
|
745
|
-
detail: { row:
|
|
810
|
+
detail: { row: n, col: r }
|
|
746
811
|
});
|
|
747
|
-
return this.gridElement.dispatchEvent(m), u.defaultPrevented || m.defaultPrevented ? (e.preventDefault(), !0) : (this.beginBulkEdit(
|
|
812
|
+
return this.gridElement.dispatchEvent(m), u.defaultPrevented || m.defaultPrevented ? (e.preventDefault(), !0) : (this.beginBulkEdit(n), !0);
|
|
748
813
|
}
|
|
749
814
|
return !1;
|
|
750
815
|
}
|
|
@@ -758,18 +823,18 @@ class K extends O {
|
|
|
758
823
|
* @internal
|
|
759
824
|
*/
|
|
760
825
|
processColumns(e) {
|
|
761
|
-
const t = this.grid, i = t.effectiveConfig?.typeDefaults,
|
|
762
|
-
return !i && !
|
|
763
|
-
if (!
|
|
826
|
+
const t = this.grid, i = t.effectiveConfig?.typeDefaults, n = t.__frameworkAdapter;
|
|
827
|
+
return !i && !n?.getTypeDefault ? e : e.map((r) => {
|
|
828
|
+
if (!r.type) return r;
|
|
764
829
|
let l;
|
|
765
|
-
if (i?.[
|
|
766
|
-
const o =
|
|
830
|
+
if (i?.[r.type]?.editorParams && (l = i[r.type].editorParams), !l && n?.getTypeDefault) {
|
|
831
|
+
const o = n.getTypeDefault(r.type);
|
|
767
832
|
o?.editorParams && (l = o.editorParams);
|
|
768
833
|
}
|
|
769
834
|
return l ? {
|
|
770
|
-
...
|
|
771
|
-
editorParams: { ...l, ...
|
|
772
|
-
} :
|
|
835
|
+
...r,
|
|
836
|
+
editorParams: { ...l, ...r.editorParams }
|
|
837
|
+
} : r;
|
|
773
838
|
});
|
|
774
839
|
}
|
|
775
840
|
/**
|
|
@@ -780,20 +845,30 @@ class K extends O {
|
|
|
780
845
|
*/
|
|
781
846
|
afterRender() {
|
|
782
847
|
const e = this.grid;
|
|
783
|
-
if (this.#
|
|
784
|
-
const t = this.#
|
|
785
|
-
this.#
|
|
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");
|
|
786
851
|
}
|
|
787
|
-
if (this.#
|
|
788
|
-
for (const t of this.#
|
|
789
|
-
const [i,
|
|
852
|
+
if (!this.#t && this.#o.size !== 0)
|
|
853
|
+
for (const t of this.#o) {
|
|
854
|
+
const [i, n] = t.split(":"), r = parseInt(i, 10), l = parseInt(n, 10), o = e.findRenderedRowElement?.(r);
|
|
790
855
|
if (!o) continue;
|
|
791
856
|
const a = o.querySelector(`.cell[data-col="${l}"]`);
|
|
792
857
|
if (!a || a.classList.contains("editing")) continue;
|
|
793
|
-
const c = e._rows[
|
|
794
|
-
c && d && this.#
|
|
858
|
+
const c = e._rows[r], d = e._visibleColumns[l];
|
|
859
|
+
c && d && this.#g(c, r, d, l, a, !0);
|
|
795
860
|
}
|
|
796
861
|
}
|
|
862
|
+
/**
|
|
863
|
+
* Hook called after each cell is rendered.
|
|
864
|
+
* In grid mode, injects editors into editable cells during render (no DOM queries needed).
|
|
865
|
+
* @internal
|
|
866
|
+
*/
|
|
867
|
+
afterCellRender(e) {
|
|
868
|
+
if (!this.#t) return;
|
|
869
|
+
const { row: t, rowIndex: i, column: n, colIndex: r, cellElement: l } = e;
|
|
870
|
+
n.editable && (l.classList.contains("editing") || this.#g(t, i, n, r, l, !0));
|
|
871
|
+
}
|
|
797
872
|
/**
|
|
798
873
|
* On scroll render, reapply editors to recycled cells.
|
|
799
874
|
* @internal
|
|
@@ -809,7 +884,7 @@ class K extends O {
|
|
|
809
884
|
*/
|
|
810
885
|
get changedRows() {
|
|
811
886
|
const e = [];
|
|
812
|
-
for (const t of this.#
|
|
887
|
+
for (const t of this.#r) {
|
|
813
888
|
const i = this.grid.getRow(t);
|
|
814
889
|
i && e.push(i);
|
|
815
890
|
}
|
|
@@ -819,7 +894,7 @@ class K extends O {
|
|
|
819
894
|
* Get IDs of all modified rows.
|
|
820
895
|
*/
|
|
821
896
|
get changedRowIds() {
|
|
822
|
-
return Array.from(this.#
|
|
897
|
+
return Array.from(this.#r);
|
|
823
898
|
}
|
|
824
899
|
/**
|
|
825
900
|
* Get the currently active edit row index, or -1 if not editing.
|
|
@@ -831,7 +906,7 @@ class K extends O {
|
|
|
831
906
|
* Get the currently active edit column index, or -1 if not editing.
|
|
832
907
|
*/
|
|
833
908
|
get activeEditCol() {
|
|
834
|
-
return this.#
|
|
909
|
+
return this.#c;
|
|
835
910
|
}
|
|
836
911
|
/**
|
|
837
912
|
* Check if a specific row is currently being edited.
|
|
@@ -843,7 +918,7 @@ class K extends O {
|
|
|
843
918
|
* Check if a specific cell is currently being edited.
|
|
844
919
|
*/
|
|
845
920
|
isCellEditing(e, t) {
|
|
846
|
-
return this.#
|
|
921
|
+
return this.#o.has(`${e}:${t}`);
|
|
847
922
|
}
|
|
848
923
|
/**
|
|
849
924
|
* Check if a specific row has been modified.
|
|
@@ -853,8 +928,8 @@ class K extends O {
|
|
|
853
928
|
const t = this.grid, i = t._rows[e];
|
|
854
929
|
if (!i) return !1;
|
|
855
930
|
try {
|
|
856
|
-
const
|
|
857
|
-
return
|
|
931
|
+
const n = t.getRowId?.(i);
|
|
932
|
+
return n ? this.#r.has(n) : !1;
|
|
858
933
|
} catch {
|
|
859
934
|
return !1;
|
|
860
935
|
}
|
|
@@ -864,7 +939,7 @@ class K extends O {
|
|
|
864
939
|
* @param rowId - Row ID to check
|
|
865
940
|
*/
|
|
866
941
|
isRowChangedById(e) {
|
|
867
|
-
return this.#
|
|
942
|
+
return this.#r.has(e);
|
|
868
943
|
}
|
|
869
944
|
// #region Cell Validation
|
|
870
945
|
/**
|
|
@@ -889,8 +964,8 @@ class K extends O {
|
|
|
889
964
|
* ```
|
|
890
965
|
*/
|
|
891
966
|
setInvalid(e, t, i = "") {
|
|
892
|
-
let
|
|
893
|
-
|
|
967
|
+
let n = this.#i.get(e);
|
|
968
|
+
n || (n = /* @__PURE__ */ new Map(), this.#i.set(e, n)), n.set(t, i), this.#f(e, t, !0);
|
|
894
969
|
}
|
|
895
970
|
/**
|
|
896
971
|
* Clear the invalid state for a specific cell.
|
|
@@ -899,8 +974,8 @@ class K extends O {
|
|
|
899
974
|
* @param field - The field name
|
|
900
975
|
*/
|
|
901
976
|
clearInvalid(e, t) {
|
|
902
|
-
const i = this.#
|
|
903
|
-
i && (i.delete(t), i.size === 0 && this.#
|
|
977
|
+
const i = this.#i.get(e);
|
|
978
|
+
i && (i.delete(t), i.size === 0 && this.#i.delete(e)), this.#f(e, t, !1);
|
|
904
979
|
}
|
|
905
980
|
/**
|
|
906
981
|
* Clear all invalid cells for a specific row.
|
|
@@ -908,19 +983,19 @@ class K extends O {
|
|
|
908
983
|
* @param rowId - The row ID (from getRowId)
|
|
909
984
|
*/
|
|
910
985
|
clearRowInvalid(e) {
|
|
911
|
-
const t = this.#
|
|
986
|
+
const t = this.#i.get(e);
|
|
912
987
|
if (t) {
|
|
913
988
|
const i = Array.from(t.keys());
|
|
914
|
-
this.#
|
|
989
|
+
this.#i.delete(e), i.forEach((n) => this.#f(e, n, !1));
|
|
915
990
|
}
|
|
916
991
|
}
|
|
917
992
|
/**
|
|
918
993
|
* Clear all invalid cell states across all rows.
|
|
919
994
|
*/
|
|
920
995
|
clearAllInvalid() {
|
|
921
|
-
const e = Array.from(this.#
|
|
922
|
-
this.#
|
|
923
|
-
i.forEach((
|
|
996
|
+
const e = Array.from(this.#i.entries());
|
|
997
|
+
this.#i.clear(), e.forEach(([t, i]) => {
|
|
998
|
+
i.forEach((n, r) => this.#f(t, r, !1));
|
|
924
999
|
});
|
|
925
1000
|
}
|
|
926
1001
|
/**
|
|
@@ -931,7 +1006,7 @@ class K extends O {
|
|
|
931
1006
|
* @returns True if the cell is marked as invalid
|
|
932
1007
|
*/
|
|
933
1008
|
isCellInvalid(e, t) {
|
|
934
|
-
return this.#
|
|
1009
|
+
return this.#i.get(e)?.has(t) ?? !1;
|
|
935
1010
|
}
|
|
936
1011
|
/**
|
|
937
1012
|
* Get the validation message for an invalid cell.
|
|
@@ -941,7 +1016,7 @@ class K extends O {
|
|
|
941
1016
|
* @returns The validation message, or undefined if cell is valid
|
|
942
1017
|
*/
|
|
943
1018
|
getInvalidMessage(e, t) {
|
|
944
|
-
return this.#
|
|
1019
|
+
return this.#i.get(e)?.get(t);
|
|
945
1020
|
}
|
|
946
1021
|
/**
|
|
947
1022
|
* Check if a row has any invalid cells.
|
|
@@ -950,7 +1025,7 @@ class K extends O {
|
|
|
950
1025
|
* @returns True if the row has at least one invalid cell
|
|
951
1026
|
*/
|
|
952
1027
|
hasInvalidCells(e) {
|
|
953
|
-
const t = this.#
|
|
1028
|
+
const t = this.#i.get(e);
|
|
954
1029
|
return t ? t.size > 0 : !1;
|
|
955
1030
|
}
|
|
956
1031
|
/**
|
|
@@ -960,27 +1035,27 @@ class K extends O {
|
|
|
960
1035
|
* @returns Map of field names to validation messages
|
|
961
1036
|
*/
|
|
962
1037
|
getInvalidFields(e) {
|
|
963
|
-
return new Map(this.#
|
|
1038
|
+
return new Map(this.#i.get(e) ?? []);
|
|
964
1039
|
}
|
|
965
1040
|
/**
|
|
966
1041
|
* Sync the data-invalid attribute on a cell element.
|
|
967
1042
|
*/
|
|
968
|
-
#
|
|
969
|
-
const
|
|
970
|
-
if (
|
|
971
|
-
const o =
|
|
1043
|
+
#f(e, t, i) {
|
|
1044
|
+
const n = this.grid, r = n._visibleColumns?.findIndex((d) => d.field === t);
|
|
1045
|
+
if (r === -1 || r === void 0) return;
|
|
1046
|
+
const o = n._rows?.findIndex((d) => {
|
|
972
1047
|
try {
|
|
973
|
-
return
|
|
1048
|
+
return n.getRowId?.(d) === e;
|
|
974
1049
|
} catch {
|
|
975
1050
|
return !1;
|
|
976
1051
|
}
|
|
977
1052
|
});
|
|
978
1053
|
if (o === -1 || o === void 0) return;
|
|
979
|
-
const c =
|
|
1054
|
+
const c = n.findRenderedRowElement?.(o)?.querySelector(`.cell[data-col="${r}"]`);
|
|
980
1055
|
if (c)
|
|
981
1056
|
if (i) {
|
|
982
1057
|
c.setAttribute("data-invalid", "true");
|
|
983
|
-
const d = this.#
|
|
1058
|
+
const d = this.#i.get(e)?.get(t);
|
|
984
1059
|
d && c.setAttribute("title", d);
|
|
985
1060
|
} else
|
|
986
1061
|
c.removeAttribute("data-invalid"), c.removeAttribute("title");
|
|
@@ -993,7 +1068,7 @@ class K extends O {
|
|
|
993
1068
|
*/
|
|
994
1069
|
resetChangedRows(e) {
|
|
995
1070
|
const t = this.changedRows, i = this.changedRowIds;
|
|
996
|
-
this.#
|
|
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"));
|
|
997
1072
|
}
|
|
998
1073
|
/**
|
|
999
1074
|
* Programmatically begin editing a cell.
|
|
@@ -1002,10 +1077,10 @@ class K extends O {
|
|
|
1002
1077
|
* @fires cell-commit - Emitted when the cell value is committed (on blur or Enter)
|
|
1003
1078
|
*/
|
|
1004
1079
|
beginCellEdit(e, t) {
|
|
1005
|
-
const i = this.grid,
|
|
1006
|
-
if (
|
|
1007
|
-
const o = i.findRenderedRowElement?.(e)?.querySelector(`.cell[data-col="${
|
|
1008
|
-
o && this.#
|
|
1080
|
+
const i = this.grid, n = i._visibleColumns.findIndex((a) => a.field === t);
|
|
1081
|
+
if (n === -1 || !i._visibleColumns[n]?.editable) return;
|
|
1082
|
+
const o = i.findRenderedRowElement?.(e)?.querySelector(`.cell[data-col="${n}"]`);
|
|
1083
|
+
o && this.#w(e, n, o);
|
|
1009
1084
|
}
|
|
1010
1085
|
/**
|
|
1011
1086
|
* Programmatically begin editing all editable cells in a row.
|
|
@@ -1016,19 +1091,19 @@ class K extends O {
|
|
|
1016
1091
|
beginBulkEdit(e) {
|
|
1017
1092
|
const t = this.grid;
|
|
1018
1093
|
if ((this.config.editOn ?? t.effectiveConfig?.editOn) === !1 || !t._columns?.some((o) => o.editable)) return;
|
|
1019
|
-
const
|
|
1020
|
-
if (!
|
|
1094
|
+
const r = t.findRenderedRowElement?.(e);
|
|
1095
|
+
if (!r) return;
|
|
1021
1096
|
const l = t._rows[e];
|
|
1022
|
-
this.#
|
|
1097
|
+
this.#m(e, l), Array.from(r.children).forEach((o, a) => {
|
|
1023
1098
|
const c = t._visibleColumns[a];
|
|
1024
1099
|
if (c?.editable) {
|
|
1025
1100
|
const d = o;
|
|
1026
|
-
d.classList.contains("editing") || this.#
|
|
1101
|
+
d.classList.contains("editing") || this.#g(l, e, c, a, d, !0);
|
|
1027
1102
|
}
|
|
1028
1103
|
}), setTimeout(() => {
|
|
1029
|
-
let o =
|
|
1030
|
-
if (o?.classList.contains("editing") || (o =
|
|
1031
|
-
const a = o.querySelector(
|
|
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);
|
|
1032
1107
|
try {
|
|
1033
1108
|
a?.focus({ preventScroll: !0 });
|
|
1034
1109
|
} catch {
|
|
@@ -1054,115 +1129,131 @@ class K extends O {
|
|
|
1054
1129
|
/**
|
|
1055
1130
|
* Begin editing a single cell.
|
|
1056
1131
|
*/
|
|
1057
|
-
#
|
|
1058
|
-
const
|
|
1059
|
-
!
|
|
1132
|
+
#w(e, t, i) {
|
|
1133
|
+
const n = this.grid, r = n._rows[e], l = n._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));
|
|
1135
|
+
}
|
|
1136
|
+
/**
|
|
1137
|
+
* Focus the editor input in the currently focused cell (grid mode only).
|
|
1138
|
+
* Used when pressing Enter to enter edit mode from navigation mode.
|
|
1139
|
+
*/
|
|
1140
|
+
#v() {
|
|
1141
|
+
const e = this.grid, t = e._focusRow, i = e._focusCol;
|
|
1142
|
+
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.#s = !0, l instanceof HTMLInputElement && (l.type === "text" || l.type === "number") && l.select());
|
|
1147
|
+
}
|
|
1060
1148
|
}
|
|
1061
1149
|
/**
|
|
1062
1150
|
* Handle Tab/Shift+Tab navigation while editing.
|
|
1063
1151
|
* Moves to next/previous editable cell, staying in edit mode.
|
|
1064
1152
|
* Wraps to next/previous row when reaching row boundaries.
|
|
1065
1153
|
*/
|
|
1066
|
-
#
|
|
1067
|
-
const t = this.grid, i = t._rows,
|
|
1068
|
-
if (
|
|
1069
|
-
const o =
|
|
1070
|
-
if (o >= 0 && o <
|
|
1071
|
-
t._focusCol =
|
|
1072
|
-
const d = t.findRenderedRowElement?.(
|
|
1073
|
-
d?.classList.contains("editing") && d.querySelector(
|
|
1154
|
+
#b(e) {
|
|
1155
|
+
const t = this.grid, i = t._rows, n = 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?.(n)?.querySelector(`.cell[data-col="${r[o]}"]`);
|
|
1161
|
+
d?.classList.contains("editing") && d.querySelector(v)?.focus({ preventScroll: !0 }), R(t, { forceHorizontalScroll: !0 });
|
|
1074
1162
|
return;
|
|
1075
1163
|
}
|
|
1076
|
-
const a =
|
|
1077
|
-
a >= 0 && a < i.length && (this.#
|
|
1164
|
+
const a = n + (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.#n(n, !1), t._focusRow = a, t._focusCol = e ? r[0] : r[r.length - 1], this.beginBulkEdit(a), R(t, { forceHorizontalScroll: !0 })));
|
|
1078
1169
|
}
|
|
1079
1170
|
/**
|
|
1080
1171
|
* Sync the internal grid state with the plugin's editing state.
|
|
1081
1172
|
*/
|
|
1082
|
-
#
|
|
1173
|
+
#h() {
|
|
1083
1174
|
const e = this.grid;
|
|
1084
|
-
e._activeEditRows = this.#e, e._rowEditSnapshots = this.#
|
|
1175
|
+
e._activeEditRows = this.#e, e._rowEditSnapshots = this.#l;
|
|
1085
1176
|
}
|
|
1086
1177
|
/**
|
|
1087
1178
|
* Snapshot original row data and mark as editing.
|
|
1088
1179
|
*/
|
|
1089
|
-
#
|
|
1090
|
-
this.#e !== e && (this.#
|
|
1180
|
+
#m(e, t) {
|
|
1181
|
+
this.#e !== e && (this.#l.set(e, { ...t }), this.#e = e, this.#h());
|
|
1091
1182
|
}
|
|
1092
1183
|
/**
|
|
1093
1184
|
* Exit editing for a row.
|
|
1094
1185
|
*/
|
|
1095
1186
|
#n(e, t) {
|
|
1096
1187
|
if (this.#e !== e) return;
|
|
1097
|
-
const i = this.grid,
|
|
1188
|
+
const i = this.grid, n = this.#l.get(e), r = i._rows[e], l = i.findRenderedRowElement?.(e);
|
|
1098
1189
|
let o;
|
|
1099
|
-
if (
|
|
1190
|
+
if (r)
|
|
1100
1191
|
try {
|
|
1101
|
-
o = i.getRowId?.(
|
|
1192
|
+
o = i.getRowId?.(r);
|
|
1102
1193
|
} catch {
|
|
1103
1194
|
}
|
|
1104
|
-
if (!t && l &&
|
|
1195
|
+
if (!t && l && r && l.querySelectorAll(".cell.editing").forEach((c) => {
|
|
1105
1196
|
const d = Number(c.getAttribute("data-col"));
|
|
1106
1197
|
if (isNaN(d)) return;
|
|
1107
|
-
const
|
|
1108
|
-
if (!
|
|
1198
|
+
const h = i._visibleColumns[d];
|
|
1199
|
+
if (!h || c.hasAttribute("data-editor-managed"))
|
|
1109
1200
|
return;
|
|
1110
1201
|
const u = c.querySelector("input,textarea,select");
|
|
1111
1202
|
if (u) {
|
|
1112
|
-
const m =
|
|
1113
|
-
p !== g && this.#
|
|
1203
|
+
const m = h.field, p = r[m], g = y(u, h, p);
|
|
1204
|
+
p !== g && this.#p(e, h, g, r);
|
|
1114
1205
|
}
|
|
1115
|
-
}), t &&
|
|
1116
|
-
Object.keys(
|
|
1117
|
-
|
|
1118
|
-
}), o && (this.#
|
|
1119
|
-
else if (!t &&
|
|
1120
|
-
const a = this.#
|
|
1206
|
+
}), t && n && r)
|
|
1207
|
+
Object.keys(n).forEach((a) => {
|
|
1208
|
+
r[a] = n[a];
|
|
1209
|
+
}), o && (this.#r.delete(o), this.clearRowInvalid(o));
|
|
1210
|
+
else if (!t && r) {
|
|
1211
|
+
const a = this.#C(n, r), c = o ? this.#r.has(o) : a, d = this.emitCancelable("row-commit", {
|
|
1121
1212
|
rowIndex: e,
|
|
1122
1213
|
rowId: o ?? "",
|
|
1123
|
-
row:
|
|
1124
|
-
oldValue:
|
|
1125
|
-
newValue:
|
|
1214
|
+
row: r,
|
|
1215
|
+
oldValue: n,
|
|
1216
|
+
newValue: r,
|
|
1126
1217
|
changed: c,
|
|
1127
1218
|
changedRows: this.changedRows,
|
|
1128
1219
|
changedRowIds: this.changedRowIds
|
|
1129
1220
|
});
|
|
1130
|
-
d &&
|
|
1131
|
-
|
|
1132
|
-
}), o && (this.#
|
|
1221
|
+
d && n ? (Object.keys(n).forEach((h) => {
|
|
1222
|
+
r[h] = n[h];
|
|
1223
|
+
}), o && (this.#r.delete(o), this.clearRowInvalid(o))) : !d && a && this.isAnimationEnabled && (this.#u = e);
|
|
1133
1224
|
}
|
|
1134
|
-
this.#
|
|
1135
|
-
for (const a of this.#
|
|
1136
|
-
a.startsWith(`${e}:`) && this.#
|
|
1225
|
+
this.#l.delete(e), this.#e = -1, this.#c = -1, this.#h();
|
|
1226
|
+
for (const a of this.#o)
|
|
1227
|
+
a.startsWith(`${e}:`) && this.#o.delete(a);
|
|
1137
1228
|
l && (l.querySelectorAll(".cell.editing").forEach((a) => {
|
|
1138
|
-
a.classList.remove("editing"),
|
|
1139
|
-
}), this.requestRender()), this.#
|
|
1229
|
+
a.classList.remove("editing"), F(a.parentElement);
|
|
1230
|
+
}), this.requestRender()), this.#d = !0, l || (this.#E(i), this.#d = !1);
|
|
1140
1231
|
}
|
|
1141
1232
|
/**
|
|
1142
1233
|
* Commit a single cell value change.
|
|
1143
1234
|
* Uses ID-based change tracking for stability when rows are reordered.
|
|
1144
1235
|
*/
|
|
1145
|
-
#
|
|
1146
|
-
const
|
|
1147
|
-
if (!
|
|
1148
|
-
const l = r
|
|
1236
|
+
#p(e, t, i, n) {
|
|
1237
|
+
const r = t.field;
|
|
1238
|
+
if (!C(r)) return;
|
|
1239
|
+
const l = n[r];
|
|
1149
1240
|
if (l === i) return;
|
|
1150
1241
|
const o = this.grid;
|
|
1151
1242
|
let a;
|
|
1152
1243
|
try {
|
|
1153
|
-
a = this.grid.getRowId(
|
|
1244
|
+
a = this.grid.getRowId(n);
|
|
1154
1245
|
} catch {
|
|
1155
1246
|
}
|
|
1156
|
-
const c = a ? !this.#
|
|
1157
|
-
let
|
|
1247
|
+
const c = a ? !this.#r.has(a) : !0, d = a ? (g) => this.grid.updateRow(a, g, "cascade") : A;
|
|
1248
|
+
let h = !1;
|
|
1158
1249
|
const u = a ? (g) => {
|
|
1159
|
-
|
|
1250
|
+
h = !0, this.setInvalid(a, r, g ?? "");
|
|
1160
1251
|
} : () => {
|
|
1161
1252
|
};
|
|
1162
1253
|
if (this.emitCancelable("cell-commit", {
|
|
1163
|
-
row:
|
|
1254
|
+
row: n,
|
|
1164
1255
|
rowId: a ?? "",
|
|
1165
|
-
field:
|
|
1256
|
+
field: r,
|
|
1166
1257
|
oldValue: l,
|
|
1167
1258
|
value: i,
|
|
1168
1259
|
rowIndex: e,
|
|
@@ -1172,9 +1263,9 @@ class K extends O {
|
|
|
1172
1263
|
updateRow: d,
|
|
1173
1264
|
setInvalid: u
|
|
1174
1265
|
})) return;
|
|
1175
|
-
a && !
|
|
1266
|
+
a && !h && this.isCellInvalid(a, r) && this.clearInvalid(a, r), n[r] = i, a && this.#r.add(a), this.#h(), this.emitPluginEvent("cell-edit-committed", {
|
|
1176
1267
|
rowIndex: e,
|
|
1177
|
-
field:
|
|
1268
|
+
field: r,
|
|
1178
1269
|
oldValue: l,
|
|
1179
1270
|
newValue: i
|
|
1180
1271
|
});
|
|
@@ -1184,124 +1275,134 @@ class K extends O {
|
|
|
1184
1275
|
/**
|
|
1185
1276
|
* Inject an editor into a cell.
|
|
1186
1277
|
*/
|
|
1187
|
-
#
|
|
1188
|
-
if (!i.editable ||
|
|
1278
|
+
#g(e, t, i, n, r, l) {
|
|
1279
|
+
if (!i.editable || r.classList.contains("editing")) return;
|
|
1189
1280
|
let o;
|
|
1190
1281
|
try {
|
|
1191
1282
|
o = this.grid.getRowId(e);
|
|
1192
1283
|
} catch {
|
|
1193
1284
|
}
|
|
1194
|
-
const a = o ? (
|
|
1195
|
-
|
|
1196
|
-
const d =
|
|
1197
|
-
d &&
|
|
1198
|
-
let
|
|
1199
|
-
const u = (
|
|
1200
|
-
|
|
1285
|
+
const a = o ? (f) => this.grid.updateRow(o, f, "cascade") : A, c = C(i.field) ? e[i.field] : void 0;
|
|
1286
|
+
r.classList.add("editing"), this.#o.add(`${t}:${n}`);
|
|
1287
|
+
const d = r.parentElement;
|
|
1288
|
+
d && $(d);
|
|
1289
|
+
let h = !1;
|
|
1290
|
+
const u = (f) => {
|
|
1291
|
+
h || !this.#t && this.#e === -1 || this.#p(t, i, f, e);
|
|
1201
1292
|
}, m = () => {
|
|
1202
|
-
|
|
1293
|
+
h = !0, C(i.field) && (e[i.field] = c);
|
|
1203
1294
|
}, p = document.createElement("div");
|
|
1204
|
-
p.className = "tbw-editor-host",
|
|
1205
|
-
if (
|
|
1206
|
-
if (this
|
|
1295
|
+
p.className = "tbw-editor-host", r.innerHTML = "", r.appendChild(p), p.addEventListener("keydown", (f) => {
|
|
1296
|
+
if (f.key === "Enter") {
|
|
1297
|
+
if (this.#t) {
|
|
1298
|
+
f.stopPropagation(), f.preventDefault();
|
|
1299
|
+
const E = p.querySelector("input,textarea,select");
|
|
1300
|
+
E && u(y(E, i, c));
|
|
1301
|
+
return;
|
|
1302
|
+
}
|
|
1303
|
+
if (this.config.onBeforeEditClose && this.config.onBeforeEditClose(f) === !1)
|
|
1207
1304
|
return;
|
|
1208
|
-
|
|
1305
|
+
f.stopPropagation(), f.preventDefault(), h = !0, this.#n(t, !1);
|
|
1209
1306
|
}
|
|
1210
|
-
if (
|
|
1211
|
-
if (this
|
|
1307
|
+
if (f.key === "Escape") {
|
|
1308
|
+
if (this.#t) {
|
|
1309
|
+
f.stopPropagation(), f.preventDefault();
|
|
1310
|
+
return;
|
|
1311
|
+
}
|
|
1312
|
+
if (this.config.onBeforeEditClose && this.config.onBeforeEditClose(f) === !1)
|
|
1212
1313
|
return;
|
|
1213
|
-
|
|
1314
|
+
f.stopPropagation(), f.preventDefault(), m(), this.#n(t, !0);
|
|
1214
1315
|
}
|
|
1215
1316
|
});
|
|
1216
|
-
const g = i,
|
|
1217
|
-
if (
|
|
1218
|
-
this.#
|
|
1219
|
-
else if (typeof
|
|
1220
|
-
const
|
|
1221
|
-
|
|
1222
|
-
p.querySelector(
|
|
1317
|
+
const g = i, b = g.__editorTemplate, w = G(this.grid, g) ?? z(i), _ = c;
|
|
1318
|
+
if (w === "template" && b)
|
|
1319
|
+
this.#y(p, g, e, c, u, m, l, t);
|
|
1320
|
+
else if (typeof w == "string") {
|
|
1321
|
+
const f = document.createElement(w);
|
|
1322
|
+
f.value = _, f.addEventListener("change", () => u(f.value)), p.appendChild(f), l || queueMicrotask(() => {
|
|
1323
|
+
p.querySelector(v)?.focus({ preventScroll: !0 });
|
|
1223
1324
|
});
|
|
1224
|
-
} else if (typeof
|
|
1225
|
-
const
|
|
1325
|
+
} else if (typeof w == "function") {
|
|
1326
|
+
const f = {
|
|
1226
1327
|
row: e,
|
|
1227
1328
|
rowId: o ?? "",
|
|
1228
|
-
value:
|
|
1329
|
+
value: _,
|
|
1229
1330
|
field: i.field,
|
|
1230
1331
|
column: i,
|
|
1231
1332
|
commit: u,
|
|
1232
1333
|
cancel: m,
|
|
1233
1334
|
updateRow: a
|
|
1234
|
-
},
|
|
1235
|
-
typeof
|
|
1236
|
-
p.querySelector(
|
|
1335
|
+
}, E = w(f);
|
|
1336
|
+
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(() => {
|
|
1337
|
+
p.querySelector(v)?.focus({ preventScroll: !0 });
|
|
1237
1338
|
});
|
|
1238
|
-
} else if (
|
|
1239
|
-
const
|
|
1240
|
-
|
|
1241
|
-
const
|
|
1339
|
+
} else if (w && typeof w == "object") {
|
|
1340
|
+
const f = document.createElement("div");
|
|
1341
|
+
f.setAttribute("data-external-editor", ""), f.setAttribute("data-field", i.field), p.appendChild(f), r.setAttribute("data-editor-managed", "");
|
|
1342
|
+
const E = {
|
|
1242
1343
|
row: e,
|
|
1243
1344
|
rowId: o ?? "",
|
|
1244
|
-
value:
|
|
1345
|
+
value: _,
|
|
1245
1346
|
field: i.field,
|
|
1246
1347
|
column: i,
|
|
1247
1348
|
commit: u,
|
|
1248
1349
|
cancel: m,
|
|
1249
1350
|
updateRow: a
|
|
1250
1351
|
};
|
|
1251
|
-
if (
|
|
1352
|
+
if (w.mount)
|
|
1252
1353
|
try {
|
|
1253
|
-
|
|
1254
|
-
} catch (
|
|
1255
|
-
console.warn(`[tbw-grid] External editor mount error for column '${i.field}':`,
|
|
1354
|
+
w.mount({ placeholder: f, context: E, spec: w });
|
|
1355
|
+
} catch (S) {
|
|
1356
|
+
console.warn(`[tbw-grid] External editor mount error for column '${i.field}':`, S);
|
|
1256
1357
|
}
|
|
1257
1358
|
else
|
|
1258
1359
|
this.grid.dispatchEvent(
|
|
1259
|
-
new CustomEvent("mount-external-editor", { detail: { placeholder:
|
|
1360
|
+
new CustomEvent("mount-external-editor", { detail: { placeholder: f, spec: w, context: E } })
|
|
1260
1361
|
);
|
|
1261
1362
|
}
|
|
1262
1363
|
}
|
|
1263
1364
|
/**
|
|
1264
1365
|
* Render a template-based editor.
|
|
1265
1366
|
*/
|
|
1266
|
-
#
|
|
1367
|
+
#y(e, t, i, n, r, l, o, a) {
|
|
1267
1368
|
const c = t.__editorTemplate;
|
|
1268
1369
|
if (!c) return;
|
|
1269
|
-
const d = c.cloneNode(!0),
|
|
1270
|
-
|
|
1370
|
+
const d = c.cloneNode(!0), h = t.__compiledEditor;
|
|
1371
|
+
h ? d.innerHTML = h({
|
|
1271
1372
|
row: i,
|
|
1272
|
-
value:
|
|
1373
|
+
value: n,
|
|
1273
1374
|
field: t.field,
|
|
1274
1375
|
column: t,
|
|
1275
|
-
commit:
|
|
1376
|
+
commit: r,
|
|
1276
1377
|
cancel: l
|
|
1277
1378
|
}) : d.querySelectorAll("*").forEach((m) => {
|
|
1278
|
-
m.childNodes.length === 1 && m.firstChild?.nodeType === Node.TEXT_NODE && (m.textContent = m.textContent?.replace(/{{\s*value\s*}}/g,
|
|
1279
|
-
if (!
|
|
1280
|
-
const
|
|
1281
|
-
return
|
|
1379
|
+
m.childNodes.length === 1 && m.firstChild?.nodeType === Node.TEXT_NODE && (m.textContent = m.textContent?.replace(/{{\s*value\s*}}/g, n == null ? "" : String(n)).replace(/{{\s*row\.([a-zA-Z0-9_]+)\s*}}/g, (p, g) => {
|
|
1380
|
+
if (!C(g)) return "";
|
|
1381
|
+
const b = i[g];
|
|
1382
|
+
return b == null ? "" : String(b);
|
|
1282
1383
|
}) || "");
|
|
1283
1384
|
});
|
|
1284
1385
|
const u = d.querySelector(
|
|
1285
1386
|
"input,textarea,select"
|
|
1286
1387
|
);
|
|
1287
1388
|
if (u) {
|
|
1288
|
-
u instanceof HTMLInputElement && u.type === "checkbox" ? u.checked = !!
|
|
1389
|
+
u instanceof HTMLInputElement && u.type === "checkbox" ? u.checked = !!n : u.value = String(n ?? "");
|
|
1289
1390
|
let m = !1;
|
|
1290
1391
|
u.addEventListener("blur", () => {
|
|
1291
|
-
m ||
|
|
1392
|
+
m || r(y(u, t, n));
|
|
1292
1393
|
}), u.addEventListener("keydown", (p) => {
|
|
1293
1394
|
const g = p;
|
|
1294
1395
|
if (g.key === "Enter") {
|
|
1295
1396
|
if (this.config.onBeforeEditClose && this.config.onBeforeEditClose(g) === !1)
|
|
1296
1397
|
return;
|
|
1297
|
-
g.stopPropagation(), g.preventDefault(), m = !0,
|
|
1398
|
+
g.stopPropagation(), g.preventDefault(), m = !0, r(y(u, t, n)), this.#n(a, !1);
|
|
1298
1399
|
}
|
|
1299
1400
|
if (g.key === "Escape") {
|
|
1300
1401
|
if (this.config.onBeforeEditClose && this.config.onBeforeEditClose(g) === !1)
|
|
1301
1402
|
return;
|
|
1302
1403
|
g.stopPropagation(), g.preventDefault(), l(), this.#n(a, !0);
|
|
1303
1404
|
}
|
|
1304
|
-
}), u instanceof HTMLInputElement && u.type === "checkbox" && u.addEventListener("change", () =>
|
|
1405
|
+
}), u instanceof HTMLInputElement && u.type === "checkbox" && u.addEventListener("change", () => r(u.checked)), o || setTimeout(() => u.focus({ preventScroll: !0 }), 0);
|
|
1305
1406
|
}
|
|
1306
1407
|
e.appendChild(d);
|
|
1307
1408
|
}
|
|
@@ -1309,27 +1410,27 @@ class K extends O {
|
|
|
1309
1410
|
* Compare snapshot vs current row to detect if any values changed during this edit session.
|
|
1310
1411
|
* Uses shallow comparison of all properties.
|
|
1311
1412
|
*/
|
|
1312
|
-
#
|
|
1413
|
+
#C(e, t) {
|
|
1313
1414
|
if (!e) return !1;
|
|
1314
|
-
const i = e,
|
|
1315
|
-
for (const l of
|
|
1316
|
-
if (i[l] !==
|
|
1415
|
+
const i = e, n = t, r = /* @__PURE__ */ new Set([...Object.keys(i), ...Object.keys(n)]);
|
|
1416
|
+
for (const l of r)
|
|
1417
|
+
if (i[l] !== n[l])
|
|
1317
1418
|
return !0;
|
|
1318
1419
|
return !1;
|
|
1319
1420
|
}
|
|
1320
1421
|
/**
|
|
1321
1422
|
* Restore focus to cell after exiting edit mode.
|
|
1322
1423
|
*/
|
|
1323
|
-
#
|
|
1424
|
+
#E(e) {
|
|
1324
1425
|
queueMicrotask(() => {
|
|
1325
1426
|
try {
|
|
1326
|
-
const t = e._focusRow, i = e._focusCol,
|
|
1327
|
-
if (
|
|
1427
|
+
const t = e._focusRow, i = e._focusCol, n = e.findRenderedRowElement?.(t);
|
|
1428
|
+
if (n) {
|
|
1328
1429
|
Array.from(e._bodyEl.querySelectorAll(".cell-focus")).forEach(
|
|
1329
1430
|
(l) => l.classList.remove("cell-focus")
|
|
1330
1431
|
);
|
|
1331
|
-
const
|
|
1332
|
-
|
|
1432
|
+
const r = n.querySelector(`.cell[data-row="${t}"][data-col="${i}"]`);
|
|
1433
|
+
r && (r.classList.add("cell-focus"), r.setAttribute("aria-selected", "true"), r.hasAttribute("tabindex") || r.setAttribute("tabindex", "-1"), r.focus({ preventScroll: !0 }));
|
|
1333
1434
|
}
|
|
1334
1435
|
} catch {
|
|
1335
1436
|
}
|
|
@@ -1338,7 +1439,7 @@ class K extends O {
|
|
|
1338
1439
|
// #endregion
|
|
1339
1440
|
}
|
|
1340
1441
|
export {
|
|
1341
|
-
|
|
1342
|
-
|
|
1442
|
+
W as EditingPlugin,
|
|
1443
|
+
z as defaultEditorFor
|
|
1343
1444
|
};
|
|
1344
1445
|
//# sourceMappingURL=index.js.map
|