@toolbox-web/grid 0.4.1 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -13
- package/all.js +1678 -1588
- package/all.js.map +1 -1
- package/index.js +762 -568
- package/index.js.map +1 -1
- package/lib/core/grid.d.ts +21 -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/dom-builder.d.ts +2 -0
- package/lib/core/internal/dom-builder.d.ts.map +1 -1
- package/lib/core/internal/header.d.ts.map +1 -1
- package/lib/core/internal/keyboard.d.ts.map +1 -1
- package/lib/core/internal/resize.d.ts.map +1 -1
- package/lib/core/internal/rows.d.ts.map +1 -1
- package/lib/core/internal/shell.d.ts +19 -13
- package/lib/core/internal/shell.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 +70 -3
- 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/plugin-manager.d.ts +6 -2
- 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 +10 -5
- 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 +295 -190
- 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 +143 -56
- 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 +189 -102
- package/lib/plugins/context-menu/index.js.map +1 -1
- package/lib/plugins/editing/EditingPlugin.d.ts +2 -7
- package/lib/plugins/editing/EditingPlugin.d.ts.map +1 -1
- package/lib/plugins/editing/index.js +227 -150
- 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 +184 -97
- package/lib/plugins/export/index.js.map +1 -1
- package/lib/plugins/filtering/FilteringPlugin.d.ts +14 -3
- package/lib/plugins/filtering/FilteringPlugin.d.ts.map +1 -1
- package/lib/plugins/filtering/index.js +296 -176
- package/lib/plugins/filtering/index.js.map +1 -1
- package/lib/plugins/grouping-columns/GroupingColumnsPlugin.d.ts +2 -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 +169 -61
- 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 +243 -140
- 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 +278 -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 +125 -40
- 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 +156 -75
- package/lib/plugins/pinned-columns/index.js.map +1 -1
- package/lib/plugins/pinned-columns/pinned-columns.d.ts +2 -2
- package/lib/plugins/pinned-columns/pinned-columns.d.ts.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 +202 -117
- 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 +413 -314
- 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.d.ts +1 -1
- package/lib/plugins/reorder/index.d.ts.map +1 -1
- package/lib/plugins/reorder/index.js +296 -223
- 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 +282 -141
- 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 +96 -9
- 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 +209 -113
- 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 +98 -11
- 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 +155 -64
- package/lib/plugins/visibility/index.js.map +1 -1
- package/package.json +1 -1
- package/themes/dg-theme-bootstrap.css +55 -53
- package/themes/dg-theme-contrast.css +42 -40
- package/themes/dg-theme-large.css +38 -37
- package/themes/dg-theme-material.css +54 -52
- package/themes/dg-theme-standard.css +19 -17
- package/themes/dg-theme-vibrant.css +16 -14
- package/umd/grid.all.umd.js +23 -24
- package/umd/grid.all.umd.js.map +1 -1
- package/umd/grid.umd.js +12 -11
- 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 v = {
|
|
2
2
|
expand: "▶",
|
|
3
3
|
collapse: "▼",
|
|
4
4
|
sortAsc: "▲",
|
|
@@ -25,8 +25,11 @@ class R {
|
|
|
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 R {
|
|
|
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 r = new CustomEvent(e, { detail: t, bubbles: !0, cancelable: !0 });
|
|
125
|
+
return this.grid?.dispatchEvent?.(r), r.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.
|
|
@@ -153,10 +172,34 @@ class R {
|
|
|
153
172
|
return this.grid?._visibleColumns ?? [];
|
|
154
173
|
}
|
|
155
174
|
/**
|
|
156
|
-
* Get the
|
|
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
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Get the render root of the grid for DOM queries.
|
|
189
|
+
* @deprecated Use `gridElement` instead. This getter exists only for backward compatibility.
|
|
190
|
+
*
|
|
191
|
+
* With Shadow DOM removed, the grid element itself is the render root.
|
|
192
|
+
* All new code should use `this.gridElement` for DOM queries.
|
|
193
|
+
*
|
|
194
|
+
* @example
|
|
195
|
+
* // OLD (deprecated)
|
|
196
|
+
* const rows = this.shadowRoot?.querySelector('.rows');
|
|
197
|
+
*
|
|
198
|
+
* // NEW (preferred)
|
|
199
|
+
* const rows = this.gridElement.querySelector('.rows');
|
|
157
200
|
*/
|
|
158
201
|
get shadowRoot() {
|
|
159
|
-
return this.
|
|
202
|
+
return this.gridElement;
|
|
160
203
|
}
|
|
161
204
|
/**
|
|
162
205
|
* Get the disconnect signal for event listener cleanup.
|
|
@@ -184,8 +227,53 @@ class R {
|
|
|
184
227
|
*/
|
|
185
228
|
get gridIcons() {
|
|
186
229
|
const e = this.grid?.gridConfig?.icons ?? {};
|
|
187
|
-
return { ...
|
|
230
|
+
return { ...v, ...e };
|
|
231
|
+
}
|
|
232
|
+
// #region Animation Helpers
|
|
233
|
+
/**
|
|
234
|
+
* Check if animations are enabled at the grid level.
|
|
235
|
+
* Respects gridConfig.animation.mode and the CSS variable set by the grid.
|
|
236
|
+
*
|
|
237
|
+
* Plugins should use this to skip animations when:
|
|
238
|
+
* - Animation mode is 'off' or `false`
|
|
239
|
+
* - User prefers reduced motion and mode is 'reduced-motion' (default)
|
|
240
|
+
*
|
|
241
|
+
* @example
|
|
242
|
+
* ```ts
|
|
243
|
+
* private get animationStyle(): 'slide' | 'fade' | false {
|
|
244
|
+
* if (!this.isAnimationEnabled) return false;
|
|
245
|
+
* return this.config.animation ?? 'slide';
|
|
246
|
+
* }
|
|
247
|
+
* ```
|
|
248
|
+
*/
|
|
249
|
+
get isAnimationEnabled() {
|
|
250
|
+
const e = this.grid?.effectiveConfig?.animation?.mode ?? "reduced-motion";
|
|
251
|
+
if (e === !1 || e === "off") return !1;
|
|
252
|
+
if (e === !0 || e === "on") return !0;
|
|
253
|
+
const t = this.gridElement;
|
|
254
|
+
return t ? getComputedStyle(t).getPropertyValue("--tbw-animation-enabled").trim() !== "0" : !0;
|
|
188
255
|
}
|
|
256
|
+
/**
|
|
257
|
+
* Get the animation duration in milliseconds from CSS variable.
|
|
258
|
+
* Falls back to 200ms if not set.
|
|
259
|
+
*
|
|
260
|
+
* Plugins can use this for their animation timing to stay consistent
|
|
261
|
+
* with the grid-level animation.duration setting.
|
|
262
|
+
*
|
|
263
|
+
* @example
|
|
264
|
+
* ```ts
|
|
265
|
+
* element.animate(keyframes, { duration: this.animationDuration });
|
|
266
|
+
* ```
|
|
267
|
+
*/
|
|
268
|
+
get animationDuration() {
|
|
269
|
+
const e = this.gridElement;
|
|
270
|
+
if (e) {
|
|
271
|
+
const t = getComputedStyle(e).getPropertyValue("--tbw-animation-duration").trim(), r = parseInt(t, 10);
|
|
272
|
+
if (!isNaN(r)) return r;
|
|
273
|
+
}
|
|
274
|
+
return 200;
|
|
275
|
+
}
|
|
276
|
+
// #endregion
|
|
189
277
|
/**
|
|
190
278
|
* Resolve an icon value to string or HTMLElement.
|
|
191
279
|
* Checks plugin config first, then grid-level icons, then defaults.
|
|
@@ -215,10 +303,14 @@ class R {
|
|
|
215
303
|
}
|
|
216
304
|
// #endregion
|
|
217
305
|
}
|
|
218
|
-
const
|
|
219
|
-
|
|
306
|
+
const x = "__tbw_expander";
|
|
307
|
+
function C(n) {
|
|
308
|
+
return n.field === x;
|
|
309
|
+
}
|
|
310
|
+
const _ = {
|
|
311
|
+
sum: (n, e) => n.reduce((t, r) => t + (Number(r[e]) || 0), 0),
|
|
220
312
|
avg: (n, e) => {
|
|
221
|
-
const t = n.reduce((
|
|
313
|
+
const t = n.reduce((r, s) => r + (Number(s[e]) || 0), 0);
|
|
222
314
|
return n.length ? t / n.length : 0;
|
|
223
315
|
},
|
|
224
316
|
count: (n) => n.length,
|
|
@@ -226,104 +318,104 @@ const m = {
|
|
|
226
318
|
max: (n, e) => Math.max(...n.map((t) => Number(t[e]) || -1 / 0)),
|
|
227
319
|
first: (n, e) => n[0]?.[e],
|
|
228
320
|
last: (n, e) => n[n.length - 1]?.[e]
|
|
229
|
-
},
|
|
321
|
+
}, w = /* @__PURE__ */ new Map(), c = {
|
|
230
322
|
/**
|
|
231
323
|
* Register a custom aggregator function.
|
|
232
324
|
*/
|
|
233
325
|
register(n, e) {
|
|
234
|
-
|
|
326
|
+
w.set(n, e);
|
|
235
327
|
},
|
|
236
328
|
/**
|
|
237
329
|
* Unregister a custom aggregator function.
|
|
238
330
|
*/
|
|
239
331
|
unregister(n) {
|
|
240
|
-
|
|
332
|
+
w.delete(n);
|
|
241
333
|
},
|
|
242
334
|
/**
|
|
243
335
|
* Get an aggregator function by reference.
|
|
244
336
|
*/
|
|
245
337
|
get(n) {
|
|
246
338
|
if (n !== void 0)
|
|
247
|
-
return typeof n == "function" ? n :
|
|
339
|
+
return typeof n == "function" ? n : w.get(n) ?? _[n];
|
|
248
340
|
},
|
|
249
341
|
/**
|
|
250
342
|
* Run an aggregator on a set of rows.
|
|
251
343
|
*/
|
|
252
|
-
run(n, e, t,
|
|
253
|
-
const
|
|
254
|
-
return
|
|
344
|
+
run(n, e, t, r) {
|
|
345
|
+
const s = this.get(n);
|
|
346
|
+
return s ? s(e, t, r) : void 0;
|
|
255
347
|
},
|
|
256
348
|
/**
|
|
257
349
|
* Check if an aggregator exists.
|
|
258
350
|
*/
|
|
259
351
|
has(n) {
|
|
260
|
-
return
|
|
352
|
+
return w.has(n) || n in _;
|
|
261
353
|
},
|
|
262
354
|
/**
|
|
263
355
|
* List all available aggregator names.
|
|
264
356
|
*/
|
|
265
357
|
list() {
|
|
266
|
-
return [...Object.keys(
|
|
358
|
+
return [...Object.keys(_), ...w.keys()];
|
|
267
359
|
}
|
|
268
360
|
};
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
const
|
|
273
|
-
|
|
274
|
-
function
|
|
275
|
-
const
|
|
276
|
-
if (typeof
|
|
361
|
+
c.register.bind(c);
|
|
362
|
+
c.unregister.bind(c);
|
|
363
|
+
c.get.bind(c);
|
|
364
|
+
const y = c.run.bind(c);
|
|
365
|
+
c.list.bind(c);
|
|
366
|
+
function A({ rows: n, config: e, expanded: t }) {
|
|
367
|
+
const r = e.groupOn;
|
|
368
|
+
if (typeof r != "function")
|
|
277
369
|
return [];
|
|
278
|
-
const
|
|
279
|
-
if (n.forEach((
|
|
280
|
-
let
|
|
281
|
-
|
|
282
|
-
let
|
|
283
|
-
|
|
284
|
-
const
|
|
285
|
-
let
|
|
286
|
-
|
|
287
|
-
}),
|
|
288
|
-
}),
|
|
370
|
+
const s = { key: "__root__", value: null, depth: -1, rows: [], children: /* @__PURE__ */ new Map() };
|
|
371
|
+
if (n.forEach((o) => {
|
|
372
|
+
let a = r(o);
|
|
373
|
+
a == null || a === !1 ? a = ["__ungrouped__"] : Array.isArray(a) || (a = [a]);
|
|
374
|
+
let u = s;
|
|
375
|
+
a.forEach((h, p) => {
|
|
376
|
+
const f = h == null ? "∅" : String(h), l = u.key === "__root__" ? f : u.key + "||" + f;
|
|
377
|
+
let g = u.children.get(f);
|
|
378
|
+
g || (g = { key: l, value: h, depth: p, rows: [], children: /* @__PURE__ */ new Map(), parent: u }, u.children.set(f, g)), u = g;
|
|
379
|
+
}), u.rows.push(o);
|
|
380
|
+
}), s.children.size === 1 && s.children.has("__ungrouped__") && s.children.get("__ungrouped__").rows.length === n.length)
|
|
289
381
|
return [];
|
|
290
|
-
const
|
|
291
|
-
if (
|
|
292
|
-
|
|
382
|
+
const i = [], d = (o) => {
|
|
383
|
+
if (o === s) {
|
|
384
|
+
o.children.forEach((u) => d(u));
|
|
293
385
|
return;
|
|
294
386
|
}
|
|
295
|
-
const
|
|
296
|
-
|
|
387
|
+
const a = t.has(o.key);
|
|
388
|
+
i.push({
|
|
297
389
|
kind: "group",
|
|
298
|
-
key:
|
|
299
|
-
value:
|
|
300
|
-
depth:
|
|
301
|
-
rows:
|
|
302
|
-
expanded:
|
|
303
|
-
}),
|
|
390
|
+
key: o.key,
|
|
391
|
+
value: o.value,
|
|
392
|
+
depth: o.depth,
|
|
393
|
+
rows: o.rows,
|
|
394
|
+
expanded: a
|
|
395
|
+
}), a && (o.children.size ? o.children.forEach((u) => d(u)) : o.rows.forEach((u) => i.push({ kind: "data", row: u, rowIndex: n.indexOf(u) })));
|
|
304
396
|
};
|
|
305
|
-
return
|
|
397
|
+
return d(s), i;
|
|
306
398
|
}
|
|
307
|
-
function
|
|
399
|
+
function k(n, e) {
|
|
308
400
|
const t = new Set(n);
|
|
309
401
|
return t.has(e) ? t.delete(e) : t.add(e), t;
|
|
310
402
|
}
|
|
311
|
-
function
|
|
403
|
+
function E(n) {
|
|
312
404
|
const e = /* @__PURE__ */ new Set();
|
|
313
405
|
for (const t of n)
|
|
314
406
|
t.kind === "group" && e.add(t.key);
|
|
315
407
|
return e;
|
|
316
408
|
}
|
|
317
|
-
function
|
|
409
|
+
function S() {
|
|
318
410
|
return /* @__PURE__ */ new Set();
|
|
319
411
|
}
|
|
320
412
|
function K(n) {
|
|
321
413
|
return n.kind !== "group" ? 0 : n.rows.length;
|
|
322
414
|
}
|
|
323
|
-
const
|
|
324
|
-
class
|
|
415
|
+
const G = "@layer tbw-plugins{.group-row{display:grid;grid-template-columns:var(--tbw-column-template);background:var(--tbw-grouping-rows-bg, var(--tbw-color-panel-bg));font-weight:500;border-bottom:var(--tbw-row-divider);min-height:var(--tbw-row-height)}.group-row .cell{display:flex;align-items:center;padding:var(--tbw-cell-padding, .125rem .5rem)}.group-row:hover{background:var(--tbw-grouping-rows-bg-hover, var(--tbw-color-row-hover))}.group-toggle{cursor:pointer;-webkit-user-select:none;user-select:none;display:inline-flex;align-items:center;justify-content:center;width:var(--tbw-toggle-size, 1.25rem);height:var(--tbw-toggle-size, 1.25rem);margin-right:.25rem;background:none;border:0;font:inherit}.group-toggle:hover{background:var(--tbw-grouping-rows-toggle-hover, var(--tbw-color-row-hover));border-radius:var(--tbw-border-radius, .125rem)}.group-label{display:inline-flex;align-items:center;gap:var(--tbw-panel-gap, var(--tbw-spacing-md, .5rem))}.group-count{color:var(--tbw-grouping-rows-count-color, var(--tbw-color-fg-muted));font-size:var(--tbw-font-size-xs, .85em);font-weight:400}.group-row{padding-left:calc(var(--tbw-group-depth, 0) * var(--tbw-group-indent-width, 1.25em))}.data-grid-row.tbw-group-slide-in{animation:tbw-group-slide-in var(--tbw-animation-duration, .2s) var(--tbw-animation-easing, ease-out) forwards}@keyframes tbw-group-slide-in{0%{opacity:0;transform:translate(-8px)}to{opacity:1;transform:translate(0)}}.data-grid-row.tbw-group-fade-in{animation:tbw-group-fade-in var(--tbw-animation-duration, .2s) var(--tbw-animation-easing, ease-out) forwards}@keyframes tbw-group-fade-in{0%{opacity:0}to{opacity:1}}}";
|
|
416
|
+
class T extends R {
|
|
325
417
|
name = "groupingRows";
|
|
326
|
-
|
|
418
|
+
styles = G;
|
|
327
419
|
get defaultConfig() {
|
|
328
420
|
return {
|
|
329
421
|
defaultExpanded: !1,
|
|
@@ -341,15 +433,12 @@ class E extends R {
|
|
|
341
433
|
keysToAnimate = /* @__PURE__ */ new Set();
|
|
342
434
|
// #endregion
|
|
343
435
|
// #region Animation
|
|
436
|
+
/**
|
|
437
|
+
* Get expand/collapse animation style from plugin config.
|
|
438
|
+
* Uses base class isAnimationEnabled to respect grid-level settings.
|
|
439
|
+
*/
|
|
344
440
|
get animationStyle() {
|
|
345
|
-
|
|
346
|
-
if (t === !1 || t === "off") return !1;
|
|
347
|
-
if (t !== !0 && t !== "on") {
|
|
348
|
-
const i = this.shadowRoot?.host;
|
|
349
|
-
if (i && getComputedStyle(i).getPropertyValue("--tbw-animation-enabled").trim() === "0")
|
|
350
|
-
return !1;
|
|
351
|
-
}
|
|
352
|
-
return this.config.animation ?? "slide";
|
|
441
|
+
return this.isAnimationEnabled ? this.config.animation ?? "slide" : !1;
|
|
353
442
|
}
|
|
354
443
|
// #endregion
|
|
355
444
|
// #region Lifecycle
|
|
@@ -369,119 +458,136 @@ class E extends R {
|
|
|
369
458
|
const t = this.config;
|
|
370
459
|
if (typeof t.groupOn != "function")
|
|
371
460
|
return this.isActive = !1, this.flattenedRows = [], [...e];
|
|
372
|
-
const
|
|
461
|
+
const r = A({
|
|
373
462
|
rows: [...e],
|
|
374
463
|
config: t,
|
|
375
464
|
expanded: this.expandedKeys
|
|
376
465
|
});
|
|
377
|
-
if (
|
|
466
|
+
if (r.length === 0)
|
|
378
467
|
return this.isActive = !1, this.flattenedRows = [], [...e];
|
|
379
|
-
this.isActive = !0, this.flattenedRows =
|
|
380
|
-
const
|
|
381
|
-
return
|
|
382
|
-
if (
|
|
383
|
-
const
|
|
384
|
-
|
|
468
|
+
this.isActive = !0, this.flattenedRows = r, this.keysToAnimate.clear();
|
|
469
|
+
const s = /* @__PURE__ */ new Set();
|
|
470
|
+
return r.forEach((i, d) => {
|
|
471
|
+
if (i.kind === "data") {
|
|
472
|
+
const o = `data-${d}`;
|
|
473
|
+
s.add(o), this.previousVisibleKeys.has(o) || this.keysToAnimate.add(o);
|
|
385
474
|
}
|
|
386
|
-
}), this.previousVisibleKeys =
|
|
475
|
+
}), this.previousVisibleKeys = s, r.map((i) => i.kind === "group" ? {
|
|
387
476
|
__isGroupRow: !0,
|
|
388
|
-
__groupKey:
|
|
389
|
-
__groupValue:
|
|
390
|
-
__groupDepth:
|
|
391
|
-
__groupRows:
|
|
392
|
-
__groupExpanded:
|
|
393
|
-
__groupRowCount: K(
|
|
394
|
-
} :
|
|
477
|
+
__groupKey: i.key,
|
|
478
|
+
__groupValue: i.value,
|
|
479
|
+
__groupDepth: i.depth,
|
|
480
|
+
__groupRows: i.rows,
|
|
481
|
+
__groupExpanded: i.expanded,
|
|
482
|
+
__groupRowCount: K(i)
|
|
483
|
+
} : i.row);
|
|
395
484
|
}
|
|
396
485
|
onCellClick(e) {
|
|
397
486
|
const t = e.row;
|
|
398
487
|
if (t?.__isGroupRow && e.originalEvent.target?.closest(".group-toggle"))
|
|
399
488
|
return this.toggle(t.__groupKey), !0;
|
|
400
489
|
}
|
|
490
|
+
onKeyDown(e) {
|
|
491
|
+
if (e.key !== " ") return;
|
|
492
|
+
const t = this.grid._focusRow, r = this.rows[t];
|
|
493
|
+
if (r?.__isGroupRow)
|
|
494
|
+
return e.preventDefault(), this.toggle(r.__groupKey), this.requestRenderWithFocus(), !0;
|
|
495
|
+
}
|
|
401
496
|
/**
|
|
402
497
|
* Render a row. Returns true if we handled the row (group row), false otherwise.
|
|
403
498
|
*/
|
|
404
|
-
renderRow(e, t,
|
|
499
|
+
renderRow(e, t, r) {
|
|
405
500
|
if (!e?.__isGroupRow)
|
|
406
501
|
return !1;
|
|
407
|
-
const
|
|
408
|
-
if (
|
|
409
|
-
const
|
|
502
|
+
const s = this.config;
|
|
503
|
+
if (s.groupRowRenderer) {
|
|
504
|
+
const o = () => {
|
|
410
505
|
this.toggle(e.__groupKey);
|
|
411
|
-
},
|
|
506
|
+
}, a = s.groupRowRenderer({
|
|
412
507
|
key: e.__groupKey,
|
|
413
508
|
value: e.__groupValue,
|
|
414
509
|
depth: e.__groupDepth,
|
|
415
510
|
rows: e.__groupRows,
|
|
416
511
|
expanded: e.__groupExpanded,
|
|
417
|
-
toggleExpand:
|
|
512
|
+
toggleExpand: o
|
|
418
513
|
});
|
|
419
|
-
if (
|
|
420
|
-
return t.className = "group-row", t.__isCustomRow = !0, t.setAttribute("data-group-depth", String(e.__groupDepth)), typeof
|
|
514
|
+
if (a)
|
|
515
|
+
return t.className = "data-grid-row group-row", t.__isCustomRow = !0, t.setAttribute("data-group-depth", String(e.__groupDepth)), typeof a == "string" ? t.innerHTML = a : (t.innerHTML = "", t.appendChild(a)), !0;
|
|
421
516
|
}
|
|
422
|
-
const
|
|
517
|
+
const i = () => {
|
|
423
518
|
this.toggle(e.__groupKey);
|
|
424
519
|
};
|
|
425
|
-
return t.className = "group-row", t.__isCustomRow = !0, t.setAttribute("data-group-depth", String(e.__groupDepth)), t.setAttribute("role", "row"), t.setAttribute("aria-expanded", String(e.__groupExpanded)), t.style.
|
|
520
|
+
return t.className = "data-grid-row group-row", t.__isCustomRow = !0, t.setAttribute("data-group-depth", String(e.__groupDepth)), t.setAttribute("role", "row"), t.setAttribute("aria-expanded", String(e.__groupExpanded)), t.style.setProperty("--tbw-group-depth", String(e.__groupDepth || 0)), s.indentWidth !== void 0 && t.style.setProperty("--tbw-group-indent-width", `${s.indentWidth}px`), t.innerHTML = "", s.fullWidth !== !1 ? this.renderFullWidthGroupRow(e, t, i) : this.renderPerColumnGroupRow(e, t, i), !0;
|
|
426
521
|
}
|
|
427
522
|
afterRender() {
|
|
428
523
|
const e = this.animationStyle;
|
|
429
524
|
if (e === !1 || this.keysToAnimate.size === 0) return;
|
|
430
|
-
const t = this.
|
|
525
|
+
const t = this.gridElement?.querySelector(".rows");
|
|
431
526
|
if (!t) return;
|
|
432
|
-
const
|
|
433
|
-
for (const
|
|
434
|
-
const
|
|
435
|
-
|
|
527
|
+
const r = e === "fade" ? "tbw-group-fade-in" : "tbw-group-slide-in";
|
|
528
|
+
for (const s of t.querySelectorAll(".data-grid-row:not(.group-row)")) {
|
|
529
|
+
const i = s.querySelector(".cell[data-row]"), d = i ? parseInt(i.getAttribute("data-row") ?? "-1", 10) : -1, a = this.flattenedRows[d]?.kind === "data" ? `data-${d}` : void 0;
|
|
530
|
+
a && this.keysToAnimate.has(a) && (s.classList.add(r), s.addEventListener("animationend", () => s.classList.remove(r), { once: !0 }));
|
|
436
531
|
}
|
|
437
532
|
this.keysToAnimate.clear();
|
|
438
533
|
}
|
|
439
534
|
// #endregion
|
|
440
535
|
// #region Private Rendering Helpers
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
536
|
+
/**
|
|
537
|
+
* Create a toggle button for expanding/collapsing a group.
|
|
538
|
+
*/
|
|
539
|
+
createToggleButton(e, t) {
|
|
540
|
+
const r = document.createElement("button");
|
|
541
|
+
return r.type = "button", r.className = `group-toggle${e ? " expanded" : ""}`, r.setAttribute("aria-label", e ? "Collapse group" : "Expand group"), this.setIcon(r, this.resolveIcon(e ? "collapse" : "expand")), r.addEventListener("click", (s) => {
|
|
542
|
+
s.stopPropagation(), t();
|
|
543
|
+
}), r;
|
|
544
|
+
}
|
|
545
|
+
/**
|
|
546
|
+
* Get the formatted label text for a group.
|
|
547
|
+
*/
|
|
548
|
+
getGroupLabelText(e, t, r) {
|
|
549
|
+
const s = this.config;
|
|
550
|
+
return s.formatLabel ? s.formatLabel(e, t, r) : String(e);
|
|
551
|
+
}
|
|
552
|
+
renderFullWidthGroupRow(e, t, r) {
|
|
553
|
+
const s = this.config, i = document.createElement("div");
|
|
554
|
+
i.className = "cell group-full", i.style.gridColumn = "1 / -1", i.setAttribute("role", "gridcell"), i.setAttribute("data-col", "0"), i.appendChild(this.createToggleButton(e.__groupExpanded, r));
|
|
555
|
+
const d = document.createElement("span");
|
|
556
|
+
if (d.className = "group-label", d.textContent = this.getGroupLabelText(e.__groupValue, e.__groupDepth || 0, e.__groupKey), i.appendChild(d), s.showRowCount !== !1) {
|
|
557
|
+
const o = document.createElement("span");
|
|
558
|
+
o.className = "group-count", o.textContent = `(${e.__groupRowCount ?? e.__groupRows?.length ?? 0})`, i.appendChild(o);
|
|
454
559
|
}
|
|
455
|
-
t.appendChild(
|
|
560
|
+
t.appendChild(i);
|
|
456
561
|
}
|
|
457
|
-
renderPerColumnGroupRow(e, t,
|
|
458
|
-
const
|
|
459
|
-
|
|
562
|
+
renderPerColumnGroupRow(e, t, r) {
|
|
563
|
+
const s = this.config, i = s.aggregators ?? {}, d = this.columns, o = e.__groupRows ?? [], u = this.gridElement?.querySelector(".body")?.style.gridTemplateColumns || "";
|
|
564
|
+
u && (t.style.display = "grid", t.style.gridTemplateColumns = u);
|
|
565
|
+
let h = !1;
|
|
566
|
+
d.forEach((p, f) => {
|
|
460
567
|
const l = document.createElement("div");
|
|
461
|
-
if (l.className = "cell group-cell", l.setAttribute("data-col", String(
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
const
|
|
467
|
-
if (y) {
|
|
468
|
-
const h = w(y, s, c.field, c);
|
|
469
|
-
p.textContent = h != null ? String(h) : String(e.__groupValue);
|
|
470
|
-
} else {
|
|
471
|
-
const h = r.formatLabel ? r.formatLabel(e.__groupValue, e.__groupDepth || 0, e.__groupKey) : String(e.__groupValue);
|
|
472
|
-
p.textContent = h;
|
|
473
|
-
}
|
|
474
|
-
if (l.appendChild(p), r.showRowCount !== !1) {
|
|
475
|
-
const h = document.createElement("span");
|
|
476
|
-
h.className = "group-count", h.textContent = ` (${s.length})`, l.appendChild(h);
|
|
477
|
-
}
|
|
478
|
-
} else {
|
|
479
|
-
const g = o[c.field];
|
|
568
|
+
if (l.className = "cell group-cell", l.setAttribute("data-col", String(f)), l.setAttribute("role", "gridcell"), C(p)) {
|
|
569
|
+
l.setAttribute("data-field", p.field), t.appendChild(l);
|
|
570
|
+
return;
|
|
571
|
+
}
|
|
572
|
+
if (h) {
|
|
573
|
+
const g = i[p.field];
|
|
480
574
|
if (g) {
|
|
481
|
-
const
|
|
482
|
-
l.textContent =
|
|
575
|
+
const b = y(g, o, p.field, p);
|
|
576
|
+
l.textContent = b != null ? String(b) : "";
|
|
483
577
|
} else
|
|
484
578
|
l.textContent = "";
|
|
579
|
+
} else {
|
|
580
|
+
h = !0, l.appendChild(this.createToggleButton(e.__groupExpanded, r));
|
|
581
|
+
const g = document.createElement("span"), b = i[p.field];
|
|
582
|
+
if (b) {
|
|
583
|
+
const m = y(b, o, p.field, p);
|
|
584
|
+
g.textContent = m != null ? String(m) : String(e.__groupValue);
|
|
585
|
+
} else
|
|
586
|
+
g.textContent = this.getGroupLabelText(e.__groupValue, e.__groupDepth || 0, e.__groupKey);
|
|
587
|
+
if (l.appendChild(g), s.showRowCount !== !1) {
|
|
588
|
+
const m = document.createElement("span");
|
|
589
|
+
m.className = "group-count", m.textContent = ` (${o.length})`, l.appendChild(m);
|
|
590
|
+
}
|
|
485
591
|
}
|
|
486
592
|
t.appendChild(l);
|
|
487
593
|
});
|
|
@@ -492,21 +598,21 @@ class E extends R {
|
|
|
492
598
|
* Expand all groups.
|
|
493
599
|
*/
|
|
494
600
|
expandAll() {
|
|
495
|
-
this.expandedKeys =
|
|
601
|
+
this.expandedKeys = E(this.flattenedRows), this.requestRender();
|
|
496
602
|
}
|
|
497
603
|
/**
|
|
498
604
|
* Collapse all groups.
|
|
499
605
|
*/
|
|
500
606
|
collapseAll() {
|
|
501
|
-
this.expandedKeys =
|
|
607
|
+
this.expandedKeys = S(), this.requestRender();
|
|
502
608
|
}
|
|
503
609
|
/**
|
|
504
610
|
* Toggle expansion of a specific group.
|
|
505
611
|
* @param key - The group key to toggle
|
|
506
612
|
*/
|
|
507
613
|
toggle(e) {
|
|
508
|
-
this.expandedKeys =
|
|
509
|
-
const t = this.flattenedRows.find((
|
|
614
|
+
this.expandedKeys = k(this.expandedKeys, e);
|
|
615
|
+
const t = this.flattenedRows.find((r) => r.kind === "group" && r.key === e);
|
|
510
616
|
this.emit("group-toggle", {
|
|
511
617
|
key: e,
|
|
512
618
|
expanded: this.expandedKeys.has(e),
|
|
@@ -595,11 +701,8 @@ class E extends R {
|
|
|
595
701
|
this.config.groupOn = e, this.requestRender();
|
|
596
702
|
}
|
|
597
703
|
// #endregion
|
|
598
|
-
// #region Styles
|
|
599
|
-
styles = S;
|
|
600
|
-
// #endregion
|
|
601
704
|
}
|
|
602
705
|
export {
|
|
603
|
-
|
|
706
|
+
T as GroupingRowsPlugin
|
|
604
707
|
};
|
|
605
708
|
//# sourceMappingURL=index.js.map
|