@toolbox-web/grid 2.13.0 → 2.14.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 (75) hide show
  1. package/all.js +2 -2
  2. package/all.js.map +1 -1
  3. package/custom-elements.json +18 -0
  4. package/index.js +1 -1
  5. package/index.js.map +1 -1
  6. package/lib/core/grid.d.ts +23 -0
  7. package/lib/core/internal/style-injector.d.ts +0 -8
  8. package/lib/core/types.d.ts +32 -0
  9. package/lib/plugins/clipboard/index.js.map +1 -1
  10. package/lib/plugins/column-virtualization/index.js.map +1 -1
  11. package/lib/plugins/context-menu/index.js.map +1 -1
  12. package/lib/plugins/editing/index.js.map +1 -1
  13. package/lib/plugins/export/index.js.map +1 -1
  14. package/lib/plugins/filtering/index.js +1 -1
  15. package/lib/plugins/filtering/index.js.map +1 -1
  16. package/lib/plugins/filtering/types.d.ts +0 -28
  17. package/lib/plugins/grouping-columns/index.js.map +1 -1
  18. package/lib/plugins/grouping-rows/GroupingRowsPlugin.d.ts +53 -2
  19. package/lib/plugins/grouping-rows/index.js +2 -2
  20. package/lib/plugins/grouping-rows/index.js.map +1 -1
  21. package/lib/plugins/grouping-rows/types.d.ts +10 -8
  22. package/lib/plugins/master-detail/MasterDetailPlugin.d.ts +0 -1
  23. package/lib/plugins/master-detail/index.js +1 -1
  24. package/lib/plugins/master-detail/index.js.map +1 -1
  25. package/lib/plugins/master-detail/types.d.ts +0 -2
  26. package/lib/plugins/multi-sort/index.js.map +1 -1
  27. package/lib/plugins/pinned-columns/index.js.map +1 -1
  28. package/lib/plugins/pinned-rows/index.js.map +1 -1
  29. package/lib/plugins/pivot/index.js.map +1 -1
  30. package/lib/plugins/print/index.js.map +1 -1
  31. package/lib/plugins/reorder-columns/index.js.map +1 -1
  32. package/lib/plugins/reorder-rows/index.js.map +1 -1
  33. package/lib/plugins/responsive/index.js +1 -1
  34. package/lib/plugins/responsive/index.js.map +1 -1
  35. package/lib/plugins/responsive/types.d.ts +11 -2
  36. package/lib/plugins/row-drag-drop/index.js.map +1 -1
  37. package/lib/plugins/selection/index.js.map +1 -1
  38. package/lib/plugins/server-side/datasource-types.d.ts +8 -0
  39. package/lib/plugins/server-side/index.js +1 -1
  40. package/lib/plugins/server-side/index.js.map +1 -1
  41. package/lib/plugins/server-side/types.d.ts +9 -10
  42. package/lib/plugins/sticky-rows/index.js.map +1 -1
  43. package/lib/plugins/tooltip/index.js +1 -1
  44. package/lib/plugins/tooltip/index.js.map +1 -1
  45. package/lib/plugins/tree/index.js.map +1 -1
  46. package/lib/plugins/undo-redo/index.js.map +1 -1
  47. package/lib/plugins/visibility/index.js +1 -1
  48. package/lib/plugins/visibility/index.js.map +1 -1
  49. package/lib/plugins/visibility/types.d.ts +5 -10
  50. package/lib/plugins/visibility/visibility.d.ts +5 -3
  51. package/package.json +1 -1
  52. package/themes/dg-theme-bootstrap.css +2 -2
  53. package/themes/dg-theme-contrast.css +1 -1
  54. package/themes/dg-theme-large.css +1 -1
  55. package/themes/dg-theme-material.css +2 -2
  56. package/themes/dg-theme-standard.css +1 -1
  57. package/themes/dg-theme-vibrant.css +1 -1
  58. package/umd/grid.all.umd.js +1 -1
  59. package/umd/grid.all.umd.js.map +1 -1
  60. package/umd/grid.umd.js +1 -1
  61. package/umd/grid.umd.js.map +1 -1
  62. package/umd/plugins/filtering.umd.js +1 -1
  63. package/umd/plugins/filtering.umd.js.map +1 -1
  64. package/umd/plugins/grouping-rows.umd.js +1 -1
  65. package/umd/plugins/grouping-rows.umd.js.map +1 -1
  66. package/umd/plugins/master-detail.umd.js +1 -1
  67. package/umd/plugins/master-detail.umd.js.map +1 -1
  68. package/umd/plugins/responsive.umd.js +1 -1
  69. package/umd/plugins/responsive.umd.js.map +1 -1
  70. package/umd/plugins/server-side.umd.js +1 -1
  71. package/umd/plugins/server-side.umd.js.map +1 -1
  72. package/umd/plugins/tooltip.umd.js +1 -1
  73. package/umd/plugins/tooltip.umd.js.map +1 -1
  74. package/umd/plugins/visibility.umd.js +1 -1
  75. package/umd/plugins/visibility.umd.js.map +1 -1
@@ -1,5 +1,5 @@
1
1
  import { BaseGridPlugin, CellClickEvent, HeaderClickEvent, GridElement, PluginManifest, PluginQuery } from '../../core/plugin/base-plugin';
2
- import { GroupDefinition, GroupingRowsConfig, RenderRow } from './types';
2
+ import { DefaultExpandedValue, GroupDefinition, GroupingRowsConfig, RenderRow } from './types';
3
3
  /**
4
4
  * Group state information returned by getGroupState()
5
5
  * @since 0.1.1
@@ -102,6 +102,20 @@ export declare class GroupingRowsPlugin extends BaseGridPlugin<GroupingRowsConfi
102
102
  private keysToAnimate;
103
103
  /** Track if initial defaultExpanded has been applied */
104
104
  private hasAppliedDefaultExpanded;
