@toolbox-web/grid 1.28.2 → 1.30.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 (107) hide show
  1. package/all.js +2 -2
  2. package/all.js.map +1 -1
  3. package/custom-elements.json +43 -1
  4. package/index.js +1 -1
  5. package/index.js.map +1 -1
  6. package/lib/core/constants.d.ts +1 -7
  7. package/lib/core/grid.d.ts +47 -3
  8. package/lib/core/internal/render-scheduler.d.ts +3 -1
  9. package/lib/core/plugin/base-plugin.d.ts +1 -1
  10. package/lib/core/plugin/plugin-manager.d.ts +2 -0
  11. package/lib/core/types.d.ts +55 -0
  12. package/lib/plugins/clipboard/ClipboardPlugin.d.ts +0 -21
  13. package/lib/plugins/clipboard/index.js.map +1 -1
  14. package/lib/plugins/column-virtualization/ColumnVirtualizationPlugin.d.ts +0 -16
  15. package/lib/plugins/column-virtualization/index.js.map +1 -1
  16. package/lib/plugins/context-menu/index.js.map +1 -1
  17. package/lib/plugins/editing/index.js +1 -1
  18. package/lib/plugins/editing/index.js.map +1 -1
  19. package/lib/plugins/export/ExportPlugin.d.ts +0 -18
  20. package/lib/plugins/export/index.js.map +1 -1
  21. package/lib/plugins/filtering/FilteringPlugin.d.ts +0 -21
  22. package/lib/plugins/filtering/filter-model.d.ts +8 -1
  23. package/lib/plugins/filtering/index.js +1 -1
  24. package/lib/plugins/filtering/index.js.map +1 -1
  25. package/lib/plugins/grouping-columns/GroupingColumnsPlugin.d.ts +0 -16
  26. package/lib/plugins/grouping-columns/grouping-columns.d.ts +23 -3
  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/GroupingRowsPlugin.d.ts +0 -23
  30. package/lib/plugins/grouping-rows/index.js +2 -2
  31. package/lib/plugins/grouping-rows/index.js.map +1 -1
  32. package/lib/plugins/master-detail/MasterDetailPlugin.d.ts +0 -22
  33. package/lib/plugins/master-detail/index.js.map +1 -1
  34. package/lib/plugins/multi-sort/MultiSortPlugin.d.ts +0 -18
  35. package/lib/plugins/multi-sort/index.js +1 -1
  36. package/lib/plugins/multi-sort/index.js.map +1 -1
  37. package/lib/plugins/multi-sort/multi-sort.d.ts +7 -0
  38. package/lib/plugins/pinned-columns/PinnedColumnsPlugin.d.ts +18 -4
  39. package/lib/plugins/pinned-columns/index.js +1 -1
  40. package/lib/plugins/pinned-columns/index.js.map +1 -1
  41. package/lib/plugins/pinned-columns/pinned-columns.d.ts +38 -2
  42. package/lib/plugins/pinned-rows/PinnedRowsPlugin.d.ts +0 -11
  43. package/lib/plugins/pinned-rows/index.js.map +1 -1
  44. package/lib/plugins/pivot/PivotPlugin.d.ts +0 -24
  45. package/lib/plugins/pivot/index.js +1 -1
  46. package/lib/plugins/pivot/index.js.map +1 -1
  47. package/lib/plugins/print/PrintPlugin.d.ts +2 -21
  48. package/lib/plugins/print/index.js.map +1 -1
  49. package/lib/plugins/reorder-columns/ReorderPlugin.d.ts +0 -7
  50. package/lib/plugins/reorder-columns/index.js +1 -1
  51. package/lib/plugins/reorder-columns/index.js.map +1 -1
  52. package/lib/plugins/reorder-rows/RowReorderPlugin.d.ts +1 -13
  53. package/lib/plugins/reorder-rows/index.js +1 -1
  54. package/lib/plugins/reorder-rows/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/selection/index.js +1 -1
  58. package/lib/plugins/selection/index.js.map +1 -1
  59. package/lib/plugins/server-side/ServerSidePlugin.d.ts +0 -16
  60. package/lib/plugins/server-side/index.js.map +1 -1
  61. package/lib/plugins/tooltip/index.js.map +1 -1
  62. package/lib/plugins/tree/TreePlugin.d.ts +0 -22
  63. package/lib/plugins/tree/index.js +1 -1
  64. package/lib/plugins/tree/index.js.map +1 -1
  65. package/lib/plugins/undo-redo/UndoRedoPlugin.d.ts +0 -19
  66. package/lib/plugins/undo-redo/index.js +1 -1
  67. package/lib/plugins/undo-redo/index.js.map +1 -1
  68. package/lib/plugins/visibility/VisibilityPlugin.d.ts +0 -16
  69. package/lib/plugins/visibility/index.js +1 -1
  70. package/lib/plugins/visibility/index.js.map +1 -1
  71. package/package.json +1 -1
  72. package/themes/dg-theme-material.css +5 -0
  73. package/umd/grid.all.umd.js +1 -1
  74. package/umd/grid.all.umd.js.map +1 -1
  75. package/umd/grid.umd.js +1 -1
  76. package/umd/grid.umd.js.map +1 -1
  77. package/umd/plugins/clipboard.umd.js.map +1 -1
  78. package/umd/plugins/column-virtualization.umd.js.map +1 -1
  79. package/umd/plugins/export.umd.js.map +1 -1
  80. package/umd/plugins/filtering.umd.js +1 -1
  81. package/umd/plugins/filtering.umd.js.map +1 -1
  82. package/umd/plugins/grouping-columns.umd.js +1 -1
  83. package/umd/plugins/grouping-columns.umd.js.map +1 -1
  84. package/umd/plugins/grouping-rows.umd.js +1 -1
  85. package/umd/plugins/grouping-rows.umd.js.map +1 -1
  86. package/umd/plugins/master-detail.umd.js.map +1 -1
  87. package/umd/plugins/multi-sort.umd.js +1 -1
  88. package/umd/plugins/multi-sort.umd.js.map +1 -1
  89. package/umd/plugins/pinned-columns.umd.js +1 -1
  90. package/umd/plugins/pinned-columns.umd.js.map +1 -1
  91. package/umd/plugins/pinned-rows.umd.js.map +1 -1
  92. package/umd/plugins/pivot.umd.js +1 -1
  93. package/umd/plugins/pivot.umd.js.map +1 -1
  94. package/umd/plugins/print.umd.js.map +1 -1
  95. package/umd/plugins/reorder-columns.umd.js +1 -1
  96. package/umd/plugins/reorder-columns.umd.js.map +1 -1
  97. package/umd/plugins/reorder-rows.umd.js +1 -1
  98. package/umd/plugins/reorder-rows.umd.js.map +1 -1
  99. package/umd/plugins/selection.umd.js +1 -1
  100. package/umd/plugins/selection.umd.js.map +1 -1
  101. package/umd/plugins/server-side.umd.js.map +1 -1
  102. package/umd/plugins/tree.umd.js +1 -1
  103. package/umd/plugins/tree.umd.js.map +1 -1
  104. package/umd/plugins/undo-redo.umd.js +1 -1
  105. package/umd/plugins/undo-redo.umd.js.map +1 -1
  106. package/umd/plugins/visibility.umd.js +1 -1
  107. package/umd/plugins/visibility.umd.js.map +1 -1
