@toolbox-web/grid 0.4.0 → 0.4.2
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 +10 -13
- package/all.js +1124 -1047
- package/all.js.map +1 -1
- package/index.js +688 -515
- package/index.js.map +1 -1
- package/lib/core/grid.d.ts +10 -0
- package/lib/core/grid.d.ts.map +1 -1
- package/lib/core/internal/config-manager.d.ts +1 -0
- package/lib/core/internal/config-manager.d.ts.map +1 -1
- package/lib/core/internal/keyboard.d.ts.map +1 -1
- package/lib/core/internal/utils.d.ts +1 -0
- package/lib/core/internal/utils.d.ts.map +1 -1
- package/lib/core/internal/validate-config.d.ts +14 -0
- package/lib/core/internal/validate-config.d.ts.map +1 -1
- package/lib/core/plugin/base-plugin.d.ts +105 -1
- package/lib/core/plugin/base-plugin.d.ts.map +1 -1
- package/lib/core/plugin/expander-column.d.ts +51 -0
- package/lib/core/plugin/expander-column.d.ts.map +1 -0
- package/lib/core/plugin/index.d.ts +1 -0
- package/lib/core/plugin/index.d.ts.map +1 -1
- package/lib/core/plugin/plugin-manager.d.ts +1 -1
- package/lib/core/plugin/plugin-manager.d.ts.map +1 -1
- package/lib/core/plugin/types.d.ts +117 -1
- package/lib/core/plugin/types.d.ts.map +1 -1
- package/lib/core/types.d.ts +4 -2
- package/lib/core/types.d.ts.map +1 -1
- package/lib/plugins/clipboard/ClipboardPlugin.d.ts +9 -2
- package/lib/plugins/clipboard/ClipboardPlugin.d.ts.map +1 -1
- package/lib/plugins/clipboard/index.d.ts +1 -1
- package/lib/plugins/clipboard/index.d.ts.map +1 -1
- package/lib/plugins/clipboard/index.js +303 -185
- package/lib/plugins/clipboard/index.js.map +1 -1
- package/lib/plugins/clipboard/types.d.ts +72 -2
- package/lib/plugins/clipboard/types.d.ts.map +1 -1
- package/lib/plugins/column-virtualization/ColumnVirtualizationPlugin.d.ts +0 -1
- package/lib/plugins/column-virtualization/ColumnVirtualizationPlugin.d.ts.map +1 -1
- package/lib/plugins/column-virtualization/index.js +116 -24
- package/lib/plugins/column-virtualization/index.js.map +1 -1
- package/lib/plugins/context-menu/ContextMenuPlugin.d.ts +0 -1
- package/lib/plugins/context-menu/ContextMenuPlugin.d.ts.map +1 -1
- package/lib/plugins/context-menu/index.js +164 -72
- package/lib/plugins/context-menu/index.js.map +1 -1
- package/lib/plugins/editing/EditingPlugin.d.ts +1 -7
- package/lib/plugins/editing/EditingPlugin.d.ts.map +1 -1
- package/lib/plugins/editing/index.js +213 -133
- package/lib/plugins/editing/index.js.map +1 -1
- package/lib/plugins/export/ExportPlugin.d.ts +0 -1
- package/lib/plugins/export/ExportPlugin.d.ts.map +1 -1
- package/lib/plugins/export/index.js +195 -103
- package/lib/plugins/export/index.js.map +1 -1
- package/lib/plugins/filtering/FilteringPlugin.d.ts +5 -2
- package/lib/plugins/filtering/FilteringPlugin.d.ts.map +1 -1
- package/lib/plugins/filtering/index.js +145 -43
- package/lib/plugins/filtering/index.js.map +1 -1
- package/lib/plugins/grouping-columns/GroupingColumnsPlugin.d.ts +1 -2
- package/lib/plugins/grouping-columns/GroupingColumnsPlugin.d.ts.map +1 -1
- package/lib/plugins/grouping-columns/grouping-columns.d.ts +1 -1
- package/lib/plugins/grouping-columns/grouping-columns.d.ts.map +1 -1
- package/lib/plugins/grouping-columns/index.js +162 -68
- package/lib/plugins/grouping-columns/index.js.map +1 -1
- package/lib/plugins/grouping-rows/GroupingRowsPlugin.d.ts +14 -2
- package/lib/plugins/grouping-rows/GroupingRowsPlugin.d.ts.map +1 -1
- package/lib/plugins/grouping-rows/index.js +246 -138
- package/lib/plugins/grouping-rows/index.js.map +1 -1
- package/lib/plugins/master-detail/MasterDetailPlugin.d.ts +13 -11
- package/lib/plugins/master-detail/MasterDetailPlugin.d.ts.map +1 -1
- package/lib/plugins/master-detail/index.js +281 -196
- package/lib/plugins/master-detail/index.js.map +1 -1
- package/lib/plugins/master-detail/types.d.ts +0 -10
- package/lib/plugins/master-detail/types.d.ts.map +1 -1
- package/lib/plugins/multi-sort/MultiSortPlugin.d.ts +1 -2
- package/lib/plugins/multi-sort/MultiSortPlugin.d.ts.map +1 -1
- package/lib/plugins/multi-sort/index.js +121 -31
- package/lib/plugins/multi-sort/index.js.map +1 -1
- package/lib/plugins/pinned-columns/PinnedColumnsPlugin.d.ts +0 -1
- package/lib/plugins/pinned-columns/PinnedColumnsPlugin.d.ts.map +1 -1
- package/lib/plugins/pinned-columns/index.js +144 -52
- package/lib/plugins/pinned-columns/index.js.map +1 -1
- package/lib/plugins/pinned-rows/PinnedRowsPlugin.d.ts +1 -2
- package/lib/plugins/pinned-rows/PinnedRowsPlugin.d.ts.map +1 -1
- package/lib/plugins/pinned-rows/index.js +178 -88
- package/lib/plugins/pinned-rows/index.js.map +1 -1
- package/lib/plugins/pivot/PivotPlugin.d.ts +26 -4
- package/lib/plugins/pivot/PivotPlugin.d.ts.map +1 -1
- package/lib/plugins/pivot/index.js +414 -310
- package/lib/plugins/pivot/index.js.map +1 -1
- package/lib/plugins/pivot/pivot-rows.d.ts +2 -1
- package/lib/plugins/pivot/pivot-rows.d.ts.map +1 -1
- package/lib/plugins/reorder/ReorderPlugin.d.ts +13 -10
- package/lib/plugins/reorder/ReorderPlugin.d.ts.map +1 -1
- package/lib/plugins/reorder/index.js +304 -226
- package/lib/plugins/reorder/index.js.map +1 -1
- package/lib/plugins/selection/SelectionPlugin.d.ts +21 -3
- package/lib/plugins/selection/SelectionPlugin.d.ts.map +1 -1
- package/lib/plugins/selection/index.d.ts +2 -2
- package/lib/plugins/selection/index.d.ts.map +1 -1
- package/lib/plugins/selection/index.js +292 -145
- package/lib/plugins/selection/index.js.map +1 -1
- package/lib/plugins/selection/types.d.ts +24 -0
- package/lib/plugins/selection/types.d.ts.map +1 -1
- package/lib/plugins/server-side/ServerSidePlugin.d.ts +0 -1
- package/lib/plugins/server-side/ServerSidePlugin.d.ts.map +1 -1
- package/lib/plugins/server-side/index.js +95 -3
- package/lib/plugins/server-side/index.js.map +1 -1
- package/lib/plugins/tree/TreePlugin.d.ts +5 -1
- package/lib/plugins/tree/TreePlugin.d.ts.map +1 -1
- package/lib/plugins/tree/index.js +213 -112
- package/lib/plugins/tree/index.js.map +1 -1
- package/lib/plugins/tree/types.d.ts +0 -10
- package/lib/plugins/tree/types.d.ts.map +1 -1
- package/lib/plugins/undo-redo/UndoRedoPlugin.d.ts +7 -2
- package/lib/plugins/undo-redo/UndoRedoPlugin.d.ts.map +1 -1
- package/lib/plugins/undo-redo/index.js +112 -12
- package/lib/plugins/undo-redo/index.js.map +1 -1
- package/lib/plugins/visibility/VisibilityPlugin.d.ts +14 -5
- package/lib/plugins/visibility/VisibilityPlugin.d.ts.map +1 -1
- package/lib/plugins/visibility/index.js +168 -65
- package/lib/plugins/visibility/index.js.map +1 -1
- package/package.json +1 -1
- package/umd/grid.all.umd.js +21 -17
- package/umd/grid.all.umd.js.map +1 -1
- package/umd/grid.umd.js +14 -8
- package/umd/grid.umd.js.map +1 -1
- package/umd/plugins/clipboard.umd.js +5 -7
- package/umd/plugins/clipboard.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/export.umd.js +1 -1
- package/umd/plugins/export.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/grouping-rows.umd.js +1 -1
- 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/multi-sort.umd.js +1 -1
- package/umd/plugins/multi-sort.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/pinned-rows.umd.js +1 -1
- package/umd/plugins/pinned-rows.umd.js.map +1 -1
- package/umd/plugins/pivot.umd.js +1 -1
- package/umd/plugins/pivot.umd.js.map +1 -1
- package/umd/plugins/reorder.umd.js +1 -1
- package/umd/plugins/reorder.umd.js.map +1 -1
- package/umd/plugins/selection.umd.js +1 -1
- package/umd/plugins/selection.umd.js.map +1 -1
- package/umd/plugins/server-side.umd.js +1 -1
- package/umd/plugins/server-side.umd.js.map +1 -1
- package/umd/plugins/tree.umd.js +1 -1
- package/umd/plugins/tree.umd.js.map +1 -1
- package/umd/plugins/undo-redo.umd.js +1 -1
- package/umd/plugins/undo-redo.umd.js.map +1 -1
- package/umd/plugins/visibility.umd.js +1 -1
- package/umd/plugins/visibility.umd.js.map +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const
|
|
1
|
+
const _ = {
|
|
2
2
|
expand: "▶",
|
|
3
3
|
collapse: "▼",
|
|
4
4
|
sortAsc: "▲",
|
|
@@ -8,9 +8,28 @@ const R = {
|
|
|
8
8
|
dragHandle: "⋮⋮",
|
|
9
9
|
toolPanel: "☰"
|
|
10
10
|
};
|
|
11
|
-
class
|
|
12
|
-
/**
|
|
13
|
-
|
|
11
|
+
class S {
|
|
12
|
+
/**
|
|
13
|
+
* Plugin dependencies - declare other plugins this one requires.
|
|
14
|
+
*
|
|
15
|
+
* Dependencies are validated when the plugin is attached.
|
|
16
|
+
* Required dependencies throw an error if missing.
|
|
17
|
+
* Optional dependencies log an info message if missing.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```typescript
|
|
21
|
+
* static readonly dependencies: PluginDependency[] = [
|
|
22
|
+
* { name: 'editing', required: true, reason: 'Tracks cell edits for undo/redo' },
|
|
23
|
+
* { name: 'selection', required: false, reason: 'Enables selection-based undo' },
|
|
24
|
+
* ];
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
static dependencies;
|
|
28
|
+
/**
|
|
29
|
+
* Plugin version - defaults to grid version for built-in plugins.
|
|
30
|
+
* Third-party plugins can override with their own semver.
|
|
31
|
+
*/
|
|
32
|
+
version = typeof __GRID_VERSION__ < "u" ? __GRID_VERSION__ : "dev";
|
|
14
33
|
/** CSS styles to inject into the grid's shadow DOM */
|
|
15
34
|
styles;
|
|
16
35
|
/** Custom cell renderers keyed by type name */
|
|
@@ -97,12 +116,28 @@ class _ {
|
|
|
97
116
|
emit(e, t) {
|
|
98
117
|
this.grid?.dispatchEvent?.(new CustomEvent(e, { detail: t, bubbles: !0 }));
|
|
99
118
|
}
|
|
119
|
+
/**
|
|
120
|
+
* Emit a cancelable custom event from the grid.
|
|
121
|
+
* @returns `true` if the event was cancelled (preventDefault called), `false` otherwise
|
|
122
|
+
*/
|
|
123
|
+
emitCancelable(e, t) {
|
|
124
|
+
const i = new CustomEvent(e, { detail: t, bubbles: !0, cancelable: !0 });
|
|
125
|
+
return this.grid?.dispatchEvent?.(i), i.defaultPrevented;
|
|
126
|
+
}
|
|
100
127
|
/**
|
|
101
128
|
* Request a re-render of the grid.
|
|
102
129
|
*/
|
|
103
130
|
requestRender() {
|
|
104
131
|
this.grid?.requestRender?.();
|
|
105
132
|
}
|
|
133
|
+
/**
|
|
134
|
+
* Request a re-render and restore focus styling afterward.
|
|
135
|
+
* Use this when a plugin action (like expand/collapse) triggers a render
|
|
136
|
+
* but needs to maintain keyboard navigation focus.
|
|
137
|
+
*/
|
|
138
|
+
requestRenderWithFocus() {
|
|
139
|
+
this.grid?.requestRenderWithFocus?.();
|
|
140
|
+
}
|
|
106
141
|
/**
|
|
107
142
|
* Request a lightweight style update without rebuilding DOM.
|
|
108
143
|
* Use this instead of requestRender() when only CSS classes need updating.
|
|
@@ -136,6 +171,19 @@ class _ {
|
|
|
136
171
|
get visibleColumns() {
|
|
137
172
|
return this.grid?._visibleColumns ?? [];
|
|
138
173
|
}
|
|
174
|
+
/**
|
|
175
|
+
* Get the grid as an HTMLElement for direct DOM operations.
|
|
176
|
+
* Use sparingly - prefer the typed GridElementRef API when possible.
|
|
177
|
+
*
|
|
178
|
+
* @example
|
|
179
|
+
* ```ts
|
|
180
|
+
* const width = this.gridElement.clientWidth;
|
|
181
|
+
* this.gridElement.classList.add('my-plugin-active');
|
|
182
|
+
* ```
|
|
183
|
+
*/
|
|
184
|
+
get gridElement() {
|
|
185
|
+
return this.grid;
|
|
186
|
+
}
|
|
139
187
|
/**
|
|
140
188
|
* Get the shadow root of the grid.
|
|
141
189
|
*/
|
|
@@ -168,8 +216,53 @@ class _ {
|
|
|
168
216
|
*/
|
|
169
217
|
get gridIcons() {
|
|
170
218
|
const e = this.grid?.gridConfig?.icons ?? {};
|
|
171
|
-
return { ...
|
|
219
|
+
return { ..._, ...e };
|
|
172
220
|
}
|
|
221
|
+
// #region Animation Helpers
|
|
222
|
+
/**
|
|
223
|
+
* Check if animations are enabled at the grid level.
|
|
224
|
+
* Respects gridConfig.animation.mode and the CSS variable set by the grid.
|
|
225
|
+
*
|
|
226
|
+
* Plugins should use this to skip animations when:
|
|
227
|
+
* - Animation mode is 'off' or `false`
|
|
228
|
+
* - User prefers reduced motion and mode is 'reduced-motion' (default)
|
|
229
|
+
*
|
|
230
|
+
* @example
|
|
231
|
+
* ```ts
|
|
232
|
+
* private get animationStyle(): 'slide' | 'fade' | false {
|
|
233
|
+
* if (!this.isAnimationEnabled) return false;
|
|
234
|
+
* return this.config.animation ?? 'slide';
|
|
235
|
+
* }
|
|
236
|
+
* ```
|
|
237
|
+
*/
|
|
238
|
+
get isAnimationEnabled() {
|
|
239
|
+
const e = this.grid?.effectiveConfig?.animation?.mode ?? "reduced-motion";
|
|
240
|
+
if (e === !1 || e === "off") return !1;
|
|
241
|
+
if (e === !0 || e === "on") return !0;
|
|
242
|
+
const t = this.shadowRoot?.host;
|
|
243
|
+
return t ? getComputedStyle(t).getPropertyValue("--tbw-animation-enabled").trim() !== "0" : !0;
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Get the animation duration in milliseconds from CSS variable.
|
|
247
|
+
* Falls back to 200ms if not set.
|
|
248
|
+
*
|
|
249
|
+
* Plugins can use this for their animation timing to stay consistent
|
|
250
|
+
* with the grid-level animation.duration setting.
|
|
251
|
+
*
|
|
252
|
+
* @example
|
|
253
|
+
* ```ts
|
|
254
|
+
* element.animate(keyframes, { duration: this.animationDuration });
|
|
255
|
+
* ```
|
|
256
|
+
*/
|
|
257
|
+
get animationDuration() {
|
|
258
|
+
const e = this.shadowRoot?.host;
|
|
259
|
+
if (e) {
|
|
260
|
+
const t = getComputedStyle(e).getPropertyValue("--tbw-animation-duration").trim(), i = parseInt(t, 10);
|
|
261
|
+
if (!isNaN(i)) return i;
|
|
262
|
+
}
|
|
263
|
+
return 200;
|
|
264
|
+
}
|
|
265
|
+
// #endregion
|
|
173
266
|
/**
|
|
174
267
|
* Resolve an icon value to string or HTMLElement.
|
|
175
268
|
* Checks plugin config first, then grid-level icons, then defaults.
|
|
@@ -199,8 +292,8 @@ class _ {
|
|
|
199
292
|
}
|
|
200
293
|
// #endregion
|
|
201
294
|
}
|
|
202
|
-
function
|
|
203
|
-
switch (
|
|
295
|
+
function L(l) {
|
|
296
|
+
switch (l.type) {
|
|
204
297
|
case "number":
|
|
205
298
|
return (e) => {
|
|
206
299
|
const t = document.createElement("input");
|
|
@@ -230,7 +323,7 @@ function k(f) {
|
|
|
230
323
|
const c = document.createElement("option");
|
|
231
324
|
c.value = String(r.value), c.textContent = r.label, (i.multi && Array.isArray(e.value) && e.value.includes(r.value) || !i.multi && e.value === r.value) && (c.selected = !0), t.appendChild(c);
|
|
232
325
|
});
|
|
233
|
-
const
|
|
326
|
+
const o = () => {
|
|
234
327
|
if (i.multi) {
|
|
235
328
|
const r = [];
|
|
236
329
|
Array.from(t.selectedOptions).forEach((c) => {
|
|
@@ -239,7 +332,7 @@ function k(f) {
|
|
|
239
332
|
} else
|
|
240
333
|
e.commit(t.value);
|
|
241
334
|
};
|
|
242
|
-
return t.addEventListener("change",
|
|
335
|
+
return t.addEventListener("change", o), t.addEventListener("blur", o), t.addEventListener("keydown", (r) => {
|
|
243
336
|
r.key === "Escape" && e.cancel();
|
|
244
337
|
}), t;
|
|
245
338
|
};
|
|
@@ -253,30 +346,30 @@ function k(f) {
|
|
|
253
346
|
}
|
|
254
347
|
}
|
|
255
348
|
const C = 'input,select,textarea,[contenteditable="true"],[contenteditable=""],[tabindex]:not([tabindex="-1"])';
|
|
256
|
-
function b(
|
|
257
|
-
return !(typeof
|
|
349
|
+
function b(l) {
|
|
350
|
+
return !(typeof l != "string" || l === "__proto__" || l === "constructor" || l === "prototype");
|
|
351
|
+
}
|
|
352
|
+
function T(l) {
|
|
353
|
+
return (l.__editingCellCount ?? 0) > 0;
|
|
258
354
|
}
|
|
259
|
-
function
|
|
260
|
-
|
|
355
|
+
function k(l) {
|
|
356
|
+
const e = (l.__editingCellCount ?? 0) + 1;
|
|
357
|
+
l.__editingCellCount = e, l.setAttribute("data-has-editing", "");
|
|
261
358
|
}
|
|
262
|
-
function
|
|
263
|
-
|
|
264
|
-
f.__editingCellCount = e, f.setAttribute("data-has-editing", "");
|
|
359
|
+
function A(l) {
|
|
360
|
+
l.__editingCellCount = 0, l.removeAttribute("data-has-editing");
|
|
265
361
|
}
|
|
266
|
-
function
|
|
267
|
-
|
|
362
|
+
function y(l, e) {
|
|
363
|
+
return l instanceof HTMLInputElement ? l.type === "checkbox" ? l.checked : l.type === "number" ? l.value === "" ? null : Number(l.value) : l.type === "date" ? l.valueAsDate : l.value : e?.type === "number" && l.value !== "" ? Number(l.value) : l.value;
|
|
268
364
|
}
|
|
269
|
-
function
|
|
270
|
-
const i =
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
i.addEventListener("
|
|
274
|
-
t(s());
|
|
275
|
-
}), i instanceof HTMLInputElement && i.type === "checkbox" ? i.addEventListener("change", () => t(i.checked)) : i instanceof HTMLSelectElement && i.addEventListener("change", () => t(s()));
|
|
365
|
+
function q(l, e, t) {
|
|
366
|
+
const i = l.querySelector("input,textarea,select");
|
|
367
|
+
i && (i.addEventListener("blur", () => {
|
|
368
|
+
t(y(i, e));
|
|
369
|
+
}), i instanceof HTMLInputElement && i.type === "checkbox" ? i.addEventListener("change", () => t(i.checked)) : i instanceof HTMLSelectElement && i.addEventListener("change", () => t(y(i, e))));
|
|
276
370
|
}
|
|
277
|
-
class
|
|
371
|
+
class O extends S {
|
|
278
372
|
name = "editing";
|
|
279
|
-
version = "1.0.0";
|
|
280
373
|
get defaultConfig() {
|
|
281
374
|
return {
|
|
282
375
|
editOn: "click"
|
|
@@ -328,15 +421,6 @@ class q extends _ {
|
|
|
328
421
|
this.#e = -1, this.#r = -1, this.#s.clear(), this.#t.clear(), this.#n.clear(), super.detach();
|
|
329
422
|
}
|
|
330
423
|
// #endregion
|
|
331
|
-
// #region Config Augmentation (processColumns hook)
|
|
332
|
-
/**
|
|
333
|
-
* Augment columns with editing metadata.
|
|
334
|
-
* This enables the grid to recognize editable columns without core knowledge.
|
|
335
|
-
*/
|
|
336
|
-
processColumns(e) {
|
|
337
|
-
return e;
|
|
338
|
-
}
|
|
339
|
-
// #endregion
|
|
340
424
|
// #region Event Handlers (event distribution)
|
|
341
425
|
/**
|
|
342
426
|
* Handle cell clicks - start editing if configured for click mode.
|
|
@@ -361,12 +445,12 @@ class q extends _ {
|
|
|
361
445
|
if (e.key === " " || e.key === "Spacebar") {
|
|
362
446
|
const i = t._focusRow, s = t._focusCol;
|
|
363
447
|
if (i >= 0 && s >= 0) {
|
|
364
|
-
const n = t._visibleColumns[s],
|
|
365
|
-
if (n?.editable && n.type === "boolean" &&
|
|
448
|
+
const n = t._visibleColumns[s], o = t._rows[i];
|
|
449
|
+
if (n?.editable && n.type === "boolean" && o) {
|
|
366
450
|
const r = n.field;
|
|
367
451
|
if (b(r)) {
|
|
368
|
-
const
|
|
369
|
-
return this.#c(i, n,
|
|
452
|
+
const f = !o[r];
|
|
453
|
+
return this.#c(i, n, f, o), e.preventDefault(), this.requestRender(), !0;
|
|
370
454
|
}
|
|
371
455
|
}
|
|
372
456
|
}
|
|
@@ -378,7 +462,7 @@ class q extends _ {
|
|
|
378
462
|
const i = this.config.editOn ?? t.effectiveConfig?.editOn;
|
|
379
463
|
if (i === !1 || i === "manual") return !1;
|
|
380
464
|
const s = t._focusRow;
|
|
381
|
-
return s >= 0 && t._columns?.some((
|
|
465
|
+
return s >= 0 && t._columns?.some((o) => o.editable) ? (this.beginBulkEdit(s), !0) : !1;
|
|
382
466
|
}
|
|
383
467
|
return !1;
|
|
384
468
|
}
|
|
@@ -393,12 +477,12 @@ class q extends _ {
|
|
|
393
477
|
const e = this.grid;
|
|
394
478
|
if (this.#o && (this.#o = !1, this.#u(e)), this.#n.size !== 0)
|
|
395
479
|
for (const t of this.#n) {
|
|
396
|
-
const [i, s] = t.split(":"), n = parseInt(i, 10),
|
|
480
|
+
const [i, s] = t.split(":"), n = parseInt(i, 10), o = parseInt(s, 10), r = e.findRenderedRowElement?.(n);
|
|
397
481
|
if (!r) continue;
|
|
398
|
-
const c = r.querySelector(`.cell[data-col="${
|
|
482
|
+
const c = r.querySelector(`.cell[data-col="${o}"]`);
|
|
399
483
|
if (!c || c.classList.contains("editing")) continue;
|
|
400
|
-
const
|
|
401
|
-
|
|
484
|
+
const f = e._rows[n], d = e._visibleColumns[o];
|
|
485
|
+
f && d && this.#a(f, n, d, o, c, !0);
|
|
402
486
|
}
|
|
403
487
|
}
|
|
404
488
|
/**
|
|
@@ -476,12 +560,12 @@ class q extends _ {
|
|
|
476
560
|
if ((this.config.editOn ?? t.effectiveConfig?.editOn) === !1 || !t._columns?.some((r) => r.editable)) return;
|
|
477
561
|
const n = t.findRenderedRowElement?.(e);
|
|
478
562
|
if (!n) return;
|
|
479
|
-
const
|
|
480
|
-
this.#d(e,
|
|
481
|
-
const
|
|
482
|
-
if (
|
|
483
|
-
const
|
|
484
|
-
|
|
563
|
+
const o = t._rows[e];
|
|
564
|
+
this.#d(e, o), Array.from(n.children).forEach((r, c) => {
|
|
565
|
+
const f = t._visibleColumns[c];
|
|
566
|
+
if (f?.editable) {
|
|
567
|
+
const d = r;
|
|
568
|
+
d.classList.contains("editing") || this.#a(o, e, f, c, d, !0);
|
|
485
569
|
}
|
|
486
570
|
}), setTimeout(() => {
|
|
487
571
|
let r = n.querySelector(`.cell[data-col="${t._focusCol}"]`);
|
|
@@ -512,8 +596,8 @@ class q extends _ {
|
|
|
512
596
|
* Begin editing a single cell.
|
|
513
597
|
*/
|
|
514
598
|
#f(e, t, i) {
|
|
515
|
-
const s = this.grid, n = s._rows[e],
|
|
516
|
-
!n || !
|
|
599
|
+
const s = this.grid, n = s._rows[e], o = s._visibleColumns[t];
|
|
600
|
+
!n || !o?.editable || i.classList.contains("editing") || (this.#e !== e && this.#d(e, n), this.#r = t, this.#a(n, e, o, t, i, !1));
|
|
517
601
|
}
|
|
518
602
|
/**
|
|
519
603
|
* Sync the internal grid state with the plugin's editing state.
|
|
@@ -533,16 +617,16 @@ class q extends _ {
|
|
|
533
617
|
*/
|
|
534
618
|
#i(e, t) {
|
|
535
619
|
if (this.#e !== e) return;
|
|
536
|
-
const i = this.grid, s = this.#s.get(e), n = i._rows[e],
|
|
537
|
-
if (!t &&
|
|
538
|
-
const
|
|
539
|
-
if (isNaN(
|
|
540
|
-
const
|
|
541
|
-
if (!
|
|
542
|
-
const
|
|
543
|
-
if (
|
|
544
|
-
|
|
545
|
-
|
|
620
|
+
const i = this.grid, s = this.#s.get(e), n = i._rows[e], o = i.findRenderedRowElement?.(e);
|
|
621
|
+
if (!t && o && n && o.querySelectorAll(".cell.editing").forEach((c) => {
|
|
622
|
+
const f = Number(c.getAttribute("data-col"));
|
|
623
|
+
if (isNaN(f)) return;
|
|
624
|
+
const d = i._visibleColumns[f];
|
|
625
|
+
if (!d) return;
|
|
626
|
+
const p = c.querySelector("input,textarea,select");
|
|
627
|
+
if (p) {
|
|
628
|
+
const a = y(p, d);
|
|
629
|
+
n[d.field] !== a && this.#c(e, d, a, n);
|
|
546
630
|
}
|
|
547
631
|
}), t && s && n)
|
|
548
632
|
Object.keys(s).forEach((r) => {
|
|
@@ -561,119 +645,115 @@ class q extends _ {
|
|
|
561
645
|
this.#s.delete(e), this.#e = -1, this.#r = -1, this.#l();
|
|
562
646
|
for (const r of this.#n)
|
|
563
647
|
r.startsWith(`${e}:`) && this.#n.delete(r);
|
|
564
|
-
|
|
565
|
-
r.classList.remove("editing"),
|
|
566
|
-
}), this.requestRender()), this.#o = !0,
|
|
648
|
+
o && (o.querySelectorAll(".cell.editing").forEach((r) => {
|
|
649
|
+
r.classList.remove("editing"), A(r.parentElement);
|
|
650
|
+
}), this.requestRender()), this.#o = !0, o || (this.#u(i), this.#o = !1);
|
|
567
651
|
}
|
|
568
652
|
/**
|
|
569
653
|
* Commit a single cell value change.
|
|
570
654
|
*/
|
|
571
655
|
#c(e, t, i, s) {
|
|
572
656
|
const n = t.field;
|
|
573
|
-
if (!b(n)
|
|
574
|
-
s[n]
|
|
657
|
+
if (!b(n)) return;
|
|
658
|
+
const o = s[n];
|
|
659
|
+
if (o === i) return;
|
|
575
660
|
const r = !this.#t.has(e);
|
|
576
|
-
this
|
|
577
|
-
const u = this.grid.findRenderedRowElement?.(e);
|
|
578
|
-
u && u.classList.add("changed"), this.emit("cell-commit", {
|
|
661
|
+
if (this.emitCancelable("cell-commit", {
|
|
579
662
|
row: s,
|
|
580
663
|
field: n,
|
|
664
|
+
oldValue: o,
|
|
581
665
|
value: i,
|
|
582
666
|
rowIndex: e,
|
|
583
667
|
changedRows: this.changedRows,
|
|
584
668
|
changedRowIndices: this.changedRowIndices,
|
|
585
669
|
firstTimeForRow: r
|
|
586
|
-
});
|
|
670
|
+
})) return;
|
|
671
|
+
s[n] = i, this.#t.add(e), this.#l();
|
|
672
|
+
const d = this.grid.findRenderedRowElement?.(e);
|
|
673
|
+
d && d.classList.add("changed");
|
|
587
674
|
}
|
|
588
675
|
/**
|
|
589
676
|
* Inject an editor into a cell.
|
|
590
677
|
*/
|
|
591
|
-
#a(e, t, i, s, n,
|
|
678
|
+
#a(e, t, i, s, n, o) {
|
|
592
679
|
if (!i.editable || n.classList.contains("editing")) return;
|
|
593
680
|
const r = b(i.field) ? e[i.field] : void 0;
|
|
594
681
|
n.classList.add("editing"), this.#n.add(`${t}:${s}`);
|
|
595
682
|
const c = n.parentElement;
|
|
596
|
-
c &&
|
|
597
|
-
let
|
|
598
|
-
const
|
|
599
|
-
|
|
600
|
-
},
|
|
601
|
-
|
|
602
|
-
},
|
|
603
|
-
|
|
604
|
-
h.key === "Enter" && (h.stopPropagation(), h.preventDefault(),
|
|
683
|
+
c && k(c);
|
|
684
|
+
let f = !1;
|
|
685
|
+
const d = (h) => {
|
|
686
|
+
f || this.#e === -1 || this.#c(t, i, h, e);
|
|
687
|
+
}, p = () => {
|
|
688
|
+
f = !0, b(i.field) && (e[i.field] = r);
|
|
689
|
+
}, a = document.createElement("div");
|
|
690
|
+
a.className = "tbw-editor-host", n.innerHTML = "", n.appendChild(a), a.addEventListener("keydown", (h) => {
|
|
691
|
+
h.key === "Enter" && (h.stopPropagation(), h.preventDefault(), f = !0, this.#i(t, !1)), h.key === "Escape" && (h.stopPropagation(), h.preventDefault(), p(), this.#i(t, !0));
|
|
605
692
|
});
|
|
606
|
-
const
|
|
607
|
-
if (
|
|
608
|
-
this.#h(
|
|
609
|
-
else if (typeof
|
|
610
|
-
const h = document.createElement(
|
|
611
|
-
h.value = m, h.addEventListener("change", () =>
|
|
612
|
-
|
|
693
|
+
const g = i, v = g.__editorTemplate, u = g.editor || (v ? "template" : L(i)), m = r;
|
|
694
|
+
if (u === "template" && v)
|
|
695
|
+
this.#h(a, g, e, r, d, p, o, t);
|
|
696
|
+
else if (typeof u == "string") {
|
|
697
|
+
const h = document.createElement(u);
|
|
698
|
+
h.value = m, h.addEventListener("change", () => d(h.value)), a.appendChild(h), o || queueMicrotask(() => {
|
|
699
|
+
a.querySelector(C)?.focus({ preventScroll: !0 });
|
|
613
700
|
});
|
|
614
|
-
} else if (typeof
|
|
615
|
-
const h = { row: e, value: m, field: i.field, column: i, commit:
|
|
616
|
-
typeof E == "string" ? (
|
|
617
|
-
|
|
701
|
+
} else if (typeof u == "function") {
|
|
702
|
+
const h = { row: e, value: m, field: i.field, column: i, commit: d, cancel: p }, E = u(h);
|
|
703
|
+
typeof E == "string" ? (a.innerHTML = E, q(a, i, d)) : E instanceof Node && a.appendChild(E), o || queueMicrotask(() => {
|
|
704
|
+
a.querySelector(C)?.focus({ preventScroll: !0 });
|
|
618
705
|
});
|
|
619
|
-
} else if (
|
|
706
|
+
} else if (u && typeof u == "object") {
|
|
620
707
|
const h = this.grid, E = document.createElement("div");
|
|
621
|
-
E.setAttribute("data-external-editor", ""), E.setAttribute("data-field", i.field),
|
|
622
|
-
const
|
|
623
|
-
if (
|
|
708
|
+
E.setAttribute("data-external-editor", ""), E.setAttribute("data-field", i.field), a.appendChild(E);
|
|
709
|
+
const w = { row: e, value: m, field: i.field, column: i, commit: d, cancel: p };
|
|
710
|
+
if (u.mount)
|
|
624
711
|
try {
|
|
625
|
-
|
|
626
|
-
} catch (
|
|
627
|
-
console.warn(`[tbw-grid] External editor mount error for column '${i.field}':`,
|
|
712
|
+
u.mount({ placeholder: E, context: w, spec: u });
|
|
713
|
+
} catch (R) {
|
|
714
|
+
console.warn(`[tbw-grid] External editor mount error for column '${i.field}':`, R);
|
|
628
715
|
}
|
|
629
716
|
else
|
|
630
717
|
h.dispatchEvent(
|
|
631
|
-
new CustomEvent("mount-external-editor", { detail: { placeholder: E, spec:
|
|
718
|
+
new CustomEvent("mount-external-editor", { detail: { placeholder: E, spec: u, context: w } })
|
|
632
719
|
);
|
|
633
720
|
}
|
|
634
721
|
}
|
|
635
722
|
/**
|
|
636
723
|
* Render a template-based editor.
|
|
637
724
|
*/
|
|
638
|
-
#h(e, t, i, s, n,
|
|
639
|
-
const
|
|
640
|
-
if (!
|
|
641
|
-
const
|
|
642
|
-
|
|
725
|
+
#h(e, t, i, s, n, o, r, c) {
|
|
726
|
+
const f = t.__editorTemplate;
|
|
727
|
+
if (!f) return;
|
|
728
|
+
const d = f.cloneNode(!0), p = t.__compiledEditor;
|
|
729
|
+
p ? d.innerHTML = p({
|
|
643
730
|
row: i,
|
|
644
731
|
value: s,
|
|
645
732
|
field: t.field,
|
|
646
733
|
column: t,
|
|
647
734
|
commit: n,
|
|
648
|
-
cancel:
|
|
649
|
-
}) :
|
|
650
|
-
|
|
651
|
-
if (!b(
|
|
652
|
-
const m = i[
|
|
735
|
+
cancel: o
|
|
736
|
+
}) : d.querySelectorAll("*").forEach((g) => {
|
|
737
|
+
g.childNodes.length === 1 && g.firstChild?.nodeType === Node.TEXT_NODE && (g.textContent = g.textContent?.replace(/{{\s*value\s*}}/g, s == null ? "" : String(s)).replace(/{{\s*row\.([a-zA-Z0-9_]+)\s*}}/g, (v, u) => {
|
|
738
|
+
if (!b(u)) return "";
|
|
739
|
+
const m = i[u];
|
|
653
740
|
return m == null ? "" : String(m);
|
|
654
741
|
}) || "");
|
|
655
742
|
});
|
|
656
|
-
const
|
|
743
|
+
const a = d.querySelector(
|
|
657
744
|
"input,textarea,select"
|
|
658
745
|
);
|
|
659
|
-
if (
|
|
660
|
-
|
|
661
|
-
let
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
if (d.key === "Enter") {
|
|
669
|
-
d.stopPropagation(), d.preventDefault(), p = !0;
|
|
670
|
-
const m = o instanceof HTMLInputElement && o.type === "checkbox" ? o.checked : o.value;
|
|
671
|
-
n(m), this.#i(c, !1);
|
|
672
|
-
}
|
|
673
|
-
d.key === "Escape" && (d.stopPropagation(), d.preventDefault(), l(), this.#i(c, !0));
|
|
674
|
-
}), o instanceof HTMLInputElement && o.type === "checkbox" && o.addEventListener("change", () => n(o.checked)), r || setTimeout(() => o.focus({ preventScroll: !0 }), 0);
|
|
746
|
+
if (a) {
|
|
747
|
+
a instanceof HTMLInputElement && a.type === "checkbox" ? a.checked = !!s : a.value = String(s ?? "");
|
|
748
|
+
let g = !1;
|
|
749
|
+
a.addEventListener("blur", () => {
|
|
750
|
+
g || n(y(a, t));
|
|
751
|
+
}), a.addEventListener("keydown", (v) => {
|
|
752
|
+
const u = v;
|
|
753
|
+
u.key === "Enter" && (u.stopPropagation(), u.preventDefault(), g = !0, n(y(a, t)), this.#i(c, !1)), u.key === "Escape" && (u.stopPropagation(), u.preventDefault(), o(), this.#i(c, !0));
|
|
754
|
+
}), a instanceof HTMLInputElement && a.type === "checkbox" && a.addEventListener("change", () => n(a.checked)), r || setTimeout(() => a.focus({ preventScroll: !0 }), 0);
|
|
675
755
|
}
|
|
676
|
-
e.appendChild(
|
|
756
|
+
e.appendChild(d);
|
|
677
757
|
}
|
|
678
758
|
/**
|
|
679
759
|
* Restore focus to cell after exiting edit mode.
|
|
@@ -684,7 +764,7 @@ class q extends _ {
|
|
|
684
764
|
const t = e._focusRow, i = e._focusCol, s = e.findRenderedRowElement?.(t);
|
|
685
765
|
if (s) {
|
|
686
766
|
Array.from(e._bodyEl.querySelectorAll(".cell-focus")).forEach(
|
|
687
|
-
(
|
|
767
|
+
(o) => o.classList.remove("cell-focus")
|
|
688
768
|
);
|
|
689
769
|
const n = s.querySelector(`.cell[data-row="${t}"][data-col="${i}"]`);
|
|
690
770
|
n && (n.classList.add("cell-focus"), n.setAttribute("aria-selected", "true"), n.hasAttribute("tabindex") || n.setAttribute("tabindex", "-1"), n.focus({ preventScroll: !0 }));
|
|
@@ -696,10 +776,10 @@ class q extends _ {
|
|
|
696
776
|
// #endregion
|
|
697
777
|
}
|
|
698
778
|
export {
|
|
699
|
-
|
|
779
|
+
O as EditingPlugin,
|
|
700
780
|
C as FOCUSABLE_EDITOR_SELECTOR,
|
|
701
|
-
|
|
702
|
-
|
|
781
|
+
A as clearEditingState,
|
|
782
|
+
L as defaultEditorFor,
|
|
703
783
|
T as hasEditingCells
|
|
704
784
|
};
|
|
705
785
|
//# sourceMappingURL=index.js.map
|