105
+ /**
106
+ * Expansion override to apply on the next `processRows` rebuild instead of
107
+ * — or in addition to — `config.defaultExpanded`. Set by `setGroupOn(fn, expanded)`
108
+ * and by `expandAll()` / `collapseAll()` when the grouping config has just
109
+ * changed (so `flattenedRows` is stale). Cleared once consumed by a rebuild.
110
+ * See issue #335.
111
+ */
112
+ private pendingExpansion;
113
+ /**
114
+ * Set by `setGroupOn` to mark the cached `flattenedRows` as stale until the
115
+ * next `processRows` runs. While true, `expandAll`/`collapseAll` defer via
116
+ * `pendingExpansion` instead of reading the stale snapshot. See issue #335.
117
+ */
118
+ private groupConfigDirty;
105
119
  /** Pre-defined group definitions (from config, setGroups(), or datasource:data) */
106
120
  private preDefinedGroups;
107
121
  /** Row data keyed by group key (from setGroupRows() or datasource:children) */
@@ -225,10 +239,20 @@ export declare class GroupingRowsPlugin extends BaseGridPlugin<GroupingRowsConfi
225
239
  private renderPerColumnGroupRow;
226
240
  /**
227
241
  * Expand all groups.
242
+ *
243
+ * Safe to call immediately after {@link setGroupOn}: when the grouping
244
+ * config has just changed, the cached `flattenedRows` is stale, so the
245
+ * call defers until the next render rebuilds the group model against the
246
+ * new `groupOn` (issue #335). The `group-toggle` event is emitted once
247
+ * the new keys are known.
228
248
  */
229
249
  expandAll(): void;
230
250
  /**
231
251
  * Collapse all groups.
252
+ *
253
+ * Safe to call immediately after {@link setGroupOn}: defers until the next
254
+ * render rebuilds the group model so the collapse targets the new groups
255
+ * rather than a stale snapshot (issue #335).
232
256
  */
233
257
  collapseAll(): void;
234
258
  /**
@@ -285,9 +309,36 @@ export declare class GroupingRowsPlugin extends BaseGridPlugin<GroupingRowsConfi
285
309
  isGroupingActive(): boolean;
286
310
  /**
287
311
  * Set the groupOn function dynamically.
312
+ *
313
+ * Optionally specify the initial expansion state to apply against the new
314
+ * group set. Without it, the previous `expandedKeys` are kept (and most
315
+ * likely won't match the new keys, so groups land collapsed). With it,
316
+ * the new groups are expanded synchronously on the next render — no need
317
+ * to chain `setGroupOn(fn); expandAll()` or wait for `requestAnimationFrame`.
318
+ *
319
+ * If you do call `expandAll()` / `collapseAll()` separately right after
320
+ * `setGroupOn`, those calls automatically defer to the same mechanism so
321
+ * they target the new groups rather than the stale snapshot. See issue #335.
322
+ *
288
323
  * @param fn - The groupOn function or undefined to disable
324
+ * @param expanded - Optional initial expansion for the new grouping:
325
+ * - `true`: expand all new groups
326
+ * - `false`: collapse all new groups
327
+ * - `string` / `string[]`: expand specific group key(s)
328
+ * - `number`: expand the group at this index
329
+ * When omitted, existing `expandedKeys` are preserved (legacy behavior).
330
+ *
331
+ * @example Group by a new field and expand everything
332
+ * ```ts
333
+ * plugin.setGroupOn((row) => row.counterparty, true);
334
+ * ```
335
+ *
336
+ * @example Group by a new field but keep all groups collapsed
337
+ * ```ts
338
+ * plugin.setGroupOn((row) => row.region, false);
339
+ * ```
289
340
  */