@@ -13,13 +13,6 @@ import { ColumnGroup, GroupingColumnsConfig } from './types';
13
13
  * import { GroupingColumnsPlugin } from '@toolbox-web/grid/plugins/grouping-columns';
14
14
  * ```
15
15
  *
16
- * ## Configuration Options
17
- *
18
- * | Option | Type | Default | Description |
19
- * |--------|------|---------|-------------|
20
- * | `showGroupBorders` | `boolean` | `true` | Show borders between groups |
21
- * | `groupHeaderRenderer` | `function` | - | Custom renderer for group header content |
22
- *
23
16
  * ## Grid Config: `columnGroups`
24
17
  *
25
18
  * | Property | Type | Description |
@@ -35,15 +28,6 @@ import { ColumnGroup, GroupingColumnsConfig } from './types';
35
28
  * | `string` | Simple group ID (used as both id and label) |
36
29
  * | `{ id: string; label?: string }` | Group object with explicit id and optional label |
37
30
  *
38
- * ## Programmatic API
39
- *
40
- * | Method | Signature | Description |
41
- * |--------|-----------|-------------|
42
- * | `isGroupingActive` | `() => boolean` | Check if grouping is active |
43
- * | `getGroups` | `() => ColumnGroup[]` | Get all computed groups |
44
- * | `getGroupColumns` | `(groupId) => ColumnConfig[]` | Get columns in a specific group |
45
- * | `refresh` | `() => void` | Force refresh of column groups |
46
- *
47
31
  * @example Declarative columnGroups (Recommended)
48
32
  * ```ts
49
33
  * import '@toolbox-web/grid';
