@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 R = {
|
|
2
2
|
expand: "▶",
|
|
3
3
|
collapse: "▼",
|
|
4
4
|
sortAsc: "▲",
|
|
@@ -8,9 +8,28 @@ const x = {
|
|
|
8
8
|
dragHandle: "⋮⋮",
|
|
9
9
|
toolPanel: "☰"
|
|
10
10
|
};
|
|
11
|
-
class
|
|
12
|
-
/**
|
|
13
|
-
|
|
11
|
+
class x {
|
|
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 R {
|
|
|
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 r = new CustomEvent(e, { detail: t, bubbles: !0, cancelable: !0 });
|
|
125
|
+
return this.grid?.dispatchEvent?.(r), r.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 R {
|
|
|
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 R {
|
|
|
168
216
|
*/
|
|
169
217
|
get gridIcons() {
|
|
170
218
|
const e = this.grid?.gridConfig?.icons ?? {};
|
|
171
|
-
return { ...
|
|
219
|
+
return { ...R, ...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(), r = parseInt(t, 10);
|
|
261
|
+
if (!isNaN(r)) return r;
|
|
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,10 +292,14 @@ class R {
|
|
|
199
292
|
}
|
|
200
293
|
// #endregion
|
|
201
294
|
}
|
|
295
|
+
const v = "__tbw_expander";
|
|
296
|
+
function C(n) {
|
|
297
|
+
return n.field === v;
|
|
298
|
+
}
|
|
202
299
|
const m = {
|
|
203
|
-
sum: (n, e) => n.reduce((t,
|
|
300
|
+
sum: (n, e) => n.reduce((t, r) => t + (Number(r[e]) || 0), 0),
|
|
204
301
|
avg: (n, e) => {
|
|
205
|
-
const t = n.reduce((
|
|
302
|
+
const t = n.reduce((r, o) => r + (Number(o[e]) || 0), 0);
|
|
206
303
|
return n.length ? t / n.length : 0;
|
|
207
304
|
},
|
|
208
305
|
count: (n) => n.length,
|
|
@@ -210,104 +307,104 @@ const m = {
|
|
|
210
307
|
max: (n, e) => Math.max(...n.map((t) => Number(t[e]) || -1 / 0)),
|
|
211
308
|
first: (n, e) => n[0]?.[e],
|
|
212
309
|
last: (n, e) => n[n.length - 1]?.[e]
|
|
213
|
-
},
|
|
310
|
+
}, w = /* @__PURE__ */ new Map(), c = {
|
|
214
311
|
/**
|
|
215
312
|
* Register a custom aggregator function.
|
|
216
313
|
*/
|
|
217
314
|
register(n, e) {
|
|
218
|
-
|
|
315
|
+
w.set(n, e);
|
|
219
316
|
},
|
|
220
317
|
/**
|
|
221
318
|
* Unregister a custom aggregator function.
|
|
222
319
|
*/
|
|
223
320
|
unregister(n) {
|
|
224
|
-
|
|
321
|
+
w.delete(n);
|
|
225
322
|
},
|
|
226
323
|
/**
|
|
227
324
|
* Get an aggregator function by reference.
|
|
228
325
|
*/
|
|
229
326
|
get(n) {
|
|
230
327
|
if (n !== void 0)
|
|
231
|
-
return typeof n == "function" ? n :
|
|
328
|
+
return typeof n == "function" ? n : w.get(n) ?? m[n];
|
|
232
329
|
},
|
|
233
330
|
/**
|
|
234
331
|
* Run an aggregator on a set of rows.
|
|
235
332
|
*/
|
|
236
|
-
run(n, e, t,
|
|
237
|
-
const
|
|
238
|
-
return
|
|
333
|
+
run(n, e, t, r) {
|
|
334
|
+
const o = this.get(n);
|
|
335
|
+
return o ? o(e, t, r) : void 0;
|
|
239
336
|
},
|
|
240
337
|
/**
|
|
241
338
|
* Check if an aggregator exists.
|
|
242
339
|
*/
|
|
243
340
|
has(n) {
|
|
244
|
-
return
|
|
341
|
+
return w.has(n) || n in m;
|
|
245
342
|
},
|
|
246
343
|
/**
|
|
247
344
|
* List all available aggregator names.
|
|
248
345
|
*/
|
|
249
346
|
list() {
|
|
250
|
-
return [...Object.keys(m), ...
|
|
347
|
+
return [...Object.keys(m), ...w.keys()];
|
|
251
348
|
}
|
|
252
349
|
};
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
const
|
|
257
|
-
|
|
258
|
-
function
|
|
259
|
-
const
|
|
260
|
-
if (typeof
|
|
350
|
+
c.register.bind(c);
|
|
351
|
+
c.unregister.bind(c);
|
|
352
|
+
c.get.bind(c);
|
|
353
|
+
const y = c.run.bind(c);
|
|
354
|
+
c.list.bind(c);
|
|
355
|
+
function A({ rows: n, config: e, expanded: t }) {
|
|
356
|
+
const r = e.groupOn;
|
|
357
|
+
if (typeof r != "function")
|
|
261
358
|
return [];
|
|
262
|
-
const
|
|
263
|
-
if (n.forEach((
|
|
264
|
-
let
|
|
265
|
-
|
|
266
|
-
let
|
|
267
|
-
|
|
268
|
-
const
|
|
269
|
-
let
|
|
270
|
-
|
|
271
|
-
}),
|
|
272
|
-
}),
|
|
359
|
+
const o = { key: "__root__", value: null, depth: -1, rows: [], children: /* @__PURE__ */ new Map() };
|
|
360
|
+
if (n.forEach((i) => {
|
|
361
|
+
let a = r(i);
|
|
362
|
+
a == null || a === !1 ? a = ["__ungrouped__"] : Array.isArray(a) || (a = [a]);
|
|
363
|
+
let d = o;
|
|
364
|
+
a.forEach((h, p) => {
|
|
365
|
+
const f = h == null ? "∅" : String(h), l = d.key === "__root__" ? f : d.key + "||" + f;
|
|
366
|
+
let g = d.children.get(f);
|
|
367
|
+
g || (g = { key: l, value: h, depth: p, rows: [], children: /* @__PURE__ */ new Map(), parent: d }, d.children.set(f, g)), d = g;
|
|
368
|
+
}), d.rows.push(i);
|
|
369
|
+
}), o.children.size === 1 && o.children.has("__ungrouped__") && o.children.get("__ungrouped__").rows.length === n.length)
|
|
273
370
|
return [];
|
|
274
|
-
const
|
|
275
|
-
if (
|
|
276
|
-
|
|
371
|
+
const s = [], u = (i) => {
|
|
372
|
+
if (i === o) {
|
|
373
|
+
i.children.forEach((d) => u(d));
|
|
277
374
|
return;
|
|
278
375
|
}
|
|
279
|
-
const
|
|
280
|
-
|
|
376
|
+
const a = t.has(i.key);
|
|
377
|
+
s.push({
|
|
281
378
|
kind: "group",
|
|
282
|
-
key:
|
|
283
|
-
value:
|
|
284
|
-
depth:
|
|
285
|
-
rows:
|
|
286
|
-
expanded:
|
|
287
|
-
}),
|
|
379
|
+
key: i.key,
|
|
380
|
+
value: i.value,
|
|
381
|
+
depth: i.depth,
|
|
382
|
+
rows: i.rows,
|
|
383
|
+
expanded: a
|
|
384
|
+
}), a && (i.children.size ? i.children.forEach((d) => u(d)) : i.rows.forEach((d) => s.push({ kind: "data", row: d, rowIndex: n.indexOf(d) })));
|
|
288
385
|
};
|
|
289
|
-
return u(
|
|
386
|
+
return u(o), s;
|
|
290
387
|
}
|
|
291
|
-
function
|
|
388
|
+
function k(n, e) {
|
|
292
389
|
const t = new Set(n);
|
|
293
390
|
return t.has(e) ? t.delete(e) : t.add(e), t;
|
|
294
391
|
}
|
|
295
|
-
function
|
|
392
|
+
function K(n) {
|
|
296
393
|
const e = /* @__PURE__ */ new Set();
|
|
297
394
|
for (const t of n)
|
|
298
395
|
t.kind === "group" && e.add(t.key);
|
|
299
396
|
return e;
|
|
300
397
|
}
|
|
301
|
-
function
|
|
398
|
+
function S() {
|
|
302
399
|
return /* @__PURE__ */ new Set();
|
|
303
400
|
}
|
|
304
|
-
function
|
|
401
|
+
function E(n) {
|
|
305
402
|
return n.kind !== "group" ? 0 : n.rows.length;
|
|
306
403
|
}
|
|
307
|
-
const
|
|
308
|
-
class
|
|
404
|
+
const G = '.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, 2px 8px)}.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:20px;height:20px;margin-right:4px;background:none;border:0;font:inherit}.group-toggle:hover{background:var(--tbw-grouping-rows-toggle-hover, var(--tbw-color-row-hover));border-radius:2px}.group-label{display:inline-flex;align-items:center;gap:8px}.group-count{color:var(--tbw-grouping-rows-count-color, var(--tbw-color-fg-muted));font-size:.85em;font-weight:400}[data-group-depth="0"] .group-label{padding-left:0}[data-group-depth="1"] .group-label{padding-left:20px}[data-group-depth="2"] .group-label{padding-left:40px}[data-group-depth="3"] .group-label{padding-left:60px}[data-group-depth="4"] .group-label{padding-left:80px}.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}}';
|
|
405
|
+
class T extends x {
|
|
309
406
|
name = "groupingRows";
|
|
310
|
-
|
|
407
|
+
styles = G;
|
|
311
408
|
get defaultConfig() {
|
|
312
409
|
return {
|
|
313
410
|
defaultExpanded: !1,
|
|
@@ -325,15 +422,12 @@ class E extends R {
|
|
|
325
422
|
keysToAnimate = /* @__PURE__ */ new Set();
|
|
326
423
|
// #endregion
|
|
327
424
|
// #region Animation
|
|
425
|
+
/**
|
|
426
|
+
* Get expand/collapse animation style from plugin config.
|
|
427
|
+
* Uses base class isAnimationEnabled to respect grid-level settings.
|
|
428
|
+
*/
|
|
328
429
|
get animationStyle() {
|
|
329
|
-
|
|
330
|
-
if (t === !1 || t === "off") return !1;
|
|
331
|
-
if (t !== !0 && t !== "on") {
|
|
332
|
-
const i = this.shadowRoot?.host;
|
|
333
|
-
if (i && getComputedStyle(i).getPropertyValue("--tbw-animation-enabled").trim() === "0")
|
|
334
|
-
return !1;
|
|
335
|
-
}
|
|
336
|
-
return this.config.animation ?? "slide";
|
|
430
|
+
return this.isAnimationEnabled ? this.config.animation ?? "slide" : !1;
|
|
337
431
|
}
|
|
338
432
|
// #endregion
|
|
339
433
|
// #region Lifecycle
|
|
@@ -353,119 +447,136 @@ class E extends R {
|
|
|
353
447
|
const t = this.config;
|
|
354
448
|
if (typeof t.groupOn != "function")
|
|
355
449
|
return this.isActive = !1, this.flattenedRows = [], [...e];
|
|
356
|
-
const
|
|
450
|
+
const r = A({
|
|
357
451
|
rows: [...e],
|
|
358
452
|
config: t,
|
|
359
453
|
expanded: this.expandedKeys
|
|
360
454
|
});
|
|
361
|
-
if (
|
|
455
|
+
if (r.length === 0)
|
|
362
456
|
return this.isActive = !1, this.flattenedRows = [], [...e];
|
|
363
|
-
this.isActive = !0, this.flattenedRows =
|
|
364
|
-
const
|
|
365
|
-
return
|
|
366
|
-
if (
|
|
367
|
-
const
|
|
368
|
-
|
|
457
|
+
this.isActive = !0, this.flattenedRows = r, this.keysToAnimate.clear();
|
|
458
|
+
const o = /* @__PURE__ */ new Set();
|
|
459
|
+
return r.forEach((s, u) => {
|
|
460
|
+
if (s.kind === "data") {
|
|
461
|
+
const i = `data-${u}`;
|
|
462
|
+
o.add(i), this.previousVisibleKeys.has(i) || this.keysToAnimate.add(i);
|
|
369
463
|
}
|
|
370
|
-
}), this.previousVisibleKeys =
|
|
464
|
+
}), this.previousVisibleKeys = o, r.map((s) => s.kind === "group" ? {
|
|
371
465
|
__isGroupRow: !0,
|
|
372
|
-
__groupKey:
|
|
373
|
-
__groupValue:
|
|
374
|
-
__groupDepth:
|
|
375
|
-
__groupRows:
|
|
376
|
-
__groupExpanded:
|
|
377
|
-
__groupRowCount:
|
|
378
|
-
} :
|
|
466
|
+
__groupKey: s.key,
|
|
467
|
+
__groupValue: s.value,
|
|
468
|
+
__groupDepth: s.depth,
|
|
469
|
+
__groupRows: s.rows,
|
|
470
|
+
__groupExpanded: s.expanded,
|
|
471
|
+
__groupRowCount: E(s)
|
|
472
|
+
} : s.row);
|
|
379
473
|
}
|
|
380
474
|
onCellClick(e) {
|
|
381
475
|
const t = e.row;
|
|
382
476
|
if (t?.__isGroupRow && e.originalEvent.target?.closest(".group-toggle"))
|
|
383
477
|
return this.toggle(t.__groupKey), !0;
|
|
384
478
|
}
|
|
479
|
+
onKeyDown(e) {
|
|
480
|
+
if (e.key !== " ") return;
|
|
481
|
+
const t = this.grid._focusRow, r = this.rows[t];
|
|
482
|
+
if (r?.__isGroupRow)
|
|
483
|
+
return e.preventDefault(), this.toggle(r.__groupKey), this.requestRenderWithFocus(), !0;
|
|
484
|
+
}
|
|
385
485
|
/**
|
|
386
486
|
* Render a row. Returns true if we handled the row (group row), false otherwise.
|
|
387
487
|
*/
|
|
388
|
-
renderRow(e, t,
|
|
488
|
+
renderRow(e, t, r) {
|
|
389
489
|
if (!e?.__isGroupRow)
|
|
390
490
|
return !1;
|
|
391
|
-
const
|
|
392
|
-
if (
|
|
393
|
-
const
|
|
491
|
+
const o = this.config;
|
|
492
|
+
if (o.groupRowRenderer) {
|
|
493
|
+
const i = () => {
|
|
394
494
|
this.toggle(e.__groupKey);
|
|
395
|
-
},
|
|
495
|
+
}, a = o.groupRowRenderer({
|
|
396
496
|
key: e.__groupKey,
|
|
397
497
|
value: e.__groupValue,
|
|
398
498
|
depth: e.__groupDepth,
|
|
399
499
|
rows: e.__groupRows,
|
|
400
500
|
expanded: e.__groupExpanded,
|
|
401
|
-
toggleExpand:
|
|
501
|
+
toggleExpand: i
|
|
402
502
|
});
|
|
403
|
-
if (
|
|
404
|
-
return t.className = "group-row", t.__isCustomRow = !0, t.setAttribute("data-group-depth", String(e.__groupDepth)), typeof
|
|
503
|
+
if (a)
|
|
504
|
+
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;
|
|
405
505
|
}
|
|
406
|
-
const
|
|
506
|
+
const s = () => {
|
|
407
507
|
this.toggle(e.__groupKey);
|
|
408
508
|
};
|
|
409
|
-
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.paddingLeft = `${(e.__groupDepth || 0) * (
|
|
509
|
+
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.paddingLeft = `${(e.__groupDepth || 0) * (o.indentWidth ?? 20)}px`, t.innerHTML = "", o.fullWidth !== !1 ? this.renderFullWidthGroupRow(e, t, s) : this.renderPerColumnGroupRow(e, t, s), !0;
|
|
410
510
|
}
|
|
411
511
|
afterRender() {
|
|
412
512
|
const e = this.animationStyle;
|
|
413
513
|
if (e === !1 || this.keysToAnimate.size === 0) return;
|
|
414
514
|
const t = this.shadowRoot?.querySelector(".rows");
|
|
415
515
|
if (!t) return;
|
|
416
|
-
const
|
|
417
|
-
for (const
|
|
418
|
-
const
|
|
419
|
-
|
|
516
|
+
const r = e === "fade" ? "tbw-group-fade-in" : "tbw-group-slide-in";
|
|
517
|
+
for (const o of t.querySelectorAll(".data-grid-row:not(.group-row)")) {
|
|
518
|
+
const s = o.querySelector(".cell[data-row]"), u = s ? parseInt(s.getAttribute("data-row") ?? "-1", 10) : -1, a = this.flattenedRows[u]?.kind === "data" ? `data-${u}` : void 0;
|
|
519
|
+
a && this.keysToAnimate.has(a) && (o.classList.add(r), o.addEventListener("animationend", () => o.classList.remove(r), { once: !0 }));
|
|
420
520
|
}
|
|
421
521
|
this.keysToAnimate.clear();
|
|
422
522
|
}
|
|
423
523
|
// #endregion
|
|
424
524
|
// #region Private Rendering Helpers
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
525
|
+
/**
|
|
526
|
+
* Create a toggle button for expanding/collapsing a group.
|
|
527
|
+
*/
|
|
528
|
+
createToggleButton(e, t) {
|
|
529
|
+
const r = document.createElement("button");
|
|
530
|
+
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", (o) => {
|
|
531
|
+
o.stopPropagation(), t();
|
|
532
|
+
}), r;
|
|
533
|
+
}
|
|
534
|
+
/**
|
|
535
|
+
* Get the formatted label text for a group.
|
|
536
|
+
*/
|
|
537
|
+
getGroupLabelText(e, t, r) {
|
|
538
|
+
const o = this.config;
|
|
539
|
+
return o.formatLabel ? o.formatLabel(e, t, r) : String(e);
|
|
540
|
+
}
|
|
541
|
+
renderFullWidthGroupRow(e, t, r) {
|
|
542
|
+
const o = this.config, s = document.createElement("div");
|
|
543
|
+
s.className = "cell group-full", s.style.gridColumn = "1 / -1", s.setAttribute("role", "gridcell"), s.setAttribute("data-col", "0"), s.appendChild(this.createToggleButton(e.__groupExpanded, r));
|
|
544
|
+
const u = document.createElement("span");
|
|
545
|
+
if (u.className = "group-label", u.textContent = this.getGroupLabelText(e.__groupValue, e.__groupDepth || 0, e.__groupKey), s.appendChild(u), o.showRowCount !== !1) {
|
|
546
|
+
const i = document.createElement("span");
|
|
547
|
+
i.className = "group-count", i.textContent = `(${e.__groupRowCount ?? e.__groupRows?.length ?? 0})`, s.appendChild(i);
|
|
438
548
|
}
|
|
439
|
-
t.appendChild(
|
|
549
|
+
t.appendChild(s);
|
|
440
550
|
}
|
|
441
|
-
renderPerColumnGroupRow(e, t,
|
|
442
|
-
const
|
|
443
|
-
|
|
551
|
+
renderPerColumnGroupRow(e, t, r) {
|
|
552
|
+
const o = this.config, s = o.aggregators ?? {}, u = this.columns, i = e.__groupRows ?? [], d = this.shadowRoot?.querySelector(".body")?.style.gridTemplateColumns || "";
|
|
553
|
+
d && (t.style.display = "grid", t.style.gridTemplateColumns = d);
|
|
554
|
+
let h = !1;
|
|
555
|
+
u.forEach((p, f) => {
|
|
444
556
|
const l = document.createElement("div");
|
|
445
|
-
if (l.className = "cell group-cell", l.setAttribute("data-col", String(
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
const
|
|
451
|
-
if (y) {
|
|
452
|
-
const h = w(y, s, c.field, c);
|
|
453
|
-
p.textContent = h != null ? String(h) : String(e.__groupValue);
|
|
454
|
-
} else {
|
|
455
|
-
const h = r.formatLabel ? r.formatLabel(e.__groupValue, e.__groupDepth || 0, e.__groupKey) : String(e.__groupValue);
|
|
456
|
-
p.textContent = h;
|
|
457
|
-
}
|
|
458
|
-
if (l.appendChild(p), r.showRowCount !== !1) {
|
|
459
|
-
const h = document.createElement("span");
|
|
460
|
-
h.className = "group-count", h.textContent = ` (${s.length})`, l.appendChild(h);
|
|
461
|
-
}
|
|
462
|
-
} else {
|
|
463
|
-
const g = o[c.field];
|
|
557
|
+
if (l.className = "cell group-cell", l.setAttribute("data-col", String(f)), l.setAttribute("role", "gridcell"), C(p)) {
|
|
558
|
+
l.setAttribute("data-field", p.field), t.appendChild(l);
|
|
559
|
+
return;
|
|
560
|
+
}
|
|
561
|
+
if (h) {
|
|
562
|
+
const g = s[p.field];
|
|
464
563
|
if (g) {
|
|
465
|
-
const
|
|
466
|
-
l.textContent =
|
|
564
|
+
const b = y(g, i, p.field, p);
|
|
565
|
+
l.textContent = b != null ? String(b) : "";
|
|
467
566
|
} else
|
|
468
567
|
l.textContent = "";
|
|
568
|
+
} else {
|
|
569
|
+
h = !0, l.appendChild(this.createToggleButton(e.__groupExpanded, r));
|
|
570
|
+
const g = document.createElement("span"), b = s[p.field];
|
|
571
|
+
if (b) {
|
|
572
|
+
const _ = y(b, i, p.field, p);
|
|
573
|
+
g.textContent = _ != null ? String(_) : String(e.__groupValue);
|
|
574
|
+
} else
|
|
575
|
+
g.textContent = this.getGroupLabelText(e.__groupValue, e.__groupDepth || 0, e.__groupKey);
|
|
576
|
+
if (l.appendChild(g), o.showRowCount !== !1) {
|
|
577
|
+
const _ = document.createElement("span");
|
|
578
|
+
_.className = "group-count", _.textContent = ` (${i.length})`, l.appendChild(_);
|
|
579
|
+
}
|
|
469
580
|
}
|
|
470
581
|
t.appendChild(l);
|
|
471
582
|
});
|
|
@@ -476,21 +587,21 @@ class E extends R {
|
|
|
476
587
|
* Expand all groups.
|
|
477
588
|
*/
|
|
478
589
|
expandAll() {
|
|
479
|
-
this.expandedKeys =
|
|
590
|
+
this.expandedKeys = K(this.flattenedRows), this.requestRender();
|
|
480
591
|
}
|
|
481
592
|
/**
|
|
482
593
|
* Collapse all groups.
|
|
483
594
|
*/
|
|
484
595
|
collapseAll() {
|
|
485
|
-
this.expandedKeys =
|
|
596
|
+
this.expandedKeys = S(), this.requestRender();
|
|
486
597
|
}
|
|
487
598
|
/**
|
|
488
599
|
* Toggle expansion of a specific group.
|
|
489
600
|
* @param key - The group key to toggle
|
|
490
601
|
*/
|
|
491
602
|
toggle(e) {
|
|
492
|
-
this.expandedKeys =
|
|
493
|
-
const t = this.flattenedRows.find((
|
|
603
|
+
this.expandedKeys = k(this.expandedKeys, e);
|
|
604
|
+
const t = this.flattenedRows.find((r) => r.kind === "group" && r.key === e);
|
|
494
605
|
this.emit("group-toggle", {
|
|
495
606
|
key: e,
|
|
496
607
|
expanded: this.expandedKeys.has(e),
|
|
@@ -579,11 +690,8 @@ class E extends R {
|
|
|
579
690
|
this.config.groupOn = e, this.requestRender();
|
|
580
691
|
}
|
|
581
692
|
// #endregion
|
|
582
|
-
// #region Styles
|
|
583
|
-
styles = S;
|
|
584
|
-
// #endregion
|
|
585
693
|
}
|
|
586
694
|
export {
|
|
587
|
-
|
|
695
|
+
T as GroupingRowsPlugin
|
|
588
696
|
};
|
|
589
697
|
//# sourceMappingURL=index.js.map
|