@toolbox-web/grid 3.8.2 → 3.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. package/all.d.ts +1 -0
  2. package/all.js +1 -1
  3. package/all.js.map +1 -1
  4. package/index.js +1 -1
  5. package/index.js.map +1 -1
  6. package/lib/core/defaults.d.ts +1 -1
  7. package/lib/core/internal/aria.d.ts +1 -1
  8. package/lib/core/internal/config-manager.d.ts +0 -4
  9. package/lib/core/plugin/base-plugin.d.ts +14 -0
  10. package/lib/core/plugin/plugin-manager.d.ts +5 -1
  11. package/lib/core/plugin/types.d.ts +2 -0
  12. package/lib/core/types.d.ts +6 -0
  13. package/lib/features/registry.js +1 -1
  14. package/lib/plugins/clipboard/clipboard-plugin.d.ts +2 -3
  15. package/lib/plugins/clipboard/index.js +1 -1
  16. package/lib/plugins/clipboard/index.js.map +1 -1
  17. package/lib/plugins/column-virtualization/index.js +1 -1
  18. package/lib/plugins/column-virtualization/index.js.map +1 -1
  19. package/lib/plugins/context-menu/index.js +1 -1
  20. package/lib/plugins/context-menu/index.js.map +1 -1
  21. package/lib/plugins/editing/index.js +1 -1
  22. package/lib/plugins/editing/index.js.map +1 -1
  23. package/lib/plugins/export/index.js +1 -1
  24. package/lib/plugins/export/index.js.map +1 -1
  25. package/lib/plugins/filtering/index.js +1 -1
  26. package/lib/plugins/filtering/index.js.map +1 -1
  27. package/lib/plugins/grouping-columns/index.js +1 -1
  28. package/lib/plugins/grouping-columns/index.js.map +1 -1
  29. package/lib/plugins/grouping-rows/grouping-rows-plugin.d.ts +20 -24
  30. package/lib/plugins/grouping-rows/grouping-rows.d.ts +9 -4
  31. package/lib/plugins/grouping-rows/index.d.ts +1 -1
  32. package/lib/plugins/grouping-rows/index.js +1 -1
  33. package/lib/plugins/grouping-rows/index.js.map +1 -1
  34. package/lib/plugins/grouping-rows/types.d.ts +32 -4
  35. package/lib/plugins/hierarchy/hierarchy-plugin.d.ts +79 -0
  36. package/lib/plugins/hierarchy/hierarchy.d.ts +28 -0
  37. package/lib/plugins/hierarchy/index.d.ts +9 -0
  38. package/lib/plugins/hierarchy/index.js +2 -0
  39. package/lib/plugins/hierarchy/index.js.map +1 -0
  40. package/lib/plugins/hierarchy/types.d.ts +92 -0
  41. package/lib/plugins/master-detail/index.js +1 -1
  42. package/lib/plugins/master-detail/index.js.map +1 -1
  43. package/lib/plugins/multi-sort/index.js +1 -1
  44. package/lib/plugins/multi-sort/index.js.map +1 -1
  45. package/lib/plugins/pinned-columns/index.js +1 -1
  46. package/lib/plugins/pinned-columns/index.js.map +1 -1
  47. package/lib/plugins/pinned-rows/index.js +1 -1
  48. package/lib/plugins/pinned-rows/index.js.map +1 -1
  49. package/lib/plugins/pivot/index.js +1 -1
  50. package/lib/plugins/pivot/index.js.map +1 -1
  51. package/lib/plugins/print/index.js +1 -1
  52. package/lib/plugins/print/index.js.map +1 -1
  53. package/lib/plugins/reorder-columns/index.js +1 -1
  54. package/lib/plugins/reorder-columns/index.js.map +1 -1
  55. package/lib/plugins/responsive/index.js +1 -1
  56. package/lib/plugins/responsive/index.js.map +1 -1
  57. package/lib/plugins/row-drag-drop/index.js +1 -1
  58. package/lib/plugins/row-drag-drop/index.js.map +1 -1
  59. package/lib/plugins/row-drag-drop/row-drag-drop-plugin.d.ts +1 -0
  60. package/lib/plugins/row-drag-drop/types.d.ts +3 -2
  61. package/lib/plugins/selection/index.js +1 -1
  62. package/lib/plugins/selection/index.js.map +1 -1
  63. package/lib/plugins/selection/selection-plugin.d.ts +2 -2
  64. package/lib/plugins/server-side/index.js +1 -1
  65. package/lib/plugins/server-side/index.js.map +1 -1
  66. package/lib/plugins/shell/index.js +1 -1
  67. package/lib/plugins/shell/index.js.map +1 -1
  68. package/lib/plugins/sticky-rows/index.js +1 -1
  69. package/lib/plugins/sticky-rows/index.js.map +1 -1
  70. package/lib/plugins/tooltip/index.js +1 -1
  71. package/lib/plugins/tooltip/index.js.map +1 -1
  72. package/lib/plugins/tree/index.js +1 -1
  73. package/lib/plugins/tree/index.js.map +1 -1
  74. package/lib/plugins/tree/tree-datasource.d.ts +7 -10
  75. package/lib/plugins/tree/tree-plugin.d.ts +23 -3
  76. package/lib/plugins/undo-redo/index.js +1 -1
  77. package/lib/plugins/undo-redo/index.js.map +1 -1
  78. package/lib/plugins/visibility/index.js +1 -1
  79. package/lib/plugins/visibility/index.js.map +1 -1
  80. package/package.json +1 -1
  81. package/umd/grid.all.umd.js +1 -1
  82. package/umd/grid.all.umd.js.map +1 -1
  83. package/umd/grid.umd.js +1 -1
  84. package/umd/grid.umd.js.map +1 -1
  85. package/umd/plugins/clipboard.umd.js +1 -1
  86. package/umd/plugins/clipboard.umd.js.map +1 -1
  87. package/umd/plugins/editing.umd.js +1 -1
  88. package/umd/plugins/editing.umd.js.map +1 -1
  89. package/umd/plugins/grouping-rows.umd.js +1 -1
  90. package/umd/plugins/grouping-rows.umd.js.map +1 -1
  91. package/umd/plugins/hierarchy.umd.js +2 -0
  92. package/umd/plugins/hierarchy.umd.js.map +1 -0
  93. package/umd/plugins/row-drag-drop.umd.js +1 -1
  94. package/umd/plugins/row-drag-drop.umd.js.map +1 -1
  95. package/umd/plugins/selection.umd.js +1 -1
  96. package/umd/plugins/selection.umd.js.map +1 -1
  97. package/umd/plugins/tooltip.umd.js +1 -1
  98. package/umd/plugins/tooltip.umd.js.map +1 -1
  99. package/umd/plugins/tree.umd.js +1 -1
  100. package/umd/plugins/tree.umd.js.map +1 -1
@@ -1,4 +1,5 @@
1
1
  import { BaseGridPlugin, CellClickEvent, HeaderClickEvent, GridElement, PluginManifest, PluginQuery } from '../../core/plugin/base-plugin';
2
+ import { HierarchyContributor, HierarchyNode, HierarchySiblingContext, HierarchyPlugin } from '../hierarchy';
2
3
  import { DefaultExpandedValue, GroupDefinition, GroupingRowsConfig, RenderRow } from './types';
