@toolbox-web/grid 1.26.1 → 1.27.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 (114) hide show
  1. package/all.js +2 -2
  2. package/all.js.map +1 -1
  3. package/index.js +1 -1
  4. package/index.js.map +1 -1
  5. package/lib/core/grid.d.ts +64 -1
  6. package/lib/core/internal/diagnostics.d.ts +4 -3
  7. package/lib/core/internal/row-manager.d.ts +3 -1
  8. package/lib/core/plugin/base-plugin.d.ts +2 -2
  9. package/lib/core/types.d.ts +59 -3
  10. package/lib/features/registry.js.map +1 -1
  11. package/lib/plugins/clipboard/ClipboardPlugin.d.ts +1 -1
  12. package/lib/plugins/clipboard/index.js.map +1 -1
  13. package/lib/plugins/column-virtualization/index.js.map +1 -1
  14. package/lib/plugins/context-menu/ContextMenuPlugin.d.ts +24 -5
  15. package/lib/plugins/context-menu/index.js.map +1 -1
  16. package/lib/plugins/editing/EditingPlugin.d.ts +1 -1
  17. package/lib/plugins/editing/index.js.map +1 -1
  18. package/lib/plugins/export/ExportPlugin.d.ts +1 -1
  19. package/lib/plugins/export/index.js.map +1 -1
  20. package/lib/plugins/filtering/index.d.ts +2 -2
  21. package/lib/plugins/filtering/index.js +1 -1
  22. package/lib/plugins/filtering/index.js.map +1 -1
  23. package/lib/plugins/grouping-columns/GroupingColumnsPlugin.d.ts +2 -2
  24. package/lib/plugins/grouping-columns/grouping-columns.d.ts +18 -3
  25. package/lib/plugins/grouping-columns/index.d.ts +0 -1
  26. package/lib/plugins/grouping-columns/index.js +1 -1
  27. package/lib/plugins/grouping-columns/index.js.map +1 -1
  28. package/lib/plugins/grouping-columns/types.d.ts +1 -7
  29. package/lib/plugins/grouping-rows/index.d.ts +2 -1
  30. package/lib/plugins/grouping-rows/index.js +1 -1
  31. package/lib/plugins/grouping-rows/index.js.map +1 -1
  32. package/lib/plugins/master-detail/MasterDetailPlugin.d.ts +2 -0
  33. package/lib/plugins/master-detail/index.js +1 -1
  34. package/lib/plugins/master-detail/index.js.map +1 -1
  35. package/lib/plugins/master-detail/types.d.ts +20 -1
  36. package/lib/plugins/multi-sort/index.js.map +1 -1
  37. package/lib/plugins/pinned-columns/PinnedColumnsPlugin.d.ts +8 -1
  38. package/lib/plugins/pinned-columns/index.js +1 -1
  39. package/lib/plugins/pinned-columns/index.js.map +1 -1
  40. package/lib/plugins/pinned-columns/pinned-columns.d.ts +11 -1
  41. package/lib/plugins/pinned-rows/index.d.ts +1 -1
  42. package/lib/plugins/pinned-rows/index.js +1 -1
  43. package/lib/plugins/pinned-rows/index.js.map +1 -1
  44. package/lib/plugins/pinned-rows/types.d.ts +10 -3
  45. package/lib/plugins/pivot/PivotPlugin.d.ts +107 -1
  46. package/lib/plugins/pivot/index.d.ts +2 -1
  47. package/lib/plugins/pivot/index.js +1 -1
  48. package/lib/plugins/pivot/index.js.map +1 -1
  49. package/lib/plugins/print/index.js.map +1 -1
  50. package/lib/plugins/print/types.d.ts +0 -3
  51. package/lib/plugins/reorder-columns/ReorderPlugin.d.ts +19 -2
  52. package/lib/plugins/reorder-columns/index.js +1 -1
  53. package/lib/plugins/reorder-columns/index.js.map +1 -1
  54. package/lib/plugins/reorder-rows/index.d.ts +1 -1
  55. package/lib/plugins/reorder-rows/index.js.map +1 -1
  56. package/lib/plugins/responsive/ResponsivePlugin.d.ts +1 -1
  57. package/lib/plugins/responsive/index.js +1 -1
  58. package/lib/plugins/responsive/index.js.map +1 -1
  59. package/lib/plugins/selection/SelectionPlugin.d.ts +1 -1
  60. package/lib/plugins/selection/index.js +1 -1
  61. package/lib/plugins/selection/index.js.map +1 -1
  62. package/lib/plugins/selection/types.d.ts +3 -3
  63. package/lib/plugins/server-side/ServerSidePlugin.d.ts +6 -1
  64. package/lib/plugins/server-side/index.js +1 -1
  65. package/lib/plugins/server-side/index.js.map +1 -1
  66. package/lib/plugins/tree/TreePlugin.d.ts +116 -0
  67. package/lib/plugins/tree/index.d.ts +1 -1
  68. package/lib/plugins/tree/index.js +1 -1
  69. package/lib/plugins/tree/index.js.map +1 -1
  70. package/lib/plugins/tree/types.d.ts +16 -1
  71. package/lib/plugins/undo-redo/UndoRedoPlugin.d.ts +1 -1
  72. package/lib/plugins/undo-redo/index.js.map +1 -1
  73. package/lib/plugins/undo-redo/types.d.ts +15 -3
  74. package/lib/plugins/visibility/VisibilityPlugin.d.ts +18 -5
  75. package/lib/plugins/visibility/index.js +1 -1
  76. package/lib/plugins/visibility/index.js.map +1 -1
  77. package/package.json +1 -1
  78. package/public.d.ts +2 -4
  79. package/themes/dg-theme-material.css +16 -4
  80. package/umd/grid.all.umd.js +1 -1
  81. package/umd/grid.all.umd.js.map +1 -1
  82. package/umd/grid.umd.js +1 -1
  83. package/umd/grid.umd.js.map +1 -1
  84. package/umd/plugins/clipboard.umd.js.map +1 -1
  85. package/umd/plugins/context-menu.umd.js.map +1 -1
  86. package/umd/plugins/editing.umd.js.map +1 -1
  87. package/umd/plugins/export.umd.js.map +1 -1
  88. package/umd/plugins/filtering.umd.js +1 -1
  89. package/umd/plugins/filtering.umd.js.map +1 -1
  90. package/umd/plugins/grouping-columns.umd.js +1 -1
  91. package/umd/plugins/grouping-columns.umd.js.map +1 -1
  92. package/umd/plugins/grouping-rows.umd.js +1 -1
  93. package/umd/plugins/grouping-rows.umd.js.map +1 -1
  94. package/umd/plugins/master-detail.umd.js +1 -1
  95. package/umd/plugins/master-detail.umd.js.map +1 -1
  96. package/umd/plugins/pinned-columns.umd.js +1 -1
  97. package/umd/plugins/pinned-columns.umd.js.map +1 -1
  98. package/umd/plugins/pinned-rows.umd.js +1 -1
  99. package/umd/plugins/pinned-rows.umd.js.map +1 -1
  100. package/umd/plugins/pivot.umd.js +1 -1
  101. package/umd/plugins/pivot.umd.js.map +1 -1
  102. package/umd/plugins/reorder-columns.umd.js +1 -1
  103. package/umd/plugins/reorder-columns.umd.js.map +1 -1
  104. package/umd/plugins/responsive.umd.js +1 -1
  105. package/umd/plugins/responsive.umd.js.map +1 -1
  106. package/umd/plugins/selection.umd.js +1 -1
  107. package/umd/plugins/selection.umd.js.map +1 -1
  108. package/umd/plugins/server-side.umd.js +1 -1
  109. package/umd/plugins/server-side.umd.js.map +1 -1
  110. package/umd/plugins/tree.umd.js +1 -1
  111. package/umd/plugins/tree.umd.js.map +1 -1
  112. package/umd/plugins/undo-redo.umd.js.map +1 -1
  113. package/umd/plugins/visibility.umd.js +1 -1
  114. package/umd/plugins/visibility.umd.js.map +1 -1