@@ -22,14 +22,29 @@ export declare function resolveColumnGroupDefs(defs: ColumnGroupDefinition[]): (
22
22
  * @returns Array of column groups, or empty if no meaningful groups
23
23
  */
24
24
  export declare function computeColumnGroups<T>(columns: ColumnConfig<T>[]): ColumnGroup<T>[];
25
+ /**
26
+ * Merge column groups into their final form for rendering:
27
+ * identifies embedded implicit groups and collapses adjacent same-ID fragments.
28
+ *
29
+ * Call once per render and pass the result to both `buildGroupHeaderRow` and
30
+ * `applyGroupedHeaderCellClasses` to avoid redundant computation.
31
+ */
32
+ export declare function mergeGroups<T>(groups: ColumnGroup<T>[]): {
33
+ merged: ColumnGroup<T>[];
34
+ embedded: Set<string>;
35
+ };
25
36
  /**
26
37
  * Apply CSS classes to header cells based on their group membership.
27
38
  *
28
39
  * @param headerRowEl - The header row element
29
- * @param groups - The computed column groups
40
+ * @param groups - The computed column groups (raw, before merging)
30
41
  * @param columns - The column configurations
42
+ * @param precomputed - Optional pre-computed merged groups (avoids redundant merge)
31
43
  */
32
- export declare function applyGroupedHeaderCellClasses(headerRowEl: HTMLElement | null, groups: ColumnGroup[], columns: ColumnConfig[]): void;
44
+ export declare function applyGroupedHeaderCellClasses(headerRowEl: HTMLElement | null, groups: ColumnGroup[], columns: ColumnConfig[], precomputed?: {
45
+ merged: ColumnGroup[];
46
+ embedded: Set<string>;
47
+ }): void;
33
48
  /**
34
49
  * Find implicit groups that are sandwiched between two fragments of the same
35
50
  * explicit group (e.g. a utility column inserted between members of the same group).
@@ -57,9 +72,14 @@ export declare function mergeAdjacentSameIdGroups<T>(groups: ColumnGroup<T>[], e
57
72
  *
58
73
  * @param groups - The computed column groups
59
74
  * @param columns - The column configurations (final array including any plugin-added columns)
75
+ * @param renderer - Optional custom group header renderer
76
+ * @param precomputed - Optional pre-computed merged groups (avoids redundant merge)
60
77
  * @returns The group header row element, or null if no groups
61
78
  */
62
- export declare function buildGroupHeaderRow(groups: ColumnGroup[], columns: ColumnConfig[], renderer?: GroupingColumnsConfig['groupHeaderRenderer']): HTMLElement | null;
79
+ export declare function buildGroupHeaderRow(groups: ColumnGroup[], columns: ColumnConfig[], renderer?: GroupingColumnsConfig['groupHeaderRenderer'], precomputed?: {
80
+ merged: ColumnGroup[];
81
+ embedded: Set<string>;
82
+ }): HTMLElement | null;
63
83
  /**
64
84
  * Check if any columns have group configuration.
65
85
  *
@@ -1,2 +1,2 @@
1
- function e(e,t){return`[tbw-grid${e?`#${e}`:""}${t?`:${t}`:""}]`}function t(t,r,o,i){return`${e(o,i)} ${t}: ${r}\n\n → More info: ${function(e){return`https://toolboxjs.com/grid/errors#${e.toLowerCase()}`}(t)}`}const r=/* @__PURE__ */new Set(["script","iframe","object","embed","form","input","button","textarea","select","link","meta","base","style","template","slot","portal","frame","frameset","applet","noscript","noembed","plaintext","xmp","listing"]),o=/^on\w+$/i,i=/* @__PURE__ */new Set(["href","src","action","formaction","data","srcdoc","xlink:href","poster","srcset"]),n=/^\s*(javascript|vbscript|data|blob):/i;function s(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=[],s=e.querySelectorAll("*");for(const l of s){const e=l.tagName.toLowerCase();if(r.has(e)){t.push(l);continue}if("svg"===e||"http://www.w3.org/2000/svg"===l.namespaceURI){if(Array.from(l.attributes).some(e=>o.test(e.name)||"href"===e.name||"xlink:href"===e.name)){t.push(l);continue}}const s=[];for(const t of l.attributes){const e=t.name.toLowerCase();o.test(e)?s.push(t.name):(i.has(e)&&n.test(t.value)||"style"===e&&/expression\s*\(|javascript:|behavior\s*:/i.test(t.value))&&s.push(t.name)}s.forEach(e=>l.removeAttribute(e))}t.forEach(e=>e.remove())}(t.content),t.innerHTML}const l='<svg viewBox="0 0 16 16" width="12" height="12"><path fill="currentColor" d="M6 10.5a.5.5 0 0 1 .5-.5h3a.5.5 0 0 1 0 1h-3a.5.5 0 0 1-.5-.5zm-2-3a.5.5 0 0 1 .5-.5h7a.5.5 0 0 1 0 1h-7a.5.5 0 0 1-.5-.5zm-2-3a.5.5 0 0 1 .5-.5h11a.5.5 0 0 1 0 1h-11a.5.5 0 0 1-.5-.5z"/></svg>',d={expand:"▶",collapse:"▼",sortAsc:"▲",sortDesc:"▼",sortNone:"⇅",submenuArrow:"▶",dragHandle:"⋮⋮",toolPanel:"☰",filter:l,filterActive:l,print:"🖨️"};class u{static dependencies;static manifest;aliases;version="undefined"!=typeof __GRID_VERSION__?__GRID_VERSION__:"dev";styles;cellRenderers;headerRenderers;cellEditors;grid;config;userConfig;#e;get defaultConfig(){return{}}constructor(e={}){this.userConfig=e}attach(e){this.#e?.abort(),this.#e=new AbortController,this.grid=e,this.config={...this.defaultConfig,...this.userConfig}}detach(){this.#e?.abort(),this.#e=void 0}getPlugin(e){return this.grid?.getPlugin(e)}emit(e,t){this.grid?.dispatchEvent?.(new CustomEvent(e,{detail:t,bubbles:!0}))}emitCancelable(e,t){const r=new CustomEvent(e,{detail:t,bubbles:!0,cancelable:!0});return this.grid?.dispatchEvent?.(r),r.defaultPrevented}on(e,t){this.grid?._pluginManager?.subscribe(this,e,t)}off(e){this.grid?._pluginManager?.unsubscribe(this,e)}emitPluginEvent(e,t){this.grid?._pluginManager?.emitPluginEvent(e,t)}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{...d,...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}resolveIcon(e,t){return void 0!==t?t:this.gridIcons[e]}setIcon(e,t){"string"==typeof t?e.innerHTML=s(t):t instanceof HTMLElement&&(e.innerHTML="",e.appendChild(t.cloneNode(!0)))}warn(r,o){void 0!==o?console.warn(t(r,o,this.gridElement.id,this.name)):console.warn(`${e(this.gridElement.id,this.name)} ${r}`)}throwDiagnostic(e,r){throw new Error(t(e,r,this.gridElement.id,this.name))}}function c(e){return e.map(e=>{return e.id?e:(e.header||function(e,r,o,i){throw new Error(t(e,r,o,i))}("TBW113",'ColumnGroupDefinition requires either an "id" or a "header" to generate an id from.'),{...e,id:(r=e.header,r.toLowerCase().trim().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,""))});var r})}function a(e){if(!e.length)return[];const t=[],r=/* @__PURE__ */new Map,o=(e,r)=>{if(!r.length)return;const o=t[t.length-1];o&&o.implicit&&o.firstIndex+o.columns.length===e?o.columns.push(...r):t.push({id:"__implicit__"+e,label:void 0,columns:r,firstIndex:e,implicit:!0})};let i=[],n=0;return e.forEach((e,s)=>{const l=e.group;if(!l)return 0===i.length&&(n=s),void i.push(e);i.length&&(o(n,i.slice()),i=[]);const d="string"==typeof l?l:l.id,u="string"==typeof l?void 0:l.label;u&&!r.has(d)&&r.set(d,u);const c=r.get(d)??u,a=t[t.length-1];a&&!a.implicit&&a.id===d?a.columns.push(e):t.push({id:d,label:c,columns:[e],firstIndex:s})}),i.length&&o(n,i),1===t.length&&t[0].implicit&&t[0].columns.length===e.length?[]:t}function g(e,t){const r=e.columns[0],o=e.columns[e.columns.length-1],i=r?t.findIndex(e=>e.field===r.field):-1,n=o?t.findIndex(e=>e.field===o.field):-1;return-1!==i&&-1!==n?[i,n]:null}function h(e){const t=/* @__PURE__ */new Set;for(let r=0;r<e.length;r++){if(!String(e[r].id).startsWith("__implicit__"))continue;if(!e[r].columns.every(e=>e.field?.startsWith("__tbw_")))continue;let o=null;for(let t=r-1;t>=0;t--)if(!String(e[t].id).startsWith("__implicit__")){o=e[t].id;break}let i=null;for(let t=r+1;t<e.length;t++)if(!String(e[t].id).startsWith("__implicit__")){i=e[t].id;break}o&&i&&o===i&&t.add(String(e[r].id))}return t}function f(e,t){const r=[];for(const o of e){if(String(o.id).startsWith("__implicit__")&&t.has(String(o.id)))continue;const e=r[r.length-1];e&&!String(o.id).startsWith("__implicit__")&&e.id===o.id?r[r.length-1]={...e,columns:[...e.columns,...o.columns]}:r.push({...o,columns:[...o.columns]})}return r}class p extends u{static manifest={ownedProperties:[{property:"group",level:"column",description:'the "group" column property'},{property:"columnGroups",level:"config",description:'the "columnGroups" config property',isUsed:e=>Array.isArray(e)&&e.length>0}],queries:[{type:"getColumnGrouping",description:"Returns column group metadata for the visibility panel"}]};name="groupingColumns";styles="@layer tbw-plugins{.header-group-row{display:grid;grid-auto-flow:column;background:var(--tbw-grouping-columns-header-bg, var(--tbw-color-header-bg));border-bottom:1px solid var(--tbw-grouping-columns-border, var(--tbw-color-border))}.header-group-cell{display:flex;align-items:center;justify-content:center;padding:var(--tbw-button-padding-sm, .25rem .5rem);font-weight:600;font-size:var(--tbw-font-size-sm, .9em);text-transform:uppercase;letter-spacing:.5px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0;border-right:2px solid var(--tbw-grouping-columns-separator, var(--tbw-color-border-strong, var(--tbw-color-border)))}.header-group-cell:last-child{border-right:none}.header-row .cell.grouped{border-top:none}.header-row .cell.group-end{border-right:2px solid var(--tbw-grouping-columns-separator, var(--tbw-color-border-strong, var(--tbw-color-border)))}.header-row .cell.group-end:last-child{border-right:none}.rows .cell.group-end{border-right:2px solid var(--tbw-grouping-columns-separator, var(--tbw-color-border-strong, var(--tbw-color-border)))}.rows .cell.group-end:last-child{border-right:none}.header-group-row.no-borders{border-bottom:none}.header-group-row.no-borders .header-group-cell{border-right:none}.header-row.no-group-borders .cell.group-end{border-right:1px solid var(--tbw-color-border)}}";get defaultConfig(){return{showGroupBorders:!0,lockGroupOrder:!1}}groups=[];isActive=!1;#t=/* @__PURE__ */new Set;#r=[];#o=/* @__PURE__ */new Map;attach(e){super.attach(e),this.gridElement.addEventListener("column-move",this.#i,{signal:this.disconnectSignal})}detach(){this.groups=[],this.isActive=!1,this.#t.clear(),this.#r=[],this.#o.clear()}#i=e=>{if(!this.isActive)return;const t=e,{field:r,columnOrder:o}=t.detail;if(this.config.lockGroupOrder){const e=/* @__PURE__ */new Map;for(const t of this.groups){if(t.id.startsWith("__implicit__"))continue;const r=e.get(t.id);r?r.push(...t.columns):e.set(t.id,[...t.columns])}for(const[,i]of e)if(!this.#n(i,o))return t.preventDefault(),void this.#s(r)}this.#l(o)};#l(e){this.#t.clear();const t=/* @__PURE__ */new Map;for(const r of this.groups)for(const e of r.columns)t.set(e.field,r.id);for(let r=0;r<e.length-1;r++){t.get(e[r])!==t.get(e[r+1])&&this.#t.add(e[r])}}#n(e,t){const r=e.map(e=>t.indexOf(e.field)).filter(e=>-1!==e).sort((e,t)=>e-t);return r.length<=1||r.length===r[r.length-1]-r[0]+1}#s(e){const t=this.gridElement?.querySelector(`.header-row [part~="header-cell"][data-field="${e}"]`);t&&(t.style.setProperty("--_flash-color","var(--tbw-color-error)"),t.animate([{backgroundColor:"rgba(from var(--_flash-color) r g b / 30%)"},{backgroundColor:"transparent"}],{duration:400,easing:"ease-out"}))}handleQuery(e){if("getColumnGrouping"===e.type)return this.#d()}#d(){let e;if(this.#r.length>0)e=this.#r.filter(e=>e.children.length>0).map(e=>({id:e.id,label:e.header,fields:[...e.children]}));else if(this.isActive&&this.groups.length>0){const t=/* @__PURE__ */new Map;for(const e of this.groups){if(e.id.startsWith("__implicit__"))continue;const r=t.get(e.id);if(r)for(const t of e.columns)r.fields.includes(t.field)||r.fields.push(t.field);else t.set(e.id,{id:e.id,label:e.label??e.id,fields:e.columns.map(e=>e.field)})}e=Array.from(t.values());const r=this.columns;for(const o of r)if(o.hidden&&o.group){const t="string"==typeof o.group?o.group:o.group.id,r="string"==typeof o.group?o.group:o.group.label??o.group.id,i=e.find(e=>e.id===t);i?i.fields.includes(o.field)||i.fields.push(o.field):e.push({id:t,label:r,fields:[o.field]})}}else{const t=this.columns,r=/* @__PURE__ */new Map;for(const e of t){if(!e.group)continue;const t="string"==typeof e.group?e.group:e.group.id,o="string"==typeof e.group?e.group:e.group.label??e.group.id,i=r.get(t);i?i.fields.includes(e.field)||i.fields.push(e.field):r.set(t,{id:t,label:o,fields:[e.field]})}e=Array.from(r.values())}const t=this.grid?.getColumnOrder();if(t&&t.length>0){const r=new Map(t.map((e,t)=>[e,t]));for(const t of e)t.fields.sort((e,t)=>(r.get(e)??1/0)-(r.get(t)??1/0))}return e}static detect(e,t){const r=t?.features?.groupingColumns;if(r&&"object"==typeof r&&Array.isArray(r.columnGroups)&&r.columnGroups.length>0)return!0;if(t?.columnGroups&&Array.isArray(t.columnGroups)&&t.columnGroups.length>0)return!0;const o=t?.columns;return!!Array.isArray(o)&&function(e){return e.some(e=>null!=e.group)}(o)}processColumns(e){const t=this.config?.columnGroups,r=this.grid?.gridConfig?.columnGroups;let o,i;if(t&&Array.isArray(t)&&t.length>0?(r&&Array.isArray(r)&&r.length>0&&this.warn("TBW114","columnGroups defined in both gridConfig and groupingColumns feature config. Using feature config (higher precedence)."),o=t):r&&Array.isArray(r)&&r.length>0&&(o=r),o&&o.length>0){const t=c(o);this.#r=t,this.#o.clear();for(const e of t)e.renderer&&this.#o.set(e.id,e.renderer);const r=/* @__PURE__ */new Map;for(const e of t)for(const t of e.children)r.set(t,{id:e.id,label:e.header});i=e.map(e=>{const t=r.get(e.field);return t&&!e.group?{...e,group:t}:e})}else this.#r=[],this.#o.clear(),i=[...e];const n=a(i);if(0===n.length)return this.isActive=!1,this.groups=[],i;if(this.#o.size>0)for(const s of n){const e=this.#o.get(s.id);e&&(s.renderer=e)}this.isActive=!0,this.groups=n,this.#t.clear();for(const s of n){const e=s.columns[s.columns.length-1];e?.field&&this.#t.add(e.field)}return i}afterRender(){if(!this.isActive){const e=this.gridElement?.querySelector(".header"),t=e?.querySelector(".header-group-row");return void(t&&t.remove())}const e=this.gridElement?.querySelector(".header");if(!e)return;const t=e.querySelector(".header-group-row");t&&t.remove();const r=this.visibleColumns,o=a(r);if(0===o.length)return;if(this.#o.size>0)for(const l of o){const e=this.#o.get(l.id);e&&(l.renderer=e)}this.#t.clear();const i=f(o,h(o));for(let l=0;l<i.length;l++){const e=i[l],t=e.columns[e.columns.length-1];t?.field&&l<i.length-1&&this.#t.add(t.field)}const n=function(e,t,r){if(0===e.length)return null;const o=document.createElement("div");o.className="header-group-row",o.setAttribute("role","row");const i=f(e,h(e));for(const n of i){const e=String(n.id),i=e.startsWith("__implicit__"),s=g(n,t);if(!s)continue;const[l,d]=s,u=d-l+1,c=i?"":n.label||n.id,a=document.createElement("div");a.className="cell header-group-cell",i&&a.classList.add("implicit-group"),a.setAttribute("data-group",e),a.style.gridColumn=`${l+1} / span ${u}`;const h=!i&&(n.renderer||r)||void 0;if(h&&!i){const t=h({id:e,label:String(c),columns:n.columns,firstIndex:l,isImplicit:!1});t instanceof HTMLElement?a.appendChild(t):"string"==typeof t?a.innerHTML=t:a.textContent=c}else a.textContent=c;o.appendChild(a)}return o}(o,r,this.config.groupHeaderRenderer);if(n){n.classList.toggle("no-borders",!this.config.showGroupBorders);const t=e.querySelector(".header-row");t?e.insertBefore(n,t):e.appendChild(n)}const s=e.querySelector(".header-row");s&&(s.classList.toggle("no-group-borders",!this.config.showGroupBorders),function(e,t){if(!t.length||!e)return;const r=h(t),o=f(t,r),i=/* @__PURE__ */new Map;for(const s of o)if(!String(s.id).startsWith("__implicit__"))for(const e of s.columns)e.field&&i.set(e.field,s.id);for(let s=0;s<t.length;s++){const e=t[s];if(String(e.id).startsWith("__implicit__")&&r.has(String(e.id)))for(let r=s-1;r>=0;r--)if(!String(t[r].id).startsWith("__implicit__")){for(const o of e.columns)o.field&&i.set(o.field,t[r].id);break}}const n=Array.from(e.querySelectorAll(".cell[data-field]"));n.forEach(e=>{const t=e.getAttribute("data-field")||"",r=i.get(t);r&&(e.classList.add("grouped"),e.getAttribute("data-group")||e.setAttribute("data-group",r))});for(const s of o){const e=s.columns[s.columns.length-1],t=n.find(t=>t.getAttribute("data-field")===e.field);t&&t.classList.add("group-end")}}(s,o))}afterCellRender(e){this.isActive&&this.config.showGroupBorders&&e.cellElement.classList.toggle("group-end",this.#t.has(e.column.field))}isGroupingActive(){return this.isActive}getGroups(){return this.groups}getGroupColumns(e){return this.groups.filter(t=>t.id===e).flatMap(e=>e.columns)}refresh(){this.requestRender()}}export{p as GroupingColumnsPlugin};
1
+ function e(e,r){return`[tbw-grid${e?`#${e}`:""}${r?`:${r}`:""}]`}function r(r,t,o,i){return`${e(o,i)} ${r}: ${t}\n\n → More info: ${function(e){return`https://toolboxjs.com/grid/errors#${e.toLowerCase()}`}(r)}`}const t=/* @__PURE__ */new Set(["script","iframe","object","embed","form","input","button","textarea","select","link","meta","base","style","template","slot","portal","frame","frameset","applet","noscript","noembed","plaintext","xmp","listing"]),o=/^on\w+$/i,i=/* @__PURE__ */new Set(["href","src","action","formaction","data","srcdoc","xlink:href","poster","srcset"]),n=/^\s*(javascript|vbscript|data|blob):/i;function s(e){if(!e||"string"!=typeof e)return"";if(-1===e.indexOf("<"))return e;const r=document.createElement("template");return r.innerHTML=e,function(e){const r=[],s=e.querySelectorAll("*");for(const l of s){const e=l.tagName.toLowerCase();if(t.has(e)){r.push(l);continue}if("svg"===e||"http://www.w3.org/2000/svg"===l.namespaceURI){if(Array.from(l.attributes).some(e=>o.test(e.name)||"href"===e.name||"xlink:href"===e.name)){r.push(l);continue}}const s=[];for(const r of l.attributes){const e=r.name.toLowerCase();o.test(e)?s.push(r.name):(i.has(e)&&n.test(r.value)||"style"===e&&/expression\s*\(|javascript:|behavior\s*:/i.test(r.value))&&s.push(r.name)}s.forEach(e=>l.removeAttribute(e))}r.forEach(e=>e.remove())}(r.content),r.innerHTML}const l='<svg viewBox="0 0 16 16" width="12" height="12"><path fill="currentColor" d="M6 10.5a.5.5 0 0 1 .5-.5h3a.5.5 0 0 1 0 1h-3a.5.5 0 0 1-.5-.5zm-2-3a.5.5 0 0 1 .5-.5h7a.5.5 0 0 1 0 1h-7a.5.5 0 0 1-.5-.5zm-2-3a.5.5 0 0 1 .5-.5h11a.5.5 0 0 1 0 1h-11a.5.5 0 0 1-.5-.5z"/></svg>',d={expand:"▶",collapse:"▼",sortAsc:"▲",sortDesc:"▼",sortNone:"⇅",submenuArrow:"▶",dragHandle:"⋮⋮",toolPanel:"☰",filter:l,filterActive:l,print:"🖨️"};class u{static dependencies;static manifest;aliases;version="undefined"!=typeof __GRID_VERSION__?__GRID_VERSION__:"dev";styles;cellRenderers;headerRenderers;cellEditors;grid;config;userConfig;#e;get defaultConfig(){return{}}constructor(e={}){this.userConfig=e}attach(e){this.#e?.abort(),this.#e=new AbortController,this.grid=e,this.config={...this.defaultConfig,...this.userConfig}}detach(){this.#e?.abort(),this.#e=void 0}getPlugin(e){return this.grid?.getPlugin(e)}emit(e,r){this.grid?.dispatchEvent?.(new CustomEvent(e,{detail:r,bubbles:!0}))}emitCancelable(e,r){const t=new CustomEvent(e,{detail:r,bubbles:!0,cancelable:!0});return this.grid?.dispatchEvent?.(t),t.defaultPrevented}on(e,r){this.grid?._pluginManager?.subscribe(this,e,r)}off(e){this.grid?._pluginManager?.unsubscribe(this,e)}emitPluginEvent(e,r){this.grid?._pluginManager?.emitPluginEvent(e,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{...d,...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 r=this.gridElement;if(r){return"0"!==getComputedStyle(r).getPropertyValue("--tbw-animation-enabled").trim()}return!0}get animationDuration(){const e=this.gridElement;if(e){const r=getComputedStyle(e).getPropertyValue("--tbw-animation-duration").trim(),t=parseInt(r,10);if(!isNaN(t))return t}return 200}resolveIcon(e,r){return void 0!==r?r:this.gridIcons[e]}setIcon(e,r){"string"==typeof r?e.innerHTML=s(r):r instanceof HTMLElement&&(e.innerHTML="",e.appendChild(r.cloneNode(!0)))}warn(t,o){void 0!==o?console.warn(r(t,o,this.gridElement.id,this.name)):console.warn(`${e(this.gridElement.id,this.name)} ${t}`)}throwDiagnostic(e,t){throw new Error(r(e,t,this.gridElement.id,this.name))}}function c(e){return e.map(e=>{return e.id?e:(e.header||function(e,t,o,i){throw new Error(r(e,t,o,i))}("TBW113",'ColumnGroupDefinition requires either an "id" or a "header" to generate an id from.'),{...e,id:(t=e.header,t.toLowerCase().trim().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,""))});var t})}function a(e){if(!e.length)return[];const r=[],t=/* @__PURE__ */new Map,o=(e,t)=>{if(!t.length)return;const o=r[r.length-1];o&&o.implicit&&o.firstIndex+o.columns.length===e?o.columns.push(...t):r.push({id:"__implicit__"+e,label:void 0,columns:t,firstIndex:e,implicit:!0})};let i=[],n=0;return e.forEach((e,s)=>{const l=e.group;if(!l)return 0===i.length&&(n=s),void i.push(e);i.length&&(o(n,i.slice()),i=[]);const d="string"==typeof l?l:l.id,u="string"==typeof l?void 0:l.label;u&&!t.has(d)&&t.set(d,u);const c=t.get(d)??u,a=r[r.length-1];a&&!a.implicit&&a.id===d?a.columns.push(e):r.push({id:d,label:c,columns:[e],firstIndex:s})}),i.length&&o(n,i),1===r.length&&r[0].implicit&&r[0].columns.length===e.length?[]:r}function g(e){const r=function(e){const r=/* @__PURE__ */new Set;for(let t=0;t<e.length;t++){if(!String(e[t].id).startsWith("__implicit__"))continue;if(!e[t].columns.every(e=>e.field?.startsWith("__tbw_")))continue;let o=null;for(let r=t-1;r>=0;r--)if(!String(e[r].id).startsWith("__implicit__")){o=e[r].id;break}let i=null;for(let r=t+1;r<e.length;r++)if(!String(e[r].id).startsWith("__implicit__")){i=e[r].id;break}o&&i&&o===i&&r.add(String(e[t].id))}return r}(e),t=function(e,r){const t=[];for(const o of e){if(String(o.id).startsWith("__implicit__")&&r.has(String(o.id)))continue;const e=t[t.length-1];e&&!String(o.id).startsWith("__implicit__")&&e.id===o.id?t[t.length-1]={...e,columns:[...e.columns,...o.columns]}:t.push({...o,columns:[...o.columns]})}return t}(e,r);return{merged:t,embedded:r}}function h(e,r){const t=e.columns[0],o=e.columns[e.columns.length-1],i=t?r.findIndex(e=>e.field===t.field):-1,n=o?r.findIndex(e=>e.field===o.field):-1;return-1!==i&&-1!==n?[i,n]:null}class f extends u{static manifest={ownedProperties:[{property:"group",level:"column",description:'the "group" column property'},{property:"columnGroups",level:"config",description:'the "columnGroups" config property',isUsed:e=>Array.isArray(e)&&e.length>0}],queries:[{type:"getColumnGrouping",description:"Returns column group metadata for the visibility panel"}]};name="groupingColumns";styles="@layer tbw-plugins{.header-group-row{display:grid;grid-auto-flow:column;background:var(--tbw-grouping-columns-header-bg, var(--tbw-color-header-bg));border-bottom:1px solid var(--tbw-grouping-columns-border, var(--tbw-color-border))}.header-group-cell{display:flex;align-items:center;justify-content:center;padding:var(--tbw-button-padding-sm, .25rem .5rem);font-weight:600;font-size:var(--tbw-font-size-sm, .9em);text-transform:uppercase;letter-spacing:.5px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0;border-right:2px solid var(--tbw-grouping-columns-separator, var(--tbw-color-border-strong, var(--tbw-color-border)))}.header-group-cell:last-child{border-right:none}.header-row .cell.grouped{border-top:none}.header-row .cell.group-end{border-right:2px solid var(--tbw-grouping-columns-separator, var(--tbw-color-border-strong, var(--tbw-color-border)))}.header-row .cell.group-end:last-child{border-right:none}.rows .cell.group-end{border-right:2px solid var(--tbw-grouping-columns-separator, var(--tbw-color-border-strong, var(--tbw-color-border)))}.rows .cell.group-end:last-child{border-right:none}.header-group-row.no-borders{border-bottom:none}.header-group-row.no-borders .header-group-cell{border-right:none}.header-row.no-group-borders .cell.group-end{border-right:1px solid var(--tbw-color-border)}}";get defaultConfig(){return{showGroupBorders:!0,lockGroupOrder:!1}}groups=[];isActive=!1;#r=/* @__PURE__ */new Set;#t=[];#o=/* @__PURE__ */new Map;attach(e){super.attach(e),this.gridElement.addEventListener("column-move",this.#i,{signal:this.disconnectSignal})}detach(){this.groups=[],this.isActive=!1,this.#r.clear(),this.#t=[],this.#o.clear()}#i=e=>{if(!this.isActive)return;const r=e,{field:t,columnOrder:o}=r.detail;if(this.config.lockGroupOrder){const e=/* @__PURE__ */new Map;for(const r of this.groups){if(r.id.startsWith("__implicit__"))continue;const t=e.get(r.id);t?t.push(...r.columns):e.set(r.id,[...r.columns])}for(const[,i]of e)if(!this.#n(i,o))return r.preventDefault(),void this.#s(t)}this.#l(o)};#l(e){this.#r.clear();const r=/* @__PURE__ */new Map;for(const t of this.groups)for(const e of t.columns)r.set(e.field,t.id);for(let t=0;t<e.length-1;t++){r.get(e[t])!==r.get(e[t+1])&&this.#r.add(e[t])}}#n(e,r){const t=e.map(e=>r.indexOf(e.field)).filter(e=>-1!==e).sort((e,r)=>e-r);return t.length<=1||t.length===t[t.length-1]-t[0]+1}#s(e){const r=this.gridElement?.querySelector(`.header-row [part~="header-cell"][data-field="${e}"]`);r&&(r.style.setProperty("--_flash-color","var(--tbw-color-error)"),r.animate([{backgroundColor:"rgba(from var(--_flash-color) r g b / 30%)"},{backgroundColor:"transparent"}],{duration:400,easing:"ease-out"}))}handleQuery(e){if("getColumnGrouping"===e.type)return this.#d()}#d(){let e;if(this.#t.length>0)e=this.#t.filter(e=>e.children.length>0).map(e=>({id:e.id,label:e.header,fields:[...e.children]}));else if(this.isActive&&this.groups.length>0){const r=/* @__PURE__ */new Map;for(const e of this.groups){if(e.id.startsWith("__implicit__"))continue;const t=r.get(e.id);if(t)for(const r of e.columns)t.fields.includes(r.field)||t.fields.push(r.field);else r.set(e.id,{id:e.id,label:e.label??e.id,fields:e.columns.map(e=>e.field)})}e=Array.from(r.values());const t=this.columns;for(const o of t)if(o.hidden&&o.group){const r="string"==typeof o.group?o.group:o.group.id,t="string"==typeof o.group?o.group:o.group.label??o.group.id,i=e.find(e=>e.id===r);i?i.fields.includes(o.field)||i.fields.push(o.field):e.push({id:r,label:t,fields:[o.field]})}}else{const r=this.columns,t=/* @__PURE__ */new Map;for(const e of r){if(!e.group)continue;const r="string"==typeof e.group?e.group:e.group.id,o="string"==typeof e.group?e.group:e.group.label??e.group.id,i=t.get(r);i?i.fields.includes(e.field)||i.fields.push(e.field):t.set(r,{id:r,label:o,fields:[e.field]})}e=Array.from(t.values())}const r=this.grid?.getColumnOrder();if(r&&r.length>0){const t=new Map(r.map((e,r)=>[e,r]));for(const r of e)r.fields.sort((e,r)=>(t.get(e)??1/0)-(t.get(r)??1/0))}return e}static detect(e,r){const t=r?.features?.groupingColumns;if(t&&"object"==typeof t&&Array.isArray(t.columnGroups)&&t.columnGroups.length>0)return!0;if(r?.columnGroups&&Array.isArray(r.columnGroups)&&r.columnGroups.length>0)return!0;const o=r?.columns;return!!Array.isArray(o)&&function(e){return e.some(e=>null!=e.group)}(o)}processColumns(e){const r=this.config?.columnGroups,t=this.grid?.gridConfig?.columnGroups;let o,i;if(r&&Array.isArray(r)&&r.length>0?(t&&Array.isArray(t)&&t.length>0&&this.warn("TBW114","columnGroups defined in both gridConfig and groupingColumns feature config. Using feature config (higher precedence)."),o=r):t&&Array.isArray(t)&&t.length>0&&(o=t),o&&o.length>0){const r=c(o);this.#t=r,this.#o.clear();for(const e of r)e.renderer&&this.#o.set(e.id,e.renderer);const t=/* @__PURE__ */new Map;for(const e of r)for(const r of e.children)t.set(r,{id:e.id,label:e.header});i=e.map(e=>{const r=t.get(e.field);return r&&!e.group?{...e,group:r}:e})}else this.#t=[],this.#o.clear(),i=[...e];const n=a(i);if(0===n.length)return this.isActive=!1,this.groups=[],i;if(this.#o.size>0)for(const s of n){const e=this.#o.get(s.id);e&&(s.renderer=e)}this.isActive=!0,this.groups=n,this.#r.clear();for(const s of n){const e=s.columns[s.columns.length-1];e?.field&&this.#r.add(e.field)}return i}afterRender(){if(!this.isActive){const e=this.gridElement?.querySelector(".header"),r=e?.querySelector(".header-group-row");return void(r&&r.remove())}const e=this.gridElement?.querySelector(".header");if(!e)return;const r=e.querySelector(".header-group-row");r&&r.remove();const t=this.visibleColumns,o=a(t);if(0===o.length)return;if(this.#o.size>0)for(const l of o){const e=this.#o.get(l.id);e&&(l.renderer=e)}this.#r.clear();const i=g(o);for(let l=0;l<i.merged.length;l++){const e=i.merged[l],r=e.columns[e.columns.length-1];r?.field&&l<i.merged.length-1&&this.#r.add(r.field)}const n=function(e,r,t,o){if(0===e.length)return null;const i=document.createElement("div");i.className="header-group-row",i.setAttribute("role","row");const{merged:n}=o??g(e);for(const s of n){const e=String(s.id),o=e.startsWith("__implicit__"),n=h(s,r);if(!n)continue;const[l,d]=n,u=d-l+1,c=o?"":s.label||s.id,a=document.createElement("div");a.className="cell header-group-cell",o&&a.classList.add("implicit-group"),a.setAttribute("data-group",e),a.style.gridColumn=`${l+1} / span ${u}`;const g=!o&&(s.renderer||t)||void 0;if(g&&!o){const r=g({id:e,label:String(c),columns:s.columns,firstIndex:l,isImplicit:!1});r instanceof HTMLElement?a.appendChild(r):"string"==typeof r?a.innerHTML=r:a.textContent=c}else a.textContent=c;i.appendChild(a)}return i}(o,t,this.config.groupHeaderRenderer,i);if(n){n.classList.toggle("no-borders",!this.config.showGroupBorders);const r=e.querySelector(".header-row");r?e.insertBefore(n,r):e.appendChild(n)}const s=e.querySelector(".header-row");s&&(s.classList.toggle("no-group-borders",!this.config.showGroupBorders),function(e,r,t,o){if(!r.length||!e)return;const{merged:i,embedded:n}=o??g(r),s=/* @__PURE__ */new Map;for(const d of i)if(!String(d.id).startsWith("__implicit__"))for(const e of d.columns)e.field&&s.set(e.field,d.id);for(let d=0;d<r.length;d++){const e=r[d];if(String(e.id).startsWith("__implicit__")&&n.has(String(e.id)))for(let t=d-1;t>=0;t--)if(!String(r[t].id).startsWith("__implicit__")){for(const o of e.columns)o.field&&s.set(o.field,r[t].id);break}}const l=Array.from(e.querySelectorAll(".cell[data-field]"));l.forEach(e=>{const r=e.getAttribute("data-field")||"",t=s.get(r);t&&(e.classList.add("grouped"),e.getAttribute("data-group")||e.setAttribute("data-group",t))});for(const d of i){const e=d.columns[d.columns.length-1],r=l.find(r=>r.getAttribute("data-field")===e.field);r&&r.classList.add("group-end")}}(s,o,0,i))}afterCellRender(e){this.isActive&&this.config.showGroupBorders&&e.cellElement.classList.toggle("group-end",this.#r.has(e.column.field))}isGroupingActive(){return this.isActive}getGroups(){return this.groups}getGroupColumns(e){return this.groups.filter(r=>r.id===e).flatMap(e=>e.columns)}refresh(){this.requestRender()}}export{f as GroupingColumnsPlugin};
2
2
  //# sourceMappingURL=index.js.map