@toolbox-web/grid 2.0.0-rc.1 → 2.0.0-rc.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 +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/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/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 +33 -1
- 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/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/index.js +1 -1
- package/lib/plugins/server-side/index.js.map +1 -1
- package/lib/plugins/tooltip/index.js +1 -1
- package/lib/plugins/tooltip/index.js.map +1 -1
- package/lib/plugins/tree/TreePlugin.d.ts +16 -0
- package/lib/plugins/tree/index.js +1 -1
- package/lib/plugins/tree/index.js.map +1 -1
- package/lib/plugins/tree/types.d.ts +6 -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/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/grouping-rows.umd.js +1 -1
- package/umd/plugins/grouping-rows.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, 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 */
|
|
@@ -98,6 +108,12 @@ export declare class GroupingRowsPlugin extends BaseGridPlugin<GroupingRowsConfi
|
|
|
98
108
|
private loadingGroups;
|
|
99
109
|
/** Whether an async groups fetch is currently in progress */
|
|
100
110
|
private groupsFetchInFlight;
|
|
111
|
+
/** Column fields that produce group values (depth 0, 1, ...). Cached for
|
|
112
|
+
* the `grouping:get-grouped-fields` query so MultiSort can filter them out. */
|
|
113
|
+
private groupedFields;
|
|
114
|
+
/** User-specified sort directions per group depth level. Toggled via
|
|
115
|
+
* header clicks on grouped columns. */
|
|
116
|
+
private userGroupSortDirections;
|
|
101
117
|
/** Group keys with an in-flight rows fetch */
|
|
102
118
|
private rowsFetchInFlight;
|
|
103
119
|
/**
|
|
@@ -126,6 +142,22 @@ export declare class GroupingRowsPlugin extends BaseGridPlugin<GroupingRowsConfi
|
|
|
126
142
|
* @internal
|
|
127
143
|
*/
|
|
128
144
|
handleQuery(query: PluginQuery): unknown;
|
|
145
|
+
/**
|
|
146
|
+
* Intercept header clicks on grouped columns to toggle group sort direction.
|
|
147
|
+
* Returns `true` for grouped columns to prevent MultiSort from handling them.
|
|
148
|
+
* @internal
|
|
149
|
+
*/
|
|
150
|
+
onHeaderClick(event: HeaderClickEvent): boolean | void;
|
|
151
|
+
/**
|
|
152
|
+
* Build a sort-direction map for each group depth level by cross-referencing
|
|
153
|
+
* the active sort state with the column fields that produce group values.
|
|
154
|
+
*
|
|
155
|
+
* Supports three direction sources (in priority order):
|
|
156
|
+
* 1. User-set directions via header clicks on grouped columns
|
|
157
|
+
* 2. MultiSort plugin model (for backwards compatibility / state restore)
|
|
158
|
+
* 3. Core single-column sort state
|
|
159
|
+
*/
|
|
160
|
+
private resolveGroupSortDirections;
|
|
129
161
|
/**
|
|
130
162
|
* Auto-detect grouping configuration from grid config.
|
|
131
163
|
* Called by plugin system to determine if plugin should activate.
|
|
@@ -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",n="group-count",o={sum:(e,t)=>{let r=0;for(let n=0;n<e.length;n++)r+=Number(e[n][t])||0;return r},avg:(e,t)=>{if(!e.length)return 0;let r=0;for(let n=0;n<e.length;n++)r+=Number(e[n][t])||0;return r/e.length},count:e=>e.length,min:(e,t)=>{if(!e.length)return 0;let r=1/0;for(let n=0;n<e.length;n++){const o=Number(e[n][t]);o<r&&(r=o)}return r},max:(e,t)=>{if(!e.length)return 0;let r=-1/0;for(let n=0;n<e.length;n++){const o=Number(e[n][t]);o>r&&(r=o)}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)??o[e]},run(e,t,r,n){const o=this.get(e);return o?o(t,r,n):void 0},has:e=>i.has(e)||e in o,list:()=>[...Object.keys(o),...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>',l={expand:"▶",collapse:"▼",sortAsc:"▲",sortDesc:"▼",sortNone:"⇅",submenuArrow:"▶",dragHandle:"⋮⋮",toolPanel:"☰",filter:d,filterActive:d,print:"🖨️"};function u(e,t){if(!e)return;const r="effectiveConfig"in e?e.effectiveConfig:void 0;if(!1===r?.a11y?.announcements)return;const n=e.querySelector?.(".tbw-sr-only");n&&(n.textContent="",requestAnimationFrame(()=>{n.textContent=t}))}function p(e,t,...r){const n=e&&"effectiveConfig"in e?e.effectiveConfig:void 0,o=n?.a11y?.messages?.[t];return o?o(...r):a[t](...r)}function g(e,t){return`[tbw-grid${e?`#${e}`:""}${t?`:${t}`:""}]`}function
|
|
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",n="group-count",o={sum:(e,t)=>{let r=0;for(let n=0;n<e.length;n++)r+=Number(e[n][t])||0;return r},avg:(e,t)=>{if(!e.length)return 0;let r=0;for(let n=0;n<e.length;n++)r+=Number(e[n][t])||0;return r/e.length},count:e=>e.length,min:(e,t)=>{if(!e.length)return 0;let r=1/0;for(let n=0;n<e.length;n++){const o=Number(e[n][t]);o<r&&(r=o)}return r},max:(e,t)=>{if(!e.length)return 0;let r=-1/0;for(let n=0;n<e.length;n++){const o=Number(e[n][t]);o>r&&(r=o)}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)??o[e]},run(e,t,r,n){const o=this.get(e);return o?o(t,r,n):void 0},has:e=>i.has(e)||e in o,list:()=>[...Object.keys(o),...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>',l={expand:"▶",collapse:"▼",sortAsc:"▲",sortDesc:"▼",sortNone:"⇅",submenuArrow:"▶",dragHandle:"⋮⋮",toolPanel:"☰",filter:d,filterActive:d,print:"🖨️"};function u(e,t){if(!e)return;const r="effectiveConfig"in e?e.effectiveConfig:void 0;if(!1===r?.a11y?.announcements)return;const n=e.querySelector?.(".tbw-sr-only");n&&(n.textContent="",requestAnimationFrame(()=>{n.textContent=t}))}function p(e,t,...r){const n=e&&"effectiveConfig"in e?e.effectiveConfig:void 0,o=n?.a11y?.messages?.[t];return o?o(...r):a[t](...r)}function g(e,t){return`[tbw-grid${e?`#${e}`:""}${t?`:${t}`:""}]`}function c(e,t,r,n){return`${g(r,n)} ${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 n of r){const e=n.tagName.toLowerCase();if(h.has(e)){t.push(n);continue}if("svg"===e||"http://www.w3.org/2000/svg"===n.namespaceURI){if(Array.from(n.attributes).some(e=>f.test(e.name)||"href"===e.name||"xlink:href"===e.name)){t.push(n);continue}}const r=[];for(const t of n.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=>n.removeAttribute(e))}t.forEach(e=>e.remove())}(t.content),t.innerHTML}class b{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{...l,...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 n=this.#t(t,r);void 0!==n?"string"==typeof n?e.innerHTML=y(n):n instanceof HTMLElement&&(e.innerHTML="",e.appendChild(n.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 n=e.querySelector(".tbw-filter-btn")??e.querySelector(".resize-handle");return n?e.insertBefore(r,n):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 _({rows:e,config:t,expanded:r,initialExpanded:n,groupSortDirections:o}){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,n)=>{const o=null==t?"∅":String(t),i="__root__"===r.key?o:r.key+"||"+o;let s=r.children.get(o);s||(s={key:i,value:t,depth:n,rows:[],children:/* @__PURE__ */new Map,parent:r},r.children.set(o,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,...n??[]]),l=e=>{const t=[...e.children.values()],r=e===s?0:e.depth+1,n=o?.get(r)??1;return t.sort((e,t)=>{const r=e.value,o=t.value;return null==r&&null==o?0:null==r?n:null==o?-n:r>o?n:r<o?-n:0}),t},u=[],p=e=>{if(e===s){for(const t of l(e))p(t);return}const t=d.has(e.key);if(u.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 l(e))p(r);else e.rows.forEach(e=>u.push({kind:"data",row:e,rowIndex:a.get(e)??-1}))};return p(s),u}function v(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: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={modifiesRowStructure:!0,hookPriority:{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:"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)"},{type:"grouping:get-grouped-fields",description:"Returns the column field names that match group depth levels (string[])"}],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="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;groupedFields=[];userGroupSortDirections=/* @__PURE__ */new Map;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.groupedFields=[],this.userGroupSortDirections.clear(),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}if("grouping:get-grouped-fields"===e.type)return[...this.groupedFields]}onHeaderClick(e){const t=this.groupedFields.indexOf(e.field);if(-1===t)return;if(!e.column.sortable)return;const r=t,n=this.userGroupSortDirections.get(r)??1;return this.userGroupSortDirections.set(r,1===n?-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),n=function(e,t,r){const n=/* @__PURE__ */new Map;if(0===e.length)return n;const o=e[0];let i=t(o);if(null==i||!1===i)return n;Array.isArray(i)||(i=[i]);for(let s=0;s<i.length;s++){const e=i[s];for(const t of r)if(o[t]===e){n.set(s,t);break}}return n}([...e],t.groupOn,r);if(this.groupedFields=[...n.values()],0===n.size)return;const o=new Map(this.userGroupSortDirections);if(o.size<n.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 n)if(!o.has(r)){const t=e.get(i);void 0!==t&&o.set(r,t)}}return o.size>0?o:void 0}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=this.resolveGroupSortDirections(e),n=_({rows:[...e],config:t,expanded:/* @__PURE__ */new Set,groupSortDirections:r});if(0===n.length)return this.isActive=!1,this.flattenedRows=[],[...e];let o;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)}(n);o=v(t.defaultExpanded??!1,e),o.size>0&&(this.expandedKeys=new Set(o),this.hasAppliedDefaultExpanded=!0)}const i=_({rows:[...e],config:t,expanded:this.expandedKeys,initialExpanded:o,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 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};
|
|
3
3
|
//# sourceMappingURL=index.js.map
|