3
4
  /**
4
5
  * Group state information returned by getGroupState()
@@ -73,7 +74,8 @@ export interface GroupState {
73
74
  * @internal Extends BaseGridPlugin
74
75
  * @since 0.1.1
75
76
  */
76
- export declare class GroupingRowsPlugin extends BaseGridPlugin<GroupingRowsConfig> {
77
+ export declare class GroupingRowsPlugin extends BaseGridPlugin<GroupingRowsConfig> implements HierarchyContributor {
78
+ #private;
77
79
  /**
78
80
  * Plugin manifest - declares configuration validation rules and events.
79
81
  * @internal
@@ -84,14 +86,22 @@ export declare class GroupingRowsPlugin extends BaseGridPlugin<GroupingRowsConfi
84
86
  * When MultiSort is loaded, GroupingRows queries its sort model to determine
85
87
  * group header ordering. Without it, falls back to core sort state.
86
88
  */
87
- static readonly dependencies: {
89
+ static readonly dependencies: ({
88
90
  name: string;
89
91
  required: boolean;
90
92
  reason: string;
91
- }[];
93
+ provide: () => HierarchyPlugin;
94
+ } | {
95
+ name: string;
96
+ required: boolean;
97
+ reason: string;
98
+ provide?: undefined;
99
+ })[];
92
100
  /** @internal */
93
101
  readonly name = "groupingRows";
94
102
  /** @internal */
103
+ readonly hierarchyStage = "transform";
104
+ /** @internal */
95
105
  readonly styles: string;
96
106
  /** @internal */
97
107
  protected get defaultConfig(): Partial<GroupingRowsConfig>;
@@ -128,13 +138,6 @@ export declare class GroupingRowsPlugin extends BaseGridPlugin<GroupingRowsConfi
128
138
  /** User-specified sort directions per group depth level. Toggled via
129
139
  * header clicks on grouped columns. */
130
140
  private userGroupSortDirections;
131
- /**
132
- * Per-flatten-index ARIA position metadata for `aria-level` /
133
- * `aria-setsize` / `aria-posinset` (WAI-ARIA Treegrid pattern). Computed
134
- * once per `flattenedRows` rebuild by {@link computeFlatMeta}; consumed
135
- * by {@link afterRender} on every visible row.
136
- */
137
- private flatMeta;
138
141
  /**
139
142
  * Get expand/collapse animation style from plugin config.
140
143
  * Uses base class isAnimationEnabled to respect grid-level settings.
@@ -191,6 +194,12 @@ export declare class GroupingRowsPlugin extends BaseGridPlugin<GroupingRowsConfi
191
194
  static detect(rows: readonly any[], config: any): boolean;
192
195
  /** @internal */
193
196
  processRows(rows: readonly any[]): any[];
197
+ /** @internal Hierarchy contributor hook */
198
+ beginHierarchy(_rows: readonly unknown[]): boolean;
199
+ /** @internal Hierarchy contributor hook */
200
+ processSiblings(nodes: HierarchyNode[], context: HierarchySiblingContext): HierarchyNode[];
201
+ /** @internal Hierarchy contributor hook */
202
+ endHierarchy(rows: readonly unknown[]): boolean;
194
203
  /** @internal */
195
204
  onCellClick(event: CellClickEvent): boolean | void;
196
205
  /** @internal */
@@ -202,19 +211,6 @@ export declare class GroupingRowsPlugin extends BaseGridPlugin<GroupingRowsConfi
202
211
  renderRow(row: any, rowEl: HTMLElement, _rowIndex: number): boolean;
203
212
  /** @internal */
204
213
  afterRender(): void;
205
- /**
206
- * Compute per-row ARIA hierarchy metadata (`aria-level` / `aria-setsize` /
207
- * `aria-posinset`) from `flattenedRows`. Two-pass over the flat list:
208
- * first pass tallies group siblings per (parent-prefix, depth) and counts
209
- * the data rows that follow each group header; second pass assigns per-row
210
- * meta. Called once per `flattenedRows` rebuild (not per render).
211
- */
212
- private computeFlatMeta;
213
- /**
214
- * Build the row model from pre-defined group definitions.
215
- * Used when `groups` config or `setGroups()` provides external group structure.
216
- */
217
- private processPreDefinedGroups;
218
214
  /**
219
215
  * Collect all group keys from a pre-defined group tree.
220
216
  */
@@ -338,7 +334,7 @@ export declare class GroupingRowsPlugin extends BaseGridPlugin<GroupingRowsConfi
338
334
  * plugin.setGroupOn((row) => row.region, false);
339
335
  * ```
340
336
  */
341
- setGroupOn(fn: ((row: any) => any[] | any | null | false) | undefined, expanded?: DefaultExpandedValue): void;
337
+ setGroupOn(fn: GroupingRowsConfig['groupOn'], expanded?: DefaultExpandedValue): void;
342
338
  /**
343
339
  * Replace auto-detected groups with an externally provided group structure.
344
340
  *
@@ -1,4 +1,4 @@
1
- import { DefaultExpandedValue, GroupDefinition, GroupingRowsConfig, RenderRow } from './types';
1
+ import { DefaultExpandedValue, GroupDefinition, GroupingRowsConfig, GroupOnContext, RenderRow } from './types';
2
2
  interface BuildGroupingArgs {
3
3
  rows: any[];
4
4
  config: GroupingRowsConfig;
@@ -8,6 +8,10 @@ interface BuildGroupingArgs {
8
8
  /** Sort direction per group depth level. 1 = ascending, -1 = descending.
9
9
  * When omitted, groups at all levels sort ascending. */
10
10
  groupSortDirections?: Map<number, 1 | -1>;
11
+ /** Passed to `groupOn` as its second argument (default: the root list). */
12
+ context?: GroupOnContext;
13
+ /** Prepended to every top-level group key so nested lists get unique keys. */
14
+ keyPrefix?: string;
11
15
  }
12
16
  /**
13
17
  * Build a flattened grouping projection (collapsed by default).
@@ -16,18 +20,19 @@ interface BuildGroupingArgs {
16
20
  * @param args - The grouping arguments
17
21
  * @returns Flattened array of render rows (groups + data rows)
18
22
  */
19
- export declare function buildGroupedRowModel({ rows, config, expanded, initialExpanded, groupSortDirections, }: BuildGroupingArgs): RenderRow[];
23
+ export declare function buildGroupedRowModel({ rows, config, expanded, initialExpanded, groupSortDirections, context, keyPrefix, }: BuildGroupingArgs): RenderRow[];
20
24
  /**
21
25
  * Discover which column field produces the group value at each depth level.
22
26
  *
23
- * Samples the first row's `groupOn` output to get the group path, then checks
27
+ * Samples the first grouped row's `groupOn` output to get the group path, then checks
24
28
  * which column fields produce matching values for that row. This mapping allows
25
29
  * the plugin to apply user-invoked column sort directions to the correct group
26
30
  * depth levels.
27
31
  *
32
+ * @param context - Passed to `groupOn` (default: the root list).
28
33
  * @returns Map from depth index to column field name, or empty map if unmappable
29
34
  */
30
- export declare function resolveGroupFields(rows: any[], groupOn: (row: any) => any[] | any | null | false, columnFields: string[]): Map<number, string>;
35
+ export declare function resolveGroupFields(rows: any[], groupOn: NonNullable<GroupingRowsConfig['groupOn']>, columnFields: string[], context?: GroupOnContext): Map<number, string>;
31
36
  /**
32
37
  * Toggle expansion state for a group key.
33
38
  *
@@ -6,4 +6,4 @@
6
6
  */
7
7
  export { GroupingRowsPlugin } from './grouping-rows-plugin';
8
8
  export type { GroupState } from './grouping-rows-plugin';
9
- export type { AggregatorMap, DataRowModelItem, DefaultExpandedValue, GroupCollapseDetail, GroupDefinition, GroupExpandDetail, GroupingRowsConfig, GroupRowModelItem, GroupRowRenderParams, GroupToggleDetail, RenderRow, } from './types';
9
+ export type { AggregatorMap, DataRowModelItem, DefaultExpandedValue, GroupCollapseDetail, GroupDefinition, GroupExpandDetail, GroupingRowsConfig, GroupOnContext, GroupRowModelItem, GroupRowRenderParams, GroupToggleDetail, RenderRow, } from './types';
@@ -1,2 +1,2 @@
1
- var e="expanded",t="group-toggle",r="group-label",o="group-count",n=/* @__PURE__ */new WeakMap;function i(e){return"__proto__"===e||"constructor"===e||"prototype"===e}var s=/* @__PURE__ */new Map;function a(e,t){if(null==e)return;const r=function(e){if(-1===e.indexOf("."))return null;let t=s.get(e);return void 0===t&&(t=Object.freeze(e.split(".")),s.set(e,t)),t}(t),o=e;return null===r?i(t)?void 0:o[t]:Object.prototype.hasOwnProperty.call(o,t)?o[t]:function(e,t){let r=e;for(let o=0;o<t.length;o++){if(null==r||"object"!=typeof r)return;const e=t[o];if(i(e))return;r=r[e]}return r}(o,r)}function d(e,t,r){return r?.valueAccessor?function(e,t,r=-1){if(!t.valueAccessor)return a(e,t.field);if("object"!=typeof e||null===e)return t.valueAccessor({row:e,column:t,rowIndex:r});const o=e,i=t.field;let s=n.get(o);if(s){const e=s.get(i);if(void 0!==e)return e.v}else s=/* @__PURE__ */new Map,n.set(o,s);const d=t.valueAccessor({row:e,column:t,rowIndex:r});return s.set(i,{v:d}),d}(e,r):a(e,t)}function l(e){return null==e||""===e||"number"==typeof e&&isNaN(e)}var u={sum:(e,t,r)=>{let o=0;for(let n=0;n<e.length;n++){const i=d(e[n],t,r);if(l(i))continue;const s=Number(i);isNaN(s)||(o+=s)}return o},avg:(e,t,r)=>{if(!e.length)return 0;let o=0,n=0;for(let i=0;i<e.length;i++){const s=d(e[i],t,r);if(l(s))continue;const a=Number(s);isNaN(a)||(o+=a,n++)}return n>0?o/n:0},count:e=>e.length,min:(e,t,r)=>{if(!e.length)return 0;let o=1/0;for(let n=0;n<e.length;n++){const i=d(e[n],t,r);if(l(i))continue;const s=Number(i);isNaN(s)||s<o&&(o=s)}return o===1/0?0:o},max:(e,t,r)=>{if(!e.length)return 0;let o=-1/0;for(let n=0;n<e.length;n++){const i=d(e[n],t,r);if(l(i))continue;const s=Number(i);isNaN(s)||s>o&&(o=s)}return o===-1/0?0:o},first:(e,t,r)=>e[0]?d(e[0],t,r):void 0,last:(e,t,r)=>e.length?d(e[e.length-1],t,r):void 0},p=/* @__PURE__ */new Map,c={register(e,t){p.set(e,t)},unregister(e){p.delete(e)},get(e){if(void 0!==e)return"function"==typeof e?e:p.get(e)??u[e]},run(e,t,r,o){const n=this.get(e);return n?n(t,r,o):void 0},has:e=>p.has(e)||e in u,list:()=>[...Object.keys(u),...p.keys()]},g={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`,selectAllRows:()=>"Select all rows",selectRow:e=>`Select row ${e+1}`,columnSelected:e=>`Column ${e} selected`,columnSelectionChanged:e=>`${e} columns selected`,columnSelectionCleared:()=>"Column selection cleared",selectionAxisChanged:e=>"column"===e?"Row selection cleared, column selection active":"Column selection cleared, row selection active",editingStarted:e=>`Editing row ${e+1}`,editingCommitted:e=>`Row ${e+1} saved`,dataLoaded:e=>`${e} rows loaded`},h={expand:"▶",collapse:"▼",sortAsc:"▲",sortDesc:"▼",sortNone:"⇅",submenuArrow:"▶",dragHandle:"⋮⋮",toolPanel:"☰",filter:"",filterActive:"",print:"🖨️"};function f(e,t){if(!e)return;if(!1===("effectiveConfig"in e?e.effectiveConfig:void 0)?.a11y?.announcements)return;const r=e.querySelector?.(".tbw-sr-only");r&&(r.textContent="","function"==typeof requestAnimationFrame?requestAnimationFrame(()=>{r.textContent=t}):r.textContent=t)}function w(e,t,...r){const o=(e&&"effectiveConfig"in e?e.effectiveConfig:void 0)?.a11y?.messages?.[t];return o?o(...r):g[t](...r)}var m="__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".split("|").map(e=>e.split("").reverse().join("")),y=(new RegExp(`__(proto|defineGetter|defineSetter)|${m.slice(3).join("|")}|this\\b`),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|math".split("|"))),v=/^on\w+$/i,b=new Set("href|src|action|formaction|data|srcdoc|xlink:href|poster|srcset".split("|")),x=/^\s*(javascript|vbscript|data|blob):/i;function _(e){const t=document.createElement("template");return e&&"string"==typeof e&&(t.innerHTML=e,function(e){const t=[],r=e.querySelectorAll("*");for(const o of r){const e=o.tagName.toLowerCase();if(y.has(e)){t.push(o);continue}if(("svg"===e||"http://www.w3.org/2000/svg"===o.namespaceURI)&&Array.from(o.attributes).some(e=>v.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();v.test(e)?r.push(t.name):"is"!==e?(b.has(e)&&x.test(t.value)||"style"===e&&/expression\s*\(|javascript:|behavior\s*:/i.test(t.value))&&r.push(t.name):r.push(t.name)}r.forEach(e=>o.removeAttribute(e))}t.forEach(e=>e.remove())}(t.content)),t.content}function C(e,t){t&&"string"==typeof t?-1!==t.indexOf("<")||-1!==t.indexOf("&")?e.replaceChildren(_(t)):e.textContent=t:e.replaceChildren()}function R(e,t){return`[tbw-grid${e?`#${e}`:""}${t?`:${t}`:""}]`}function A(e,t,r,o){return`${R(r,o)} ${e}: ${t}\n\n → More info: ${function(e){return`https://toolboxjs.com/grid/errors#${e.toLowerCase()}`}(e)}`}var E=class{static dependencies;static manifest;aliases;version="3.8.2";styles;cellRenderers;headerRenderers;cellEditors;grid;config;userConfig;#e;get defaultConfig(){return{}}constructor(e={}){this.userConfig=e}get resolvedConfig(){return this.#e?this.config:{...this.defaultConfig,...this.userConfig}}mergeConfigsFrom(e){if(0===e.length)return;const t={...this.userConfig},r={};for(const o of Object.keys(t))r[o]=this;for(const o of e){const e=o.userConfig;for(const[n,i]of Object.entries(e)){if(void 0===i)continue;if(!(n in t)){t[n]=i,r[n]=o;continue}if(t[n]===i)continue;const e=r[n]?.constructor.name??this.constructor.name,s=o.constructor.name,a=A("TBW025",`Cannot merge plugin configs for "${this.name}": conflicting value for "${n}" supplied by both ${e} and ${s}. Pass the option on a single instance, or remove the duplicate.`,void 0,this.name);throw new Error(a)}}Object.assign(this.userConfig,t)}refreshUserConfigFrom(e){const t=this.userConfig,r={...e.userConfig};for(const o of Object.keys(t))delete t[o];Object.assign(t,r)}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)}queryBoolean(e,t=null){const r=this.grid?.query?.(e,t);return Array.isArray(r)?r.some(Boolean):!!r}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{...h,...e}}t(e,t){return this.grid?.effectiveConfig?.locale?.[e]??t}get translate(){return(e,t)=>this.t(e,t)}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;return!t||"0"!==getComputedStyle(t).getPropertyValue("--tbw-animation-enabled").trim()}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?C(e,o):o instanceof HTMLElement&&e.replaceChildren(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(A(e,t,this.gridElement.id,this.name)):console.warn(`${R(this.gridElement.id,this.name)} ${e}`)}throwDiagnostic(e,t){throw new Error(A(e,t,this.gridElement.id,this.name))}};function S({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__")&&s.children.get("__ungrouped__").rows.length===e.length)return[];const a=/* @__PURE__ */new Map;for(let c=0;c<e.length;c++)a.set(e[c],c);const d=/* @__PURE__ */new Set([...r,...o??[]]),l=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},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 k(e,t){if(!0===e)return new Set(t);if(!1===e||null==e)/* @__PURE__ */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 G({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),l=r.get(a.key)??[],u=o.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 n=G({groups:a.children,expanded:t,groupRows:r,loadingGroups:o,parentPath:e});i.push(...n)}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 K(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=K(o.children,t,e);if(r.length>0)return r}}return[]}var D=class extends E{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{grid-template-columns:var(--tbw-column-template);background:var(--tbw-grouping-rows-bg,var(--tbw-color-panel-bg));border-bottom:var(--tbw-row-divider);min-height:var(--tbw-row-height);font-weight:500;display:grid}.group-row .cell{padding:var(--tbw-cell-padding,.125rem .5rem);align-items:center;display:flex}@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;width:var(--tbw-toggle-size,1.25rem);height:var(--tbw-toggle-size,1.25rem);font:inherit;background:0 0;border:0;justify-content:center;align-items:center;margin-right:.25rem;display:inline-flex}.group-toggle:hover{background:var(--tbw-grouping-rows-toggle-hover,var(--tbw-color-row-hover));border-radius:var(--tbw-border-radius,.125rem)}.group-toggle{position:relative}.group-toggle:after{content:"";inline-size:var(--tbw-touch-target-min,24px);block-size:var(--tbw-touch-target-min,24px);position:absolute;inset-block-start:50%;inset-inline-start:50%;translate:-50% -50%}@media (pointer:coarse){.group-toggle{min-width:var(--tbw-touch-target-min,24px);min-height:var(--tbw-touch-target-min,24px)}}.group-label{align-items:center;gap:var(--tbw-panel-gap,var(--tbw-spacing-md,.5rem));display:inline-flex}.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{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));display:inline-flex}.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;pendingExpansion;groupConfigDirty=!1;preDefinedGroups=[];groupRowsMap=/* @__PURE__ */new Map;loadingGroups=/* @__PURE__ */new Set;groupedFields=[];userGroupSortDirections=/* @__PURE__ */new Map;flatMeta=[];get animationStyle(){return!!this.isAnimationEnabled&&(this.config.animation??"slide")}detach(){(this.gridElement?.querySelector(".rows-body"))?.setAttribute("role","grid"),this.expandedKeys.clear(),this.flattenedRows=[],this.flatMeta=[],this.isActive=!1,this.previousVisibleKeys.clear(),this.keysToAnimate.clear(),this.hasAppliedDefaultExpanded=!1,this.pendingExpansion=void 0,this.groupConfigDirty=!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&&!0===e.context?.__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._sortState;t&&e.set(t.field,t.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){const t=this.pendingExpansion;if(this.pendingExpansion=void 0,this.groupConfigDirty=!1,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 r=this.config;if("function"!=typeof r.groupOn)return this.isActive=!1,this.flattenedRows=[],[...e];const o=this.resolveGroupSortDirections(e),n=S({rows:[...e],config:r,expanded:/* @__PURE__ */new Set,groupSortDirections:o});if(0===n.length)return this.isActive=!1,this.flattenedRows=[],[...e];let i;const s=void 0!==t;let a;if(s?i=t:this.hasAppliedDefaultExpanded||0!==this.expandedKeys.size||!1===r.defaultExpanded||(i=r.defaultExpanded??!1),void 0!==i){const e=function(e){return e.filter(e=>"group"===e.kind).map(e=>e.key)}(n);a=k(i,e),(s||a.size>0)&&(this.expandedKeys=new Set(a),this.hasAppliedDefaultExpanded=!0)}const d=S({rows:[...e],config:r,expanded:this.expandedKeys,initialExpanded:a,groupSortDirections:o});this.isActive=!0,this.flattenedRows=d,this.computeFlatMeta(),s&&this.broadcast("group-toggle",{expandedKeys:[...this.expandedKeys]}),this.keysToAnimate.clear();const l=/* @__PURE__ */new Set;return d.forEach((e,t)=>{if("data"===e.kind){const e=`data-${t}`;l.add(e),this.previousVisibleKeys.has(e)||this.keysToAnimate.add(e)}}),this.previousVisibleKeys=l,d.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&&e.originalEvent.target?.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,t){if(t){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)}}else e.classList.remove("tbw-row-loading"),e.removeAttribute("aria-busy"),e.querySelector(".tbw-row-loading-overlay")?.remove()}(t,!0),!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?C(t,n):t.replaceChildren(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.classList.toggle("tbw-row-expanded",!!e.__groupExpanded);const i=this.flatMeta[r];return i&&(t.setAttribute("aria-level",String(i.level)),t.setAttribute("aria-setsize",String(i.setSize)),t.setAttribute("aria-posinset",String(i.posInSet))),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="",!1!==o.fullWidth?this.renderFullWidthGroupRow(e,t,n):this.renderPerColumnGroupRow(e,t,n),!0}afterRender(){const e=this.gridElement?.querySelector(".rows");if(!e)return;const t=this.gridElement?.querySelector(".rows-body");t&&"treegrid"!==t.getAttribute("role")&&t.setAttribute("role","treegrid");for(const n of e.querySelectorAll(".data-grid-row:not(.group-row)")){const e=n.querySelector(".cell[data-row]"),t=e?parseInt(e.getAttribute("data-row")??"-1",10):-1,r=this.flatMeta[t];r&&(n.setAttribute("aria-level",String(r.level)),n.setAttribute("aria-setsize",String(r.setSize)),n.setAttribute("aria-posinset",String(r.posInSet)))}const r=this.animationStyle;if(!1===r||0===this.keysToAnimate.size)return;const o="fade"===r?"tbw-group-fade-in":"tbw-group-slide-in";for(const n of e.querySelectorAll(".data-grid-row:not(.group-row)")){const e=n.querySelector(".cell[data-row]"),t=e?parseInt(e.getAttribute("data-row")??"-1",10):-1,r="data"===this.flattenedRows[t]?.kind?`data-${t}`:void 0;r&&this.keysToAnimate.has(r)&&(n.classList.add(o),n.addEventListener("animationend",()=>n.classList.remove(o),{once:!0}))}this.keysToAnimate.clear()}computeFlatMeta(){const e=this.flattenedRows,t=new Array(e.length),r=/* @__PURE__ */new Map,o=/* @__PURE__ */new Map;let n=null,i=0;for(const l of e)if("group"===l.kind){n&&o.set(n.key,i),n=l,i=0;const e=`${l.key.split("||").slice(0,-1).join("||")}@${l.depth}`;r.set(e,(r.get(e)??0)+1)}else i++;n&&o.set(n.key,i);const s=/* @__PURE__ */new Map;let a=null,d=0;for(let l=0;l<e.length;l++){const n=e[l];if("group"===n.kind){const e=`${n.key.split("||").slice(0,-1).join("||")}@${n.depth}`,o=(s.get(e)??0)+1;s.set(e,o),t[l]={level:n.depth+1,setSize:r.get(e)??1,posInSet:o},a=n,d=0}else{d++;const r=a?.depth??-1,n=a?o.get(a.key)??1:e.length;t[l]={level:r+2,setSize:n,posInSet:d}}}this.flatMeta=t}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=k(this.config.defaultExpanded??!1,t);r.size>0&&(this.expandedKeys=new Set(r),this.hasAppliedDefaultExpanded=!0)}const t=G({groups:e,expanded:this.expandedKeys,groupRows:this.groupRowsMap,loadingGroups:this.loadingGroups});this.isActive=!0,this.flattenedRows=t,this.computeFlatMeta(),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)?.rowCount??t.rows.length;return{__isGroupRow:!0,__groupKey:t.key,__groupValue:t.value,__groupDepth:t.depth,__groupRows:t.rows,__groupExpanded:t.expanded,__groupRowCount:r,__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,s=i.aggregators??{},a=e.__groupRows??[],d=document.createElement("div");d.className="cell group-full",d.style.gridColumn="1 / -1",d.setAttribute("role","gridcell"),d.setAttribute("data-col","0"),d.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),d.appendChild(l),!1!==i.showRowCount){const t=document.createElement("span");t.className=o,t.textContent=`(${e.__groupRowCount??e.__groupRows?.length??0})`,d.appendChild(t)}const u=Object.entries(s);if(u.length>0){const e=document.createElement("span");e.className="group-aggregates";for(const[t,r]of u){const o=this.columns.find(e=>e.field===t),n=c.run(r,a,t,o);if(null!=n){const r=document.createElement("span");r.className="group-aggregate",r.setAttribute("data-field",t),r.textContent=`${o?.header??t}: ${n}`,e.appendChild(r)}}e.children.length>0&&d.appendChild(e)}t.appendChild(d)}renderPerColumnGroupRow(e,t,r){const n=this.config,i=n.aggregators??{},s=this.columns,a=e.__groupRows??[],d=(this.gridElement?.querySelector(".body"))?.style.gridTemplateColumns||"";d&&(t.style.display="grid",t.style.gridTemplateColumns=d);let l=!1;s.forEach((s,d)=>{const u=document.createElement("div");if(u.className="cell group-cell",u.setAttribute("data-col",String(d)),u.setAttribute("role","gridcell"),"__tbw_expander"===s.field)return u.setAttribute("data-field",s.field),void t.appendChild(u);if(l){const e=i[s.field];if(e){const t=c.run(e,a,s.field,s);u.textContent=null!=t?String(t):""}else u.textContent=""}else{l=!0,u.appendChild(this.createToggleButton(e.__groupExpanded,r));const t=document.createElement("span"),d=i[s.field];if(d){const r=c.run(d,a,s.field,s);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!==n.showRowCount){const e=document.createElement("span");e.className=o,e.textContent=` (${a.length})`,u.appendChild(e)}}t.appendChild(u)})}expandAll(){if(this.groupConfigDirty)return this.pendingExpansion=!0,this.expandedKeys=/* @__PURE__ */new Set,void this.requestRender();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.broadcast("group-toggle",{expandedKeys:[...this.expandedKeys]}),this.requestRender()}collapseAll(){if(this.groupConfigDirty)return this.pendingExpansion=!1,this.expandedKeys=/* @__PURE__ */new Set,void this.requestRender();this.expandedKeys=/* @__PURE__ */new Set,this.broadcast("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=K(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;f(this.gridElement,w(this.gridElement,"groupExpanded",s,e))}else f(this.gridElement,w(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,t){this.config.groupOn=e,this.groupConfigDirty=!0,void 0!==t&&(this.pendingExpansion=t,this.expandedKeys=/* @__PURE__ */new Set,this.hasAppliedDefaultExpanded=!1),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{D as GroupingRowsPlugin};
1
+ import{HierarchyPlugin as e,buildHierarchy as t}from"@toolbox-web/grid/plugins/hierarchy";var r="expanded",n="group-toggle",o="group-label",i="group-count",s=/* @__PURE__ */new WeakMap;function a(e){return"__proto__"===e||"constructor"===e||"prototype"===e}var d=/* @__PURE__ */new Map;function l(e,t){if(null==e)return;const r=function(e){if(-1===e.indexOf("."))return null;let t=d.get(e);return void 0===t&&(t=Object.freeze(e.split(".")),d.set(e,t)),t}(t),n=e;return null===r?a(t)?void 0:n[t]:Object.prototype.hasOwnProperty.call(n,t)?n[t]:function(e,t){let r=e;for(let n=0;n<t.length;n++){if(null==r||"object"!=typeof r)return;const e=t[n];if(a(e))return;r=r[e]}return r}(n,r)}function u(e,t,r){return r?.valueAccessor?function(e,t,r=-1){if(!t.valueAccessor)return l(e,t.field);if("object"!=typeof e||null===e)return t.valueAccessor({row:e,column:t,rowIndex:r});const n=e,o=t.field;let i=s.get(n);if(i){const e=i.get(o);if(void 0!==e)return e.v}else i=/* @__PURE__ */new Map,s.set(n,i);const a=t.valueAccessor({row:e,column:t,rowIndex:r});return i.set(o,{v:a}),a}(e,r):l(e,t)}function p(e){return null==e||""===e||"number"==typeof e&&isNaN(e)}var c={sum:(e,t,r)=>{let n=0;for(let o=0;o<e.length;o++){const i=u(e[o],t,r);if(p(i))continue;const s=Number(i);isNaN(s)||(n+=s)}return n},avg:(e,t,r)=>{if(!e.length)return 0;let n=0,o=0;for(let i=0;i<e.length;i++){const s=u(e[i],t,r);if(p(s))continue;const a=Number(s);isNaN(a)||(n+=a,o++)}return o>0?n/o:0},count:e=>e.length,min:(e,t,r)=>{if(!e.length)return 0;let n=1/0;for(let o=0;o<e.length;o++){const i=u(e[o],t,r);if(p(i))continue;const s=Number(i);isNaN(s)||s<n&&(n=s)}return n===1/0?0:n},max:(e,t,r)=>{if(!e.length)return 0;let n=-1/0;for(let o=0;o<e.length;o++){const i=u(e[o],t,r);if(p(i))continue;const s=Number(i);isNaN(s)||s>n&&(n=s)}return n===-1/0?0:n},first:(e,t,r)=>e[0]?u(e[0],t,r):void 0,last:(e,t,r)=>e.length?u(e[e.length-1],t,r):void 0},g=/* @__PURE__ */new Map,h={register(e,t){g.set(e,t)},unregister(e){g.delete(e)},get(e){if(void 0!==e)return"function"==typeof e?e:g.get(e)??c[e]},run(e,t,r,n){const o=this.get(e);return o?o(t,r,n):void 0},has:e=>g.has(e)||e in c,list:()=>[...Object.keys(c),...g.keys()]},f={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`,selectAllRows:()=>"Select all rows",selectRow:e=>`Select row ${e+1}`,columnSelected:e=>`Column ${e} selected`,columnSelectionChanged:e=>`${e} columns selected`,columnSelectionCleared:()=>"Column selection cleared",selectionAxisChanged:e=>"column"===e?"Row selection cleared, column selection active":"Column selection cleared, row selection active",rangeSpanSelected:(e,t)=>1===t?("row"===e?"Row":"Column")+" selected":`${t} ${e}s selected`,editingStarted:e=>`Editing row ${e+1}`,editingCommitted:e=>`Row ${e+1} saved`,dataLoaded:e=>`${e} rows loaded`},w={expand:"▶",collapse:"▼",sortAsc:"▲",sortDesc:"▼",sortNone:"⇅",submenuArrow:"▶",dragHandle:"⋮⋮",toolPanel:"☰",filter:"",filterActive:"",print:"🖨️"};function m(e,t){if(!e)return;if(!1===("effectiveConfig"in e?e.effectiveConfig:void 0)?.a11y?.announcements)return;const r=e.querySelector?.(".tbw-sr-only");r&&(r.textContent="","function"==typeof requestAnimationFrame?requestAnimationFrame(()=>{r.textContent=t}):r.textContent=t)}function y(e,t,...r){const n=(e&&"effectiveConfig"in e?e.effectiveConfig:void 0)?.a11y?.messages?.[t];return n?n(...r):f[t](...r)}var v="__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".split("|").map(e=>e.split("").reverse().join("")),b=(new RegExp(`__(proto|defineGetter|defineSetter)|${v.slice(3).join("|")}|this\\b`),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|math".split("|"))),x=/^on\w+$/i,_=new Set("href|src|action|formaction|data|srcdoc|xlink:href|poster|srcset".split("|")),R=/^\s*(javascript|vbscript|data|blob):/i;function C(e){const t=document.createElement("template");return e&&"string"==typeof e&&(t.innerHTML=e,function(e){const t=[],r=e.querySelectorAll("*");for(const n of r){const e=n.tagName.toLowerCase();if(b.has(e)){t.push(n);continue}if(("svg"===e||"http://www.w3.org/2000/svg"===n.namespaceURI)&&Array.from(n.attributes).some(e=>x.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();x.test(e)?r.push(t.name):"is"!==e?(_.has(e)&&R.test(t.value)||"style"===e&&/expression\s*\(|javascript:|behavior\s*:/i.test(t.value))&&r.push(t.name):r.push(t.name)}r.forEach(e=>n.removeAttribute(e))}t.forEach(e=>e.remove())}(t.content)),t.content}function A(e,t){t&&"string"==typeof t?-1!==t.indexOf("<")||-1!==t.indexOf("&")?e.replaceChildren(C(t)):e.textContent=t:e.replaceChildren()}function E(e,t){return`[tbw-grid${e?`#${e}`:""}${t?`:${t}`:""}]`}function S(e,t,r,n){return`${E(r,n)} ${e}: ${t}\n\n → More info: ${function(e){return`https://toolboxjs.com/grid/errors#${e.toLowerCase()}`}(e)}`}var k=class{static dependencies;static manifest;aliases;version="3.9.0";styles;cellRenderers;headerRenderers;cellEditors;grid;config;userConfig;#e;get defaultConfig(){return{}}constructor(e={}){this.userConfig=e}get resolvedConfig(){return this.#e?this.config:{...this.defaultConfig,...this.userConfig}}mergeConfigsFrom(e){if(0===e.length)return;const t={...this.userConfig},r={};for(const n of Object.keys(t))r[n]=this;for(const n of e){const e=n.userConfig;for(const[o,i]of Object.entries(e)){if(void 0===i)continue;if(!(o in t)){t[o]=i,r[o]=n;continue}if(t[o]===i)continue;const e=r[o]?.constructor.name??this.constructor.name,s=n.constructor.name,a=S("TBW025",`Cannot merge plugin configs for "${this.name}": conflicting value for "${o}" supplied by both ${e} and ${s}. Pass the option on a single instance, or remove the duplicate.`,void 0,this.name);throw new Error(a)}}Object.assign(this.userConfig,t)}refreshUserConfigFrom(e){const t=this.userConfig,r={...e.userConfig};for(const n of Object.keys(t))delete t[n];Object.assign(t,r)}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)}queryBoolean(e,t=null){const r=this.grid?.query?.(e,t);return Array.isArray(r)?r.some(Boolean):!!r}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{...w,...e}}t(e,t){return this.grid?.effectiveConfig?.locale?.[e]??t}get translate(){return(e,t)=>this.t(e,t)}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;return!t||"0"!==getComputedStyle(t).getPropertyValue("--tbw-animation-enabled").trim()}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?A(e,n):n instanceof HTMLElement&&e.replaceChildren(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(S(e,t,this.gridElement.id,this.name)):console.warn(`${E(this.gridElement.id,this.name)} ${e}`)}throwDiagnostic(e,t){throw new Error(S(e,t,this.gridElement.id,this.name))}};var G={parent:null,depth:0};function K(e,t){if(!0===e)return new Set(t);if(!1===e||null==e)/* @__PURE__ */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 D(e){return"group"!==e.kind?0:e.rows.length}function q({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=q({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 N(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=N(n.children,t,e);if(r.length>0)return r}}return[]}var $=class extends k{static manifest={modifiesRowStructure:!0,hookPriority:{processRows:10,onHeaderClick:-1},incompatibleWith:[{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:"hierarchy",required:!0,reason:"Builds the hierarchical row model",provide:()=>new e},{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";hierarchyStage="transform";styles='@layer tbw-plugins{.group-row{grid-template-columns:var(--tbw-column-template);background:var(--tbw-grouping-rows-bg,var(--tbw-color-panel-bg));border-bottom:var(--tbw-row-divider);min-height:var(--tbw-row-height);font-weight:500;display:grid}.group-row .cell{padding:var(--tbw-cell-padding,.125rem .5rem);align-items:center;display:flex}@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;width:var(--tbw-toggle-size,1.25rem);height:var(--tbw-toggle-size,1.25rem);font:inherit;background:0 0;border:0;justify-content:center;align-items:center;margin-right:.25rem;display:inline-flex}.group-toggle:hover{background:var(--tbw-grouping-rows-toggle-hover,var(--tbw-color-row-hover));border-radius:var(--tbw-border-radius,.125rem)}.group-toggle{position:relative}.group-toggle:after{content:"";inline-size:var(--tbw-touch-target-min,24px);block-size:var(--tbw-touch-target-min,24px);position:absolute;inset-block-start:50%;inset-inline-start:50%;translate:-50% -50%}@media (pointer:coarse){.group-toggle{min-width:var(--tbw-touch-target-min,24px);min-height:var(--tbw-touch-target-min,24px)}}.group-label{align-items:center;gap:var(--tbw-panel-gap,var(--tbw-spacing-md,.5rem));display:inline-flex}.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{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));display:inline-flex}.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;pendingExpansion;groupConfigDirty=!1;preDefinedGroups=[];groupRowsMap=/* @__PURE__ */new Map;loadingGroups=/* @__PURE__ */new Set;groupedFields=[];userGroupSortDirections=/* @__PURE__ */new Map;#r="groupOn";#n;#o=!1;#i;#s=!1;#a=/* @__PURE__ */new WeakMap;#d=!1;#l=/* @__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.pendingExpansion=void 0,this.groupConfigDirty=!1,this.preDefinedGroups=[],this.groupRowsMap.clear(),this.loadingGroups.clear(),this.groupedFields=[],this.userGroupSortDirections.clear(),this.#l.clear()}getRowHeight(e,t){if(null!=this.config.groupRowHeight)return!0===e.__isGroupRow?this.config.groupRowHeight:void 0}handleQuery(e){if("canMoveRow"===e.type&&!0===e.context?.__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 n=this.getActiveGroups();return{startNode:this.getTopLevelGroupIndex(t),endNode:this.getTopLevelGroupIndex(r)+1,totalLoadedNodes:n.length}}}getTopLevelGroupIndex(e){let t=-1;const r=Math.min(e,this.flattenedRows.length-1);for(let n=0;n<=r;n++){const e=this.flattenedRows[n];"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,n=this.userGroupSortDirections.get(r)??1;return this.userGroupSortDirections.set(r,1===n?-1:1),this.requestRender(),!0}resolveGroupSortDirections(e,t){const r=this.config;if("function"!=typeof r.groupOn||0===e.length)return void(this.groupedFields=[]);const n=this.columns.map(e=>e.field),o=function(e,t,r,n=G){const o=/* @__PURE__ */new Map;let i,s=null;for(const a of e)if(s=t(a,n),null!=s&&!1!==s){i=a;break}if(void 0===i)return o;Array.isArray(s)||(s=[s]);for(let a=0;a<s.length;a++){const e=s[a];for(const t of r)if(i[t]===e){o.set(a,t);break}}return o}([...e],r.groupOn,n,t);if(this.groupedFields=[...o.values()],0===o.size)return;const i=new Map(this.userGroupSortDirections);if(i.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._sortState;t&&e.set(t.field,t.direction)}for(const[r,n]of o)if(!i.has(r)){const t=e.get(n);void 0!==t&&i.set(r,t)}}return i.size>0?i:void 0}static detect(e,t){return"function"==typeof t?.groupOn||"boolean"==typeof t?.enableRowGrouping||Array.isArray(t?.groups)}processRows(e){const r=this.grid?.getPluginByName?.("hierarchy");return r?r.process(e,this):t(e,[this])}beginHierarchy(e){return this.#n=this.pendingExpansion,this.pendingExpansion=void 0,this.groupConfigDirty=!1,this.#o=!1,this.#d=!1,this.#a=/* @__PURE__ */new WeakMap,this.preDefinedGroups.length>0||Array.isArray(this.config.groups)?(this.#r="predefined",!0):"function"!=typeof this.config.groupOn?(this.isActive=!1,this.flattenedRows=[],this.groupedFields=[],!1):(this.#r="groupOn",this.groupedFields=[],this.#i=void 0,this.#s=!1,!0)}processSiblings(e,t){const r=null===t.parentKey&&null===t.parent;if("predefined"===this.#r)return r?this.#u(t.depth):e;const n=this.config,o=e.map(e=>e.row),i={parent:t.parent,depth:t.depth};this.#s||(this.#i=this.resolveGroupSortDirections(o,i),this.#s=this.groupedFields.length>0);const s=(e,s)=>function({rows:e,config:t,expanded:r,initialExpanded:n,groupSortDirections:o,context:i=G,keyPrefix:s=""}){const a=t.groupOn;if("function"!=typeof a)return[];const d={key:"__root__",value:null,depth:-1,rows:[],children:/* @__PURE__ */new Map};if(e.forEach(e=>{let t=a(e,i);null==t||!1===t?t=["__ungrouped__"]:Array.isArray(t)||(t=[t]);let r=d;t.forEach((t,n)=>{const o=null==t?"∅":String(t),i="__root__"===r.key?s+o:r.key+"||"+o;let a=r.children.get(o);a||(a={key:i,value:t,depth:n,rows:[],children:/* @__PURE__ */new Map,parent:r},r.children.set(o,a)),a.rows.push(e),r=a})}),1===d.children.size&&d.children.has("__ungrouped__")&&d.children.get("__ungrouped__").rows.length===e.length)return[];const l=/* @__PURE__ */new Map;for(let h=0;h<e.length;h++)l.set(e[h],h);const u=/* @__PURE__ */new Set([...r,...n??[]]),p=e=>{const t=[...e.children.values()],r=e===d?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},c=[],g=e=>{if(e===d){for(const t of p(e))g(t);return}const t=u.has(e.key);if(c.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 p(e))g(r);else e.rows.forEach(e=>c.push({kind:"data",row:e,rowIndex:l.get(e)??-1}))};return g(d),c}({rows:o,config:n,expanded:e,initialExpanded:s,groupSortDirections:this.#i,context:i,keyPrefix:r?"":`${t.parentKey??""}::`}),a=r?this.#p(s):this.#c(s);if(0===a.length)return e;const d=/* @__PURE__ */new Map;for(const l of e)d.set(l.row,l);return this.#g(a,t.depth,e=>d.get(e)??{row:e},D)}endHierarchy(e){if(!this.#d)return this.isActive=!1,this.flattenedRows=[],!1;this.isActive=!0,this.flattenedRows=e.map(e=>this.#a.get(e)??{kind:"data",row:e,rowIndex:-1}),this.#o&&this.broadcast("group-toggle",{expandedKeys:[...this.expandedKeys]}),this.keysToAnimate.clear();const t=/* @__PURE__ */new Set;return this.flattenedRows.forEach((e,r)=>{if("data"===e.kind){const e=`data-${r}`;t.add(e),this.previousVisibleKeys.has(e)||this.keysToAnimate.add(e)}}),this.previousVisibleKeys=t,!0}#p(e){const t=this.config,r=e(/* @__PURE__ */new Set);if(0===r.length)return r;const n=this.#n;let o;const i=void 0!==n;let s;if(i?o=n:this.hasAppliedDefaultExpanded||0!==this.expandedKeys.size||!1===t.defaultExpanded||(o=t.defaultExpanded??!1),void 0!==o){s=K(o,r.filter(e=>"group"===e.kind).map(e=>e.key)),(i||s.size>0)&&(this.expandedKeys=new Set(s),this.hasAppliedDefaultExpanded=!0)}return this.#o=i,e(this.expandedKeys,s)}#c(e){const t=e(this.expandedKeys),r=this.#n;if(void 0===r&&!0!==this.config.defaultExpanded)return t;const n=[];for(const s of t)"group"===s.kind&&0===s.depth&&n.push(s.key);const o=void 0!==r?K(r,n):new Set(n.filter(e=>!this.#l.has(e)));void 0!==r&&(this.#o=!0);let i=!1;for(const s of n)this.#l.add(s),o.has(s)&&!this.expandedKeys.has(s)&&(this.expandedKeys.add(s),i=!0);return i?e(this.expandedKeys):t}#g(e,t,r,n){this.#d=!0;const o=[],i=[];for(const s of e){if("data"===s.kind){const e=r(s.row);(i.length>0?i[i.length-1].children:o).push(e),"object"==typeof s.row&&null!==s.row&&this.#a.set(s.row,s);continue}const e=0===t?s:{...s,depth:t+s.depth},a={__isGroupRow:!0,__groupKey:s.key,__groupValue:s.value,__groupDepth:e.depth,__groupRows:s.rows,__groupExpanded:s.expanded,__groupRowCount:n(s),__rowCacheKey:`group:${s.key}`};this.#a.set(a,e);const d={row:a,key:s.key,expanded:s.expanded,shaped:!0,children:[]};i.length=s.depth,(s.depth>0?i[s.depth-1].children:o).push(d),i.push(d)}return o}onCellClick(e){const t=e.row;if(t?.__isGroupRow&&e.originalEvent.target?.closest(`.${n}`))return this.toggle(t.__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,t){if(t){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)}}else e.classList.remove("tbw-row-loading"),e.removeAttribute("aria-busy"),e.querySelector(".tbw-row-loading-overlay")?.remove()}(t,!0),!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?A(t,o):t.replaceChildren(o),!0}const o=()=>{this.toggle(e.__groupKey)};return t.className="data-grid-row group-row",t.__isCustomRow=!0,t.setAttribute("data-group-depth",String(e.__groupDepth)),t.setAttribute("role","row"),t.setAttribute("aria-expanded",String(e.__groupExpanded)),t.classList.toggle("tbw-row-expanded",!!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="",!1!==n.fullWidth?this.renderFullWidthGroupRow(e,t,o):this.renderPerColumnGroupRow(e,t,o),!0}afterRender(){const e=this.gridElement?.querySelector(".rows");if(!e)return;const t=this.animationStyle;if(!(!1!==t&&this.keysToAnimate.size>0))return;const r="fade"===t?"tbw-group-fade-in":"tbw-group-slide-in";for(const n of e.querySelectorAll(".data-grid-row:not(.group-row)")){const e=n.querySelector(".cell[data-row]"),t=e?parseInt(e.getAttribute("data-row")??"-1",10):-1;"data"===this.flattenedRows[t]?.kind&&this.keysToAnimate.has(`data-${t}`)&&(n.classList.add(r),n.addEventListener("animationend",()=>n.classList.remove(r),{once:!0}))}this.keysToAnimate.clear()}#u(e){const t=this.getActiveGroups();if(0===t.length)return[];if(!this.hasAppliedDefaultExpanded&&0===this.expandedKeys.size&&!1!==this.config.defaultExpanded){const e=this.collectGroupKeys(t),r=K(this.config.defaultExpanded??!1,e);r.size>0&&(this.expandedKeys=new Set(r),this.hasAppliedDefaultExpanded=!0)}const r=q({groups:t,expanded:this.expandedKeys,groupRows:this.groupRowsMap,loadingGroups:this.loadingGroups});return this.#g(r,e,e=>({row:e}),e=>this.findGroupDefinition(t,e.key)?.rowCount??e.rows.length)}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(e,t){const o=document.createElement("button");return o.type="button",o.className=`${n}${e?` ${r}`:""}`,o.setAttribute("aria-label",e?"Collapse group":"Expand group"),this.setIcon(o,e?"collapse":"expand"),o.addEventListener("click",e=>{e.stopPropagation(),t()}),o}getGroupLabelText(e,t,r){const n=this.config;return n.formatLabel?n.formatLabel(e,t,r):String(e)}renderFullWidthGroupRow(e,t,r){const n=this.config,s=n.aggregators??{},a=e.__groupRows??[],d=document.createElement("div");d.className="cell group-full",d.style.gridColumn="1 / -1",d.setAttribute("role","gridcell"),d.setAttribute("data-col","0"),d.appendChild(this.createToggleButton(e.__groupExpanded,r));const l=document.createElement("span");if(l.className=o,l.textContent=this.getGroupLabelText(e.__groupValue,e.__groupDepth||0,e.__groupKey),d.appendChild(l),!1!==n.showRowCount){const t=document.createElement("span");t.className=i,t.textContent=`(${e.__groupRowCount??e.__groupRows?.length??0})`,d.appendChild(t)}const u=Object.entries(s);if(u.length>0){const e=document.createElement("span");e.className="group-aggregates";for(const[t,r]of u){const n=this.columns.find(e=>e.field===t),o=h.run(r,a,t,n);if(null!=o){const r=document.createElement("span");r.className="group-aggregate",r.setAttribute("data-field",t),r.textContent=`${n?.header??t}: ${o}`,e.appendChild(r)}}e.children.length>0&&d.appendChild(e)}t.appendChild(d)}renderPerColumnGroupRow(e,t,r){const n=this.config,o=n.aggregators??{},s=this.columns,a=e.__groupRows??[],d=(this.gridElement?.querySelector(".body"))?.style.gridTemplateColumns||"";d&&(t.style.display="grid",t.style.gridTemplateColumns=d);let l=!1;s.forEach((s,d)=>{const u=document.createElement("div");if(u.className="cell group-cell",u.setAttribute("data-col",String(d)),u.setAttribute("role","gridcell"),"__tbw_expander"===s.field)return u.setAttribute("data-field",s.field),void t.appendChild(u);if(l){const e=o[s.field];if(e){const t=h.run(e,a,s.field,s);u.textContent=null!=t?String(t):""}else u.textContent=""}else{l=!0,u.appendChild(this.createToggleButton(e.__groupExpanded,r));const t=document.createElement("span"),d=o[s.field];if(d){const r=h.run(d,a,s.field,s);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!==n.showRowCount){const e=document.createElement("span");e.className=i,e.textContent=` (${a.length})`,u.appendChild(e)}}t.appendChild(u)})}expandAll(){if(this.groupConfigDirty)return this.pendingExpansion=!0,this.expandedKeys=/* @__PURE__ */new Set,void this.requestRender();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.broadcast("group-toggle",{expandedKeys:[...this.expandedKeys]}),this.requestRender()}collapseAll(){if(this.groupConfigDirty)return this.pendingExpansion=!1,this.expandedKeys=/* @__PURE__ */new Set,void this.requestRender();this.expandedKeys=/* @__PURE__ */new Set,this.broadcast("group-toggle",{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(("function"==typeof r.accordion?n&&r.accordion(n.depth):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.broadcast("group-toggle",{key:e,expanded:this.expandedKeys.has(e),value:n?.value,depth:n?.depth??0,expandedKeys:[...this.expandedKeys]});const o=this.getActiveGroups();if(o.length>0){const r=N(o,e);if(t){if(this.emit("group-expand",{groupKey:e,groupPath:r}),!this.groupRowsMap.has(e)){const t=this.findGroupDefinition(o,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!=n?.value?String(n.value):e;if(i){const e=n?.rows?.length??0;m(this.gridElement,y(this.gridElement,"groupExpanded",s,e))}else m(this.gridElement,y(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,t){this.config.groupOn=e,this.groupConfigDirty=!0,void 0!==t&&(this.pendingExpansion=t,this.expandedKeys=/* @__PURE__ */new Set,this.hasAppliedDefaultExpanded=!1),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{$ as GroupingRowsPlugin};
2
2
  //# sourceMappingURL=index.js.map