@toolbox-web/grid 2.0.0-rc.1 → 2.0.0-rc.3
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 +23 -6
- package/all.js +2 -2
- package/all.js.map +1 -1
- package/index.js +1 -1
- package/index.js.map +1 -1
- package/lib/core/internal/diagnostics.d.ts +9 -1
- package/lib/core/internal/sorting.d.ts +4 -0
- package/lib/core/plugin/base-plugin.d.ts +31 -0
- package/lib/core/plugin/plugin-manager.d.ts +4 -1
- package/lib/core/plugin/types.d.ts +2 -0
- package/lib/core/types.d.ts +20 -1
- package/lib/features/registry.js.map +1 -1
- package/lib/plugins/clipboard/ClipboardPlugin.d.ts +8 -1
- package/lib/plugins/clipboard/index.js +1 -1
- package/lib/plugins/clipboard/index.js.map +1 -1
- package/lib/plugins/column-virtualization/index.js +1 -1
- package/lib/plugins/column-virtualization/index.js.map +1 -1
- package/lib/plugins/context-menu/index.js +1 -1
- package/lib/plugins/context-menu/index.js.map +1 -1
- package/lib/plugins/editing/index.js +1 -1
- package/lib/plugins/editing/index.js.map +1 -1
- package/lib/plugins/export/ExportPlugin.d.ts +8 -1
- package/lib/plugins/export/index.js +1 -1
- package/lib/plugins/export/index.js.map +1 -1
- package/lib/plugins/filtering/index.js +1 -1
- package/lib/plugins/filtering/index.js.map +1 -1
- package/lib/plugins/grouping-columns/index.js +1 -1
- package/lib/plugins/grouping-columns/index.js.map +1 -1
- package/lib/plugins/grouping-rows/GroupingRowsPlugin.d.ts +46 -22
- package/lib/plugins/grouping-rows/grouping-rows.d.ts +15 -1
- package/lib/plugins/grouping-rows/index.js +2 -2
- package/lib/plugins/grouping-rows/index.js.map +1 -1
- package/lib/plugins/grouping-rows/types.d.ts +7 -35
- package/lib/plugins/master-detail/MasterDetailPlugin.d.ts +30 -0
- package/lib/plugins/master-detail/index.js +1 -1
- package/lib/plugins/master-detail/index.js.map +1 -1
- package/lib/plugins/multi-sort/index.js +1 -1
- package/lib/plugins/multi-sort/index.js.map +1 -1
- package/lib/plugins/pinned-columns/index.js +1 -1
- package/lib/plugins/pinned-columns/index.js.map +1 -1
- package/lib/plugins/pinned-rows/index.js +1 -1
- package/lib/plugins/pinned-rows/index.js.map +1 -1
- package/lib/plugins/pivot/PivotPlugin.d.ts +10 -0
- package/lib/plugins/pivot/index.js +1 -1
- package/lib/plugins/pivot/index.js.map +1 -1
- package/lib/plugins/print/index.js +1 -1
- package/lib/plugins/print/index.js.map +1 -1
- package/lib/plugins/reorder-columns/index.js +1 -1
- package/lib/plugins/reorder-columns/index.js.map +1 -1
- package/lib/plugins/reorder-rows/RowReorderPlugin.d.ts +3 -0
- package/lib/plugins/reorder-rows/index.js +1 -1
- package/lib/plugins/reorder-rows/index.js.map +1 -1
- package/lib/plugins/responsive/index.js +1 -1
- package/lib/plugins/responsive/index.js.map +1 -1
- package/lib/plugins/selection/index.js +1 -1
- package/lib/plugins/selection/index.js.map +1 -1
- package/lib/plugins/server-side/ServerSidePlugin.d.ts +48 -14
- package/lib/plugins/server-side/datasource-types.d.ts +189 -0
- package/lib/plugins/server-side/datasource.d.ts +5 -5
- package/lib/plugins/server-side/index.d.ts +1 -1
- package/lib/plugins/server-side/index.js +1 -1
- package/lib/plugins/server-side/index.js.map +1 -1
- package/lib/plugins/server-side/types.d.ts +8 -82
- package/lib/plugins/tooltip/index.js +1 -1
- package/lib/plugins/tooltip/index.js.map +1 -1
- package/lib/plugins/tree/TreePlugin.d.ts +26 -4
- package/lib/plugins/tree/index.js +1 -1
- package/lib/plugins/tree/index.js.map +1 -1
- package/lib/plugins/tree/tree-datasource.d.ts +13 -0
- package/lib/plugins/tree/types.d.ts +19 -0
- package/lib/plugins/undo-redo/index.js +1 -1
- package/lib/plugins/undo-redo/index.js.map +1 -1
- package/lib/plugins/visibility/index.js +1 -1
- package/lib/plugins/visibility/index.js.map +1 -1
- package/package.json +1 -1
- package/public.d.ts +3 -0
- package/umd/grid.all.umd.js +1 -1
- package/umd/grid.all.umd.js.map +1 -1
- package/umd/grid.umd.js +1 -1
- package/umd/grid.umd.js.map +1 -1
- package/umd/plugins/clipboard.umd.js +1 -1
- package/umd/plugins/clipboard.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-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/pivot.umd.js +1 -1
- package/umd/plugins/pivot.umd.js.map +1 -1
- package/umd/plugins/reorder-rows.umd.js +1 -1
- package/umd/plugins/reorder-rows.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/tooltip.umd.js +1 -1
- package/umd/plugins/tooltip.umd.js.map +1 -1
- package/umd/plugins/tree.umd.js +1 -1
- package/umd/plugins/tree.umd.js.map +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BaseGridPlugin, CellClickEvent, PluginManifest, PluginQuery } from '../../core/plugin/base-plugin';
|
|
1
|
+
import { BaseGridPlugin, CellClickEvent, HeaderClickEvent, GridElement, PluginManifest, PluginQuery } from '../../core/plugin/base-plugin';
|
|
2
2
|
import { GroupDefinition, GroupingRowsConfig, RenderRow } from './types';
|
|
3
3
|
/**
|
|
4
4
|
* Group state information returned by getGroupState()
|
|
@@ -77,6 +77,16 @@ export declare class GroupingRowsPlugin extends BaseGridPlugin<GroupingRowsConfi
|
|
|
77
77
|
* @internal
|
|
78
78
|
*/
|
|
79
79
|
static readonly manifest: PluginManifest<GroupingRowsConfig>;
|
|
80
|
+
/**
|
|
81
|
+
* Optional dependency on MultiSort for coordinated sort management.
|
|
82
|
+
* When MultiSort is loaded, GroupingRows queries its sort model to determine
|
|
83
|
+
* group header ordering. Without it, falls back to core sort state.
|
|
84
|
+
*/
|
|
85
|
+
static readonly dependencies: {
|
|
86
|
+
name: string;
|
|
87
|
+
required: boolean;
|
|
88
|
+
reason: string;
|
|
89
|
+
}[];
|
|
80
90
|
/** @internal */
|
|
81
91
|
readonly name = "groupingRows";
|
|
82
92
|
/** @internal */
|
|
@@ -90,16 +100,18 @@ export declare class GroupingRowsPlugin extends BaseGridPlugin<GroupingRowsConfi
|
|
|
90
100
|
private keysToAnimate;
|
|
91
101
|
/** Track if initial defaultExpanded has been applied */
|
|
92
102
|
private hasAppliedDefaultExpanded;
|
|
93
|
-
/** Pre-defined group definitions (
|
|
103
|
+
/** Pre-defined group definitions (from config, setGroups(), or datasource:data) */
|
|
94
104
|
private preDefinedGroups;
|
|
95
|
-
/**
|
|
105
|
+
/** Row data keyed by group key (from setGroupRows() or datasource:children) */
|
|
96
106
|
private groupRowsMap;
|
|
97
107
|
/** Groups currently in a loading state */
|
|
98
108
|
private loadingGroups;
|
|
99
|
-
/**
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
109
|
+
/** Column fields that produce group values (depth 0, 1, ...). Cached for
|
|
110
|
+
* the `grouping:get-grouped-fields` query so MultiSort can filter them out. */
|
|
111
|
+
private groupedFields;
|
|
112
|
+
/** User-specified sort directions per group depth level. Toggled via
|
|
113
|
+
* header clicks on grouped columns. */
|
|
114
|
+
private userGroupSortDirections;
|
|
103
115
|
/**
|
|
104
116
|
* Get expand/collapse animation style from plugin config.
|
|
105
117
|
* Uses base class isAnimationEnabled to respect grid-level settings.
|
|
@@ -126,6 +138,29 @@ export declare class GroupingRowsPlugin extends BaseGridPlugin<GroupingRowsConfi
|
|
|
126
138
|
* @internal
|
|
127
139
|
*/
|
|
128
140
|
handleQuery(query: PluginQuery): unknown;
|
|
141
|
+
/**
|
|
142
|
+
* Translate a flat row index to the top-level group index it belongs to.
|
|
143
|
+
* Walks flattenedRows up to the given index and counts depth-0 groups encountered.
|
|
144
|
+
*/
|
|
145
|
+
private getTopLevelGroupIndex;
|
|
146
|
+
/** @internal */
|
|
147
|
+
attach(grid: GridElement): void;
|
|
148
|
+
/**
|
|
149
|
+
* Intercept header clicks on grouped columns to toggle group sort direction.
|
|
150
|
+
* Returns `true` for grouped columns to prevent MultiSort from handling them.
|
|
151
|
+
* @internal
|
|
152
|
+
*/
|
|
153
|
+
onHeaderClick(event: HeaderClickEvent): boolean | void;
|
|
154
|
+
/**
|
|
155
|
+
* Build a sort-direction map for each group depth level by cross-referencing
|
|
156
|
+
* the active sort state with the column fields that produce group values.
|
|
157
|
+
*
|
|
158
|
+
* Supports three direction sources (in priority order):
|
|
159
|
+
* 1. User-set directions via header clicks on grouped columns
|
|
160
|
+
* 2. MultiSort plugin model (for backwards compatibility / state restore)
|
|
161
|
+
* 3. Core single-column sort state
|
|
162
|
+
*/
|
|
163
|
+
private resolveGroupSortDirections;
|
|
129
164
|
/**
|
|
130
165
|
* Auto-detect grouping configuration from grid config.
|
|
131
166
|
* Called by plugin system to determine if plugin should activate.
|
|
@@ -149,16 +184,6 @@ export declare class GroupingRowsPlugin extends BaseGridPlugin<GroupingRowsConfi
|
|
|
149
184
|
* Used when `groups` config or `setGroups()` provides external group structure.
|
|
150
185
|
*/
|
|
151
186
|
private processPreDefinedGroups;
|
|
152
|
-
/**
|
|
153
|
-
* Fetch group definitions from an async callback.
|
|
154
|
-
* Sets `preDefinedGroups` when resolved and triggers re-render.
|
|
155
|
-
*/
|
|
156
|
-
private fetchGroupsAsync;
|
|
157
|
-
/**
|
|
158
|
-
* Fetch rows for a group using the `rows` callback and update state.
|
|
159
|
-
* Manages loading indicator automatically. Guards against duplicate in-flight fetches.
|
|
160
|
-
*/
|
|
161
|
-
private fetchGroupRowsAsync;
|
|
162
187
|
/**
|
|
163
188
|
* Collect all group keys from a pre-defined group tree.
|
|
164
189
|
*/
|
|
@@ -259,9 +284,8 @@ export declare class GroupingRowsPlugin extends BaseGridPlugin<GroupingRowsConfi
|
|
|
259
284
|
/**
|
|
260
285
|
* Get the current pre-defined group structure.
|
|
261
286
|
*
|
|
262
|
-
* Returns the groups set via {@link setGroups}
|
|
263
|
-
* Returns an empty array when using `groupOn`-based grouping
|
|
264
|
-
* an async `groups` callback is still in flight.
|
|
287
|
+
* Returns the groups set via {@link setGroups}, received from `datasource:data`,
|
|
288
|
+
* or the `groups` config array. Returns an empty array when using `groupOn`-based grouping.
|
|
265
289
|
*
|
|
266
290
|
* @returns Current group definitions
|
|
267
291
|
*/
|
|
@@ -272,8 +296,8 @@ export declare class GroupingRowsPlugin extends BaseGridPlugin<GroupingRowsConfi
|
|
|
272
296
|
* Call this in response to a `group-expand` event after fetching rows
|
|
273
297
|
* from the server. The plugin will re-render to show the rows.
|
|
274
298
|
*
|
|
275
|
-
*
|
|
276
|
-
*
|
|
299
|
+
* When `ServerSidePlugin` is loaded, this is handled automatically via
|
|
300
|
+
* `datasource:children` events — you only need this for the imperative API.
|
|
277
301
|
*
|
|
278
302
|
* @param groupKey - The group key to populate
|
|
279
303
|
* @param rows - The row data for this group
|
|
@@ -5,6 +5,9 @@ interface BuildGroupingArgs {
|
|
|
5
5
|
expanded: Set<string>;
|
|
6
6
|
/** Initial expanded state to apply (processed by the plugin) */
|
|
7
7
|
initialExpanded?: Set<string>;
|
|
8
|
+
/** Sort direction per group depth level. 1 = ascending, -1 = descending.
|
|
9
|
+
* When omitted, groups at all levels sort ascending. */
|
|
10
|
+
groupSortDirections?: Map<number, 1 | -1>;
|
|
8
11
|
}
|
|
9
12
|
/**
|
|
10
13
|
* Build a flattened grouping projection (collapsed by default).
|
|
@@ -13,7 +16,18 @@ interface BuildGroupingArgs {
|
|
|
13
16
|
* @param args - The grouping arguments
|
|
14
17
|
* @returns Flattened array of render rows (groups + data rows)
|
|
15
18
|
*/
|
|
16
|
-
export declare function buildGroupedRowModel({ rows, config, expanded, initialExpanded }: BuildGroupingArgs): RenderRow[];
|
|
19
|
+
export declare function buildGroupedRowModel({ rows, config, expanded, initialExpanded, groupSortDirections }: BuildGroupingArgs): RenderRow[];
|
|
20
|
+
/**
|
|
21
|
+
* Discover which column field produces the group value at each depth level.
|
|
22
|
+
*
|
|
23
|
+
* Samples the first row's `groupOn` output to get the group path, then checks
|
|
24
|
+
* which column fields produce matching values for that row. This mapping allows
|
|
25
|
+
* the plugin to apply user-invoked column sort directions to the correct group
|
|
26
|
+
* depth levels.
|
|
27
|
+
*
|
|
28
|
+
* @returns Map from depth index to column field name, or empty map if unmappable
|
|
29
|
+
*/
|
|
30
|
+
export declare function resolveGroupFields(rows: any[], groupOn: (row: any) => any[] | any | null | false, columnFields: string[]): Map<number, string>;
|
|
17
31
|
/**
|
|
18
32
|
* Toggle expansion state for a group key.
|
|
19
33
|
*
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
const e="expanded",t="group-toggle",r="group-label",
|
|
2
|
-
return new Set;if("number"==typeof e){const r=t[e];return r?/* @__PURE__ */new Set([r]):/* @__PURE__ */new Set}return"string"==typeof e?/* @__PURE__ */new Set([e]):Array.isArray(e)?new Set(e):/* @__PURE__ */new Set}function x({groups:e,expanded:t,groupRows:r,loadingGroups:n,parentPath:o=[]}){const i=[],s=o.length;for(const a of e){const e=[...o,a.key],d=t.has(a.key),l=r.get(a.key)??[],u=n.has(a.key);if(i.push({kind:"group",key:a.key,value:a.value,depth:s,rows:l,expanded:d}),d)if(a.children?.length){const o=x({groups:a.children,expanded:t,groupRows:r,loadingGroups:n,parentPath:e});i.push(...o)}else u?i.push({kind:"data",row:{__loading:!0,__groupKey:a.key},rowIndex:-1}):l.forEach((e,t)=>{i.push({kind:"data",row:e,rowIndex:t})})}return i}function R(e,t,r=[]){for(const n of e){const e=[...r,n.key];if(n.key===t)return e;if(n.children?.length){const r=R(n.children,t,e);if(r.length>0)return r}}return[]}class E extends b{static manifest={incompatibleWith:[{name:"tree",reason:"Both plugins transform the entire row model. TreePlugin flattens nested hierarchies while GroupingRowsPlugin groups flat rows with synthetic headers. Use one approach per grid."},{name:"pivot",reason:"PivotPlugin creates its own aggregated row and column structure. Row grouping cannot be applied on top of pivot-generated rows."}],events:[{type:"grouping-state-change",description:"Emitted when groups are expanded/collapsed. Subscribers can react to row visibility changes."},{type:"group-expand",description:"Emitted when a pre-defined group is expanded. Use to lazily load group row data."},{type:"group-collapse",description:"Emitted when a pre-defined group is collapsed."}],queries:[{type:"canMoveRow",description:"Returns false for group header rows (cannot be reordered)"}],configRules:[{id:"groupingRows/accordion-defaultExpanded",severity:"warn",message:'"accordion: true" and "defaultExpanded" (non-false) are used together.\n → In accordion mode, only one group can be open at a time.\n → Using defaultExpanded with multiple groups will collapse to one on first toggle.\n → Consider using "defaultExpanded: false" or a single group key/index with accordion mode.',check:e=>!0===e.accordion&&!1!==e.defaultExpanded&&void 0!==e.defaultExpanded&&!("number"==typeof e.defaultExpanded)&&!("string"==typeof e.defaultExpanded)&&(!0===e.defaultExpanded||Array.isArray(e.defaultExpanded)&&e.defaultExpanded.length>1)}]};name="groupingRows";styles="@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)}@media(hover:hover){.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-aggregates{display:inline-flex;align-items:center;gap:var(--tbw-spacing-lg, 1rem);margin-left:var(--tbw-spacing-lg, 1rem);font-weight:400;font-size:var(--tbw-font-size-sm, .875em);color:var(--tbw-grouping-rows-aggregate-color, var(--tbw-color-fg-muted))}.group-aggregate{white-space:nowrap}.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}}}";get defaultConfig(){return{defaultExpanded:!1,showRowCount:!0,indentWidth:20,aggregators:{},animation:"slide",accordion:!1}}expandedKeys=/* @__PURE__ */new Set;flattenedRows=[];isActive=!1;previousVisibleKeys=/* @__PURE__ */new Set;keysToAnimate=/* @__PURE__ */new Set;hasAppliedDefaultExpanded=!1;preDefinedGroups=[];groupRowsMap=/* @__PURE__ */new Map;loadingGroups=/* @__PURE__ */new Set;groupsFetchInFlight=!1;rowsFetchInFlight=/* @__PURE__ */new Set;get animationStyle(){return!!this.isAnimationEnabled&&(this.config.animation??"slide")}detach(){this.expandedKeys.clear(),this.flattenedRows=[],this.isActive=!1,this.previousVisibleKeys.clear(),this.keysToAnimate.clear(),this.hasAppliedDefaultExpanded=!1,this.preDefinedGroups=[],this.groupRowsMap.clear(),this.loadingGroups.clear(),this.groupsFetchInFlight=!1,this.rowsFetchInFlight.clear()}getRowHeight(e,t){if(null!=this.config.groupRowHeight)return!0===e.__isGroupRow?this.config.groupRowHeight:void 0}handleQuery(e){if("canMoveRow"===e.type){const t=e.context;if(!0===t?.__isGroupRow)return!1}}static detect(e,t){return"function"==typeof t?.groupOn||"boolean"==typeof t?.enableRowGrouping||Array.isArray(t?.groups)||"function"==typeof t?.groups}processRows(e){if(this.preDefinedGroups.length>0||null!=this.config.groups)return"function"!=typeof this.config.groups||0!==this.preDefinedGroups.length||this.groupsFetchInFlight?this.preDefinedGroups.length>0||Array.isArray(this.config.groups)&&this.config.groups.length>0?this.processPreDefinedGroups():(this.isActive="function"==typeof this.config.groups,this.flattenedRows=[],[]):(this.fetchGroupsAsync(this.config.groups),this.isActive=!0,this.flattenedRows=[],[]);const t=this.config;if("function"!=typeof t.groupOn)return this.isActive=!1,this.flattenedRows=[],[...e];const r=_({rows:[...e],config:t,expanded:/* @__PURE__ */new Set});if(0===r.length)return this.isActive=!1,this.flattenedRows=[],[...e];let n;if(!this.hasAppliedDefaultExpanded&&0===this.expandedKeys.size&&!1!==t.defaultExpanded){const e=function(e){return e.filter(e=>"group"===e.kind).map(e=>e.key)}(r);n=v(t.defaultExpanded??!1,e),n.size>0&&(this.expandedKeys=new Set(n),this.hasAppliedDefaultExpanded=!0)}const o=_({rows:[...e],config:t,expanded:this.expandedKeys,initialExpanded:n});this.isActive=!0,this.flattenedRows=o,this.keysToAnimate.clear();const i=/* @__PURE__ */new Set;return o.forEach((e,t)=>{if("data"===e.kind){const e=`data-${t}`;i.add(e),this.previousVisibleKeys.has(e)||this.keysToAnimate.add(e)}}),this.previousVisibleKeys=i,o.map(e=>{return"group"===e.kind?{__isGroupRow:!0,__groupKey:e.key,__groupValue:e.value,__groupDepth:e.depth,__groupRows:e.rows,__groupExpanded:e.expanded,__groupRowCount:(t=e,"group"!==t.kind?0:t.rows.length),__rowCacheKey:`group:${e.key}`}:e.row;var t})}onCellClick(e){const r=e.row;if(r?.__isGroupRow){const n=e.originalEvent.target;if(n?.closest(`.${t}`))return this.toggle(r.__groupKey),!0}}onKeyDown(e){if(" "!==e.key)return;const t=this.grid._focusRow,r=this.rows[t];return r?.__isGroupRow?(e.preventDefault(),this.toggle(r.__groupKey),this.requestRenderWithFocus(),!0):void 0}renderRow(e,t,r){if(!0===e?.__loading&&e?.__groupKey){t.className="data-grid-row",t.__isCustomRow=!0,t.innerHTML="";const e=document.createElement("div");return e.className="cell",e.style.gridColumn="1 / -1",e.setAttribute("role","gridcell"),e.textContent=" ",t.appendChild(e),function(e){if(e.classList.add("tbw-row-loading"),e.setAttribute("aria-busy","true"),!e.querySelector(".tbw-row-loading-overlay")){const t=document.createElement("div");t.className="tbw-row-loading-overlay",t.setAttribute("aria-hidden","true");const r=document.createElement("div");r.className="tbw-row-loading-spinner",t.appendChild(r),e.appendChild(t)}}(t),!0}if(!e?.__isGroupRow)return!1;const n=this.config;if(n.groupRowRenderer){const r=()=>{this.toggle(e.__groupKey)},o=n.groupRowRenderer({key:e.__groupKey,value:e.__groupValue,depth:e.__groupDepth,rows:e.__groupRows,expanded:e.__groupExpanded,toggleExpand:r});if(o)return t.className="data-grid-row group-row",t.__isCustomRow=!0,t.setAttribute("data-group-depth",String(e.__groupDepth)),"string"==typeof o?t.innerHTML=o:(t.innerHTML="",t.appendChild(o)),!0}const o=()=>{this.toggle(e.__groupKey)};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)),void 0!==n.indentWidth&&t.style.setProperty("--tbw-group-indent-width",`${n.indentWidth}px`),t.style.height="",t.innerHTML="";return!1!==n.fullWidth?this.renderFullWidthGroupRow(e,t,o):this.renderPerColumnGroupRow(e,t,o),!0}afterRender(){const e=this.animationStyle;if(!1===e||0===this.keysToAnimate.size)return;const t=this.gridElement?.querySelector(".rows");if(!t)return;const r="fade"===e?"tbw-group-fade-in":"tbw-group-slide-in";for(const n of t.querySelectorAll(".data-grid-row:not(.group-row)")){const e=n.querySelector(".cell[data-row]"),t=e?parseInt(e.getAttribute("data-row")??"-1",10):-1,o=this.flattenedRows[t],i="data"===o?.kind?`data-${t}`:void 0;i&&this.keysToAnimate.has(i)&&(n.classList.add(r),n.addEventListener("animationend",()=>n.classList.remove(r),{once:!0}))}this.keysToAnimate.clear()}processPreDefinedGroups(){const e=this.preDefinedGroups.length>0?this.preDefinedGroups:Array.isArray(this.config.groups)?this.config.groups:[];if(0===e.length)return this.isActive=!1,this.flattenedRows=[],[];if(!this.hasAppliedDefaultExpanded&&0===this.expandedKeys.size&&!1!==this.config.defaultExpanded){const t=this.collectGroupKeys(e),r=v(this.config.defaultExpanded??!1,t);r.size>0&&(this.expandedKeys=new Set(r),this.hasAppliedDefaultExpanded=!0)}const t=x({groups:e,expanded:this.expandedKeys,groupRows:this.groupRowsMap,loadingGroups:this.loadingGroups});this.isActive=!0,this.flattenedRows=t,this.keysToAnimate.clear();const r=/* @__PURE__ */new Set;return t.forEach((e,t)=>{if("data"===e.kind){const e=`data-${t}`;r.add(e),this.previousVisibleKeys.has(e)||this.keysToAnimate.add(e)}}),this.previousVisibleKeys=r,t.map(t=>{if("group"===t.kind){const r=this.findGroupDefinition(e,t.key),n=r?.rowCount??t.rows.length;return{__isGroupRow:!0,__groupKey:t.key,__groupValue:t.value,__groupDepth:t.depth,__groupRows:t.rows,__groupExpanded:t.expanded,__groupRowCount:n,__rowCacheKey:`group:${t.key}`}}return t.row})}fetchGroupsAsync(e){this.groupsFetchInFlight=!0,e().then(e=>{this.groupsFetchInFlight=!1,this.preDefinedGroups=e,this.requestRender()},()=>{this.groupsFetchInFlight=!1})}fetchGroupRowsAsync(e,t){const r=this.config.rows;r&&!this.rowsFetchInFlight.has(e)&&(this.rowsFetchInFlight.add(e),this.loadingGroups.add(e),this.requestRender(),r(t).then(t=>{this.rowsFetchInFlight.delete(e),this.groupRowsMap.set(e,t),this.loadingGroups.delete(e),this.requestRender()},()=>{this.rowsFetchInFlight.delete(e),this.loadingGroups.delete(e),this.requestRender()}))}collectGroupKeys(e){const t=[];for(const r of e)t.push(r.key),r.children?.length&&t.push(...this.collectGroupKeys(r.children));return t}getActiveGroups(){return this.preDefinedGroups.length>0?this.preDefinedGroups:Array.isArray(this.config.groups)?this.config.groups:[]}findGroupDefinition(e,t){for(const r of e){if(r.key===t)return r;if(r.children?.length){const e=this.findGroupDefinition(r.children,t);if(e)return e}}}createToggleButton(r,n){const o=document.createElement("button");return o.type="button",o.className=`${t}${r?` ${e}`:""}`,o.setAttribute("aria-label",r?"Collapse group":"Expand group"),this.setIcon(o,r?"collapse":"expand"),o.addEventListener("click",e=>{e.stopPropagation(),n()}),o}getGroupLabelText(e,t,r){const n=this.config;return n.formatLabel?n.formatLabel(e,t,r):String(e)}renderFullWidthGroupRow(e,t,o){const i=this.config,a=i.aggregators??{},d=e.__groupRows??[],l=document.createElement("div");l.className="cell group-full",l.style.gridColumn="1 / -1",l.setAttribute("role","gridcell"),l.setAttribute("data-col","0"),l.appendChild(this.createToggleButton(e.__groupExpanded,o));const u=document.createElement("span");if(u.className=r,u.textContent=this.getGroupLabelText(e.__groupValue,e.__groupDepth||0,e.__groupKey),l.appendChild(u),!1!==i.showRowCount){const t=document.createElement("span");t.className=n,t.textContent=`(${e.__groupRowCount??e.__groupRows?.length??0})`,l.appendChild(t)}const p=Object.entries(a);if(p.length>0){const e=document.createElement("span");e.className="group-aggregates";for(const[t,r]of p){const n=this.columns.find(e=>e.field===t),o=s.run(r,d,t,n);if(null!=o){const r=document.createElement("span");r.className="group-aggregate",r.setAttribute("data-field",t);const i=n?.header??t;r.textContent=`${i}: ${o}`,e.appendChild(r)}}e.children.length>0&&l.appendChild(e)}t.appendChild(l)}renderPerColumnGroupRow(e,t,r){const o=this.config,i=o.aggregators??{},a=this.columns,d=e.__groupRows??[],l=this.gridElement?.querySelector(".body"),u=l?.style.gridTemplateColumns||"";u&&(t.style.display="grid",t.style.gridTemplateColumns=u);let p=!1;a.forEach((a,l)=>{const u=document.createElement("div");if(u.className="cell group-cell",u.setAttribute("data-col",String(l)),u.setAttribute("role","gridcell"),"__tbw_expander"===a.field)return u.setAttribute("data-field",a.field),void t.appendChild(u);if(p){const e=i[a.field];if(e){const t=s.run(e,d,a.field,a);u.textContent=null!=t?String(t):""}else u.textContent=""}else{p=!0,u.appendChild(this.createToggleButton(e.__groupExpanded,r));const t=document.createElement("span"),l=i[a.field];if(l){const r=s.run(l,d,a.field,a);t.textContent=String(null!=r?r:e.__groupValue)}else t.textContent=this.getGroupLabelText(e.__groupValue,e.__groupDepth||0,e.__groupKey);if(u.appendChild(t),!1!==o.showRowCount){const e=document.createElement("span");e.className=n,e.textContent=` (${d.length})`,u.appendChild(e)}}t.appendChild(u)})}expandAll(){this.expandedKeys=function(e){const t=/* @__PURE__ */new Set;for(const r of e)"group"===r.kind&&t.add(r.key);return t}(this.flattenedRows),this.emitPluginEvent("grouping-state-change",{expandedKeys:[...this.expandedKeys]}),this.requestRender()}collapseAll(){this.expandedKeys=/* @__PURE__ */new Set,this.emitPluginEvent("grouping-state-change",{expandedKeys:[...this.expandedKeys]}),this.requestRender()}toggle(e){const t=!this.expandedKeys.has(e),r=this.config,n=this.flattenedRows.find(t=>"group"===t.kind&&t.key===e);if(r.accordion&&t&&n){const t=/* @__PURE__ */new Set;for(const r of this.expandedKeys)if(e.startsWith(r+"||")||r.startsWith(e+"||"))e.startsWith(r+"||")&&t.add(r);else{const e=this.flattenedRows.find(e=>"group"===e.kind&&e.key===r);e&&e.depth!==n.depth&&t.add(r)}t.add(e),this.expandedKeys=t}else this.expandedKeys=function(e,t){const r=new Set(e);return r.has(t)?r.delete(t):r.add(t),r}(this.expandedKeys,e);this.emit("group-toggle",{key:e,expanded:this.expandedKeys.has(e),value:n?.value,depth:n?.depth??0});const o=this.getActiveGroups();if(o.length>0){const n=R(o,e);if(t){if(this.emit("group-expand",{groupKey:e,groupPath:n}),r.rows&&!this.groupRowsMap.has(e)){const t=this.findGroupDefinition(o,e);t&&this.fetchGroupRowsAsync(e,t)}}else this.emit("group-collapse",{groupKey:e,groupPath:n})}const i=this.expandedKeys.has(e),s=null!=n?.value?String(n.value):e;if(i){const e=n?.rows?.length??0;u(this.gridElement,p(this.gridElement,"groupExpanded",s,e))}else u(this.gridElement,p(this.gridElement,"groupCollapsed",s));this.emitPluginEvent("grouping-state-change",{expandedKeys:[...this.expandedKeys]}),this.requestRender()}isExpanded(e){return this.expandedKeys.has(e)}expand(e){this.expandedKeys.has(e)||(this.expandedKeys=/* @__PURE__ */new Set([...this.expandedKeys,e]),this.requestRender())}collapse(e){if(this.expandedKeys.has(e)){const t=new Set(this.expandedKeys);t.delete(e),this.expandedKeys=t,this.requestRender()}}getGroupState(){const e=this.flattenedRows.filter(e=>"group"===e.kind);return{isActive:this.isActive,expandedCount:this.expandedKeys.size,totalGroups:e.length,expandedKeys:[...this.expandedKeys]}}getRowCount(){return this.flattenedRows.length}refreshGroups(){this.requestRender()}getExpandedGroups(){return[...this.expandedKeys]}getFlattenedRows(){return this.flattenedRows}isGroupingActive(){return this.isActive}setGroupOn(e){this.config.groupOn=e,this.requestRender()}setGroups(e){this.preDefinedGroups=e,this.groupRowsMap.clear(),this.loadingGroups.clear(),this.rowsFetchInFlight.clear(),this.expandedKeys.clear(),this.hasAppliedDefaultExpanded=!1,this.requestRender()}getGroups(){return this.preDefinedGroups.length>0?[...this.preDefinedGroups]:Array.isArray(this.config.groups)?[...this.config.groups]:[]}setGroupRows(e,t){this.groupRowsMap.set(e,t),this.loadingGroups.delete(e),this.requestRender()}setGroupLoading(e,t){t?this.loadingGroups.add(e):this.loadingGroups.delete(e),this.requestRender()}clearGroupRows(e){null!=e?(this.groupRowsMap.delete(e),this.rowsFetchInFlight.delete(e)):(this.groupRowsMap.clear(),this.rowsFetchInFlight.clear()),this.requestRender()}}export{E as GroupingRowsPlugin};
|
|
1
|
+
const e="expanded",t="group-toggle",r="group-label",o="group-count",n={sum:(e,t)=>{let r=0;for(let o=0;o<e.length;o++)r+=Number(e[o][t])||0;return r},avg:(e,t)=>{if(!e.length)return 0;let r=0;for(let o=0;o<e.length;o++)r+=Number(e[o][t])||0;return r/e.length},count:e=>e.length,min:(e,t)=>{if(!e.length)return 0;let r=1/0;for(let o=0;o<e.length;o++){const n=Number(e[o][t]);n<r&&(r=n)}return r},max:(e,t)=>{if(!e.length)return 0;let r=-1/0;for(let o=0;o<e.length;o++){const n=Number(e[o][t]);n>r&&(r=n)}return r},first:(e,t)=>e[0]?.[t],last:(e,t)=>e[e.length-1]?.[t]},i=/* @__PURE__ */new Map,s={register(e,t){i.set(e,t)},unregister(e){i.delete(e)},get(e){if(void 0!==e)return"function"==typeof e?e:i.get(e)??n[e]},run(e,t,r,o){const n=this.get(e);return n?n(t,r,o):void 0},has:e=>i.has(e)||e in n,list:()=>[...Object.keys(n),...i.keys()]},a={sortApplied:(e,t)=>`Sorted by ${e}, ${t}`,sortCleared:()=>"Sort cleared",filterApplied:e=>`Filter applied on ${e}`,filterCleared:e=>`Filter cleared from ${e}`,allFiltersCleared:()=>"All filters cleared",groupExpanded:(e,t)=>`Group ${e} expanded, ${t} rows`,groupCollapsed:e=>`Group ${e} collapsed`,selectionChanged:e=>`${e} rows selected`,editingStarted:e=>`Editing row ${e+1}`,editingCommitted:e=>`Row ${e+1} saved`,dataLoaded:e=>`${e} rows loaded`},d='<svg viewBox="0 0 16 16" width="12" height="12"><path fill="currentColor" d="M6 10.5a.5.5 0 0 1 .5-.5h3a.5.5 0 0 1 0 1h-3a.5.5 0 0 1-.5-.5zm-2-3a.5.5 0 0 1 .5-.5h7a.5.5 0 0 1 0 1h-7a.5.5 0 0 1-.5-.5zm-2-3a.5.5 0 0 1 .5-.5h11a.5.5 0 0 1 0 1h-11a.5.5 0 0 1-.5-.5z"/></svg>',u={expand:"▶",collapse:"▼",sortAsc:"▲",sortDesc:"▼",sortNone:"⇅",submenuArrow:"▶",dragHandle:"⋮⋮",toolPanel:"☰",filter:d,filterActive:d,print:"🖨️"};function l(e,t){if(!e)return;const r="effectiveConfig"in e?e.effectiveConfig:void 0;if(!1===r?.a11y?.announcements)return;const o=e.querySelector?.(".tbw-sr-only");o&&(o.textContent="",requestAnimationFrame(()=>{o.textContent=t}))}function p(e,t,...r){const o=e&&"effectiveConfig"in e?e.effectiveConfig:void 0,n=o?.a11y?.messages?.[t];return n?n(...r):a[t](...r)}function g(e,t){return`[tbw-grid${e?`#${e}`:""}${t?`:${t}`:""}]`}function c(e,t,r,o){return`${g(r,o)} ${e}: ${t}\n\n → More info: ${function(e){return`https://toolboxjs.com/grid/errors#${e.toLowerCase()}`}(e)}`}["__otorp__","__retteGenifed__","__retteSenifed__","rotcurtsnoc","wodniw","sihTlabolg","labolg","ssecorp","noitcnuF","tropmi","lave","tcelfeR","yxorP","rorrE","stnemugra","tnemucod","noitacol","eikooc","egarotSlacol","egarotSnoisses","BDdexedni","hctef","tseuqeRpttHLMX","tekcoSbeW","rekroW","rekroWderahS","rekroWecivreS","renepo","tnerap","pot","semarf","fles"].map(e=>e.split("").reverse().join(""));const h=/* @__PURE__ */new Set(["script","iframe","object","embed","form","input","button","textarea","select","link","meta","base","style","template","slot","portal","frame","frameset","applet","noscript","noembed","plaintext","xmp","listing"]),f=/^on\w+$/i,w=/* @__PURE__ */new Set(["href","src","action","formaction","data","srcdoc","xlink:href","poster","srcset"]),m=/^\s*(javascript|vbscript|data|blob):/i;function y(e){if(!e||"string"!=typeof e)return"";if(-1===e.indexOf("<"))return e;const t=document.createElement("template");return t.innerHTML=e,function(e){const t=[],r=e.querySelectorAll("*");for(const o of r){const e=o.tagName.toLowerCase();if(h.has(e)){t.push(o);continue}if("svg"===e||"http://www.w3.org/2000/svg"===o.namespaceURI){if(Array.from(o.attributes).some(e=>f.test(e.name)||"href"===e.name||"xlink:href"===e.name)){t.push(o);continue}}const r=[];for(const t of o.attributes){const e=t.name.toLowerCase();f.test(e)?r.push(t.name):(w.has(e)&&m.test(t.value)||"style"===e&&/expression\s*\(|javascript:|behavior\s*:/i.test(t.value))&&r.push(t.name)}r.forEach(e=>o.removeAttribute(e))}t.forEach(e=>e.remove())}(t.content),t.innerHTML}class v{static dependencies;static manifest;aliases;version="undefined"!=typeof __GRID_VERSION__?__GRID_VERSION__:"dev";styles;cellRenderers;headerRenderers;cellEditors;grid;config;userConfig;#e;get defaultConfig(){return{}}constructor(e={}){this.userConfig=e}attach(e){this.#e?.abort(),this.#e=new AbortController,this.grid=e,this.config={...this.defaultConfig,...this.userConfig}}detach(){this.#e?.abort(),this.#e=void 0}getPlugin(e){return this.grid?.getPlugin(e)}emit(e,t){this.grid?.dispatchEvent?.(new CustomEvent(e,{detail:t,bubbles:!0}))}emitCancelable(e,t){const r=new CustomEvent(e,{detail:t,bubbles:!0,cancelable:!0});return this.grid?.dispatchEvent?.(r),r.defaultPrevented}on(e,t){this.grid?._pluginManager?.subscribe(this,e,t)}off(e){this.grid?._pluginManager?.unsubscribe(this,e)}emitPluginEvent(e,t){this.grid?._pluginManager?.emitPluginEvent(e,t)}broadcast(e,t){this.emitPluginEvent(e,t),this.emit(e,t)}requestRender(){this.grid?.requestRender?.()}requestColumnsRender(){this.grid?.requestColumnsRender?.()}requestRenderWithFocus(){this.grid?.requestRenderWithFocus?.()}requestAfterRender(){this.grid?.requestAfterRender?.()}requestVirtualRefresh(){this.grid?.requestVirtualRefresh?.()}get rows(){return this.grid?.rows??[]}get sourceRows(){return this.grid?.sourceRows??[]}get columns(){return this.grid?.columns??[]}get visibleColumns(){return this.grid?._visibleColumns??[]}get gridElement(){return this.grid?._hostElement}get disconnectSignal(){return this.#e?.signal??this.grid?.disconnectSignal}get gridIcons(){const e=this.grid?.gridConfig?.icons??{};return{...u,...e}}get isAnimationEnabled(){const e=this.grid?.effectiveConfig?.animation?.mode??"reduced-motion";if(!1===e||"off"===e)return!1;if(!0===e||"on"===e)return!0;const t=this.gridElement;if(t){return"0"!==getComputedStyle(t).getPropertyValue("--tbw-animation-enabled").trim()}return!0}get animationDuration(){const e=this.gridElement;if(e){const t=getComputedStyle(e).getPropertyValue("--tbw-animation-duration").trim(),r=parseInt(t,10);if(!isNaN(r))return r}return 200}setIcon(e,t,r){e.dataset.icon=t.replace(/([A-Z])/g,"-$1").toLowerCase(),"collapse"===t?e.dataset.expanded="":"expand"===t&&delete e.dataset.expanded;const o=this.#t(t,r);void 0!==o?"string"==typeof o?e.innerHTML=y(o):o instanceof HTMLElement&&(e.innerHTML="",e.appendChild(o.cloneNode(!0))):e.innerHTML=""}#t(e,t){return void 0!==t?t:this.grid?.gridConfig?.icons?.[e]}updateSortIndicator(e,t){e.querySelector('[part~="sort-indicator"], .sort-indicator')?.remove();const r=document.createElement("span");r.setAttribute("part","sort-indicator"),r.className="sort-indicator",t?(e.setAttribute("aria-sort","asc"===t?"ascending":"descending"),e.setAttribute("data-sort",t),this.setIcon(r,"asc"===t?"sortAsc":"sortDesc")):(e.setAttribute("aria-sort","none"),e.removeAttribute("data-sort"),this.setIcon(r,"sortNone"));const o=e.querySelector(".tbw-filter-btn")??e.querySelector(".resize-handle");return o?e.insertBefore(r,o):e.appendChild(r),r}warn(e,t){void 0!==t?console.warn(c(e,t,this.gridElement.id,this.name)):console.warn(`${g(this.gridElement.id,this.name)} ${e}`)}throwDiagnostic(e,t){throw new Error(c(e,t,this.gridElement.id,this.name))}}function b({rows:e,config:t,expanded:r,initialExpanded:o,groupSortDirections:n}){const i=t.groupOn;if("function"!=typeof i)return[];const s={key:"__root__",value:null,depth:-1,rows:[],children:/* @__PURE__ */new Map};if(e.forEach(e=>{let t=i(e);null==t||!1===t?t=["__ungrouped__"]:Array.isArray(t)||(t=[t]);let r=s;t.forEach((t,o)=>{const n=null==t?"∅":String(t),i="__root__"===r.key?n:r.key+"||"+n;let s=r.children.get(n);s||(s={key:i,value:t,depth:o,rows:[],children:/* @__PURE__ */new Map,parent:r},r.children.set(n,s)),s.rows.push(e),r=s})}),1===s.children.size&&s.children.has("__ungrouped__")){if(s.children.get("__ungrouped__").rows.length===e.length)return[]}const a=/* @__PURE__ */new Map;for(let g=0;g<e.length;g++)a.set(e[g],g);const d=/* @__PURE__ */new Set([...r,...o??[]]),u=e=>{const t=[...e.children.values()],r=e===s?0:e.depth+1,o=n?.get(r)??1;return t.sort((e,t)=>{const r=e.value,n=t.value;return null==r&&null==n?0:null==r?o:null==n?-o:r>n?o:r<n?-o:0}),t},l=[],p=e=>{if(e===s){for(const t of u(e))p(t);return}const t=d.has(e.key);if(l.push({kind:"group",key:e.key,value:e.value,depth:e.depth,rows:e.rows,expanded:t}),t)if(e.children.size)for(const r of u(e))p(r);else e.rows.forEach(e=>l.push({kind:"data",row:e,rowIndex:a.get(e)??-1}))};return p(s),l}function _(e,t){if(!0===e)return new Set(t);if(!1===e||null==e)/* @__PURE__ */
|
|
2
|
+
return new Set;if("number"==typeof e){const r=t[e];return r?/* @__PURE__ */new Set([r]):/* @__PURE__ */new Set}return"string"==typeof e?/* @__PURE__ */new Set([e]):Array.isArray(e)?new Set(e):/* @__PURE__ */new Set}function x({groups:e,expanded:t,groupRows:r,loadingGroups:o,parentPath:n=[]}){const i=[],s=n.length;for(const a of e){const e=[...n,a.key],d=t.has(a.key),u=r.get(a.key)??[],l=o.has(a.key);if(i.push({kind:"group",key:a.key,value:a.value,depth:s,rows:u,expanded:d}),d)if(a.children?.length){const n=x({groups:a.children,expanded:t,groupRows:r,loadingGroups:o,parentPath:e});i.push(...n)}else l?i.push({kind:"data",row:{__loading:!0,__groupKey:a.key},rowIndex:-1}):u.forEach((e,t)=>{i.push({kind:"data",row:e,rowIndex:t})})}return i}function R(e,t,r=[]){for(const o of e){const e=[...r,o.key];if(o.key===t)return e;if(o.children?.length){const r=R(o.children,t,e);if(r.length>0)return r}}return[]}class E extends v{static manifest={modifiesRowStructure:!0,hookPriority:{processRows:10,onHeaderClick:-1},incompatibleWith:[{name:"tree",reason:"Both plugins transform the entire row model. TreePlugin flattens nested hierarchies while GroupingRowsPlugin groups flat rows with synthetic headers. Use one approach per grid."},{name:"pivot",reason:"PivotPlugin creates its own aggregated row and column structure. Row grouping cannot be applied on top of pivot-generated rows."}],events:[{type:"group-toggle",description:"Emitted when groups are expanded/collapsed. Broadcast to both DOM consumers and plugin bus."},{type:"group-expand",description:"Emitted when a pre-defined group is expanded."},{type:"group-collapse",description:"Emitted when a pre-defined group is collapsed."}],queries:[{type:"canMoveRow",description:"Returns false for group header rows (cannot be reordered)"},{type:"grouping:get-grouped-fields",description:"Returns the column field names that match group depth levels (string[])"},{type:"datasource:viewport-mapping",description:"Translates flat viewport row indices to top-level group indices for ServerSide pagination."}],configRules:[{id:"groupingRows/accordion-defaultExpanded",severity:"warn",message:'"accordion: true" and "defaultExpanded" (non-false) are used together.\n → In accordion mode, only one group can be open at a time.\n → Using defaultExpanded with multiple groups will collapse to one on first toggle.\n → Consider using "defaultExpanded: false" or a single group key/index with accordion mode.',check:e=>!0===e.accordion&&!1!==e.defaultExpanded&&void 0!==e.defaultExpanded&&!("number"==typeof e.defaultExpanded)&&!("string"==typeof e.defaultExpanded)&&(!0===e.defaultExpanded||Array.isArray(e.defaultExpanded)&&e.defaultExpanded.length>1)}]};static dependencies=[{name:"multiSort",required:!1,reason:"Queries sort model for coordinated group sorting"},{name:"serverSide",required:!1,reason:"Consumes datasource events for lazy-loaded grouped data"}];name="groupingRows";styles="@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)}@media(hover:hover){.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-aggregates{display:inline-flex;align-items:center;gap:var(--tbw-spacing-lg, 1rem);margin-left:var(--tbw-spacing-lg, 1rem);font-weight:400;font-size:var(--tbw-font-size-sm, .875em);color:var(--tbw-grouping-rows-aggregate-color, var(--tbw-color-fg-muted))}.group-aggregate{white-space:nowrap}.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}}}";get defaultConfig(){return{defaultExpanded:!1,showRowCount:!0,indentWidth:20,aggregators:{},animation:"slide",accordion:!1}}expandedKeys=/* @__PURE__ */new Set;flattenedRows=[];isActive=!1;previousVisibleKeys=/* @__PURE__ */new Set;keysToAnimate=/* @__PURE__ */new Set;hasAppliedDefaultExpanded=!1;preDefinedGroups=[];groupRowsMap=/* @__PURE__ */new Map;loadingGroups=/* @__PURE__ */new Set;groupedFields=[];userGroupSortDirections=/* @__PURE__ */new Map;get animationStyle(){return!!this.isAnimationEnabled&&(this.config.animation??"slide")}detach(){this.expandedKeys.clear(),this.flattenedRows=[],this.isActive=!1,this.previousVisibleKeys.clear(),this.keysToAnimate.clear(),this.hasAppliedDefaultExpanded=!1,this.preDefinedGroups=[],this.groupRowsMap.clear(),this.loadingGroups.clear(),this.groupedFields=[],this.userGroupSortDirections.clear()}getRowHeight(e,t){if(null!=this.config.groupRowHeight)return!0===e.__isGroupRow?this.config.groupRowHeight:void 0}handleQuery(e){if("canMoveRow"===e.type){const t=e.context;if(!0===t?.__isGroupRow)return!1}if("grouping:get-grouped-fields"===e.type)return[...this.groupedFields];if("datasource:viewport-mapping"===e.type){const{viewportStart:t,viewportEnd:r}=e.context;if(0===this.flattenedRows.length)return;if(0===this.preDefinedGroups.length&&!Array.isArray(this.config.groups))return;const o=this.getActiveGroups();return{startNode:this.getTopLevelGroupIndex(t),endNode:this.getTopLevelGroupIndex(r)+1,totalLoadedNodes:o.length}}}getTopLevelGroupIndex(e){let t=-1;const r=Math.min(e,this.flattenedRows.length-1);for(let o=0;o<=r;o++){const e=this.flattenedRows[o];"group"===e.kind&&0===e.depth&&t++}return Math.max(0,t)}attach(e){super.attach(e),this.on("datasource:data",e=>{const t=e;t.claimed||(t.claimed=!0,this.preDefinedGroups=t.rows,this.groupRowsMap.clear(),this.loadingGroups.clear(),this.hasAppliedDefaultExpanded=!1,this.requestRender())}),this.on("datasource:children",e=>{const t=e;if("grouping-rows"!==t.context?.source)return;t.claimed=!0;const r=t.context.groupKey;r&&(this.groupRowsMap.set(r,t.rows),this.loadingGroups.delete(r),this.requestRender())})}onHeaderClick(e){const t=this.groupedFields.indexOf(e.field);if(-1===t)return;if(!e.column.sortable)return;const r=t,o=this.userGroupSortDirections.get(r)??1;return this.userGroupSortDirections.set(r,1===o?-1:1),this.requestRender(),!0}resolveGroupSortDirections(e){const t=this.config;if("function"!=typeof t.groupOn||0===e.length)return void(this.groupedFields=[]);const r=this.columns.map(e=>e.field),o=function(e,t,r){const o=/* @__PURE__ */new Map;if(0===e.length)return o;const n=e[0];let i=t(n);if(null==i||!1===i)return o;Array.isArray(i)||(i=[i]);for(let s=0;s<i.length;s++){const e=i[s];for(const t of r)if(n[t]===e){o.set(s,t);break}}return o}([...e],t.groupOn,r);if(this.groupedFields=[...o.values()],0===o.size)return;const n=new Map(this.userGroupSortDirections);if(n.size<o.size){const e=/* @__PURE__ */new Map,t=this.grid?.query?.("sort:get-model",null);if(Array.isArray(t)&&t.length>0){const r=t[0];if(Array.isArray(r))for(const t of r)e.set(t.field,"desc"===t.direction?-1:1)}if(0===e.size){const t=this.grid;t._sortState&&e.set(t._sortState.field,t._sortState.direction)}for(const[r,i]of o)if(!n.has(r)){const t=e.get(i);void 0!==t&&n.set(r,t)}}return n.size>0?n:void 0}static detect(e,t){return"function"==typeof t?.groupOn||"boolean"==typeof t?.enableRowGrouping||Array.isArray(t?.groups)}processRows(e){if(this.preDefinedGroups.length>0||Array.isArray(this.config.groups))return this.preDefinedGroups.length>0||Array.isArray(this.config.groups)&&this.config.groups.length>0?this.processPreDefinedGroups():(this.isActive=!1,this.flattenedRows=[],[]);const t=this.config;if("function"!=typeof t.groupOn)return this.isActive=!1,this.flattenedRows=[],[...e];const r=this.resolveGroupSortDirections(e),o=b({rows:[...e],config:t,expanded:/* @__PURE__ */new Set,groupSortDirections:r});if(0===o.length)return this.isActive=!1,this.flattenedRows=[],[...e];let n;if(!this.hasAppliedDefaultExpanded&&0===this.expandedKeys.size&&!1!==t.defaultExpanded){const e=function(e){return e.filter(e=>"group"===e.kind).map(e=>e.key)}(o);n=_(t.defaultExpanded??!1,e),n.size>0&&(this.expandedKeys=new Set(n),this.hasAppliedDefaultExpanded=!0)}const i=b({rows:[...e],config:t,expanded:this.expandedKeys,initialExpanded:n,groupSortDirections:r});this.isActive=!0,this.flattenedRows=i,this.keysToAnimate.clear();const s=/* @__PURE__ */new Set;return i.forEach((e,t)=>{if("data"===e.kind){const e=`data-${t}`;s.add(e),this.previousVisibleKeys.has(e)||this.keysToAnimate.add(e)}}),this.previousVisibleKeys=s,i.map(e=>{return"group"===e.kind?{__isGroupRow:!0,__groupKey:e.key,__groupValue:e.value,__groupDepth:e.depth,__groupRows:e.rows,__groupExpanded:e.expanded,__groupRowCount:(t=e,"group"!==t.kind?0:t.rows.length),__rowCacheKey:`group:${e.key}`}:e.row;var t})}onCellClick(e){const r=e.row;if(r?.__isGroupRow){const o=e.originalEvent.target;if(o?.closest(`.${t}`))return this.toggle(r.__groupKey),!0}}onKeyDown(e){if(" "!==e.key)return;const t=this.grid._focusRow,r=this.rows[t];return r?.__isGroupRow?(e.preventDefault(),this.toggle(r.__groupKey),this.requestRenderWithFocus(),!0):void 0}renderRow(e,t,r){if(!0===e?.__loading&&e?.__groupKey){t.className="data-grid-row",t.__isCustomRow=!0,t.innerHTML="";const e=document.createElement("div");return e.className="cell",e.style.gridColumn="1 / -1",e.setAttribute("role","gridcell"),e.textContent=" ",t.appendChild(e),function(e){if(e.classList.add("tbw-row-loading"),e.setAttribute("aria-busy","true"),!e.querySelector(".tbw-row-loading-overlay")){const t=document.createElement("div");t.className="tbw-row-loading-overlay",t.setAttribute("aria-hidden","true");const r=document.createElement("div");r.className="tbw-row-loading-spinner",t.appendChild(r),e.appendChild(t)}}(t),!0}if(!e?.__isGroupRow)return!1;const o=this.config;if(o.groupRowRenderer){const r=()=>{this.toggle(e.__groupKey)},n=o.groupRowRenderer({key:e.__groupKey,value:e.__groupValue,depth:e.__groupDepth,rows:e.__groupRows,expanded:e.__groupExpanded,toggleExpand:r});if(n)return t.className="data-grid-row group-row",t.__isCustomRow=!0,t.setAttribute("data-group-depth",String(e.__groupDepth)),"string"==typeof n?t.innerHTML=n:(t.innerHTML="",t.appendChild(n)),!0}const n=()=>{this.toggle(e.__groupKey)};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)),void 0!==o.indentWidth&&t.style.setProperty("--tbw-group-indent-width",`${o.indentWidth}px`),t.style.height="",t.innerHTML="";return!1!==o.fullWidth?this.renderFullWidthGroupRow(e,t,n):this.renderPerColumnGroupRow(e,t,n),!0}afterRender(){const e=this.animationStyle;if(!1===e||0===this.keysToAnimate.size)return;const t=this.gridElement?.querySelector(".rows");if(!t)return;const r="fade"===e?"tbw-group-fade-in":"tbw-group-slide-in";for(const o of t.querySelectorAll(".data-grid-row:not(.group-row)")){const e=o.querySelector(".cell[data-row]"),t=e?parseInt(e.getAttribute("data-row")??"-1",10):-1,n=this.flattenedRows[t],i="data"===n?.kind?`data-${t}`:void 0;i&&this.keysToAnimate.has(i)&&(o.classList.add(r),o.addEventListener("animationend",()=>o.classList.remove(r),{once:!0}))}this.keysToAnimate.clear()}processPreDefinedGroups(){const e=this.preDefinedGroups.length>0?this.preDefinedGroups:Array.isArray(this.config.groups)?this.config.groups:[];if(0===e.length)return this.isActive=!1,this.flattenedRows=[],[];if(!this.hasAppliedDefaultExpanded&&0===this.expandedKeys.size&&!1!==this.config.defaultExpanded){const t=this.collectGroupKeys(e),r=_(this.config.defaultExpanded??!1,t);r.size>0&&(this.expandedKeys=new Set(r),this.hasAppliedDefaultExpanded=!0)}const t=x({groups:e,expanded:this.expandedKeys,groupRows:this.groupRowsMap,loadingGroups:this.loadingGroups});this.isActive=!0,this.flattenedRows=t,this.keysToAnimate.clear();const r=/* @__PURE__ */new Set;return t.forEach((e,t)=>{if("data"===e.kind){const e=`data-${t}`;r.add(e),this.previousVisibleKeys.has(e)||this.keysToAnimate.add(e)}}),this.previousVisibleKeys=r,t.map(t=>{if("group"===t.kind){const r=this.findGroupDefinition(e,t.key),o=r?.rowCount??t.rows.length;return{__isGroupRow:!0,__groupKey:t.key,__groupValue:t.value,__groupDepth:t.depth,__groupRows:t.rows,__groupExpanded:t.expanded,__groupRowCount:o,__rowCacheKey:`group:${t.key}`}}return t.row})}collectGroupKeys(e){const t=[];for(const r of e)t.push(r.key),r.children?.length&&t.push(...this.collectGroupKeys(r.children));return t}getActiveGroups(){return this.preDefinedGroups.length>0?this.preDefinedGroups:Array.isArray(this.config.groups)?this.config.groups:[]}findGroupDefinition(e,t){for(const r of e){if(r.key===t)return r;if(r.children?.length){const e=this.findGroupDefinition(r.children,t);if(e)return e}}}createToggleButton(r,o){const n=document.createElement("button");return n.type="button",n.className=`${t}${r?` ${e}`:""}`,n.setAttribute("aria-label",r?"Collapse group":"Expand group"),this.setIcon(n,r?"collapse":"expand"),n.addEventListener("click",e=>{e.stopPropagation(),o()}),n}getGroupLabelText(e,t,r){const o=this.config;return o.formatLabel?o.formatLabel(e,t,r):String(e)}renderFullWidthGroupRow(e,t,n){const i=this.config,a=i.aggregators??{},d=e.__groupRows??[],u=document.createElement("div");u.className="cell group-full",u.style.gridColumn="1 / -1",u.setAttribute("role","gridcell"),u.setAttribute("data-col","0"),u.appendChild(this.createToggleButton(e.__groupExpanded,n));const l=document.createElement("span");if(l.className=r,l.textContent=this.getGroupLabelText(e.__groupValue,e.__groupDepth||0,e.__groupKey),u.appendChild(l),!1!==i.showRowCount){const t=document.createElement("span");t.className=o,t.textContent=`(${e.__groupRowCount??e.__groupRows?.length??0})`,u.appendChild(t)}const p=Object.entries(a);if(p.length>0){const e=document.createElement("span");e.className="group-aggregates";for(const[t,r]of p){const o=this.columns.find(e=>e.field===t),n=s.run(r,d,t,o);if(null!=n){const r=document.createElement("span");r.className="group-aggregate",r.setAttribute("data-field",t);const i=o?.header??t;r.textContent=`${i}: ${n}`,e.appendChild(r)}}e.children.length>0&&u.appendChild(e)}t.appendChild(u)}renderPerColumnGroupRow(e,t,r){const n=this.config,i=n.aggregators??{},a=this.columns,d=e.__groupRows??[],u=this.gridElement?.querySelector(".body"),l=u?.style.gridTemplateColumns||"";l&&(t.style.display="grid",t.style.gridTemplateColumns=l);let p=!1;a.forEach((a,u)=>{const l=document.createElement("div");if(l.className="cell group-cell",l.setAttribute("data-col",String(u)),l.setAttribute("role","gridcell"),"__tbw_expander"===a.field)return l.setAttribute("data-field",a.field),void t.appendChild(l);if(p){const e=i[a.field];if(e){const t=s.run(e,d,a.field,a);l.textContent=null!=t?String(t):""}else l.textContent=""}else{p=!0,l.appendChild(this.createToggleButton(e.__groupExpanded,r));const t=document.createElement("span"),u=i[a.field];if(u){const r=s.run(u,d,a.field,a);t.textContent=String(null!=r?r:e.__groupValue)}else t.textContent=this.getGroupLabelText(e.__groupValue,e.__groupDepth||0,e.__groupKey);if(l.appendChild(t),!1!==n.showRowCount){const e=document.createElement("span");e.className=o,e.textContent=` (${d.length})`,l.appendChild(e)}}t.appendChild(l)})}expandAll(){this.expandedKeys=function(e){const t=/* @__PURE__ */new Set;for(const r of e)"group"===r.kind&&t.add(r.key);return t}(this.flattenedRows),this.emitPluginEvent("group-toggle",{expandedKeys:[...this.expandedKeys]}),this.requestRender()}collapseAll(){this.expandedKeys=/* @__PURE__ */new Set,this.emitPluginEvent("group-toggle",{expandedKeys:[...this.expandedKeys]}),this.requestRender()}toggle(e){const t=!this.expandedKeys.has(e),r=this.config,o=this.flattenedRows.find(t=>"group"===t.kind&&t.key===e);if(r.accordion&&t&&o){const t=/* @__PURE__ */new Set;for(const r of this.expandedKeys)if(e.startsWith(r+"||")||r.startsWith(e+"||"))e.startsWith(r+"||")&&t.add(r);else{const e=this.flattenedRows.find(e=>"group"===e.kind&&e.key===r);e&&e.depth!==o.depth&&t.add(r)}t.add(e),this.expandedKeys=t}else this.expandedKeys=function(e,t){const r=new Set(e);return r.has(t)?r.delete(t):r.add(t),r}(this.expandedKeys,e);this.broadcast("group-toggle",{key:e,expanded:this.expandedKeys.has(e),value:o?.value,depth:o?.depth??0,expandedKeys:[...this.expandedKeys]});const n=this.getActiveGroups();if(n.length>0){const r=R(n,e);if(t){if(this.emit("group-expand",{groupKey:e,groupPath:r}),!this.groupRowsMap.has(e)){const t=this.findGroupDefinition(n,e);t&&(this.loadingGroups.add(e),this.grid?.query?.("datasource:fetch-children",{context:{source:"grouping-rows",groupKey:e,group:t,groupPath:r}}))}}else this.emit("group-collapse",{groupKey:e,groupPath:r})}const i=this.expandedKeys.has(e),s=null!=o?.value?String(o.value):e;if(i){const e=o?.rows?.length??0;l(this.gridElement,p(this.gridElement,"groupExpanded",s,e))}else l(this.gridElement,p(this.gridElement,"groupCollapsed",s));this.requestRender()}isExpanded(e){return this.expandedKeys.has(e)}expand(e){this.expandedKeys.has(e)||(this.expandedKeys=/* @__PURE__ */new Set([...this.expandedKeys,e]),this.requestRender())}collapse(e){if(this.expandedKeys.has(e)){const t=new Set(this.expandedKeys);t.delete(e),this.expandedKeys=t,this.requestRender()}}getGroupState(){const e=this.flattenedRows.filter(e=>"group"===e.kind);return{isActive:this.isActive,expandedCount:this.expandedKeys.size,totalGroups:e.length,expandedKeys:[...this.expandedKeys]}}getRowCount(){return this.flattenedRows.length}refreshGroups(){this.requestRender()}getExpandedGroups(){return[...this.expandedKeys]}getFlattenedRows(){return this.flattenedRows}isGroupingActive(){return this.isActive}setGroupOn(e){this.config.groupOn=e,this.requestRender()}setGroups(e){this.preDefinedGroups=e,this.groupRowsMap.clear(),this.loadingGroups.clear(),this.expandedKeys.clear(),this.hasAppliedDefaultExpanded=!1,this.requestRender()}getGroups(){return this.preDefinedGroups.length>0?[...this.preDefinedGroups]:Array.isArray(this.config.groups)?[...this.config.groups]:[]}setGroupRows(e,t){this.groupRowsMap.set(e,t),this.loadingGroups.delete(e),this.requestRender()}setGroupLoading(e,t){t?this.loadingGroups.add(e):this.loadingGroups.delete(e),this.requestRender()}clearGroupRows(e){null!=e?this.groupRowsMap.delete(e):this.groupRowsMap.clear(),this.requestRender()}}export{E as GroupingRowsPlugin};
|
|
3
3
|
//# sourceMappingURL=index.js.map
|