@@ -76,7 +76,7 @@ import { ColumnGroup, GroupingColumnsConfig } from './types';
76
76
  *
77
77
  * @see {@link GroupingColumnsConfig} for all configuration options
78
78
  * @see {@link ColumnGroup} for the group structure
79
- * @see {@link ReorderPlugin} for drag-to-reorder within groups
79
+ * @see ReorderPlugin for drag-to-reorder within groups
80
80
  *
81
81
  * @internal Extends BaseGridPlugin
82
82
  */
@@ -128,7 +128,7 @@ export declare class GroupingColumnsPlugin extends BaseGridPlugin<GroupingColumn
128
128
  */
129
129
  getGroups(): ColumnGroup[];
130
130
  /**
131
- * Get columns in a specific group.
131
+ * Get columns in a specific group (aggregated across all fragments).
132
132
  * @param groupId - The group ID to find
133
133
  * @returns Array of columns in the group
134
134
  */
@@ -31,12 +31,27 @@ export declare function computeColumnGroups<T>(columns: ColumnConfig<T>[]): Colu
31
31
  */
32
32
  export declare function applyGroupedHeaderCellClasses(headerRowEl: HTMLElement | null, groups: ColumnGroup[], columns: ColumnConfig[]): void;
33
33
  /**
34
- * Find implicit groups whose column range falls entirely within an explicit
35
- * group's range (e.g. a utility column inserted between members of the same group).
34
+ * Find implicit groups that are sandwiched between two fragments of the same
35
+ * explicit group (e.g. a utility column inserted between members of the same group).
36
+ *
37
+ * Only implicit groups whose columns are **all** internal/utility fields (prefixed
38
+ * with `__tbw_`) qualify. When a regular data column sits between two fragments
39
+ * of the same group it represents a genuine break introduced by column reordering
40
+ * and must NOT be absorbed.
36
41
  *
37
42
  * @returns Set of implicit group IDs that are visually embedded.
38
43
  */