290
- setGroupOn(fn: ((row: any) => any[] | any | null | false) | undefined): void;
341
+ setGroupOn(fn: ((row: any) => any[] | any | null | false) | undefined, expanded?: DefaultExpandedValue): void;
291
342
  /**
292
343
  * Replace auto-detected groups with an externally provided group structure.
293
344
  *
@@ -1,3 +1,3 @@
1
- const e="expanded",t="group-toggle",r="group-label",o="group-count",n=/* @__PURE__ */new WeakMap;function i(e,t,r){return r?.valueAccessor?function(e,t,r=-1){if(!t.valueAccessor)return 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 a=t.valueAccessor({row:e,column:t,rowIndex:r});return s.set(i,{v:a}),a}(e,r):e?.[t]}function s(e){return null==e||""===e||"number"==typeof e&&isNaN(e)}const a={sum:(e,t,r)=>{let o=0;for(let n=0;n<e.length;n++){const a=i(e[n],t,r);if(s(a))continue;const d=Number(a);isNaN(d)||(o+=d)}return o},avg:(e,t,r)=>{if(!e.length)return 0;let o=0,n=0;for(let a=0;a<e.length;a++){const d=i(e[a],t,r);if(s(d))continue;const l=Number(d);isNaN(l)||(o+=l,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 a=i(e[n],t,r);if(s(a))continue;const d=Number(a);isNaN(d)||d<o&&(o=d)}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 a=i(e[n],t,r);if(s(a))continue;const d=Number(a);isNaN(d)||d>o&&(o=d)}return o===-1/0?0:o},first:(e,t,r)=>e[0]?i(e[0],t,r):void 0,last:(e,t,r)=>e.length?i(e[e.length-1],t,r):void 0},d=/* @__PURE__ */new Map,l={register(e,t){d.set(e,t)},unregister(e){d.delete(e)},get(e){if(void 0!==e)return"function"==typeof e?e:d.get(e)??a[e]},run(e,t,r,o){const n=this.get(e);return n?n(t,r,o):void 0},has:e=>d.has(e)||e in a,list:()=>[...Object.keys(a),...d.keys()]},u={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`,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`},p={expand:"▶",collapse:"▼",sortAsc:"▲",sortDesc:"▼",sortNone:"⇅",submenuArrow:"▶",dragHandle:"⋮⋮",toolPanel:"☰",filter:"",filterActive:"",print:"🖨️"};function c(e,t){if(!e)return;const r="effectiveConfig"in e?e.effectiveConfig:void 0;if(!1===r?.a11y?.announcements)return;const o=e.querySelector?.(".tbw-sr-only");o&&(o.textContent="",requestAnimationFrame(()=>{o.textContent=t}))}function g(e,t,...r){const o=e&&"effectiveConfig"in e?e.effectiveConfig:void 0,n=o?.a11y?.messages?.[t];return n?n(...r):u[t](...r)}function h(e,t){return`[tbw-grid${e?`#${e}`:""}${t?`:${t}`:""}]`}function f(e,t,r,o){return`${h(r,o)} ${e}: ${t}\n\n → More info: ${function(e){return`https://toolboxjs.com/grid/errors#${e.toLowerCase()}`}(e)}`}const w="__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(""));new RegExp(`__(proto|defineGetter|defineSetter)|${w.slice(3).join("|")}|this\\b`);const m=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".split("|")),y=/^on\w+$/i,v=new Set("href|src|action|formaction|data|srcdoc|xlink:href|poster|srcset".split("|")),b=/^\s*(javascript|vbscript|data|blob):/i;function _(e){if(!e||"string"!=typeof e)return"";if(-1===e.indexOf("<"))return e;const t=document.createElement("template");return t.innerHTML=e,function(e){const t=[],r=e.querySelectorAll("*");for(const o of r){const e=o.tagName.toLowerCase();if(m.has(e)){t.push(o);continue}if("svg"===e||"http://www.w3.org/2000/svg"===o.namespaceURI){if(Array.from(o.attributes).some(e=>y.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();y.test(e)?r.push(t.name):(v.has(e)&&b.test(t.value)||"style"===e&&/expression\s*\(|javascript:|behavior\s*:/i.test(t.value))&&r.push(t.name)}r.forEach(e=>o.removeAttribute(e))}t.forEach(e=>e.remove())}(t.content),t.innerHTML}class x{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}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=f("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)}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{...p,...e}}get isAnimationEnabled(){const e=this.grid?.effectiveConfig?.animation?.mode??"reduced-motion";if(!1===e||"off"===e)return!1;if(!0===e||"on"===e)return!0;const t=this.gridElement;if(t){return"0"!==getComputedStyle(t).getPropertyValue("--tbw-animation-enabled").trim()}return!0}get animationDuration(){const e=this.gridElement;if(e){const t=getComputedStyle(e).getPropertyValue("--tbw-animation-duration").trim(),r=parseInt(t,10);if(!isNaN(r))return r}return 200}setIcon(e,t,r){e.dataset.icon=t.replace(/([A-Z])/g,"-$1").toLowerCase(),"collapse"===t?e.dataset.expanded="":"expand"===t&&delete e.dataset.expanded;const o=this.#t(t,r);void 0!==o?"string"==typeof o?e.innerHTML=_(o):o instanceof HTMLElement&&(e.innerHTML="",e.appendChild(o.cloneNode(!0))):e.innerHTML=""}#t(e,t){return void 0!==t?t:this.grid?.gridConfig?.icons?.[e]}updateSortIndicator(e,t){e.querySelector('[part~="sort-indicator"], .sort-indicator')?.remove();const r=document.createElement("span");r.setAttribute("part","sort-indicator"),r.className="sort-indicator",t?(e.setAttribute("aria-sort","asc"===t?"ascending":"descending"),e.setAttribute("data-sort",t),this.setIcon(r,"asc"===t?"sortAsc":"sortDesc")):(e.setAttribute("aria-sort","none"),e.removeAttribute("data-sort"),this.setIcon(r,"sortNone"));const o=e.querySelector(".tbw-filter-btn")??e.querySelector(".resize-handle");return o?e.insertBefore(r,o):e.appendChild(r),r}warn(e,t){void 0!==t?console.warn(f(e,t,this.gridElement.id,this.name)):console.warn(`${h(this.gridElement.id,this.name)} ${e}`)}throwDiagnostic(e,t){throw new Error(f(e,t,this.gridElement.id,this.name))}}function R({rows:e,config:t,expanded:r,initialExpanded:o,groupSortDirections:n}){const i=t.groupOn;if("function"!=typeof i)return[];const s={key:"__root__",value:null,depth:-1,rows:[],children:/* @__PURE__ */new Map};if(e.forEach(e=>{let t=i(e);null==t||!1===t?t=["__ungrouped__"]:Array.isArray(t)||(t=[t]);let r=s;t.forEach((t,o)=>{const n=null==t?"∅":String(t),i="__root__"===r.key?n:r.key+"||"+n;let s=r.children.get(n);s||(s={key:i,value:t,depth:o,rows:[],children:/* @__PURE__ */new Map,parent:r},r.children.set(n,s)),s.rows.push(e),r=s})}),1===s.children.size&&s.children.has("__ungrouped__")){if(s.children.get("__ungrouped__").rows.length===e.length)return[]}const a=/* @__PURE__ */new Map;for(let 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 A(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 C({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=C({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 S(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=S(o.children,t,e);if(r.length>0)return r}}return[]}class E extends x{static manifest={modifiesRowStructure:!0,hookPriority:{processRows:10,onHeaderClick:-1},incompatibleWith:[{name:"tree",reason:"Both plugins transform the entire row model. TreePlugin flattens nested hierarchies while GroupingRowsPlugin groups flat rows with synthetic headers. Use one approach per grid."},{name:"pivot",reason:"PivotPlugin creates its own aggregated row and column structure. Row grouping cannot be applied on top of pivot-generated rows."}],events:[{type:"group-toggle",description:"Emitted when groups are expanded/collapsed. Broadcast to both DOM consumers and plugin bus."},{type:"group-expand",description:"Emitted when a pre-defined group is expanded."},{type:"group-collapse",description:"Emitted when a pre-defined group is collapsed."}],queries:[{type:"canMoveRow",description:"Returns false for group header rows (cannot be reordered)"},{type:"grouping:get-grouped-fields",description:"Returns the column field names that match group depth levels (string[])"},{type:"datasource:viewport-mapping",description:"Translates flat viewport row indices to top-level group indices for ServerSide pagination."}],configRules:[{id:"groupingRows/accordion-defaultExpanded",severity:"warn",message:'"accordion: true" and "defaultExpanded" (non-false) are used together.\n → In accordion mode, only one group can be open at a time.\n → Using defaultExpanded with multiple groups will collapse to one on first toggle.\n → Consider using "defaultExpanded: false" or a single group key/index with accordion mode.',check:e=>!0===e.accordion&&!1!==e.defaultExpanded&&void 0!==e.defaultExpanded&&!("number"==typeof e.defaultExpanded)&&!("string"==typeof e.defaultExpanded)&&(!0===e.defaultExpanded||Array.isArray(e.defaultExpanded)&&e.defaultExpanded.length>1)}]};static dependencies=[{name:"multiSort",required:!1,reason:"Queries sort model for coordinated group sorting"},{name:"serverSide",required:!1,reason:"Consumes datasource events for lazy-loaded grouped data"}];name="groupingRows";styles="@layer tbw-plugins{.group-row{display:grid;grid-template-columns:var(--tbw-column-template);background:var(--tbw-grouping-rows-bg, var(--tbw-color-panel-bg));font-weight:500;border-bottom:var(--tbw-row-divider);min-height:var(--tbw-row-height)}.group-row .cell{display:flex;align-items:center;padding:var(--tbw-cell-padding, .125rem .5rem)}@media(hover:hover){.group-row:hover{background:var(--tbw-grouping-rows-bg-hover, var(--tbw-color-row-hover))}}.group-toggle{cursor:pointer;-webkit-user-select:none;user-select:none;display:inline-flex;align-items:center;justify-content:center;width:var(--tbw-toggle-size, 1.25rem);height:var(--tbw-toggle-size, 1.25rem);margin-right:.25rem;background:none;border:0;font:inherit}.group-toggle:hover{background:var(--tbw-grouping-rows-toggle-hover, var(--tbw-color-row-hover));border-radius:var(--tbw-border-radius, .125rem)}.group-label{display:inline-flex;align-items:center;gap:var(--tbw-panel-gap, var(--tbw-spacing-md, .5rem))}.group-count{color:var(--tbw-grouping-rows-count-color, var(--tbw-color-fg-muted));font-size:var(--tbw-font-size-xs, .85em);font-weight:400}.group-aggregates{display:inline-flex;align-items:center;gap:var(--tbw-spacing-lg, 1rem);margin-left:var(--tbw-spacing-lg, 1rem);font-weight:400;font-size:var(--tbw-font-size-sm, .875em);color:var(--tbw-grouping-rows-aggregate-color, var(--tbw-color-fg-muted))}.group-aggregate{white-space:nowrap}.group-row{padding-left:calc(var(--tbw-group-depth, 0) * var(--tbw-group-indent-width, 1.25em))}.data-grid-row.tbw-group-slide-in{animation:tbw-group-slide-in var(--tbw-animation-duration, .2s) var(--tbw-animation-easing, ease-out) forwards}@keyframes tbw-group-slide-in{0%{opacity:0;transform:translate(-8px)}to{opacity:1;transform:translate(0)}}.data-grid-row.tbw-group-fade-in{animation:tbw-group-fade-in var(--tbw-animation-duration, .2s) var(--tbw-animation-easing, ease-out) forwards}@keyframes tbw-group-fade-in{0%{opacity:0}to{opacity:1}}}";get defaultConfig(){return{defaultExpanded:!1,showRowCount:!0,indentWidth:20,aggregators:{},animation:"slide",accordion:!1}}expandedKeys=/* @__PURE__ */new Set;flattenedRows=[];isActive=!1;previousVisibleKeys=/* @__PURE__ */new Set;keysToAnimate=/* @__PURE__ */new Set;hasAppliedDefaultExpanded=!1;preDefinedGroups=[];groupRowsMap=/* @__PURE__ */new Map;loadingGroups=/* @__PURE__ */new Set;groupedFields=[];userGroupSortDirections=/* @__PURE__ */new Map;flatMeta=[];get animationStyle(){return!!this.isAnimationEnabled&&(this.config.animation??"slide")}detach(){const e=this.gridElement?.querySelector(".rows-body");e?.setAttribute("role","grid"),this.expandedKeys.clear(),this.flattenedRows=[],this.flatMeta=[],this.isActive=!1,this.previousVisibleKeys.clear(),this.keysToAnimate.clear(),this.hasAppliedDefaultExpanded=!1,this.preDefinedGroups=[],this.groupRowsMap.clear(),this.loadingGroups.clear(),this.groupedFields=[],this.userGroupSortDirections.clear()}getRowHeight(e,t){if(null!=this.config.groupRowHeight)return!0===e.__isGroupRow?this.config.groupRowHeight:void 0}handleQuery(e){if("canMoveRow"===e.type){const t=e.context;if(!0===t?.__isGroupRow)return!1}if("grouping:get-grouped-fields"===e.type)return[...this.groupedFields];if("datasource:viewport-mapping"===e.type){const{viewportStart:t,viewportEnd:r}=e.context;if(0===this.flattenedRows.length)return;if(0===this.preDefinedGroups.length&&!Array.isArray(this.config.groups))return;const o=this.getActiveGroups();return{startNode:this.getTopLevelGroupIndex(t),endNode:this.getTopLevelGroupIndex(r)+1,totalLoadedNodes:o.length}}}getTopLevelGroupIndex(e){let t=-1;const r=Math.min(e,this.flattenedRows.length-1);for(let o=0;o<=r;o++){const e=this.flattenedRows[o];"group"===e.kind&&0===e.depth&&t++}return Math.max(0,t)}attach(e){super.attach(e),this.on("datasource:data",e=>{const t=e;t.claimed||(t.claimed=!0,this.preDefinedGroups=t.rows,this.groupRowsMap.clear(),this.loadingGroups.clear(),this.hasAppliedDefaultExpanded=!1,this.requestRender())}),this.on("datasource:children",e=>{const t=e;if("grouping-rows"!==t.context?.source)return;t.claimed=!0;const r=t.context.groupKey;r&&(this.groupRowsMap.set(r,t.rows),this.loadingGroups.delete(r),this.requestRender())})}onHeaderClick(e){const t=this.groupedFields.indexOf(e.field);if(-1===t)return;if(!e.column.sortable)return;const r=t,o=this.userGroupSortDirections.get(r)??1;return this.userGroupSortDirections.set(r,1===o?-1:1),this.requestRender(),!0}resolveGroupSortDirections(e){const t=this.config;if("function"!=typeof t.groupOn||0===e.length)return void(this.groupedFields=[]);const r=this.columns.map(e=>e.field),o=function(e,t,r){const o=/* @__PURE__ */new Map;if(0===e.length)return o;const n=e[0];let i=t(n);if(null==i||!1===i)return o;Array.isArray(i)||(i=[i]);for(let s=0;s<i.length;s++){const e=i[s];for(const t of r)if(n[t]===e){o.set(s,t);break}}return o}([...e],t.groupOn,r);if(this.groupedFields=[...o.values()],0===o.size)return;const n=new Map(this.userGroupSortDirections);if(n.size<o.size){const e=/* @__PURE__ */new Map,t=this.grid?.query?.("sort:get-model",null);if(Array.isArray(t)&&t.length>0){const r=t[0];if(Array.isArray(r))for(const t of r)e.set(t.field,"desc"===t.direction?-1:1)}if(0===e.size){const t=this.grid;t._sortState&&e.set(t._sortState.field,t._sortState.direction)}for(const[r,i]of o)if(!n.has(r)){const t=e.get(i);void 0!==t&&n.set(r,t)}}return n.size>0?n:void 0}static detect(e,t){return"function"==typeof t?.groupOn||"boolean"==typeof t?.enableRowGrouping||Array.isArray(t?.groups)}processRows(e){if(this.preDefinedGroups.length>0||Array.isArray(this.config.groups))return this.preDefinedGroups.length>0||Array.isArray(this.config.groups)&&this.config.groups.length>0?this.processPreDefinedGroups():(this.isActive=!1,this.flattenedRows=[],[]);const t=this.config;if("function"!=typeof t.groupOn)return this.isActive=!1,this.flattenedRows=[],[...e];const r=this.resolveGroupSortDirections(e),o=R({rows:[...e],config:t,expanded:/* @__PURE__ */new Set,groupSortDirections:r});if(0===o.length)return this.isActive=!1,this.flattenedRows=[],[...e];let n;if(!this.hasAppliedDefaultExpanded&&0===this.expandedKeys.size&&!1!==t.defaultExpanded){const e=function(e){return e.filter(e=>"group"===e.kind).map(e=>e.key)}(o);n=A(t.defaultExpanded??!1,e),n.size>0&&(this.expandedKeys=new Set(n),this.hasAppliedDefaultExpanded=!0)}const i=R({rows:[...e],config:t,expanded:this.expandedKeys,initialExpanded:n,groupSortDirections:r});this.isActive=!0,this.flattenedRows=i,this.computeFlatMeta(),this.keysToAnimate.clear();const s=/* @__PURE__ */new Set;return i.forEach((e,t)=>{if("data"===e.kind){const e=`data-${t}`;s.add(e),this.previousVisibleKeys.has(e)||this.keysToAnimate.add(e)}}),this.previousVisibleKeys=s,i.map(e=>{return"group"===e.kind?{__isGroupRow:!0,__groupKey:e.key,__groupValue:e.value,__groupDepth:e.depth,__groupRows:e.rows,__groupExpanded:e.expanded,__groupRowCount:(t=e,"group"!==t.kind?0:t.rows.length),__rowCacheKey:`group:${e.key}`}:e.row;var t})}onCellClick(e){const r=e.row;if(r?.__isGroupRow){const o=e.originalEvent.target;if(o?.closest(`.${t}`))return this.toggle(r.__groupKey),!0}}onKeyDown(e){if(" "!==e.key)return;const t=this.grid._focusRow,r=this.rows[t];return r?.__isGroupRow?(e.preventDefault(),this.toggle(r.__groupKey),this.requestRenderWithFocus(),!0):void 0}renderRow(e,t,r){if(!0===e?.__loading&&e?.__groupKey){t.className="data-grid-row",t.__isCustomRow=!0,t.innerHTML="";const e=document.createElement("div");return e.className="cell",e.style.gridColumn="1 / -1",e.setAttribute("role","gridcell"),e.textContent=" ",t.appendChild(e),function(e){if(e.classList.add("tbw-row-loading"),e.setAttribute("aria-busy","true"),!e.querySelector(".tbw-row-loading-overlay")){const t=document.createElement("div");t.className="tbw-row-loading-overlay",t.setAttribute("aria-hidden","true");const r=document.createElement("div");r.className="tbw-row-loading-spinner",t.appendChild(r),e.appendChild(t)}}(t),!0}if(!e?.__isGroupRow)return!1;const o=this.config;if(o.groupRowRenderer){const r=()=>{this.toggle(e.__groupKey)},n=o.groupRowRenderer({key:e.__groupKey,value:e.__groupValue,depth:e.__groupDepth,rows:e.__groupRows,expanded:e.__groupExpanded,toggleExpand:r});if(n)return t.className="data-grid-row group-row",t.__isCustomRow=!0,t.setAttribute("data-group-depth",String(e.__groupDepth)),"string"==typeof n?t.innerHTML=n:(t.innerHTML="",t.appendChild(n)),!0}const n=()=>{this.toggle(e.__groupKey)};t.className="data-grid-row group-row",t.__isCustomRow=!0,t.setAttribute("data-group-depth",String(e.__groupDepth)),t.setAttribute("role","row"),t.setAttribute("aria-expanded",String(e.__groupExpanded)),t.classList.toggle("tbw-row-expanded",!!e.__groupExpanded);const i=this.flatMeta[r];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="";return!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=this.flattenedRows[t],i="data"===r?.kind?`data-${t}`:void 0;i&&this.keysToAnimate.has(i)&&(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=A(this.config.defaultExpanded??!1,t);r.size>0&&(this.expandedKeys=new Set(r),this.hasAppliedDefaultExpanded=!0)}const t=C({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),o=r?.rowCount??t.rows.length;return{__isGroupRow:!0,__groupKey:t.key,__groupValue:t.value,__groupDepth:t.depth,__groupRows:t.rows,__groupExpanded:t.expanded,__groupRowCount:o,__rowCacheKey:`group:${t.key}`}}return t.row})}collectGroupKeys(e){const t=[];for(const r of e)t.push(r.key),r.children?.length&&t.push(...this.collectGroupKeys(r.children));return t}getActiveGroups(){return this.preDefinedGroups.length>0?this.preDefinedGroups:Array.isArray(this.config.groups)?this.config.groups:[]}findGroupDefinition(e,t){for(const r of e){if(r.key===t)return r;if(r.children?.length){const e=this.findGroupDefinition(r.children,t);if(e)return e}}}createToggleButton(r,o){const n=document.createElement("button");return n.type="button",n.className=`${t}${r?` ${e}`:""}`,n.setAttribute("aria-label",r?"Collapse group":"Expand group"),this.setIcon(n,r?"collapse":"expand"),n.addEventListener("click",e=>{e.stopPropagation(),o()}),n}getGroupLabelText(e,t,r){const o=this.config;return o.formatLabel?o.formatLabel(e,t,r):String(e)}renderFullWidthGroupRow(e,t,n){const i=this.config,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 u=document.createElement("span");if(u.className=r,u.textContent=this.getGroupLabelText(e.__groupValue,e.__groupDepth||0,e.__groupKey),d.appendChild(u),!1!==i.showRowCount){const t=document.createElement("span");t.className=o,t.textContent=`(${e.__groupRowCount??e.__groupRows?.length??0})`,d.appendChild(t)}const p=Object.entries(s);if(p.length>0){const e=document.createElement("span");e.className="group-aggregates";for(const[t,r]of p){const o=this.columns.find(e=>e.field===t),n=l.run(r,a,t,o);if(null!=n){const r=document.createElement("span");r.className="group-aggregate",r.setAttribute("data-field",t);const i=o?.header??t;r.textContent=`${i}: ${n}`,e.appendChild(r)}}e.children.length>0&&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"),u=d?.style.gridTemplateColumns||"";u&&(t.style.display="grid",t.style.gridTemplateColumns=u);let p=!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(p){const e=i[s.field];if(e){const t=l.run(e,a,s.field,s);u.textContent=null!=t?String(t):""}else u.textContent=""}else{p=!0,u.appendChild(this.createToggleButton(e.__groupExpanded,r));const t=document.createElement("span"),d=i[s.field];if(d){const r=l.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(){this.expandedKeys=function(e){const t=/* @__PURE__ */new Set;for(const r of e)"group"===r.kind&&t.add(r.key);return t}(this.flattenedRows),this.emitPluginEvent("group-toggle",{expandedKeys:[...this.expandedKeys]}),this.requestRender()}collapseAll(){this.expandedKeys=/* @__PURE__ */new Set,this.emitPluginEvent("group-toggle",{expandedKeys:[...this.expandedKeys]}),this.requestRender()}toggle(e){const t=!this.expandedKeys.has(e),r=this.config,o=this.flattenedRows.find(t=>"group"===t.kind&&t.key===e);if(r.accordion&&t&&o){const t=/* @__PURE__ */new Set;for(const r of this.expandedKeys)if(e.startsWith(r+"||")||r.startsWith(e+"||"))e.startsWith(r+"||")&&t.add(r);else{const e=this.flattenedRows.find(e=>"group"===e.kind&&e.key===r);e&&e.depth!==o.depth&&t.add(r)}t.add(e),this.expandedKeys=t}else this.expandedKeys=function(e,t){const r=new Set(e);return r.has(t)?r.delete(t):r.add(t),r}(this.expandedKeys,e);this.broadcast("group-toggle",{key:e,expanded:this.expandedKeys.has(e),value:o?.value,depth:o?.depth??0,expandedKeys:[...this.expandedKeys]});const n=this.getActiveGroups();if(n.length>0){const r=S(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;c(this.gridElement,g(this.gridElement,"groupExpanded",s,e))}else c(this.gridElement,g(this.gridElement,"groupCollapsed",s));this.requestRender()}isExpanded(e){return this.expandedKeys.has(e)}expand(e){this.expandedKeys.has(e)||(this.expandedKeys=/* @__PURE__ */new Set([...this.expandedKeys,e]),this.requestRender())}collapse(e){if(this.expandedKeys.has(e)){const t=new Set(this.expandedKeys);t.delete(e),this.expandedKeys=t,this.requestRender()}}getGroupState(){const e=this.flattenedRows.filter(e=>"group"===e.kind);return{isActive:this.isActive,expandedCount:this.expandedKeys.size,totalGroups:e.length,expandedKeys:[...this.expandedKeys]}}getRowCount(){return this.flattenedRows.length}refreshGroups(){this.requestRender()}getExpandedGroups(){return[...this.expandedKeys]}getFlattenedRows(){return this.flattenedRows}isGroupingActive(){return this.isActive}setGroupOn(e){this.config.groupOn=e,this.requestRender()}setGroups(e){this.preDefinedGroups=e,this.groupRowsMap.clear(),this.loadingGroups.clear(),this.expandedKeys.clear(),this.hasAppliedDefaultExpanded=!1,this.requestRender()}getGroups(){return this.preDefinedGroups.length>0?[...this.preDefinedGroups]:Array.isArray(this.config.groups)?[...this.config.groups]:[]}setGroupRows(e,t){this.groupRowsMap.set(e,t),this.loadingGroups.delete(e),this.requestRender()}setGroupLoading(e,t){t?this.loadingGroups.add(e):this.loadingGroups.delete(e),this.requestRender()}clearGroupRows(e){null!=e?this.groupRowsMap.delete(e):this.groupRowsMap.clear(),this.requestRender()}}export{E as GroupingRowsPlugin};
1
+ const e="expanded",t="group-toggle",r="group-label",n="group-count",o=/* @__PURE__ */new WeakMap;function i(e,t,r){return r?.valueAccessor?function(e,t,r=-1){if(!t.valueAccessor)return e?.[t.field];if("object"!=typeof e||null===e)return t.valueAccessor({row:e,column:t,rowIndex:r});const n=e,i=t.field;let s=o.get(n);if(s){const e=s.get(i);if(void 0!==e)return e.v}else s=/* @__PURE__ */new Map,o.set(n,s);const a=t.valueAccessor({row:e,column:t,rowIndex:r});return s.set(i,{v:a}),a}(e,r):e?.[t]}function s(e){return null==e||""===e||"number"==typeof e&&isNaN(e)}const a={sum:(e,t,r)=>{let n=0;for(let o=0;o<e.length;o++){const a=i(e[o],t,r);if(s(a))continue;const d=Number(a);isNaN(d)||(n+=d)}return n},avg:(e,t,r)=>{if(!e.length)return 0;let n=0,o=0;for(let a=0;a<e.length;a++){const d=i(e[a],t,r);if(s(d))continue;const l=Number(d);isNaN(l)||(n+=l,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 a=i(e[o],t,r);if(s(a))continue;const d=Number(a);isNaN(d)||d<n&&(n=d)}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 a=i(e[o],t,r);if(s(a))continue;const d=Number(a);isNaN(d)||d>n&&(n=d)}return n===-1/0?0:n},first:(e,t,r)=>e[0]?i(e[0],t,r):void 0,last:(e,t,r)=>e.length?i(e[e.length-1],t,r):void 0},d=/* @__PURE__ */new Map,l={register(e,t){d.set(e,t)},unregister(e){d.delete(e)},get(e){if(void 0!==e)return"function"==typeof e?e:d.get(e)??a[e]},run(e,t,r,n){const o=this.get(e);return o?o(t,r,n):void 0},has:e=>d.has(e)||e in a,list:()=>[...Object.keys(a),...d.keys()]},u={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`,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`},p={expand:"▶",collapse:"▼",sortAsc:"▲",sortDesc:"▼",sortNone:"⇅",submenuArrow:"▶",dragHandle:"⋮⋮",toolPanel:"☰",filter:"",filterActive:"",print:"🖨️"};function c(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 g(e,t,...r){const n=e&&"effectiveConfig"in e?e.effectiveConfig:void 0,o=n?.a11y?.messages?.[t];return o?o(...r):u[t](...r)}function h(e,t){return`[tbw-grid${e?`#${e}`:""}${t?`:${t}`:""}]`}function f(e,t,r,n){return`${h(r,n)} ${e}: ${t}\n\n → More info: ${function(e){return`https://toolboxjs.com/grid/errors#${e.toLowerCase()}`}(e)}`}const w="__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(""));new RegExp(`__(proto|defineGetter|defineSetter)|${w.slice(3).join("|")}|this\\b`);const m=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".split("|")),y=/^on\w+$/i,v=new Set("href|src|action|formaction|data|srcdoc|xlink:href|poster|srcset".split("|")),b=/^\s*(javascript|vbscript|data|blob):/i;function x(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(m.has(e)){t.push(n);continue}if("svg"===e||"http://www.w3.org/2000/svg"===n.namespaceURI){if(Array.from(n.attributes).some(e=>y.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();y.test(e)?r.push(t.name):(v.has(e)&&b.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 _{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}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=f("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)}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{...p,...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=x(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(f(e,t,this.gridElement.id,this.name)):console.warn(`${h(this.gridElement.id,this.name)} ${e}`)}throwDiagnostic(e,t){throw new Error(f(e,t,this.gridElement.id,this.name))}}function R({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 c=0;c<e.length;c++)a.set(e[c],c);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 A(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 C({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=C({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 E(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=E(n.children,t,e);if(r.length>0)return r}}return[]}class S extends _{static manifest={modifiesRowStructure:!0,hookPriority:{processRows:10,onHeaderClick:-1},incompatibleWith:[{name:"tree",reason:"Both plugins transform the entire row model. TreePlugin flattens nested hierarchies while GroupingRowsPlugin groups flat rows with synthetic headers. Use one approach per grid."},{name:"pivot",reason:"PivotPlugin creates its own aggregated row and column structure. Row grouping cannot be applied on top of pivot-generated rows."}],events:[{type:"group-toggle",description:"Emitted when groups are expanded/collapsed. Broadcast to both DOM consumers and plugin bus."},{type:"group-expand",description:"Emitted when a pre-defined group is expanded."},{type:"group-collapse",description:"Emitted when a pre-defined group is collapsed."}],queries:[{type:"canMoveRow",description:"Returns false for group header rows (cannot be reordered)"},{type:"grouping:get-grouped-fields",description:"Returns the column field names that match group depth levels (string[])"},{type:"datasource:viewport-mapping",description:"Translates flat viewport row indices to top-level group indices for ServerSide pagination."}],configRules:[{id:"groupingRows/accordion-defaultExpanded",severity:"warn",message:'"accordion: true" and "defaultExpanded" (non-false) are used together.\n → In accordion mode, only one group can be open at a time.\n → Using defaultExpanded with multiple groups will collapse to one on first toggle.\n → Consider using "defaultExpanded: false" or a single group key/index with accordion mode.',check:e=>!0===e.accordion&&!1!==e.defaultExpanded&&void 0!==e.defaultExpanded&&!("number"==typeof e.defaultExpanded)&&!("string"==typeof e.defaultExpanded)&&(!0===e.defaultExpanded||Array.isArray(e.defaultExpanded)&&e.defaultExpanded.length>1)}]};static dependencies=[{name:"multiSort",required:!1,reason:"Queries sort model for coordinated group sorting"},{name:"serverSide",required:!1,reason:"Consumes datasource events for lazy-loaded grouped data"}];name="groupingRows";styles="@layer tbw-plugins{.group-row{display:grid;grid-template-columns:var(--tbw-column-template);background:var(--tbw-grouping-rows-bg, var(--tbw-color-panel-bg));font-weight:500;border-bottom:var(--tbw-row-divider);min-height:var(--tbw-row-height)}.group-row .cell{display:flex;align-items:center;padding:var(--tbw-cell-padding, .125rem .5rem)}@media(hover:hover){.group-row:hover{background:var(--tbw-grouping-rows-bg-hover, var(--tbw-color-row-hover))}}.group-toggle{cursor:pointer;-webkit-user-select:none;user-select:none;display:inline-flex;align-items:center;justify-content:center;width:var(--tbw-toggle-size, 1.25rem);height:var(--tbw-toggle-size, 1.25rem);margin-right:.25rem;background:none;border:0;font:inherit}.group-toggle:hover{background:var(--tbw-grouping-rows-toggle-hover, var(--tbw-color-row-hover));border-radius:var(--tbw-border-radius, .125rem)}.group-label{display:inline-flex;align-items:center;gap:var(--tbw-panel-gap, var(--tbw-spacing-md, .5rem))}.group-count{color:var(--tbw-grouping-rows-count-color, var(--tbw-color-fg-muted));font-size:var(--tbw-font-size-xs, .85em);font-weight:400}.group-aggregates{display:inline-flex;align-items:center;gap:var(--tbw-spacing-lg, 1rem);margin-left:var(--tbw-spacing-lg, 1rem);font-weight:400;font-size:var(--tbw-font-size-sm, .875em);color:var(--tbw-grouping-rows-aggregate-color, var(--tbw-color-fg-muted))}.group-aggregate{white-space:nowrap}.group-row{padding-left:calc(var(--tbw-group-depth, 0) * var(--tbw-group-indent-width, 1.25em))}.data-grid-row.tbw-group-slide-in{animation:tbw-group-slide-in var(--tbw-animation-duration, .2s) var(--tbw-animation-easing, ease-out) forwards}@keyframes tbw-group-slide-in{0%{opacity:0;transform:translate(-8px)}to{opacity:1;transform:translate(0)}}.data-grid-row.tbw-group-fade-in{animation:tbw-group-fade-in var(--tbw-animation-duration, .2s) var(--tbw-animation-easing, ease-out) forwards}@keyframes tbw-group-fade-in{0%{opacity:0}to{opacity:1}}}";get defaultConfig(){return{defaultExpanded:!1,showRowCount:!0,indentWidth:20,aggregators:{},animation:"slide",accordion:!1}}expandedKeys=/* @__PURE__ */new Set;flattenedRows=[];isActive=!1;previousVisibleKeys=/* @__PURE__ */new Set;keysToAnimate=/* @__PURE__ */new Set;hasAppliedDefaultExpanded=!1;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(){const e=this.gridElement?.querySelector(".rows-body");e?.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){const t=e.context;if(!0===t?.__isGroupRow)return!1}if("grouping:get-grouped-fields"===e.type)return[...this.groupedFields];if("datasource:viewport-mapping"===e.type){const{viewportStart:t,viewportEnd:r}=e.context;if(0===this.flattenedRows.length)return;if(0===this.preDefinedGroups.length&&!Array.isArray(this.config.groups))return;const 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){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)}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 n=this.resolveGroupSortDirections(e),o=R({rows:[...e],config:r,expanded:/* @__PURE__ */new Set,groupSortDirections:n});if(0===o.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)}(o);a=A(i,e),(s||a.size>0)&&(this.expandedKeys=new Set(a),this.hasAppliedDefaultExpanded=!0)}const d=R({rows:[...e],config:r,expanded:this.expandedKeys,initialExpanded:a,groupSortDirections:n});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){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.classList.toggle("tbw-row-expanded",!!e.__groupExpanded);const i=this.flatMeta[r];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!==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.gridElement?.querySelector(".rows");if(!e)return;const t=this.gridElement?.querySelector(".rows-body");t&&"treegrid"!==t.getAttribute("role")&&t.setAttribute("role","treegrid");for(const o of e.querySelectorAll(".data-grid-row:not(.group-row)")){const e=o.querySelector(".cell[data-row]"),t=e?parseInt(e.getAttribute("data-row")??"-1",10):-1,r=this.flatMeta[t];r&&(o.setAttribute("aria-level",String(r.level)),o.setAttribute("aria-setsize",String(r.setSize)),o.setAttribute("aria-posinset",String(r.posInSet)))}const r=this.animationStyle;if(!1===r||0===this.keysToAnimate.size)return;const n="fade"===r?"tbw-group-fade-in":"tbw-group-slide-in";for(const o of e.querySelectorAll(".data-grid-row:not(.group-row)")){const e=o.querySelector(".cell[data-row]"),t=e?parseInt(e.getAttribute("data-row")??"-1",10):-1,r=this.flattenedRows[t],i="data"===r?.kind?`data-${t}`:void 0;i&&this.keysToAnimate.has(i)&&(o.classList.add(n),o.addEventListener("animationend",()=>o.classList.remove(n),{once:!0}))}this.keysToAnimate.clear()}computeFlatMeta(){const e=this.flattenedRows,t=new Array(e.length),r=/* @__PURE__ */new Map,n=/* @__PURE__ */new Map;let o=null,i=0;for(const l of e)if("group"===l.kind){o&&n.set(o.key,i),o=l,i=0;const e=`${l.key.split("||").slice(0,-1).join("||")}@${l.depth}`;r.set(e,(r.get(e)??0)+1)}else i++;o&&n.set(o.key,i);const s=/* @__PURE__ */new Map;let a=null,d=0;for(let l=0;l<e.length;l++){const o=e[l];if("group"===o.kind){const e=`${o.key.split("||").slice(0,-1).join("||")}@${o.depth}`,n=(s.get(e)??0)+1;s.set(e,n),t[l]={level:o.depth+1,setSize:r.get(e)??1,posInSet:n},a=o,d=0}else{d++;const r=a?.depth??-1,o=a?n.get(a.key)??1:e.length;t[l]={level:r+2,setSize:o,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=A(this.config.defaultExpanded??!1,t);r.size>0&&(this.expandedKeys=new Set(r),this.hasAppliedDefaultExpanded=!0)}const t=C({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),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})}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,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,o));const u=document.createElement("span");if(u.className=r,u.textContent=this.getGroupLabelText(e.__groupValue,e.__groupDepth||0,e.__groupKey),d.appendChild(u),!1!==i.showRowCount){const t=document.createElement("span");t.className=n,t.textContent=`(${e.__groupRowCount??e.__groupRows?.length??0})`,d.appendChild(t)}const p=Object.entries(s);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=l.run(r,a,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&&d.appendChild(e)}t.appendChild(d)}renderPerColumnGroupRow(e,t,r){const o=this.config,i=o.aggregators??{},s=this.columns,a=e.__groupRows??[],d=this.gridElement?.querySelector(".body"),u=d?.style.gridTemplateColumns||"";u&&(t.style.display="grid",t.style.gridTemplateColumns=u);let p=!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(p){const e=i[s.field];if(e){const t=l.run(e,a,s.field,s);u.textContent=null!=t?String(t):""}else u.textContent=""}else{p=!0,u.appendChild(this.createToggleButton(e.__groupExpanded,r));const t=document.createElement("span"),d=i[s.field];if(d){const r=l.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!==o.showRowCount){const e=document.createElement("span");e.className=n,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(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=E(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;c(this.gridElement,g(this.gridElement,"groupExpanded",s,e))}else c(this.gridElement,g(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{S as GroupingRowsPlugin};
3
3
  //# sourceMappingURL=index.js.map