@toolbox-web/grid 0.4.1 → 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 +1101 -1048
- package/all.js.map +1 -1
- package/index.js +245 -137
- 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/plugin/base-plugin.d.ts +57 -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/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 +5 -4
- 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 +282 -188
- 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 +102 -26
- 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 +154 -78
- 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 +200 -136
- 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 +175 -99
- 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 +129 -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 +144 -66
- 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 +230 -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 +265 -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 +105 -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 +128 -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 +162 -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 +398 -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 +288 -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 +276 -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 +83 -7
- 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 +197 -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 +0 -1
- package/lib/plugins/undo-redo/UndoRedoPlugin.d.ts.map +1 -1
- package/lib/plugins/undo-redo/index.js +93 -17
- package/lib/plugins/undo-redo/index.js.map +1 -1
- package/lib/plugins/visibility/VisibilityPlugin.d.ts +7 -4
- package/lib/plugins/visibility/VisibilityPlugin.d.ts.map +1 -1
- package/lib/plugins/visibility/index.js +144 -65
- package/lib/plugins/visibility/index.js.map +1 -1
- package/package.json +1 -1
- package/umd/grid.all.umd.js +17 -19
- package/umd/grid.all.umd.js.map +1 -1
- package/umd/grid.umd.js +7 -7
- 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
- package/lib/core/internal/editing.d.ts +0 -76
- package/lib/core/internal/editing.d.ts.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const
|
|
1
|
+
const _ = {
|
|
2
2
|
expand: "▶",
|
|
3
3
|
collapse: "▼",
|
|
4
4
|
sortAsc: "▲",
|
|
@@ -8,7 +8,7 @@ const R = {
|
|
|
8
8
|
dragHandle: "⋮⋮",
|
|
9
9
|
toolPanel: "☰"
|
|
10
10
|
};
|
|
11
|
-
class
|
|
11
|
+
class S {
|
|
12
12
|
/**
|
|
13
13
|
* Plugin dependencies - declare other plugins this one requires.
|
|
14
14
|
*
|
|
@@ -25,8 +25,11 @@ class _ {
|
|
|
25
25
|
* ```
|
|
26
26
|
*/
|
|
27
27
|
static dependencies;
|
|
28
|
-
/**
|
|
29
|
-
|
|
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";
|
|
30
33
|
/** CSS styles to inject into the grid's shadow DOM */
|
|
31
34
|
styles;
|
|
32
35
|
/** Custom cell renderers keyed by type name */
|
|
@@ -113,12 +116,28 @@ class _ {
|
|
|
113
116
|
emit(e, t) {
|
|
114
117
|
this.grid?.dispatchEvent?.(new CustomEvent(e, { detail: t, bubbles: !0 }));
|
|
115
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
|
+
}
|
|
116
127
|
/**
|
|
117
128
|
* Request a re-render of the grid.
|
|
118
129
|
*/
|
|
119
130
|
requestRender() {
|
|
120
131
|
this.grid?.requestRender?.();
|
|
121
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
|
+
}
|
|
122
141
|
/**
|
|
123
142
|
* Request a lightweight style update without rebuilding DOM.
|
|
124
143
|
* Use this instead of requestRender() when only CSS classes need updating.
|
|
@@ -152,6 +171,19 @@ class _ {
|
|
|
152
171
|
get visibleColumns() {
|
|
153
172
|
return this.grid?._visibleColumns ?? [];
|
|
154
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
|
+
}
|
|
155
187
|
/**
|
|
156
188
|
* Get the shadow root of the grid.
|
|
157
189
|
*/
|
|
@@ -184,8 +216,53 @@ class _ {
|
|
|
184
216
|
*/
|
|
185
217
|
get gridIcons() {
|
|
186
218
|
const e = this.grid?.gridConfig?.icons ?? {};
|
|
187
|
-
return { ...
|
|
219
|
+
return { ..._, ...e };
|
|
188
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
|
|
189
266
|
/**
|
|
190
267
|
* Resolve an icon value to string or HTMLElement.
|
|
191
268
|
* Checks plugin config first, then grid-level icons, then defaults.
|
|
@@ -215,8 +292,8 @@ class _ {
|
|
|
215
292
|
}
|
|
216
293
|
// #endregion
|
|
217
294
|
}
|
|
218
|
-
function
|
|
219
|
-
switch (
|
|
295
|
+
function L(l) {
|
|
296
|
+
switch (l.type) {
|
|
220
297
|
case "number":
|
|
221
298
|
return (e) => {
|
|
222
299
|
const t = document.createElement("input");
|
|
@@ -246,7 +323,7 @@ function k(f) {
|
|
|
246
323
|
const c = document.createElement("option");
|
|
247
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);
|
|
248
325
|
});
|
|
249
|
-
const
|
|
326
|
+
const o = () => {
|
|
250
327
|
if (i.multi) {
|
|
251
328
|
const r = [];
|
|
252
329
|
Array.from(t.selectedOptions).forEach((c) => {
|
|
@@ -255,7 +332,7 @@ function k(f) {
|
|
|
255
332
|
} else
|
|
256
333
|
e.commit(t.value);
|
|
257
334
|
};
|
|
258
|
-
return t.addEventListener("change",
|
|
335
|
+
return t.addEventListener("change", o), t.addEventListener("blur", o), t.addEventListener("keydown", (r) => {
|
|
259
336
|
r.key === "Escape" && e.cancel();
|
|
260
337
|
}), t;
|
|
261
338
|
};
|
|
@@ -268,31 +345,31 @@ function k(f) {
|
|
|
268
345
|
};
|
|
269
346
|
}
|
|
270
347
|
}
|
|
271
|
-
const
|
|
272
|
-
function b(
|
|
273
|
-
return !(typeof
|
|
348
|
+
const C = 'input,select,textarea,[contenteditable="true"],[contenteditable=""],[tabindex]:not([tabindex="-1"])';
|
|
349
|
+
function b(l) {
|
|
350
|
+
return !(typeof l != "string" || l === "__proto__" || l === "constructor" || l === "prototype");
|
|
274
351
|
}
|
|
275
|
-
function T(
|
|
276
|
-
return (
|
|
352
|
+
function T(l) {
|
|
353
|
+
return (l.__editingCellCount ?? 0) > 0;
|
|
277
354
|
}
|
|
278
|
-
function
|
|
279
|
-
const e = (
|
|
280
|
-
|
|
355
|
+
function k(l) {
|
|
356
|
+
const e = (l.__editingCellCount ?? 0) + 1;
|
|
357
|
+
l.__editingCellCount = e, l.setAttribute("data-has-editing", "");
|
|
281
358
|
}
|
|
282
|
-
function
|
|
283
|
-
|
|
359
|
+
function A(l) {
|
|
360
|
+
l.__editingCellCount = 0, l.removeAttribute("data-has-editing");
|
|
284
361
|
}
|
|
285
|
-
function
|
|
286
|
-
|
|
287
|
-
if (!i) return;
|
|
288
|
-
const s = () => i instanceof HTMLInputElement ? i.type === "checkbox" ? i.checked : i.type === "number" ? i.value === "" ? null : Number(i.value) : i.type === "date" ? i.valueAsDate : i.value : e.type === "number" && i.value !== "" ? Number(i.value) : i.value;
|
|
289
|
-
i.addEventListener("blur", () => {
|
|
290
|
-
t(s());
|
|
291
|
-
}), i instanceof HTMLInputElement && i.type === "checkbox" ? i.addEventListener("change", () => t(i.checked)) : i instanceof HTMLSelectElement && i.addEventListener("change", () => t(s()));
|
|
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;
|
|
292
364
|
}
|
|
293
|
-
|
|
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))));
|
|
370
|
+
}
|
|
371
|
+
class O extends S {
|
|
294
372
|
name = "editing";
|
|
295
|
-
version = "1.0.0";
|
|
296
373
|
get defaultConfig() {
|
|
297
374
|
return {
|
|
298
375
|
editOn: "click"
|
|
@@ -344,15 +421,6 @@ class q extends _ {
|
|
|
344
421
|
this.#e = -1, this.#r = -1, this.#s.clear(), this.#t.clear(), this.#n.clear(), super.detach();
|
|
345
422
|
}
|
|
346
423
|
// #endregion
|
|
347
|
-
// #region Config Augmentation (processColumns hook)
|
|
348
|
-
/**
|
|
349
|
-
* Augment columns with editing metadata.
|
|
350
|
-
* This enables the grid to recognize editable columns without core knowledge.
|
|
351
|
-
*/
|
|
352
|
-
processColumns(e) {
|
|
353
|
-
return e;
|
|
354
|
-
}
|
|
355
|
-
// #endregion
|
|
356
424
|
// #region Event Handlers (event distribution)
|
|
357
425
|
/**
|
|
358
426
|
* Handle cell clicks - start editing if configured for click mode.
|
|
@@ -377,12 +445,12 @@ class q extends _ {
|
|
|
377
445
|
if (e.key === " " || e.key === "Spacebar") {
|
|
378
446
|
const i = t._focusRow, s = t._focusCol;
|
|
379
447
|
if (i >= 0 && s >= 0) {
|
|
380
|
-
const n = t._visibleColumns[s],
|
|
381
|
-
if (n?.editable && n.type === "boolean" &&
|
|
448
|
+
const n = t._visibleColumns[s], o = t._rows[i];
|
|
449
|
+
if (n?.editable && n.type === "boolean" && o) {
|
|
382
450
|
const r = n.field;
|
|
383
451
|
if (b(r)) {
|
|
384
|
-
const
|
|
385
|
-
return this.#c(i, n,
|
|
452
|
+
const f = !o[r];
|
|
453
|
+
return this.#c(i, n, f, o), e.preventDefault(), this.requestRender(), !0;
|
|
386
454
|
}
|
|
387
455
|
}
|
|
388
456
|
}
|
|
@@ -394,7 +462,7 @@ class q extends _ {
|
|
|
394
462
|
const i = this.config.editOn ?? t.effectiveConfig?.editOn;
|
|
395
463
|
if (i === !1 || i === "manual") return !1;
|
|
396
464
|
const s = t._focusRow;
|
|
397
|
-
return s >= 0 && t._columns?.some((
|
|
465
|
+
return s >= 0 && t._columns?.some((o) => o.editable) ? (this.beginBulkEdit(s), !0) : !1;
|
|
398
466
|
}
|
|
399
467
|
return !1;
|
|
400
468
|
}
|
|
@@ -409,12 +477,12 @@ class q extends _ {
|
|
|
409
477
|
const e = this.grid;
|
|
410
478
|
if (this.#o && (this.#o = !1, this.#u(e)), this.#n.size !== 0)
|
|
411
479
|
for (const t of this.#n) {
|
|
412
|
-
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);
|
|
413
481
|
if (!r) continue;
|
|
414
|
-
const c = r.querySelector(`.cell[data-col="${
|
|
482
|
+
const c = r.querySelector(`.cell[data-col="${o}"]`);
|
|
415
483
|
if (!c || c.classList.contains("editing")) continue;
|
|
416
|
-
const
|
|
417
|
-
|
|
484
|
+
const f = e._rows[n], d = e._visibleColumns[o];
|
|
485
|
+
f && d && this.#a(f, n, d, o, c, !0);
|
|
418
486
|
}
|
|
419
487
|
}
|
|
420
488
|
/**
|
|
@@ -492,17 +560,17 @@ class q extends _ {
|
|
|
492
560
|
if ((this.config.editOn ?? t.effectiveConfig?.editOn) === !1 || !t._columns?.some((r) => r.editable)) return;
|
|
493
561
|
const n = t.findRenderedRowElement?.(e);
|
|
494
562
|
if (!n) return;
|
|
495
|
-
const
|
|
496
|
-
this.#d(e,
|
|
497
|
-
const
|
|
498
|
-
if (
|
|
499
|
-
const
|
|
500
|
-
|
|
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);
|
|
501
569
|
}
|
|
502
570
|
}), setTimeout(() => {
|
|
503
571
|
let r = n.querySelector(`.cell[data-col="${t._focusCol}"]`);
|
|
504
572
|
if (r?.classList.contains("editing") || (r = n.querySelector(".cell.editing")), r?.classList.contains("editing")) {
|
|
505
|
-
const c = r.querySelector(
|
|
573
|
+
const c = r.querySelector(C);
|
|
506
574
|
try {
|
|
507
575
|
c?.focus({ preventScroll: !0 });
|
|
508
576
|
} catch {
|
|
@@ -528,8 +596,8 @@ class q extends _ {
|
|
|
528
596
|
* Begin editing a single cell.
|
|
529
597
|
*/
|
|
530
598
|
#f(e, t, i) {
|
|
531
|
-
const s = this.grid, n = s._rows[e],
|
|
532
|
-
!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));
|
|
533
601
|
}
|
|
534
602
|
/**
|
|
535
603
|
* Sync the internal grid state with the plugin's editing state.
|
|
@@ -549,16 +617,16 @@ class q extends _ {
|
|
|
549
617
|
*/
|
|
550
618
|
#i(e, t) {
|
|
551
619
|
if (this.#e !== e) return;
|
|
552
|
-
const i = this.grid, s = this.#s.get(e), n = i._rows[e],
|
|
553
|
-
if (!t &&
|
|
554
|
-
const
|
|
555
|
-
if (isNaN(
|
|
556
|
-
const
|
|
557
|
-
if (!
|
|
558
|
-
const
|
|
559
|
-
if (
|
|
560
|
-
|
|
561
|
-
|
|
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);
|
|
562
630
|
}
|
|
563
631
|
}), t && s && n)
|
|
564
632
|
Object.keys(s).forEach((r) => {
|
|
@@ -577,119 +645,115 @@ class q extends _ {
|
|
|
577
645
|
this.#s.delete(e), this.#e = -1, this.#r = -1, this.#l();
|
|
578
646
|
for (const r of this.#n)
|
|
579
647
|
r.startsWith(`${e}:`) && this.#n.delete(r);
|
|
580
|
-
|
|
581
|
-
r.classList.remove("editing"),
|
|
582
|
-
}), 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);
|
|
583
651
|
}
|
|
584
652
|
/**
|
|
585
653
|
* Commit a single cell value change.
|
|
586
654
|
*/
|
|
587
655
|
#c(e, t, i, s) {
|
|
588
656
|
const n = t.field;
|
|
589
|
-
if (!b(n)
|
|
590
|
-
s[n]
|
|
657
|
+
if (!b(n)) return;
|
|
658
|
+
const o = s[n];
|
|
659
|
+
if (o === i) return;
|
|
591
660
|
const r = !this.#t.has(e);
|
|
592
|
-
this
|
|
593
|
-
const u = this.grid.findRenderedRowElement?.(e);
|
|
594
|
-
u && u.classList.add("changed"), this.emit("cell-commit", {
|
|
661
|
+
if (this.emitCancelable("cell-commit", {
|
|
595
662
|
row: s,
|
|
596
663
|
field: n,
|
|
664
|
+
oldValue: o,
|
|
597
665
|
value: i,
|
|
598
666
|
rowIndex: e,
|
|
599
667
|
changedRows: this.changedRows,
|
|
600
668
|
changedRowIndices: this.changedRowIndices,
|
|
601
669
|
firstTimeForRow: r
|
|
602
|
-
});
|
|
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");
|
|
603
674
|
}
|
|
604
675
|
/**
|
|
605
676
|
* Inject an editor into a cell.
|
|
606
677
|
*/
|
|
607
|
-
#a(e, t, i, s, n,
|
|
678
|
+
#a(e, t, i, s, n, o) {
|
|
608
679
|
if (!i.editable || n.classList.contains("editing")) return;
|
|
609
680
|
const r = b(i.field) ? e[i.field] : void 0;
|
|
610
681
|
n.classList.add("editing"), this.#n.add(`${t}:${s}`);
|
|
611
682
|
const c = n.parentElement;
|
|
612
|
-
c &&
|
|
613
|
-
let
|
|
614
|
-
const
|
|
615
|
-
|
|
616
|
-
},
|
|
617
|
-
|
|
618
|
-
},
|
|
619
|
-
|
|
620
|
-
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));
|
|
621
692
|
});
|
|
622
|
-
const
|
|
623
|
-
if (
|
|
624
|
-
this.#h(
|
|
625
|
-
else if (typeof
|
|
626
|
-
const h = document.createElement(
|
|
627
|
-
h.value = m, h.addEventListener("change", () =>
|
|
628
|
-
|
|
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 });
|
|
629
700
|
});
|
|
630
|
-
} else if (typeof
|
|
631
|
-
const h = { row: e, value: m, field: i.field, column: i, commit:
|
|
632
|
-
typeof E == "string" ? (
|
|
633
|
-
|
|
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 });
|
|
634
705
|
});
|
|
635
|
-
} else if (
|
|
706
|
+
} else if (u && typeof u == "object") {
|
|
636
707
|
const h = this.grid, E = document.createElement("div");
|
|
637
|
-
E.setAttribute("data-external-editor", ""), E.setAttribute("data-field", i.field),
|
|
638
|
-
const
|
|
639
|
-
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)
|
|
640
711
|
try {
|
|
641
|
-
|
|
642
|
-
} catch (
|
|
643
|
-
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);
|
|
644
715
|
}
|
|
645
716
|
else
|
|
646
717
|
h.dispatchEvent(
|
|
647
|
-
new CustomEvent("mount-external-editor", { detail: { placeholder: E, spec:
|
|
718
|
+
new CustomEvent("mount-external-editor", { detail: { placeholder: E, spec: u, context: w } })
|
|
648
719
|
);
|
|
649
720
|
}
|
|
650
721
|
}
|
|
651
722
|
/**
|
|
652
723
|
* Render a template-based editor.
|
|
653
724
|
*/
|
|
654
|
-
#h(e, t, i, s, n,
|
|
655
|
-
const
|
|
656
|
-
if (!
|
|
657
|
-
const
|
|
658
|
-
|
|
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({
|
|
659
730
|
row: i,
|
|
660
731
|
value: s,
|
|
661
732
|
field: t.field,
|
|
662
733
|
column: t,
|
|
663
734
|
commit: n,
|
|
664
|
-
cancel:
|
|
665
|
-
}) :
|
|
666
|
-
|
|
667
|
-
if (!b(
|
|
668
|
-
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];
|
|
669
740
|
return m == null ? "" : String(m);
|
|
670
741
|
}) || "");
|
|
671
742
|
});
|
|
672
|
-
const
|
|
743
|
+
const a = d.querySelector(
|
|
673
744
|
"input,textarea,select"
|
|
674
745
|
);
|
|
675
|
-
if (
|
|
676
|
-
|
|
677
|
-
let
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
if (d.key === "Enter") {
|
|
685
|
-
d.stopPropagation(), d.preventDefault(), p = !0;
|
|
686
|
-
const m = o instanceof HTMLInputElement && o.type === "checkbox" ? o.checked : o.value;
|
|
687
|
-
n(m), this.#i(c, !1);
|
|
688
|
-
}
|
|
689
|
-
d.key === "Escape" && (d.stopPropagation(), d.preventDefault(), l(), this.#i(c, !0));
|
|
690
|
-
}), 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);
|
|
691
755
|
}
|
|
692
|
-
e.appendChild(
|
|
756
|
+
e.appendChild(d);
|
|
693
757
|
}
|
|
694
758
|
/**
|
|
695
759
|
* Restore focus to cell after exiting edit mode.
|
|
@@ -700,7 +764,7 @@ class q extends _ {
|
|
|
700
764
|
const t = e._focusRow, i = e._focusCol, s = e.findRenderedRowElement?.(t);
|
|
701
765
|
if (s) {
|
|
702
766
|
Array.from(e._bodyEl.querySelectorAll(".cell-focus")).forEach(
|
|
703
|
-
(
|
|
767
|
+
(o) => o.classList.remove("cell-focus")
|
|
704
768
|
);
|
|
705
769
|
const n = s.querySelector(`.cell[data-row="${t}"][data-col="${i}"]`);
|
|
706
770
|
n && (n.classList.add("cell-focus"), n.setAttribute("aria-selected", "true"), n.hasAttribute("tabindex") || n.setAttribute("tabindex", "-1"), n.focus({ preventScroll: !0 }));
|
|
@@ -712,10 +776,10 @@ class q extends _ {
|
|
|
712
776
|
// #endregion
|
|
713
777
|
}
|
|
714
778
|
export {
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
779
|
+
O as EditingPlugin,
|
|
780
|
+
C as FOCUSABLE_EDITOR_SELECTOR,
|
|
781
|
+
A as clearEditingState,
|
|
782
|
+
L as defaultEditorFor,
|
|
719
783
|
T as hasEditingCells
|
|
720
784
|
};
|
|
721
785
|
//# sourceMappingURL=index.js.map
|