39
- export declare function findEmbeddedImplicitGroups(groups: ColumnGroup[], columns: ColumnConfig[]): Set<string>;
44
+ export declare function findEmbeddedImplicitGroups(groups: ColumnGroup[]): Set<string>;
45
+ /**
46
+ * Merge adjacent same-ID group fragments after removing embedded implicit groups.
47
+ * This produces the final group list for header rendering, where utility columns
48
+ * (checkbox, expander) are absorbed into the surrounding group's span.
49
+ *
50
+ * @param groups - The computed column groups (potentially fragmented)
51
+ * @param embedded - Set of embedded implicit group IDs to skip
52
+ * @returns Merged group list where same-ID fragments separated by embedded implicits are combined
53
+ */
54
+ export declare function mergeAdjacentSameIdGroups<T>(groups: ColumnGroup<T>[], embedded: Set<string>): ColumnGroup<T>[];
40
55
  /**
41
56
  * Build the group header row element.
42
57
  *
@@ -4,6 +4,5 @@
4
4
  *
5
5
  * @module Plugins/Grouping Columns
6
6
  */
7
- export { resolveColumnGroupDefs, slugifyHeader } from './grouping-columns';
8
7
  export { GroupingColumnsPlugin } from './GroupingColumnsPlugin';
9
8
  export type { ColumnGroup, ColumnGroupDefinition, GroupHeaderRenderParams, GroupingColumnsConfig } from './types';
@@ -1,2 +1,2 @@
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)}`}function t(e){return e.toLowerCase().trim().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"")}function o(e){return e.map(e=>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)}))}function i(e){if(!e.length)return[];const r=/* @__PURE__ */new Map,t=[],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;let u=r.get(d);u||(u={id:d,label:"string"==typeof l?void 0:l.label,columns:[],firstIndex:s},r.set(d,u),t.push(u)),u.columns.push(e)}),i.length&&o(n,i),1===t.length&&t[0].implicit&&t[0].columns.length===e.length?[]:t}function n(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}function s(e,r){const t=/* @__PURE__ */new Set,o=[];for(const i of e){if(String(i.id).startsWith("__implicit__"))continue;const e=n(i,r);e&&o.push(e)}for(const i of e){if(!String(i.id).startsWith("__implicit__"))continue;const e=n(i,r);if(!e)continue;const[s,l]=e;o.some(([e,r])=>s>=e&&l<=r)&&t.add(String(i.id))}return t}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=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))}}class c 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;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)for(const i of this.groups)if(!i.id.startsWith("__implicit__")&&!this.#n(i,o))return r.preventDefault(),void this.#s(t);this.#l(o)};#l(e){this.#r.clear();const r=this.#d(e);for(const t of this.groups){const o=new Set(t.columns.map(e=>e.field));for(let t=e.length-1;t>=0;t--)if(o.has(e[t])){const o=e[t];o!==r&&this.#r.add(o);break}}}#d(e){if(0===this.groups.length)return null;for(let r=e.length-1;r>=0;r--){const t=e[r];for(const r of this.groups)if(r.columns.some(e=>e.field===t)){const t=new Set(r.columns.map(e=>e.field));for(let r=e.length-1;r>=0;r--)if(t.has(e[r]))return e[r]}}return null}#n(e,r){const t=e.columns.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.#u()}#u(){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){e=this.groups.filter(e=>!e.id.startsWith("__implicit__")).map(e=>({id:e.id,label:e.label??e.id,fields:e.columns.map(e=>e.field)}));const r=this.columns;for(const t of r)if(t.hidden&&t.group){const r="string"==typeof t.group?t.group:t.group.id,o="string"==typeof t.group?t.group:t.group.label??t.group.id,i=e.find(e=>e.id===r);i?i.fields.includes(t.field)||i.fields.push(t.field):e.push({id:r,label:o,fields:[t.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 n,s;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)."),n=r):t&&Array.isArray(t)&&t.length>0&&(n=t),n&&n.length>0){const r=o(n);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});s=e.map(e=>{const r=t.get(e.field);return r&&!e.group?{...e,group:r}:e})}else this.#t=[],this.#o.clear(),s=[...e];const l=i(s);if(0===l.length)return this.isActive=!1,this.groups=[],s;if(this.#o.size>0)for(const o of l){const e=this.#o.get(o.id);e&&(o.renderer=e)}this.isActive=!0,this.groups=l,this.#r.clear();for(const o of l){const e=o.columns[o.columns.length-1];e?.field&&this.#r.add(e.field)}return s}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=i(t);if(0===o.length)return;if(this.#o.size>0)for(const i of o){const e=this.#o.get(i.id);e&&(i.renderer=e)}this.#r.clear();const l=s(o,t);for(let i=0;i<o.length;i++){const e=o[i];if(String(e.id).startsWith("__implicit__")&&l.has(String(e.id)))continue;const r=e.columns[e.columns.length-1];r?.field&&i<o.length-1&&this.#r.add(r.field)}const d=function(e,r,t){if(0===e.length)return null;const o=document.createElement("div");o.className="header-group-row",o.setAttribute("role","row");const i=s(e,r);for(const s of e){const e=String(s.id),l=e.startsWith("__implicit__");if(l&&i.has(e))continue;const d=n(s,r);if(!d)continue;const[u,c]=d,g=c-u+1,a=l?"":s.label||s.id,h=document.createElement("div");h.className="cell header-group-cell",l&&h.classList.add("implicit-group"),h.setAttribute("data-group",e),h.style.gridColumn=`${u+1} / span ${g}`;const p=!l&&(s.renderer||t)||void 0;if(p&&!l){const r=p({id:e,label:String(a),columns:s.columns,firstIndex:u,isImplicit:!1});r instanceof HTMLElement?h.appendChild(r):"string"==typeof r?h.innerHTML=r:h.textContent=a}else h.textContent=a;o.appendChild(h)}return o}(o,t,this.config.groupHeaderRenderer);if(d){d.classList.toggle("no-borders",!this.config.showGroupBorders);const r=e.querySelector(".header-row");r?e.insertBefore(d,r):e.appendChild(d)}const u=e.querySelector(".header-row");u&&(u.classList.toggle("no-group-borders",!this.config.showGroupBorders),function(e,r,t){if(!r.length||!e)return;const o=s(r,t),i=/* @__PURE__ */new Map;for(const s of r)if(!String(s.id).startsWith("__implicit__")||!o.has(String(s.id)))for(const e of s.columns)e.field&&i.set(e.field,s.id);const n=Array.from(e.querySelectorAll(".cell[data-field]"));n.forEach(e=>{const r=e.getAttribute("data-field")||"",t=i.get(r);t&&(e.classList.add("grouped"),e.getAttribute("data-group")||e.setAttribute("data-group",t))});for(const s of r){if(String(s.id).startsWith("__implicit__")&&o.has(String(s.id)))continue;const e=s.columns[s.columns.length-1],r=n.find(r=>r.getAttribute("data-field")===e.field);r&&r.classList.add("group-end")}}(u,o,t))}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){const r=this.groups.find(r=>r.id===e);return r?r.columns:[]}refresh(){this.requestRender()}}export{c as GroupingColumnsPlugin,o as resolveColumnGroupDefs,t as slugifyHeader};
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='<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>',o={expand:"▶",collapse:"▼",sortAsc:"▲",sortDesc:"▼",sortNone:"⇅",submenuArrow:"▶",dragHandle:"⋮⋮",toolPanel:"☰",filter:t,filterActive:t,print:"🖨️"};class i{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{...o,...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=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 n(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 s(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,g=r[r.length-1];g&&!g.implicit&&g.id===d?g.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 l(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}function d(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}function u(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}class c extends i{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=n(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 l=s(i);if(0===l.length)return this.isActive=!1,this.groups=[],i;if(this.#o.size>0)for(const n of l){const e=this.#o.get(n.id);e&&(n.renderer=e)}this.isActive=!0,this.groups=l,this.#r.clear();for(const n of l){const e=n.columns[n.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=s(t);if(0===o.length)return;if(this.#o.size>0)for(const s of o){const e=this.#o.get(s.id);e&&(s.renderer=e)}this.#r.clear();const i=u(o,d(o));for(let s=0;s<i.length;s++){const e=i[s],r=e.columns[e.columns.length-1];r?.field&&s<i.length-1&&this.#r.add(r.field)}const n=function(e,r,t){if(0===e.length)return null;const o=document.createElement("div");o.className="header-group-row",o.setAttribute("role","row");const i=u(e,d(e));for(const n of i){const e=String(n.id),i=e.startsWith("__implicit__"),s=l(n,r);if(!s)continue;const[d,u]=s,c=u-d+1,g=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=`${d+1} / span ${c}`;const h=!i&&(n.renderer||t)||void 0;if(h&&!i){const r=h({id:e,label:String(g),columns:n.columns,firstIndex:d,isImplicit:!1});r instanceof HTMLElement?a.appendChild(r):"string"==typeof r?a.innerHTML=r:a.textContent=g}else a.textContent=g;o.appendChild(a)}return o}(o,t,this.config.groupHeaderRenderer);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 c=e.querySelector(".header-row");c&&(c.classList.toggle("no-group-borders",!this.config.showGroupBorders),function(e,r){if(!r.length||!e)return;const t=d(r),o=u(r,t),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<r.length;s++){const e=r[s];if(String(e.id).startsWith("__implicit__")&&t.has(String(e.id)))for(let t=s-1;t>=0;t--)if(!String(r[t].id).startsWith("__implicit__")){for(const o of e.columns)o.field&&i.set(o.field,r[t].id);break}}const n=Array.from(e.querySelectorAll(".cell[data-field]"));n.forEach(e=>{const r=e.getAttribute("data-field")||"",t=i.get(r);t&&(e.classList.add("grouped"),e.getAttribute("data-group")||e.setAttribute("data-group",t))});for(const s of o){const e=s.columns[s.columns.length-1],r=n.find(r=>r.getAttribute("data-field")===e.field);r&&r.classList.add("group-end")}}(c,o))}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{c as GroupingColumnsPlugin};
2
2
  //# sourceMappingURL=index.js.map