@toolbox-web/grid 0.0.3 → 0.0.5

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 (63) hide show
  1. package/all.d.ts +50 -6
  2. package/all.js +101 -98
  3. package/all.js.map +1 -1
  4. package/index.d.ts +54 -0
  5. package/index.js +793 -692
  6. package/index.js.map +1 -1
  7. package/lib/plugins/clipboard/index.js +55 -35
  8. package/lib/plugins/clipboard/index.js.map +1 -1
  9. package/lib/plugins/column-virtualization/index.js +49 -29
  10. package/lib/plugins/column-virtualization/index.js.map +1 -1
  11. package/lib/plugins/context-menu/index.js +35 -15
  12. package/lib/plugins/context-menu/index.js.map +1 -1
  13. package/lib/plugins/export/index.js +52 -32
  14. package/lib/plugins/export/index.js.map +1 -1
  15. package/lib/plugins/filtering/index.js +116 -99
  16. package/lib/plugins/filtering/index.js.map +1 -1
  17. package/lib/plugins/grouping-columns/index.js +42 -22
  18. package/lib/plugins/grouping-columns/index.js.map +1 -1
  19. package/lib/plugins/grouping-rows/index.js +20 -0
  20. package/lib/plugins/grouping-rows/index.js.map +1 -1
  21. package/lib/plugins/master-detail/index.js +50 -27
  22. package/lib/plugins/master-detail/index.js.map +1 -1
  23. package/lib/plugins/multi-sort/index.js +25 -5
  24. package/lib/plugins/multi-sort/index.js.map +1 -1
  25. package/lib/plugins/pinned-columns/index.js +20 -0
  26. package/lib/plugins/pinned-columns/index.js.map +1 -1
  27. package/lib/plugins/pinned-rows/index.js +20 -0
  28. package/lib/plugins/pinned-rows/index.js.map +1 -1
  29. package/lib/plugins/pivot/index.js +20 -0
  30. package/lib/plugins/pivot/index.js.map +1 -1
  31. package/lib/plugins/reorder/index.js +56 -33
  32. package/lib/plugins/reorder/index.js.map +1 -1
  33. package/lib/plugins/selection/index.js +138 -100
  34. package/lib/plugins/selection/index.js.map +1 -1
  35. package/lib/plugins/server-side/index.js +20 -0
  36. package/lib/plugins/server-side/index.js.map +1 -1
  37. package/lib/plugins/tree/index.js +76 -53
  38. package/lib/plugins/tree/index.js.map +1 -1
  39. package/lib/plugins/undo-redo/index.js +20 -0
  40. package/lib/plugins/undo-redo/index.js.map +1 -1
  41. package/lib/plugins/visibility/index.js +20 -0
  42. package/lib/plugins/visibility/index.js.map +1 -1
  43. package/package.json +4 -1
  44. package/themes/dg-theme-contrast.css +43 -43
  45. package/themes/dg-theme-large.css +54 -54
  46. package/themes/dg-theme-standard.css +19 -19
  47. package/themes/dg-theme-vibrant.css +16 -16
  48. package/umd/grid.all.umd.js +24 -24
  49. package/umd/grid.all.umd.js.map +1 -1
  50. package/umd/grid.umd.js +14 -14
  51. package/umd/grid.umd.js.map +1 -1
  52. package/umd/plugins/filtering.umd.js +3 -3
  53. package/umd/plugins/filtering.umd.js.map +1 -1
  54. package/umd/plugins/master-detail.umd.js +2 -2
  55. package/umd/plugins/master-detail.umd.js.map +1 -1
  56. package/umd/plugins/multi-sort.umd.js.map +1 -1
  57. package/umd/plugins/reorder.umd.js +1 -1
  58. package/umd/plugins/reorder.umd.js.map +1 -1
  59. package/umd/plugins/selection.umd.js +2 -2
  60. package/umd/plugins/selection.umd.js.map +1 -1
  61. package/umd/plugins/tree.umd.js +2 -2
  62. package/umd/plugins/tree.umd.js.map +1 -1
  63. package/umd/plugins/visibility.umd.js.map +1 -1
package/index.js CHANGED
@@ -1,4 +1,4 @@
1
- const we = ":root{color-scheme:light dark}:host{--tbw-color-bg: transparent;--tbw-color-panel-bg: light-dark(#eeeeee, #222222);--tbw-color-fg: light-dark(#222222, #eeeeee);--tbw-color-fg-muted: light-dark(#555555, #aaaaaa);--tbw-color-accent: light-dark(#3b82f6, #3b82f6);--tbw-color-accent-fg: light-dark(#ffffff, #000000);--tbw-color-success: light-dark(hsl(122, 39%, 40%), hsl(122, 39%, 49%));--tbw-color-selection: light-dark(#fff7d6, #333333);--tbw-color-row-alt: var(--tbw-color-bg);--tbw-color-row-hover: light-dark(#f0f6ff, #1c1c1c);--tbw-color-header-bg: color-mix(in hsl, var(--tbw-color-panel-bg) 85%, var(--tbw-color-fg));--tbw-color-header-fg: color-mix(in hsl, var(--tbw-color-fg) 75%, var(--tbw-color-panel-bg));--tbw-color-border: light-dark(#d0d0d4, #454545);--tbw-color-border-strong: light-dark(#777777, #adacac);--tbw-color-border-cell: var(--tbw-color-border);--tbw-color-border-header: var(--tbw-color-border);--tbw-color-shadow: light-dark(rgba(0, 0, 0, .1), rgba(0, 0, 0, .3));--tbw-font-family: inherit;--tbw-font-size: inherit;--tbw-font-size-header: var(--tbw-font-size);--tbw-font-weight-header: bold;--tbw-cell-padding-header: 2px 8px;--tbw-cell-padding: 2px 8px;--tbw-cell-padding-input: 2px 6px;--tbw-row-height: 28px;--tbw-header-height: 30px;--tbw-border-radius: 4px;--tbw-border-input: 1px solid var(--tbw-color-border-strong);--tbw-border-header: 1px solid var(--tbw-color-border-header);--tbw-row-divider: 1px solid var(--tbw-color-border-cell);--tbw-row-hover-outline: 0;--tbw-color-active-row-bg: var(--tbw-color-selection);--tbw-active-row-outline: 0;--tbw-focus-outline: 2px solid var(--tbw-color-accent);--tbw-focus-outline-offset: -2px;--tbw-focus-background: rgba(from var(--tbw-color-accent) r g b / 12%);--tbw-range-border-color: var(--tbw-color-success);--tbw-range-selection-bg: rgba(from var(--tbw-range-border-color) r g b / 12%);--tbw-resize-handle-width: 4px;--tbw-resize-handle-color: transparent;--tbw-resize-handle-color-hover: var(--tbw-color-accent);--tbw-resize-handle-border-radius: 0;--tbw-scrollbar-thumb: var(--tbw-color-border-strong);--tbw-scrollbar-track: var(--tbw-color-bg);--tbw-transition-duration: .12s;--tbw-transition-ease: ease;--tbw-editing-bg: var(--tbw-color-selection);--tbw-editing-border: var(--tbw-border-input, 1px solid var(--tbw-color-border-strong));--tbw-padding-editing-input: var(--tbw-cell-padding-input, 2px 6px);--tbw-font-size-editor: inherit;--tbw-sort-indicator-color: var(--tbw-color-fg-muted);--tbw-sort-indicator-active-color: var(--tbw-color-accent);--tbw-header-text-transform: none;--tbw-header-letter-spacing: normal;--tbw-color-header-separator: var(--tbw-color-border-cell);--tbw-checkbox-size: 16px;--tbw-density-scale: 1}:host{position:relative;display:block;width:100%;height:100%;min-height:0;contain:content;font-family:var(--tbw-font-family);font-size:var(--tbw-font-size);background:var(--tbw-color-bg);color:var(--tbw-color-fg);border:1px solid var(--tbw-color-border);border-radius:var(--tbw-border-radius);overflow:clip;outline:none}:host,:host *{box-sizing:border-box}:host .header{display:block;flex-shrink:0;z-index:var(--tbw-z-layer-header, 30);background:var(--tbw-color-header-bg);overflow:visible}:host .header-group-row{display:grid;grid-template-columns:var(--tbw-column-template);background:var(--tbw-color-header-bg);z-index:var(--tbw-z-layer-header, 30)}:host .header-group-cell{display:flex;align-items:center;justify-content:flex-start;padding:var(--tbw-cell-padding-header, 2px 8px);color:var(--tbw-color-header-group-fg, var(--tbw-color-header-fg));font-weight:var(--tbw-font-weight-header-group, var(--tbw-font-weight-header));justify-content:var(--tbw-align-header-group, var(--tbw-align-header, flex-start))}:host .header-row{display:grid;grid-template-columns:var(--tbw-column-template);color:var(--tbw-color-header-fg);font-size:var(--tbw-font-size-header);min-height:var(--tbw-header-height);border-bottom:var(--tbw-border-header);z-index:var(--tbw-z-layer-header, 30)}:host .header-row>.cell{display:flex;align-items:center;gap:4px;padding:var(--tbw-cell-padding-header, 2px 8px);background-color:var(--tbw-color-header-bg);font-weight:var(--tbw-font-weight-header);border-right:1px solid var(--tbw-color-border-cell);overflow:hidden;min-width:0}:host .header-row>.cell>span:first-child{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}:host .header-row>.cell>span[part~=sort-indicator]{flex-shrink:0}:host .header-row>.cell:last-child{border-right:0}:host .header-group-cell,:host .header-row>.cell.grouped.group-end{border-right:2px solid var(--tbw-color-border)}:host .tbw-grid-root{display:flex;flex-direction:column;height:100%}:host .rows-body-wrapper{flex:1;min-height:0;display:flex;flex-direction:row;width:100%;min-width:fit-content}:host .rows-body{flex:1;min-width:0;min-height:0;display:flex;flex-direction:column;overflow:visible}:host .rows-container{display:flex;flex-direction:row;flex:1;min-height:0;overflow:visible}:host .rows-viewport{flex:1;min-width:0;position:relative;display:block;overflow:clip}:host .faux-vscroll{position:sticky;inset-inline-end:0;flex-shrink:0;width:auto;overflow-y:auto;overflow-x:hidden;z-index:var(--tbw-z-layer-header, 30)}:host .faux-vscroll-spacer{width:1px}:host .rows-viewport .rows{position:absolute;top:0;left:0;min-width:100%;will-change:transform;z-index:var(--tbw-z-layer-rows, 1)}:host .data-grid-row{display:grid;grid-template-columns:var(--tbw-column-template);contain:layout style}:host .data-grid-row:has(.editing){background:var(--tbw-editing-bg)}:host .selecting .data-grid-row>.cell{user-select:none}:host .data-grid-row>.cell{display:flex;align-items:center;padding:var(--tbw-cell-padding, 2px 8px);border-bottom:var(--tbw-row-divider);min-height:var(--tbw-row-height);border-right:1px solid var(--tbw-color-border-cell);overflow:hidden;min-width:0}:host .data-grid-row>.cell>*{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}:host .data-grid-row>.cell:last-child{border-right:0}:host .data-grid-row>.cell[data-type=boolean]{justify-content:center}:host .data-grid-row>.cell[data-type=boolean] input[type=checkbox]{margin:0;width:var(--tbw-checkbox-size);height:var(--tbw-checkbox-size)}:host .data-grid-row>.cell.editing{overflow:hidden;padding:0}:host .data-grid-row>.cell.editing input:not([type=checkbox]),:host .data-grid-row>.cell.editing select,:host .data-grid-row>.cell.editing textarea{width:100%;height:100%;max-width:100%;flex:1 1 auto;min-width:0;border:var(--tbw-editing-border);padding:var(--tbw-padding-editing-input);font-size:var(--tbw-font-size-editor)}:host .data-grid-row:nth-child(2n){background:var(--tbw-color-row-alt)}:host .data-grid-row:hover{background:var(--tbw-color-row-hover)}:host .sortable{cursor:pointer;user-select:none}:host .resize-handle{position:absolute;top:0;right:calc(var(--tbw-resize-handle-width) / -2);width:var(--tbw-resize-handle-width);height:100%;cursor:e-resize;user-select:none;touch-action:none;z-index:20;background:var(--tbw-resize-handle-color);transition:background .12s ease;border-radius:var(--tbw-resize-handle-border-radius)}:host .resize-handle:hover{background:var(--tbw-resize-handle-color-hover)}:host .cell-focus,:host .row-focus{outline:var(--tbw-focus-outline);outline-offset:var(--tbw-focus-outline-offset)}:host .group-row{display:grid;grid-template-columns:var(--tbw-column-template);background:var(--tbw-color-row-alt);font-weight:500;border-bottom:var(--tbw-row-divider);min-height:var(--tbw-row-height)}:host .group-row .cell{display:flex;align-items:center;padding:var(--tbw-cell-padding, 2px 8px)}:host .group-row .group-toggle{background:none;border:0;cursor:pointer;padding:0 4px 0 0;font:inherit}:host .group-row .group-count{margin-left:4px;opacity:.7}:host .sticky-left,:host .sticky-right{position:sticky;z-index:25}:host .header-row>.cell.sticky-left,:host .header-row>.cell.sticky-right{background:var(--tbw-color-header-bg);z-index:35}:host .data-grid-row>.cell.sticky-left,:host .data-grid-row>.cell.sticky-right{background:var(--tbw-color-panel-bg)}:host .sticky-left{box-shadow:1px 0 0 var(--tbw-color-border)}:host .sticky-right{box-shadow:-1px 0 0 var(--tbw-color-border)}.grid-container{position:relative;width:100%;height:100%}.grid-placeholder{padding:2rem;text-align:center;color:var(--tbw-color-fg);opacity:.6}:host{--tbw-shell-header-height: 44px;--tbw-shell-header-bg: var(--tbw-color-panel-bg);--tbw-shell-header-border: var(--tbw-color-border);--tbw-shell-title-font-size: 14px;--tbw-shell-title-font-weight: 600;--tbw-tool-panel-width: 280px;--tbw-tool-panel-bg: var(--tbw-color-panel-bg);--tbw-tool-panel-border: var(--tbw-color-border);--tbw-tool-panel-header-height: 40px;--tbw-tool-panel-transition: .2s ease-out;--tbw-toolbar-button-size: 32px;--tbw-toolbar-button-gap: 4px}:host .tbw-grid-root.has-shell{display:flex;flex-direction:column;height:100%}:host .tbw-shell-header{display:flex;align-items:center;gap:8px;min-height:var(--tbw-shell-header-height);padding:0 8px;background:var(--tbw-shell-header-bg);border-bottom:1px solid var(--tbw-shell-header-border);flex-shrink:0}:host .tbw-shell-title{font-size:var(--tbw-shell-title-font-size);font-weight:var(--tbw-shell-title-font-weight);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}:host .tbw-shell-content{flex:1;display:flex;align-items:center;gap:12px;min-width:0;overflow:hidden}:host .tbw-shell-toolbar{display:flex;align-items:center;gap:var(--tbw-toolbar-button-gap);flex-shrink:0}:host .tbw-toolbar-btn{display:inline-flex;align-items:center;justify-content:center;width:var(--tbw-toolbar-button-size);height:var(--tbw-toolbar-button-size);padding:0;border:1px solid transparent;border-radius:var(--tbw-border-radius);background:transparent;color:var(--tbw-color-fg);cursor:pointer;font-size:16px;transition:background var(--tbw-transition-duration) var(--tbw-transition-ease),border-color var(--tbw-transition-duration) var(--tbw-transition-ease)}:host .tbw-toolbar-btn:hover{background:var(--tbw-color-row-hover)}:host .tbw-toolbar-btn:focus-visible{outline:var(--tbw-focus-outline);outline-offset:var(--tbw-focus-outline-offset)}:host .tbw-toolbar-btn.active{background:var(--tbw-focus-background);border-color:var(--tbw-color-accent)}:host .tbw-toolbar-btn:disabled{opacity:.5;cursor:not-allowed}:host .tbw-toolbar-separator{width:1px;height:20px;background:var(--tbw-color-border);margin:0 4px}:host .tbw-shell-body{display:flex;flex:1;min-height:0;overflow:visible}:host .tbw-grid-content{flex:1;min-width:0;min-height:0;display:flex;flex-direction:row;overflow:hidden}:host .tbw-scroll-area{flex:1;min-width:0;min-height:0;display:flex;flex-direction:column;overflow-x:auto;overflow-y:hidden}:host .tbw-tool-panel{width:0;overflow:hidden;background:var(--tbw-tool-panel-bg);border-left:1px solid var(--tbw-tool-panel-border);transition:width var(--tbw-tool-panel-transition);display:flex;flex-direction:column;flex-shrink:0}:host .tbw-tool-panel[data-position=left]{border-left:none;border-right:1px solid var(--tbw-tool-panel-border);order:-1}:host .tbw-tool-panel.open{width:var(--tbw-tool-panel-width)}:host .tbw-tool-panel-header{display:flex;align-items:center;justify-content:space-between;min-height:var(--tbw-tool-panel-header-height);padding:0 12px;border-bottom:1px solid var(--tbw-tool-panel-border);flex-shrink:0}:host .tbw-tool-panel-title{font-weight:600;font-size:13px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}:host .tbw-tool-panel-close{display:inline-flex;align-items:center;justify-content:center;width:24px;height:24px;padding:0;border:none;border-radius:var(--tbw-border-radius);background:transparent;color:var(--tbw-color-fg-muted);cursor:pointer;font-size:14px}:host .tbw-tool-panel-close:hover{background:var(--tbw-color-row-hover);color:var(--tbw-color-fg)}:host .tbw-tool-panel-content{flex:1;overflow:auto;padding:12px}:host .tbw-quick-filter-input{flex:1;max-width:300px;height:28px;padding:0 8px;border:1px solid var(--tbw-color-border);border-radius:var(--tbw-border-radius);background:var(--tbw-color-bg);color:var(--tbw-color-fg);font-size:13px}:host .tbw-quick-filter-input:focus{outline:none;border-color:var(--tbw-color-accent)}:host .tbw-selection-summary{font-size:13px;color:var(--tbw-color-fg-muted);white-space:nowrap}";
1
+ const we = ":root{color-scheme:light dark}:host{--tbw-color-bg: transparent;--tbw-color-panel-bg: light-dark(#eeeeee, #222222);--tbw-color-fg: light-dark(#222222, #eeeeee);--tbw-color-fg-muted: light-dark(#555555, #aaaaaa);--tbw-color-accent: light-dark(#3b82f6, #3b82f6);--tbw-color-accent-fg: light-dark(#ffffff, #000000);--tbw-color-success: light-dark(hsl(122, 39%, 40%), hsl(122, 39%, 49%));--tbw-color-selection: light-dark(#fff7d6, #333333);--tbw-color-row-alt: var(--tbw-color-bg);--tbw-color-row-hover: light-dark(#f0f6ff, #1c1c1c);--tbw-color-header-bg: color-mix(in hsl, var(--tbw-color-panel-bg) 85%, var(--tbw-color-fg));--tbw-color-header-fg: color-mix(in hsl, var(--tbw-color-fg) 75%, var(--tbw-color-panel-bg));--tbw-color-border: light-dark(#d0d0d4, #454545);--tbw-color-border-strong: light-dark(#777777, #adacac);--tbw-color-border-cell: var(--tbw-color-border);--tbw-color-border-header: var(--tbw-color-border);--tbw-color-shadow: light-dark(rgba(0, 0, 0, .1), rgba(0, 0, 0, .3));--tbw-font-family: inherit;--tbw-font-size: inherit;--tbw-font-size-header: var(--tbw-font-size);--tbw-font-weight-header: bold;--tbw-cell-padding-header: 2px 8px;--tbw-cell-padding: 2px 8px;--tbw-cell-padding-input: 2px 6px;--tbw-row-height: 28px;--tbw-header-height: 30px;--tbw-border-radius: 4px;--tbw-border-input: 1px solid var(--tbw-color-border-strong);--tbw-border-header: 1px solid var(--tbw-color-border-header);--tbw-row-divider: 1px solid var(--tbw-color-border-cell);--tbw-row-hover-outline: 0;--tbw-color-active-row-bg: var(--tbw-color-selection);--tbw-active-row-outline: 0;--tbw-focus-outline: 2px solid var(--tbw-color-accent);--tbw-focus-outline-offset: -2px;--tbw-focus-background: rgba(from var(--tbw-color-accent) r g b / 12%);--tbw-range-border-color: var(--tbw-color-accent);--tbw-range-selection-bg: rgba(from var(--tbw-range-border-color) r g b / 12%);--tbw-resize-handle-width: 4px;--tbw-resize-handle-color: transparent;--tbw-resize-handle-color-hover: var(--tbw-color-accent);--tbw-resize-handle-border-radius: 0;--tbw-scrollbar-thumb: var(--tbw-color-border-strong);--tbw-scrollbar-track: var(--tbw-color-bg);--tbw-transition-duration: .12s;--tbw-transition-ease: ease;--tbw-editing-bg: var(--tbw-color-selection);--tbw-editing-border: var(--tbw-border-input, 1px solid var(--tbw-color-border-strong));--tbw-padding-editing-input: var(--tbw-cell-padding-input, 2px 6px);--tbw-font-size-editor: inherit;--tbw-sort-indicator-color: var(--tbw-color-fg-muted);--tbw-sort-indicator-active-color: var(--tbw-color-accent);--tbw-header-text-transform: none;--tbw-header-letter-spacing: normal;--tbw-color-header-separator: var(--tbw-color-border-cell);--tbw-checkbox-size: 16px;--tbw-density-scale: 1}:host{position:relative;display:block;width:100%;height:100%;min-height:0;contain:content;font-family:var(--tbw-font-family);font-size:var(--tbw-font-size);background:var(--tbw-color-bg);color:var(--tbw-color-fg);border:1px solid var(--tbw-color-border);border-radius:var(--tbw-border-radius);overflow:clip;outline:none}:host,:host *{box-sizing:border-box}:host .header{display:block;flex-shrink:0;z-index:var(--tbw-z-layer-header, 30);background:var(--tbw-color-header-bg);overflow:visible}:host .header-group-row{display:grid;grid-template-columns:var(--tbw-column-template);background:var(--tbw-color-header-bg);z-index:var(--tbw-z-layer-header, 30)}:host .header-group-cell{display:flex;align-items:center;justify-content:flex-start;padding:var(--tbw-cell-padding-header, 2px 8px);color:var(--tbw-color-header-group-fg, var(--tbw-color-header-fg));font-weight:var(--tbw-font-weight-header-group, var(--tbw-font-weight-header));justify-content:var(--tbw-align-header-group, var(--tbw-align-header, flex-start))}:host .header-row{display:grid;grid-template-columns:var(--tbw-column-template);color:var(--tbw-color-header-fg);font-size:var(--tbw-font-size-header);min-height:var(--tbw-header-height);border-bottom:var(--tbw-border-header);z-index:var(--tbw-z-layer-header, 30)}:host .header-row>.cell{display:flex;align-items:center;gap:4px;padding:var(--tbw-cell-padding-header, 2px 8px);background-color:var(--tbw-color-header-bg);font-weight:var(--tbw-font-weight-header);border-right:1px solid var(--tbw-color-border-cell);overflow:hidden;min-width:0}:host .header-row>.cell>span:first-child{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}:host .header-row>.cell>span[part~=sort-indicator]{flex-shrink:0}:host .header-row>.cell:last-child{border-right:0}:host .header-group-cell,:host .header-row>.cell.grouped.group-end{border-right:2px solid var(--tbw-color-border)}:host .tbw-grid-root{display:flex;flex-direction:column;height:100%}:host .rows-body-wrapper{flex:1;min-height:0;display:flex;flex-direction:row;width:100%;min-width:fit-content}:host .rows-body{flex:1;min-width:0;min-height:0;display:flex;flex-direction:column;overflow:visible}:host .rows-container{display:flex;flex-direction:row;flex:1;min-height:0;overflow:visible}:host .rows-viewport{flex:1;min-width:0;position:relative;display:block;overflow:clip}:host .faux-vscroll{position:sticky;inset-inline-end:0;flex-shrink:0;width:auto;overflow-y:auto;overflow-x:hidden;z-index:var(--tbw-z-layer-header, 30)}:host .faux-vscroll-spacer{width:1px}:host .rows-viewport .rows{position:absolute;top:0;left:0;min-width:100%;will-change:transform;z-index:var(--tbw-z-layer-rows, 1)}:host .data-grid-row{display:grid;grid-template-columns:var(--tbw-column-template);contain:layout style}:host .data-grid-row:has(.editing){background:var(--tbw-editing-bg)}:host .selecting .data-grid-row>.cell{user-select:none}:host .data-grid-row>.cell:focus-visible{outline:none}:host .data-grid-row>.cell{display:flex;align-items:center;padding:var(--tbw-cell-padding, 2px 8px);border-bottom:var(--tbw-row-divider);min-height:var(--tbw-row-height);border-right:1px solid var(--tbw-color-border-cell);overflow:hidden;min-width:0}:host .data-grid-row>.cell>*{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}:host .data-grid-row>.cell:last-child{border-right:0}:host .data-grid-row>.cell[data-type=boolean]{justify-content:center}:host .data-grid-row>.cell[data-type=boolean] input[type=checkbox]{margin:0;width:var(--tbw-checkbox-size);height:var(--tbw-checkbox-size)}:host .data-grid-row>.cell.editing{overflow:hidden;padding:0}:host .data-grid-row>.cell.editing input:not([type=checkbox]),:host .data-grid-row>.cell.editing select,:host .data-grid-row>.cell.editing textarea{width:100%;height:100%;max-width:100%;flex:1 1 auto;min-width:0;border:var(--tbw-editing-border);padding:var(--tbw-padding-editing-input);font-size:var(--tbw-font-size-editor)}:host .data-grid-row:nth-child(2n){background:var(--tbw-color-row-alt)}:host .data-grid-row:hover{background:var(--tbw-color-row-hover)}:host .sortable{cursor:pointer;user-select:none}:host .resize-handle{position:absolute;top:0;right:calc(var(--tbw-resize-handle-width) / -2);width:var(--tbw-resize-handle-width);height:100%;cursor:e-resize;user-select:none;touch-action:none;z-index:20;background:var(--tbw-resize-handle-color);transition:background .12s ease;border-radius:var(--tbw-resize-handle-border-radius)}:host .resize-handle:hover{background:var(--tbw-resize-handle-color-hover)}:host .cell-focus,:host .row-focus{outline:var(--tbw-focus-outline);outline-offset:var(--tbw-focus-outline-offset)}:host .group-row{display:grid;grid-template-columns:var(--tbw-column-template);background:var(--tbw-color-row-alt);font-weight:500;border-bottom:var(--tbw-row-divider);min-height:var(--tbw-row-height)}:host .group-row .cell{display:flex;align-items:center;padding:var(--tbw-cell-padding, 2px 8px)}:host .group-row .group-toggle{background:none;border:0;cursor:pointer;padding:0 4px 0 0;font:inherit}:host .group-row .group-count{margin-left:4px;opacity:.7}:host .sticky-left,:host .sticky-right{position:sticky;z-index:25}:host .header-row>.cell.sticky-left,:host .header-row>.cell.sticky-right{background:var(--tbw-color-header-bg);z-index:35}:host .data-grid-row>.cell.sticky-left,:host .data-grid-row>.cell.sticky-right{background:var(--tbw-color-panel-bg)}:host .sticky-left{box-shadow:1px 0 0 var(--tbw-color-border)}:host .sticky-right{box-shadow:-1px 0 0 var(--tbw-color-border)}.grid-container{position:relative;width:100%;height:100%}.grid-placeholder{padding:2rem;text-align:center;color:var(--tbw-color-fg);opacity:.6}:host{--tbw-shell-header-height: 44px;--tbw-shell-header-bg: var(--tbw-color-panel-bg);--tbw-shell-header-border: var(--tbw-color-border);--tbw-shell-title-font-size: 14px;--tbw-shell-title-font-weight: 600;--tbw-tool-panel-width: 280px;--tbw-tool-panel-bg: var(--tbw-color-panel-bg);--tbw-tool-panel-border: var(--tbw-color-border);--tbw-tool-panel-header-height: 40px;--tbw-tool-panel-transition: .2s ease-out;--tbw-toolbar-button-size: 32px;--tbw-toolbar-button-gap: 4px}:host .tbw-grid-root.has-shell{display:flex;flex-direction:column;height:100%}:host .tbw-shell-header{display:flex;align-items:center;gap:8px;min-height:var(--tbw-shell-header-height);padding:0 8px;background:var(--tbw-shell-header-bg);border-bottom:1px solid var(--tbw-shell-header-border);flex-shrink:0}:host .tbw-shell-title{font-size:var(--tbw-shell-title-font-size);font-weight:var(--tbw-shell-title-font-weight);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}:host .tbw-shell-content{flex:1;display:flex;align-items:center;gap:12px;min-width:0;overflow:hidden}:host .tbw-shell-toolbar{display:flex;align-items:center;gap:var(--tbw-toolbar-button-gap);flex-shrink:0}:host .tbw-toolbar-btn{display:inline-flex;align-items:center;justify-content:center;width:var(--tbw-toolbar-button-size);height:var(--tbw-toolbar-button-size);padding:0;border:1px solid transparent;border-radius:var(--tbw-border-radius);background:transparent;color:var(--tbw-color-fg);cursor:pointer;font-size:16px;transition:background var(--tbw-transition-duration) var(--tbw-transition-ease),border-color var(--tbw-transition-duration) var(--tbw-transition-ease)}:host .tbw-toolbar-btn:hover{background:var(--tbw-color-row-hover)}:host .tbw-toolbar-btn:focus-visible{outline:var(--tbw-focus-outline);outline-offset:var(--tbw-focus-outline-offset)}:host .tbw-toolbar-btn.active{background:var(--tbw-focus-background);border-color:var(--tbw-color-accent)}:host .tbw-toolbar-btn:disabled{opacity:.5;cursor:not-allowed}:host .tbw-toolbar-separator{width:1px;height:20px;background:var(--tbw-color-border);margin:0 4px}:host .tbw-shell-body{display:flex;flex:1;min-height:0;overflow:visible}:host .tbw-grid-content{flex:1;min-width:0;min-height:0;display:flex;flex-direction:row;overflow:hidden}:host .tbw-scroll-area{flex:1;min-width:0;min-height:0;display:flex;flex-direction:column;overflow-x:auto;overflow-y:hidden}:host .tbw-tool-panel{width:0;overflow:hidden;background:var(--tbw-tool-panel-bg);border-left:1px solid var(--tbw-tool-panel-border);transition:width var(--tbw-tool-panel-transition);display:flex;flex-direction:column;flex-shrink:0}:host .tbw-tool-panel[data-position=left]{border-left:none;border-right:1px solid var(--tbw-tool-panel-border);order:-1}:host .tbw-tool-panel.open{width:var(--tbw-tool-panel-width)}:host .tbw-tool-panel-header{display:flex;align-items:center;justify-content:space-between;min-height:var(--tbw-tool-panel-header-height);padding:0 12px;border-bottom:1px solid var(--tbw-tool-panel-border);flex-shrink:0}:host .tbw-tool-panel-title{font-weight:600;font-size:13px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}:host .tbw-tool-panel-close{display:inline-flex;align-items:center;justify-content:center;width:24px;height:24px;padding:0;border:none;border-radius:var(--tbw-border-radius);background:transparent;color:var(--tbw-color-fg-muted);cursor:pointer;font-size:14px}:host .tbw-tool-panel-close:hover{background:var(--tbw-color-row-hover);color:var(--tbw-color-fg)}:host .tbw-tool-panel-content{flex:1;overflow:auto;padding:12px}:host .tbw-quick-filter-input{flex:1;max-width:300px;height:28px;padding:0 8px;border:1px solid var(--tbw-color-border);border-radius:var(--tbw-border-radius);background:var(--tbw-color-bg);color:var(--tbw-color-fg);font-size:13px}:host .tbw-quick-filter-input:focus{outline:none;border-color:var(--tbw-color-accent)}:host .tbw-selection-summary{font-size:13px;color:var(--tbw-color-fg-muted);white-space:nowrap}";
2
2
  function be(o) {
3
3
  const e = /* @__PURE__ */ new Map();
4
4
  return o.sortState && e.set(o.sortState.field, {
@@ -10,49 +10,49 @@ function ae(o, e) {
10
10
  const t = o._columns, n = be(o);
11
11
  return {
12
12
  columns: t.map((i, s) => {
13
- const r = {
13
+ const l = {
14
14
  field: i.field,
15
15
  order: s,
16
16
  visible: !0
17
17
  // If it's in _columns, it's visible (hidden columns are filtered out)
18
- }, l = i;
19
- l.__renderedWidth !== void 0 ? r.width = l.__renderedWidth : i.width !== void 0 && (r.width = typeof i.width == "string" ? parseFloat(i.width) : i.width);
18
+ }, r = i;
19
+ r.__renderedWidth !== void 0 ? l.width = r.__renderedWidth : i.width !== void 0 && (l.width = typeof i.width == "string" ? parseFloat(i.width) : i.width);
20
20
  const a = n.get(i.field);
21
- a && (r.sort = a);
22
- for (const h of e)
23
- if (h.getColumnState) {
24
- const u = h.getColumnState(i.field);
25
- u && Object.assign(r, u);
21
+ a && (l.sort = a);
22
+ for (const f of e)
23
+ if (f.getColumnState) {
24
+ const p = f.getColumnState(i.field);
25
+ p && Object.assign(l, p);
26
26
  }
27
- return r;
27
+ return l;
28
28
  })
29
29
  };
30
30
  }
31
31
  function ge(o, e, t, n) {
32
32
  if (!e.columns || e.columns.length === 0) return;
33
- const i = new Map(e.columns.map((l) => [l.field, l])), s = t.map((l) => {
34
- const a = i.get(l.field);
35
- if (!a) return l;
36
- const h = { ...l };
37
- return a.width !== void 0 && (h.width = a.width, h.__renderedWidth = a.width), a.visible !== void 0 && (h.hidden = !a.visible), h;
33
+ const i = new Map(e.columns.map((r) => [r.field, r])), s = t.map((r) => {
34
+ const a = i.get(r.field);
35
+ if (!a) return r;
36
+ const f = { ...r };
37
+ return a.width !== void 0 && (f.width = a.width, f.__renderedWidth = a.width), a.visible !== void 0 && (f.hidden = !a.visible), f;
38
38
  });
39
- s.sort((l, a) => {
40
- const h = i.get(l.field)?.order ?? 1 / 0, u = i.get(a.field)?.order ?? 1 / 0;
41
- return h - u;
39
+ s.sort((r, a) => {
40
+ const f = i.get(r.field)?.order ?? 1 / 0, p = i.get(a.field)?.order ?? 1 / 0;
41
+ return f - p;
42
42
  }), o._columns = s;
43
- const r = e.columns.filter((l) => l.sort !== void 0).sort((l, a) => (l.sort?.priority ?? 0) - (a.sort?.priority ?? 0));
44
- if (r.length > 0) {
45
- const l = r[0];
46
- l.sort && (o.sortState = {
47
- field: l.field,
48
- direction: l.sort.direction === "asc" ? 1 : -1
43
+ const l = e.columns.filter((r) => r.sort !== void 0).sort((r, a) => (r.sort?.priority ?? 0) - (a.sort?.priority ?? 0));
44
+ if (l.length > 0) {
45
+ const r = l[0];
46
+ r.sort && (o.sortState = {
47
+ field: r.field,
48
+ direction: r.sort.direction === "asc" ? 1 : -1
49
49
  });
50
50
  } else
51
51
  o.sortState = null;
52
- for (const l of n)
53
- if (l.applyColumnState)
52
+ for (const r of n)
53
+ if (r.applyColumnState)
54
54
  for (const a of e.columns)
55
- l.applyColumnState(a.field, a);
55
+ r.applyColumnState(a.field, a);
56
56
  }
57
57
  function me(o, e, t) {
58
58
  let n = null;
@@ -64,7 +64,7 @@ function me(o, e, t) {
64
64
  }, 100);
65
65
  };
66
66
  }
67
- const O = {
67
+ const M = {
68
68
  STRETCH: "stretch",
69
69
  FIXED: "fixed"
70
70
  };
@@ -74,19 +74,19 @@ function ve(o) {
74
74
  function ce(o, e) {
75
75
  if (e && e.length) {
76
76
  const s = {};
77
- return e.forEach((r) => {
78
- r.type && (s[r.field] = r.type);
77
+ return e.forEach((l) => {
78
+ l.type && (s[l.field] = l.type);
79
79
  }), { columns: e, typeMap: s };
80
80
  }
81
81
  const t = o[0] || {}, n = Object.keys(t).map((s) => {
82
- const r = t[s], l = ve(r);
83
- return { field: s, header: s.charAt(0).toUpperCase() + s.slice(1), type: l };
82
+ const l = t[s], r = ve(l);
83
+ return { field: s, header: s.charAt(0).toUpperCase() + s.slice(1), type: r };
84
84
  }), i = {};
85
85
  return n.forEach((s) => {
86
86
  i[s.field] = s.type || "string";
87
87
  }), { columns: n, typeMap: i };
88
88
  }
89
- const Ce = /{{\s*([^}]+)\s*}}/g, C = "__DG_EMPTY__", ye = /^[\w$. '?+\-*/%:()!<>=,&|]+$/, Ee = /__(proto|defineGetter|defineSetter)|constructor|window|globalThis|global|process|Function|import|eval|Reflect|Proxy|Error|arguments|document|location|cookie|localStorage|sessionStorage|indexedDB|fetch|XMLHttpRequest|WebSocket|Worker|SharedWorker|ServiceWorker|opener|parent|top|frames|self|this\b/, Re = /* @__PURE__ */ new Set([
89
+ const Ce = /{{\s*([^}]+)\s*}}/g, A = "__DG_EMPTY__", ye = /^[\w$. '?+\-*/%:()!<>=,&|]+$/, Ee = /__(proto|defineGetter|defineSetter)|constructor|window|globalThis|global|process|Function|import|eval|Reflect|Proxy|Error|arguments|document|location|cookie|localStorage|sessionStorage|indexedDB|fetch|XMLHttpRequest|WebSocket|Worker|SharedWorker|ServiceWorker|opener|parent|top|frames|self|this\b/, Re = /* @__PURE__ */ new Set([
90
90
  "script",
91
91
  "iframe",
92
92
  "object",
@@ -112,7 +112,7 @@ const Ce = /{{\s*([^}]+)\s*}}/g, C = "__DG_EMPTY__", ye = /^[\w$. '?+\-*/%:()!<>
112
112
  "xmp",
113
113
  "listing"
114
114
  ]), U = /^on\w+$/i, _e = /* @__PURE__ */ new Set(["href", "src", "action", "formaction", "data", "srcdoc", "xlink:href", "poster", "srcset"]), Ae = /^\s*(javascript|vbscript|data|blob):/i;
115
- function N(o) {
115
+ function z(o) {
116
116
  if (!o || typeof o != "string") return "";
117
117
  if (o.indexOf("<") === -1) return o;
118
118
  const e = document.createElement("template");
@@ -127,58 +127,58 @@ function Se(o) {
127
127
  continue;
128
128
  }
129
129
  if ((i === "svg" || n.namespaceURI === "http://www.w3.org/2000/svg") && Array.from(n.attributes).some(
130
- (l) => U.test(l.name) || l.name === "href" || l.name === "xlink:href"
130
+ (r) => U.test(r.name) || r.name === "href" || r.name === "xlink:href"
131
131
  )) {
132
132
  e.push(n);
133
133
  continue;
134
134
  }
135
135
  const s = [];
136
- for (const r of n.attributes) {
137
- const l = r.name.toLowerCase();
138
- if (U.test(l)) {
139
- s.push(r.name);
136
+ for (const l of n.attributes) {
137
+ const r = l.name.toLowerCase();
138
+ if (U.test(r)) {
139
+ s.push(l.name);
140
140
  continue;
141
141
  }
142
- if (_e.has(l) && Ae.test(r.value)) {
143
- s.push(r.name);
142
+ if (_e.has(r) && Ae.test(l.value)) {
143
+ s.push(l.name);
144
144
  continue;
145
145
  }
146
- if (l === "style" && /expression\s*\(|javascript:|behavior\s*:/i.test(r.value)) {
147
- s.push(r.name);
146
+ if (r === "style" && /expression\s*\(|javascript:|behavior\s*:/i.test(l.value)) {
147
+ s.push(l.name);
148
148
  continue;
149
149
  }
150
150
  }
151
- s.forEach((r) => n.removeAttribute(r));
151
+ s.forEach((l) => n.removeAttribute(l));
152
152
  }
153
153
  e.forEach((n) => n.remove());
154
154
  }
155
155
  function de(o, e) {
156
156
  if (!o || o.indexOf("{{") === -1) return o;
157
- const t = [], n = o.replace(Ce, (l, a) => {
158
- const h = xe(a, e);
159
- return t.push({ expr: a.trim(), result: h }), h;
160
- }), i = Te(n), s = t.length && t.every((l) => l.result === "" || l.result === C);
157
+ const t = [], n = o.replace(Ce, (r, a) => {
158
+ const f = xe(a, e);
159
+ return t.push({ expr: a.trim(), result: f }), f;
160
+ }), i = Te(n), s = t.length && t.every((r) => r.result === "" || r.result === A);
161
161
  return /Reflect\.|\bProxy\b|ownKeys\(/.test(o) || s ? "" : i;
162
162
  }
163
163
  function xe(o, e) {
164
- if (o = (o || "").trim(), !o || /\b(Reflect|Proxy|ownKeys)\b/.test(o)) return C;
165
- if (o === "value") return e.value == null ? C : String(e.value);
164
+ if (o = (o || "").trim(), !o || /\b(Reflect|Proxy|ownKeys)\b/.test(o)) return A;
165
+ if (o === "value") return e.value == null ? A : String(e.value);
166
166
  if (o.startsWith("row.") && !/[()?]/.test(o) && !o.includes(":")) {
167
167
  const n = o.slice(4), i = e.row ? e.row[n] : void 0;
168
- return i == null ? C : String(i);
168
+ return i == null ? A : String(i);
169
169
  }
170
- if (o.length > 80 || !ye.test(o) || Ee.test(o)) return C;
170
+ if (o.length > 80 || !ye.test(o) || Ee.test(o)) return A;
171
171
  const t = o.match(/\./g);
172
- if (t && t.length > 1) return C;
172
+ if (t && t.length > 1) return A;
173
173
  try {
174
174
  const i = new Function("value", "row", `return (${o});`)(e.value, e.row), s = i == null ? "" : String(i);
175
- return /Reflect|Proxy|ownKeys/.test(s) ? C : s || C;
175
+ return /Reflect|Proxy|ownKeys/.test(s) ? A : s || A;
176
176
  } catch {
177
- return C;
177
+ return A;
178
178
  }
179
179
  }
180
180
  function Te(o) {
181
- return o && o.replace(new RegExp(C, "g"), "").replace(/Reflect\.[^<>{}\s]+/g, "").replace(/\bProxy\b/g, "").replace(/ownKeys\([^)]*\)/g, "");
181
+ return o && o.replace(new RegExp(A, "g"), "").replace(/Reflect\.[^<>{}\s]+/g, "").replace(/\bProxy\b/g, "").replace(/ownKeys\([^)]*\)/g, "");
182
182
  }
183
183
  function Le(o) {
184
184
  if (/Reflect|Proxy|ownKeys/.test(o.textContent || "")) {
@@ -200,15 +200,15 @@ function ke(o) {
200
200
  return Array.from(o.querySelectorAll("tbw-grid-column")).map((t) => {
201
201
  const n = t.getAttribute("field") || "";
202
202
  if (!n) return null;
203
- const i = t.getAttribute("type") || void 0, r = i && (/* @__PURE__ */ new Set(["number", "string", "date", "boolean", "select", "typeahead"])).has(i) ? i : void 0, l = t.getAttribute("header") || void 0, a = t.hasAttribute("sortable"), h = t.hasAttribute("editable"), u = { field: n, type: r, header: l, sortable: a, editable: h };
204
- t.hasAttribute("resizable") && (u.resizable = !0), t.hasAttribute("sizable") && (u.resizable = !0);
203
+ const i = t.getAttribute("type") || void 0, l = i && (/* @__PURE__ */ new Set(["number", "string", "date", "boolean", "select", "typeahead"])).has(i) ? i : void 0, r = t.getAttribute("header") || void 0, a = t.hasAttribute("sortable"), f = t.hasAttribute("editable"), p = { field: n, type: l, header: r, sortable: a, editable: f };
204
+ t.hasAttribute("resizable") && (p.resizable = !0), t.hasAttribute("sizable") && (p.resizable = !0);
205
205
  const w = t.getAttribute("options");
206
- w && (u.options = w.split(",").map((f) => {
207
- const [b, y] = f.includes(":") ? f.split(":") : [f.trim(), f.trim()];
208
- return { value: b.trim(), label: y?.trim() || b.trim() };
206
+ w && (p.options = w.split(",").map((d) => {
207
+ const [g, m] = d.includes(":") ? d.split(":") : [d.trim(), d.trim()];
208
+ return { value: g.trim(), label: m?.trim() || g.trim() };
209
209
  }));
210
- const c = t.querySelector("tbw-grid-column-view"), d = t.querySelector("tbw-grid-column-editor"), p = t.querySelector("tbw-grid-column-header");
211
- return c && (u.__viewTemplate = c), d && (u.__editorTemplate = d), p && (u.__headerTemplate = p), u;
210
+ const u = t.querySelector("tbw-grid-column-view"), c = t.querySelector("tbw-grid-column-editor"), h = t.querySelector("tbw-grid-column-header");
211
+ return u && (p.__viewTemplate = u), c && (p.__editorTemplate = c), h && (p.__headerTemplate = h), p;
212
212
  }).filter((t) => !!t);
213
213
  }
214
214
  function Pe(o, e) {
@@ -220,8 +220,8 @@ function Pe(o, e) {
220
220
  const n = o.map((i) => {
221
221
  const s = t[i.field];
222
222
  if (!s) return i;
223
- const r = { ...i };
224
- return s.header && !r.header && (r.header = s.header), s.type && !r.type && (r.type = s.type), r.sortable = i.sortable || s.sortable, (i.resizable === !0 || s.resizable === !0) && (r.resizable = !0), r.editable = i.editable || s.editable, s.__viewTemplate && (r.__viewTemplate = s.__viewTemplate), s.__editorTemplate && (r.__editorTemplate = s.__editorTemplate), s.__headerTemplate && (r.__headerTemplate = s.__headerTemplate), delete t[i.field], r;
223
+ const l = { ...i };
224
+ return s.header && !l.header && (l.header = s.header), s.type && !l.type && (l.type = s.type), l.sortable = i.sortable || s.sortable, (i.resizable === !0 || s.resizable === !0) && (l.resizable = !0), l.editable = i.editable || s.editable, s.__viewTemplate && (l.__viewTemplate = s.__viewTemplate), s.__editorTemplate && (l.__editorTemplate = s.__editorTemplate), s.__headerTemplate && (l.__headerTemplate = s.__headerTemplate), delete t[i.field], l;
225
225
  });
226
226
  return Object.keys(t).forEach((i) => n.push(t[i])), n;
227
227
  }
@@ -233,7 +233,7 @@ function B(o, e) {
233
233
  const t = o.getAttribute("part");
234
234
  t ? t.split(/\s+/).includes(e) || o.setAttribute("part", t + " " + e) : o.setAttribute("part", e);
235
235
  }
236
- function Oe(o) {
236
+ function Me(o) {
237
237
  o.__lightDomColumnsCache || (o.__originalColumnNodes = Array.from(
238
238
  o.querySelectorAll("tbw-grid-column")
239
239
  ), o.__lightDomColumnsCache = o.__originalColumnNodes.length ? ke(o) : []);
@@ -244,28 +244,28 @@ function Oe(o) {
244
244
  const { columns: n } = ce(o._rows, t);
245
245
  o._columns = n;
246
246
  }
247
- function Me(o) {
248
- const e = o.effectiveConfig?.fitMode || o.fitMode || O.STRETCH;
249
- if (e !== O.STRETCH && e !== O.FIXED || o.__didInitialAutoSize || !o.isConnected) return;
247
+ function Oe(o) {
248
+ const e = o.effectiveConfig?.fitMode || o.fitMode || M.STRETCH;
249
+ if (e !== M.STRETCH && e !== M.FIXED || o.__didInitialAutoSize || !o.isConnected) return;
250
250
  const t = o.headerRowEl?.children || [];
251
251
  if (!t.length) return;
252
252
  let n = !1;
253
253
  o.visibleColumns.forEach((i, s) => {
254
254
  if (i.width) return;
255
- const r = t[s];
256
- let l = r ? r.scrollWidth : 0;
255
+ const l = t[s];
256
+ let r = l ? l.scrollWidth : 0;
257
257
  for (const a of o.rowPool) {
258
- const h = a.children[s];
259
- if (h) {
260
- const u = h.scrollWidth;
261
- u > l && (l = u);
258
+ const f = a.children[s];
259
+ if (f) {
260
+ const p = f.scrollWidth;
261
+ p > r && (r = p);
262
262
  }
263
263
  }
264
- l > 0 && (i.width = l + 2, i.__autoSized = !0, n = !0);
264
+ r > 0 && (i.width = r + 2, i.__autoSized = !0, n = !0);
265
265
  }), n && he(o), o.__didInitialAutoSize = !0;
266
266
  }
267
267
  function he(o) {
268
- (o.effectiveConfig?.fitMode || o.fitMode || O.STRETCH) === O.STRETCH ? o.gridTemplate = o.visibleColumns.map((t) => {
268
+ (o.effectiveConfig?.fitMode || o.fitMode || M.STRETCH) === M.STRETCH ? o.gridTemplate = o.visibleColumns.map((t) => {
269
269
  if (t.width) return `${t.width}px`;
270
270
  const n = t.minWidth;
271
271
  return n != null ? `minmax(${n}px, 1fr)` : "1fr";
@@ -297,14 +297,14 @@ function De(o) {
297
297
  return (e) => {
298
298
  const t = document.createElement("select");
299
299
  e.column.multi && (t.multiple = !0), (typeof e.column.options == "function" ? e.column.options() : e.column.options || []).forEach((s) => {
300
- const r = document.createElement("option");
301
- r.value = String(s.value), r.textContent = s.label, (e.column.multi && Array.isArray(e.value) && e.value.includes(s.value) || !e.column.multi && e.value === s.value) && (r.selected = !0), t.appendChild(r);
300
+ const l = document.createElement("option");
301
+ l.value = String(s.value), l.textContent = s.label, (e.column.multi && Array.isArray(e.value) && e.value.includes(s.value) || !e.column.multi && e.value === s.value) && (l.selected = !0), t.appendChild(l);
302
302
  });
303
303
  const i = () => {
304
304
  if (e.column.multi) {
305
305
  const s = [];
306
- Array.from(t.selectedOptions).forEach((r) => {
307
- s.push(r.value);
306
+ Array.from(t.selectedOptions).forEach((l) => {
307
+ s.push(l.value);
308
308
  }), e.commit(s);
309
309
  } else
310
310
  e.commit(t.value);
@@ -325,15 +325,15 @@ function De(o) {
325
325
  function He(o, e) {
326
326
  if (o.dispatchKeyDown?.(e))
327
327
  return;
328
- const t = o._rows.length - 1, n = o.visibleColumns.length - 1, i = o.activeEditRows !== void 0 && o.activeEditRows !== -1, r = o.visibleColumns[o.focusCol]?.type, l = e.composedPath ? e.composedPath() : [], a = l && l.length ? l[0] : e.target, h = (u) => {
329
- if (!u) return !1;
330
- const w = u.tagName;
331
- return !!(w === "INPUT" || w === "SELECT" || w === "TEXTAREA" || u.isContentEditable);
328
+ const t = o._rows.length - 1, n = o.visibleColumns.length - 1, i = o.activeEditRows !== void 0 && o.activeEditRows !== -1, l = o.visibleColumns[o.focusCol]?.type, r = e.composedPath ? e.composedPath() : [], a = r && r.length ? r[0] : e.target, f = (p) => {
329
+ if (!p) return !1;
330
+ const w = p.tagName;
331
+ return !!(w === "INPUT" || w === "SELECT" || w === "TEXTAREA" || p.isContentEditable);
332
332
  };
333
- if (!(h(a) && (e.key === "Home" || e.key === "End")) && !(h(a) && (e.key === "ArrowUp" || e.key === "ArrowDown") && a.tagName === "INPUT" && a.type === "number") && !(i && (r === "select" || r === "typeahead") && (e.key === "ArrowDown" || e.key === "ArrowUp"))) {
333
+ if (!(f(a) && (e.key === "Home" || e.key === "End")) && !(f(a) && (e.key === "ArrowUp" || e.key === "ArrowDown") && a.tagName === "INPUT" && a.type === "number") && !(i && (l === "select" || l === "typeahead") && (e.key === "ArrowDown" || e.key === "ArrowUp"))) {
334
334
  switch (e.key) {
335
335
  case "Tab": {
336
- e.preventDefault(), !e.shiftKey ? o.focusCol < n ? o.focusCol += 1 : (typeof o.commitActiveRowEdit == "function" && o.commitActiveRowEdit(), o.focusRow < t && (o.focusRow += 1, o.focusCol = 0)) : o.focusCol > 0 ? o.focusCol -= 1 : o.focusRow > 0 && (typeof o.commitActiveRowEdit == "function" && o.activeEditRows === o.focusRow && o.commitActiveRowEdit(), o.focusRow -= 1, o.focusCol = n), M(o);
336
+ e.preventDefault(), !e.shiftKey ? o.focusCol < n ? o.focusCol += 1 : (typeof o.commitActiveRowEdit == "function" && o.commitActiveRowEdit(), o.focusRow < t && (o.focusRow += 1, o.focusCol = 0)) : o.focusCol > 0 ? o.focusCol -= 1 : o.focusRow > 0 && (typeof o.commitActiveRowEdit == "function" && o.activeEditRows === o.focusRow && o.commitActiveRowEdit(), o.focusRow -= 1, o.focusCol = n), O(o);
337
337
  return;
338
338
  }
339
339
  case "ArrowDown":
@@ -363,17 +363,17 @@ function He(o, e) {
363
363
  case "Enter":
364
364
  return typeof o.beginBulkEdit == "function" ? o.beginBulkEdit(o.focusRow) : o.dispatchEvent(
365
365
  new CustomEvent("activate-cell", { detail: { row: o.focusRow, col: o.focusCol } })
366
- ), M(o);
366
+ ), O(o);
367
367
  default:
368
368
  return;
369
369
  }
370
- M(o);
370
+ O(o);
371
371
  }
372
372
  }
373
- function M(o) {
373
+ function O(o) {
374
374
  if (o.virtualization?.enabled) {
375
- const { rowHeight: i } = o.virtualization, s = o, r = o.focusRow * i;
376
- r < s.scrollTop ? s.scrollTop = r : r + i > s.scrollTop + s.clientHeight && (s.scrollTop = r - s.clientHeight + i);
375
+ const { rowHeight: i } = o.virtualization, s = o, l = o.focusRow * i;
376
+ l < s.scrollTop ? s.scrollTop = l : l + i > s.scrollTop + s.clientHeight && (s.scrollTop = l - s.clientHeight + i);
377
377
  }
378
378
  o.refreshVirtualWindow(!1), Array.from(o.bodyEl.querySelectorAll(".cell-focus")).forEach((i) => i.classList.remove("cell-focus")), Array.from(o.bodyEl.querySelectorAll('[aria-selected="true"]')).forEach((i) => {
379
379
  i.setAttribute("aria-selected", "false");
@@ -383,12 +383,12 @@ function M(o) {
383
383
  const s = o.bodyEl.querySelectorAll(".data-grid-row")[e - t]?.children[o.focusCol];
384
384
  if (s) {
385
385
  if (s.classList.add("cell-focus"), s.setAttribute("aria-selected", "true"), o.activeEditRows !== void 0 && o.activeEditRows !== -1 && s.classList.contains("editing")) {
386
- const r = s.querySelector(
386
+ const l = s.querySelector(
387
387
  'input,select,textarea,[contenteditable="true"],[contenteditable=""],[tabindex]:not([tabindex="-1"])'
388
388
  );
389
- if (r && document.activeElement !== r)
389
+ if (l && document.activeElement !== l)
390
390
  try {
391
- r.focus();
391
+ l.focus();
392
392
  } catch {
393
393
  }
394
394
  } else if (!s.contains(document.activeElement)) {
@@ -406,213 +406,223 @@ function j(o) {
406
406
  o[ze] = void 0, o[Ne] = void 0, o.__hasSpecialColumns = void 0;
407
407
  }
408
408
  function qe(o, e, t, n, i) {
409
- const s = Math.max(0, t - e), r = o.bodyEl, l = o.visibleColumns, a = l.length;
410
- let h = o.__cachedHeaderRowCount;
411
- for (h === void 0 && (h = o.shadowRoot?.querySelector(".header-group-row") ? 2 : 1, o.__cachedHeaderRowCount = h); o.rowPool.length < s; ) {
409
+ const s = Math.max(0, t - e), l = o.bodyEl, r = o.visibleColumns, a = r.length;
410
+ let f = o.__cachedHeaderRowCount;
411
+ for (f === void 0 && (f = o.shadowRoot?.querySelector(".header-group-row") ? 2 : 1, o.__cachedHeaderRowCount = f); o.rowPool.length < s; ) {
412
412
  const w = document.createElement("div");
413
- w.className = "data-grid-row", w.setAttribute("role", "row"), w.addEventListener("click", (c) => Z(o, c, w, !1)), w.addEventListener("dblclick", (c) => Z(o, c, w, !0)), o.rowPool.push(w);
413
+ w.className = "data-grid-row", w.setAttribute("role", "row"), w.addEventListener("click", (u) => Z(o, u, w, !1)), w.addEventListener("dblclick", (u) => Z(o, u, w, !0)), o.rowPool.push(w);
414
414
  }
415
415
  if (o.rowPool.length > s) {
416
416
  for (let w = s; w < o.rowPool.length; w++) {
417
- const c = o.rowPool[w];
418
- c.parentNode === r && c.remove();
417
+ const u = o.rowPool[w];
418
+ u.parentNode === l && u.remove();
419
419
  }
420
420
  o.rowPool.length = s;
421
421
  }
422
- const u = i && o.__hasRenderRowPlugins !== !1;
422
+ const p = i && o.__hasRenderRowPlugins !== !1;
423
423
  for (let w = 0; w < s; w++) {
424
- const c = e + w, d = o._rows[c], p = o.rowPool[w];
425
- if (p.setAttribute("aria-rowindex", String(c + h + 1)), u && i(d, p, c)) {
426
- p.__epoch = n, p.__rowDataRef = d, p.parentNode !== r && r.appendChild(p);
424
+ const u = e + w, c = o._rows[u], h = o.rowPool[w];
425
+ if (h.setAttribute("aria-rowindex", String(u + f + 1)), p && i(c, h, u)) {
426
+ h.__epoch = n, h.__rowDataRef = c, h.parentNode !== l && l.appendChild(h);
427
427
  continue;
428
428
  }
429
- const f = p.__epoch, b = p.__rowDataRef, y = p.children.length, T = f === n && y === a, L = b !== d;
429
+ const d = h.__epoch, g = h.__rowDataRef, m = h.children.length, R = d === n && m === a, E = g !== c;
430
430
  let _ = !1;
431
- if (T && L) {
432
- for (let E = 0; E < a; E++)
433
- if (l[E].externalView && !p.querySelector(`.cell[data-col="${E}"] [data-external-view]`)) {
431
+ if (R && E) {
432
+ for (let S = 0; S < a; S++)
433
+ if (r[S].externalView && !h.querySelector(`.cell[data-col="${S}"] [data-external-view]`)) {
434
434
  _ = !0;
435
435
  break;
436
436
  }
437
437
  }
438
- !T || _ ? (p.__isCustomRow && (p.className = "data-grid-row", p.setAttribute("role", "row"), p.__isCustomRow = !1), F(o, p, d, c), p.__epoch = n, p.__rowDataRef = d) : L ? (Y(o, p, d, c), p.__rowDataRef = d) : Y(o, p, d, c);
439
- const g = o._changedRowIndices.has(c), m = p.classList.contains("changed");
440
- g !== m && p.classList.toggle("changed", g), p.parentNode !== r && r.appendChild(p);
438
+ !R || _ ? (h.__isCustomRow && (h.className = "data-grid-row", h.setAttribute("role", "row"), h.__isCustomRow = !1), F(o, h, c, u), h.__epoch = n, h.__rowDataRef = c) : E ? (Y(o, h, c, u), h.__rowDataRef = c) : Y(o, h, c, u);
439
+ const b = o._changedRowIndices.has(u), v = h.classList.contains("changed");
440
+ b !== v && h.classList.toggle("changed", b), h.parentNode !== l && l.appendChild(h);
441
441
  }
442
442
  }
443
443
  function Y(o, e, t, n) {
444
- const i = e.children, s = o.visibleColumns, r = s.length, l = i.length, a = r < l ? r : l;
445
- let h = o.__hasSpecialColumns;
446
- if (h === void 0) {
447
- h = !1;
448
- for (let w = 0; w < r; w++) {
449
- const c = s[w];
450
- if (c.__viewTemplate || c.__compiledView || c.viewRenderer || c.externalView || c.format || c.type === "date" || c.type === "boolean") {
451
- h = !0;
444
+ const i = e.children, s = o.visibleColumns, l = s.length, r = i.length, a = l < r ? l : r, f = o.focusRow, p = o.focusCol;
445
+ let w = o.__hasSpecialColumns;
446
+ if (w === void 0) {
447
+ w = !1;
448
+ for (let c = 0; c < l; c++) {
449
+ const h = s[c];
450
+ if (h.__viewTemplate || h.__compiledView || h.viewRenderer || h.externalView || h.format || h.type === "date" || h.type === "boolean") {
451
+ w = !0;
452
452
  break;
453
453
  }
454
454
  }
455
- o.__hasSpecialColumns = h;
455
+ o.__hasSpecialColumns = w;
456
456
  }
457
457
  const u = String(n);
458
- if (!h) {
459
- for (let w = 0; w < a; w++) {
460
- const c = i[w], d = t[s[w].field];
461
- c.textContent = d == null ? "" : String(d), c.getAttribute("data-row") !== u && c.setAttribute("data-row", u);
458
+ if (!w) {
459
+ for (let c = 0; c < a; c++) {
460
+ const h = i[c], d = t[s[c].field];
461
+ h.textContent = d == null ? "" : String(d), h.getAttribute("data-row") !== u && h.setAttribute("data-row", u);
462
+ const g = f === n && p === c, m = h.classList.contains("cell-focus");
463
+ g !== m && (h.classList.toggle("cell-focus", g), h.setAttribute("aria-selected", String(g)));
462
464
  }
463
465
  return;
464
466
  }
465
- for (let w = 0; w < a; w++)
466
- if (s[w].externalView && !i[w].querySelector("[data-external-view]")) {
467
+ for (let c = 0; c < a; c++)
468
+ if (s[c].externalView && !i[c].querySelector("[data-external-view]")) {
467
469
  F(o, e, t, n);
468
470
  return;
469
471
  }
470
- for (let w = 0; w < a; w++) {
471
- const c = s[w], d = i[w];
472
- if (d.getAttribute("data-row") !== u && d.setAttribute("data-row", u), d.classList.contains("editing") || c.__viewTemplate || c.__compiledView || c.viewRenderer || c.externalView)
472
+ for (let c = 0; c < a; c++) {
473
+ const h = s[c], d = i[c];
474
+ d.getAttribute("data-row") !== u && d.setAttribute("data-row", u);
475
+ const g = f === n && p === c, m = d.classList.contains("cell-focus");
476
+ if (g !== m && (d.classList.toggle("cell-focus", g), d.setAttribute("aria-selected", String(g))), d.classList.contains("editing")) continue;
477
+ if (h.viewRenderer) {
478
+ const E = t[h.field], _ = h.viewRenderer({ row: t, value: E, field: h.field, column: h });
479
+ typeof _ == "string" ? d.innerHTML = z(_) : _ ? (d.innerHTML = "", d.appendChild(_)) : d.textContent = E == null ? "" : String(E);
480
+ continue;
481
+ }
482
+ if (h.__viewTemplate || h.__compiledView || h.externalView)
473
483
  continue;
474
- const p = t[c.field];
475
- let f;
476
- if (c.format)
484
+ const C = t[h.field];
485
+ let R;
486
+ if (h.format)
477
487
  try {
478
- const b = c.format(p, t);
479
- f = b == null ? "" : String(b);
488
+ const E = h.format(C, t);
489
+ R = E == null ? "" : String(E);
480
490
  } catch {
481
- f = p == null ? "" : String(p);
491
+ R = C == null ? "" : String(C);
482
492
  }
483
- else if (c.type === "date")
484
- if (p == null || p === "")
485
- f = "";
486
- else if (p instanceof Date)
487
- f = isNaN(p.getTime()) ? "" : p.toLocaleDateString();
493
+ else if (h.type === "date")
494
+ if (C == null || C === "")
495
+ R = "";
496
+ else if (C instanceof Date)
497
+ R = isNaN(C.getTime()) ? "" : C.toLocaleDateString();
488
498
  else {
489
- const b = new Date(p);
490
- f = isNaN(b.getTime()) ? "" : b.toLocaleDateString();
499
+ const E = new Date(C);
500
+ R = isNaN(E.getTime()) ? "" : E.toLocaleDateString();
491
501
  }
492
- else c.type === "boolean" ? (f = p ? "🗹" : "☐", d.setAttribute("aria-checked", String(!!p))) : f = p == null ? "" : String(p);
493
- d.textContent = f;
502
+ else h.type === "boolean" ? (R = C ? "🗹" : "☐", d.setAttribute("aria-checked", String(!!C))) : R = C == null ? "" : String(C);
503
+ d.textContent = R;
494
504
  }
495
505
  }
496
506
  function F(o, e, t, n) {
497
507
  e.innerHTML = "";
498
- const i = o.visibleColumns, s = i.length, r = o.focusRow, l = o.focusCol, a = o.effectiveConfig?.editOn || o.editOn, h = o, u = document.createDocumentFragment();
508
+ const i = o.visibleColumns, s = i.length, l = o.focusRow, r = o.focusCol, a = o.effectiveConfig?.editOn || o.editOn, f = o, p = document.createDocumentFragment();
499
509
  for (let w = 0; w < s; w++) {
500
- const c = i[w], d = document.createElement("div");
501
- d.className = "cell", B(d, "cell"), c.type !== "boolean" && d.setAttribute("role", "gridcell"), d.setAttribute("data-col", String(w)), d.setAttribute("data-row", String(n)), d.setAttribute("aria-colindex", String(w + 1)), c.type && d.setAttribute("data-type", c.type);
502
- const p = c.sticky;
503
- p === "left" ? d.classList.add("sticky-left") : p === "right" && d.classList.add("sticky-right");
504
- let f = t[c.field];
505
- const b = c.format;
506
- if (b)
510
+ const u = i[w], c = document.createElement("div");
511
+ c.className = "cell", B(c, "cell"), u.type !== "boolean" && c.setAttribute("role", "gridcell"), c.setAttribute("data-col", String(w)), c.setAttribute("data-row", String(n)), c.setAttribute("aria-colindex", String(w + 1)), u.type && c.setAttribute("data-type", u.type);
512
+ const h = u.sticky;
513
+ h === "left" ? c.classList.add("sticky-left") : h === "right" && c.classList.add("sticky-right");
514
+ let d = t[u.field];
515
+ const g = u.format;
516
+ if (g)
507
517
  try {
508
- f = b(f, t);
518
+ d = g(d, t);
509
519
  } catch {
510
520
  }
511
- const y = c.__compiledView, S = c.__viewTemplate, T = c.viewRenderer, L = c.externalView;
521
+ const m = u.__compiledView, C = u.__viewTemplate, R = u.viewRenderer, E = u.externalView;
512
522
  let _ = !1;
513
- if (T) {
514
- const g = T({ row: t, value: f, field: c.field, column: c });
515
- typeof g == "string" ? (d.innerHTML = N(g), _ = !0) : g ? d.appendChild(g) : d.textContent = f == null ? "" : String(f);
516
- } else if (L) {
517
- const g = L, m = document.createElement("div");
518
- m.setAttribute("data-external-view", ""), m.setAttribute("data-field", c.field), d.appendChild(m);
519
- const E = { row: t, value: f, field: c.field, column: c };
520
- if (g.mount)
523
+ if (R) {
524
+ const b = R({ row: t, value: d, field: u.field, column: u });
525
+ typeof b == "string" ? (c.innerHTML = z(b), _ = !0) : b ? c.appendChild(b) : c.textContent = d == null ? "" : String(d);
526
+ } else if (E) {
527
+ const b = E, v = document.createElement("div");
528
+ v.setAttribute("data-external-view", ""), v.setAttribute("data-field", u.field), c.appendChild(v);
529
+ const S = { row: t, value: d, field: u.field, column: u };
530
+ if (b.mount)
521
531
  try {
522
- g.mount({ placeholder: m, context: E, spec: g });
532
+ b.mount({ placeholder: v, context: S, spec: b });
523
533
  } catch {
524
534
  }
525
535
  else
526
536
  queueMicrotask(() => {
527
537
  try {
528
- h.dispatchEvent(
538
+ f.dispatchEvent(
529
539
  new CustomEvent("mount-external-view", {
530
540
  bubbles: !0,
531
541
  composed: !0,
532
- detail: { placeholder: m, spec: g, context: E }
542
+ detail: { placeholder: v, spec: b, context: S }
533
543
  })
534
544
  );
535
545
  } catch {
536
546
  }
537
547
  });
538
- m.setAttribute("data-mounted", "");
539
- } else if (y) {
540
- const g = y({ row: t, value: f, field: c.field, column: c }), m = y.__blocked;
541
- d.innerHTML = m ? "" : N(g), _ = !0, m && (d.textContent = "", d.setAttribute("data-blocked-template", ""));
542
- } else if (S) {
543
- const g = S.innerHTML;
544
- /Reflect\.|\bProxy\b|ownKeys\(/.test(g) ? (d.textContent = "", d.setAttribute("data-blocked-template", "")) : (d.innerHTML = N(de(g, { row: t, value: f })), _ = !0);
545
- } else if (c.type === "date")
546
- if (f == null || f === "")
547
- d.textContent = "";
548
+ v.setAttribute("data-mounted", "");
549
+ } else if (m) {
550
+ const b = m({ row: t, value: d, field: u.field, column: u }), v = m.__blocked;
551
+ c.innerHTML = v ? "" : z(b), _ = !0, v && (c.textContent = "", c.setAttribute("data-blocked-template", ""));
552
+ } else if (C) {
553
+ const b = C.innerHTML;
554
+ /Reflect\.|\bProxy\b|ownKeys\(/.test(b) ? (c.textContent = "", c.setAttribute("data-blocked-template", "")) : (c.innerHTML = z(de(b, { row: t, value: d })), _ = !0);
555
+ } else if (u.type === "date")
556
+ if (d == null || d === "")
557
+ c.textContent = "";
548
558
  else {
549
- let g = null;
550
- if (f instanceof Date) g = f;
551
- else if (typeof f == "number" || typeof f == "string") {
552
- const m = new Date(f);
553
- isNaN(m.getTime()) || (g = m);
559
+ let b = null;
560
+ if (d instanceof Date) b = d;
561
+ else if (typeof d == "number" || typeof d == "string") {
562
+ const v = new Date(d);
563
+ isNaN(v.getTime()) || (b = v);
554
564
  }
555
- d.textContent = g ? g.toLocaleDateString() : "";
565
+ c.textContent = b ? b.toLocaleDateString() : "";
556
566
  }
557
- else if (c.type === "boolean") {
558
- const g = !!f;
559
- d.innerHTML = g ? "&#x1F5F9;" : "&#9744;", d.setAttribute("role", "checkbox"), d.setAttribute("aria-checked", String(g)), d.setAttribute("aria-label", String(g));
567
+ else if (u.type === "boolean") {
568
+ const b = !!d;
569
+ c.innerHTML = b ? "&#x1F5F9;" : "&#9744;", c.setAttribute("role", "checkbox"), c.setAttribute("aria-checked", String(b)), c.setAttribute("aria-label", String(b));
560
570
  } else
561
- d.textContent = f == null ? "" : String(f);
571
+ c.textContent = d == null ? "" : String(d);
562
572
  if (_) {
563
- Le(d);
564
- const g = d.textContent || "";
565
- /Proxy|Reflect\.ownKeys/.test(g) && (d.textContent = g.replace(/Proxy|Reflect\.ownKeys/g, "").trim(), /Proxy|Reflect\.ownKeys/.test(d.textContent || "") && (d.textContent = ""));
566
- }
567
- d.hasAttribute("data-blocked-template") && (d.textContent || "").trim().length && (d.textContent = ""), c.editable ? (d.tabIndex = 0, d.addEventListener("mousedown", () => {
568
- o.focusRow = n, o.focusCol = w, M(o);
569
- }), a === "click" ? d.addEventListener("click", (g) => {
570
- d.classList.contains("editing") || (g.stopPropagation(), o.focusRow = n, o.focusCol = w, x(o, t, n, c, d));
571
- }) : d.addEventListener("dblclick", (g) => {
572
- g.stopPropagation(), A(o, n, t);
573
- const m = o.findRenderedRowElement?.(n);
574
- if (m) {
575
- const E = m.children;
576
- for (let k = 0; k < E.length; k++) {
573
+ Le(c);
574
+ const b = c.textContent || "";
575
+ /Proxy|Reflect\.ownKeys/.test(b) && (c.textContent = b.replace(/Proxy|Reflect\.ownKeys/g, "").trim(), /Proxy|Reflect\.ownKeys/.test(c.textContent || "") && (c.textContent = ""));
576
+ }
577
+ c.hasAttribute("data-blocked-template") && (c.textContent || "").trim().length && (c.textContent = ""), u.editable ? (c.tabIndex = 0, c.addEventListener("mousedown", () => {
578
+ o.focusRow = n, o.focusCol = w, O(o);
579
+ }), a === "click" ? c.addEventListener("click", (b) => {
580
+ c.classList.contains("editing") || (b.stopPropagation(), o.focusRow = n, o.focusCol = w, L(o, t, n, u, c));
581
+ }) : c.addEventListener("dblclick", (b) => {
582
+ b.stopPropagation(), T(o, n, t);
583
+ const v = o.findRenderedRowElement?.(n);
584
+ if (v) {
585
+ const S = v.children;
586
+ for (let k = 0; k < S.length; k++) {
577
587
  const D = o.visibleColumns[k];
578
- D && D.editable && x(o, t, n, D, E[k]);
588
+ D && D.editable && L(o, t, n, D, S[k]);
579
589
  }
580
590
  }
581
- }), d.addEventListener("keydown", (g) => {
582
- if ((c.type === "select" || c.type === "typeahead") && !d.classList.contains("editing") && g.key === "Enter") {
583
- g.preventDefault(), o.activeEditRows !== n && A(o, n, t), x(o, t, n, c, d), setTimeout(() => {
584
- const m = d.querySelector("select");
591
+ }), c.addEventListener("keydown", (b) => {
592
+ if ((u.type === "select" || u.type === "typeahead") && !c.classList.contains("editing") && b.key === "Enter") {
593
+ b.preventDefault(), o.activeEditRows !== n && T(o, n, t), L(o, t, n, u, c), setTimeout(() => {
594
+ const v = c.querySelector("select");
585
595
  try {
586
- m?.showPicker?.();
596
+ v?.showPicker?.();
587
597
  } catch {
588
598
  }
589
- m?.focus();
599
+ v?.focus();
590
600
  }, 0);
591
601
  return;
592
602
  }
593
- if (c.type === "boolean" && g.key === " " && !d.classList.contains("editing")) {
594
- g.preventDefault(), o.activeEditRows !== n && A(o, n, t);
595
- const m = !t[c.field];
596
- $(o, n, c, m, t), d.innerHTML = m ? "&#x1F5F9;" : "&#9744;", d.setAttribute("aria-label", String(!!m));
603
+ if (u.type === "boolean" && b.key === " " && !c.classList.contains("editing")) {
604
+ b.preventDefault(), o.activeEditRows !== n && T(o, n, t);
605
+ const v = !t[u.field];
606
+ $(o, n, u, v, t), c.innerHTML = v ? "&#x1F5F9;" : "&#9744;", c.setAttribute("aria-label", String(!!v));
597
607
  return;
598
608
  }
599
- if (g.key === "Enter" && !d.classList.contains("editing")) {
600
- g.preventDefault(), o.focusRow = n, o.focusCol = w, typeof o.beginBulkEdit == "function" ? o.beginBulkEdit(n) : x(o, t, n, c, d);
609
+ if (b.key === "Enter" && !c.classList.contains("editing")) {
610
+ b.preventDefault(), o.focusRow = n, o.focusCol = w, typeof o.beginBulkEdit == "function" ? o.beginBulkEdit(n) : L(o, t, n, u, c);
601
611
  return;
602
612
  }
603
- if (g.key === "F2" && !d.classList.contains("editing")) {
604
- g.preventDefault(), x(o, t, n, c, d);
613
+ if (b.key === "F2" && !c.classList.contains("editing")) {
614
+ b.preventDefault(), L(o, t, n, u, c);
605
615
  return;
606
616
  }
607
- })) : c.type === "boolean" && (d.hasAttribute("tabindex") || (d.tabIndex = 0), d.addEventListener("keydown", (g) => {
608
- if (g.key === " ") {
609
- g.preventDefault();
610
- const m = !t[c.field];
611
- o.activeEditRows !== n && A(o, n, t), $(o, n, c, m, t), d.innerHTML = m ? "&#x1F5F9;" : "&#9744;", d.setAttribute("role", "checkbox"), d.setAttribute("aria-checked", String(!!m)), d.setAttribute("aria-label", String(!!m));
617
+ })) : u.type === "boolean" && (c.hasAttribute("tabindex") || (c.tabIndex = 0), c.addEventListener("keydown", (b) => {
618
+ if (b.key === " ") {
619
+ b.preventDefault();
620
+ const v = !t[u.field];
621
+ o.activeEditRows !== n && T(o, n, t), $(o, n, u, v, t), c.innerHTML = v ? "&#x1F5F9;" : "&#9744;", c.setAttribute("role", "checkbox"), c.setAttribute("aria-checked", String(!!v)), c.setAttribute("aria-label", String(!!v));
612
622
  }
613
- })), r === n && l === w ? d.setAttribute("aria-selected", "true") : d.setAttribute("aria-selected", "false"), u.appendChild(d);
623
+ })), l === n && r === w ? c.setAttribute("aria-selected", "true") : c.setAttribute("aria-selected", "false"), p.appendChild(c);
614
624
  }
615
- e.appendChild(u);
625
+ e.appendChild(p);
616
626
  }
617
627
  function Z(o, e, t, n) {
618
628
  if (e.target?.closest(".resize-handle")) return;
@@ -620,57 +630,57 @@ function Z(o, e, t, n) {
620
630
  if (!i) return;
621
631
  const s = Number(i.getAttribute("data-row"));
622
632
  if (isNaN(s)) return;
623
- const r = o._rows[s];
624
- if (!r) return;
625
- const l = e.target?.closest(".cell[data-col]");
626
- if (l) {
627
- const h = Number(l.getAttribute("data-col"));
628
- if (!isNaN(h)) {
629
- if (o.dispatchCellClick?.(e, s, h, l))
633
+ const l = o._rows[s];
634
+ if (!l) return;
635
+ const r = e.target?.closest(".cell[data-col]");
636
+ if (r) {
637
+ const f = Number(r.getAttribute("data-col"));
638
+ if (!isNaN(f)) {
639
+ if (o.dispatchCellClick?.(e, s, f, r))
630
640
  return;
631
- o.focusRow = s, o.focusCol = h, M(o);
641
+ o.focusRow = s, o.focusCol = f, O(o);
632
642
  }
633
643
  }
634
644
  if (t.querySelector(".cell.editing")) {
635
- const h = t.querySelectorAll(".cell.editing");
645
+ const f = t.querySelectorAll(".cell.editing");
636
646
  if (!n) return;
637
- h.forEach((u) => u.classList.remove("editing"));
647
+ f.forEach((p) => p.classList.remove("editing"));
638
648
  }
639
649
  const a = o.effectiveConfig?.editOn || o.editOn || "doubleClick";
640
- if (a === "click" || a === "doubleClick" && n) A(o, s, r);
650
+ if (a === "click" || a === "doubleClick" && n) T(o, s, l);
641
651
  else return;
642
- Array.from(t.children).forEach((h, u) => {
643
- const w = o.visibleColumns[u];
644
- w && w.editable && x(o, r, s, w, h);
645
- }), l && queueMicrotask(() => {
646
- const h = t.querySelector(`.cell[data-col="${o.focusCol}"]`);
647
- if (h?.classList.contains("editing")) {
648
- const u = h.querySelector(
652
+ Array.from(t.children).forEach((f, p) => {
653
+ const w = o.visibleColumns[p];
654
+ w && w.editable && L(o, l, s, w, f);
655
+ }), r && queueMicrotask(() => {
656
+ const f = t.querySelector(`.cell[data-col="${o.focusCol}"]`);
657
+ if (f?.classList.contains("editing")) {
658
+ const p = f.querySelector(
649
659
  'input,select,textarea,[contenteditable="true"],[contenteditable=""],[tabindex]:not([tabindex="-1"])'
650
660
  );
651
661
  try {
652
- u?.focus();
662
+ p?.focus();
653
663
  } catch {
654
664
  }
655
665
  }
656
666
  });
657
667
  }
658
- function A(o, e, t) {
668
+ function T(o, e, t) {
659
669
  o.activeEditRows !== e && (o.rowEditSnapshots.set(e, { ...t }), o.activeEditRows = e);
660
670
  }
661
671
  function Ie(o, e, t) {
662
672
  if (o.activeEditRows !== e) return;
663
673
  const n = o.rowEditSnapshots.get(e), i = o._rows[e];
664
674
  if (t && n && i)
665
- Object.keys(n).forEach((r) => i[r] = n[r]), o._changedRowIndices.delete(e);
675
+ Object.keys(n).forEach((l) => i[l] = n[l]), o._changedRowIndices.delete(e);
666
676
  else if (!t) {
667
- const r = o._changedRowIndices.has(e);
677
+ const l = o._changedRowIndices.has(e);
668
678
  o.dispatchEvent(
669
679
  new CustomEvent("row-commit", {
670
680
  detail: {
671
681
  rowIndex: e,
672
682
  row: i,
673
- changed: r,
683
+ changed: l,
674
684
  changedRows: o.changedRows,
675
685
  changedRowIndices: o.changedRowIndices
676
686
  }
@@ -682,13 +692,13 @@ function Ie(o, e, t) {
682
692
  s && (F(o, s, o._rows[e], e), o._changedRowIndices.has(e) ? s.classList.add("changed") : s.classList.remove("changed")), t && queueMicrotask(() => {
683
693
  try {
684
694
  o.focus();
685
- const r = o.focusRow, l = o.focusCol, a = o.findRenderedRowElement?.(r);
695
+ const l = o.focusRow, r = o.focusCol, a = o.findRenderedRowElement?.(l);
686
696
  if (a) {
687
697
  Array.from(o.bodyEl.querySelectorAll(".cell-focus")).forEach(
688
- (u) => u.classList.remove("cell-focus")
698
+ (p) => p.classList.remove("cell-focus")
689
699
  );
690
- const h = a.querySelector(`.cell[data-row="${r}"][data-col="${l}"]`);
691
- h && h.classList.add("cell-focus");
700
+ const f = a.querySelector(`.cell[data-row="${l}"][data-col="${r}"]`);
701
+ f && f.classList.add("cell-focus");
692
702
  }
693
703
  } catch {
694
704
  }
@@ -698,7 +708,7 @@ function $(o, e, t, n, i) {
698
708
  const s = t.field;
699
709
  if (i[s] === n) return;
700
710
  i[s] = n;
701
- const l = !o._changedRowIndices.has(e);
711
+ const r = !o._changedRowIndices.has(e);
702
712
  o._changedRowIndices.add(e);
703
713
  const a = o.findRenderedRowElement?.(e);
704
714
  a && a.classList.add("changed"), o.dispatchEvent(
@@ -710,68 +720,68 @@ function $(o, e, t, n, i) {
710
720
  rowIndex: e,
711
721
  changedRows: o.changedRows,
712
722
  changedRowIndices: o.changedRowIndices,
713
- firstTimeForRow: l
723
+ firstTimeForRow: r
714
724
  }
715
725
  })
716
726
  );
717
727
  }
718
- function x(o, e, t, n, i) {
719
- if (!n.editable || (o.activeEditRows !== t && A(o, t, e), i.classList.contains("editing"))) return;
728
+ function L(o, e, t, n, i) {
729
+ if (!n.editable || (o.activeEditRows !== t && T(o, t, e), i.classList.contains("editing"))) return;
720
730
  const s = e[n.field];
721
731
  i.classList.add("editing");
722
- const r = (c) => {
723
- $(o, t, n, c, e);
724
- }, l = () => {
732
+ const l = (u) => {
733
+ $(o, t, n, u, e);
734
+ }, r = () => {
725
735
  e[n.field] = s;
726
- const c = i.querySelector("input,textarea,select");
727
- c && (typeof HTMLInputElement < "u" && c instanceof HTMLInputElement && c.type === "checkbox" ? c.checked = !!s : "value" in c && (c.value = s ?? ""));
736
+ const u = i.querySelector("input,textarea,select");
737
+ u && (typeof HTMLInputElement < "u" && u instanceof HTMLInputElement && u.type === "checkbox" ? u.checked = !!s : "value" in u && (u.value = s ?? ""));
728
738
  }, a = document.createElement("div");
729
739
  a.style.display = "contents", i.innerHTML = "", i.appendChild(a);
730
- const h = n.__editorTemplate, u = n.editor || (h ? "template" : De(n)), w = s;
731
- if (u === "template" && h) {
732
- const c = h.cloneNode(!0), d = n.__compiledEditor;
733
- d ? c.innerHTML = d({ row: e, value: s, field: n.field, column: n }) : c.querySelectorAll("*").forEach((f) => {
734
- f.childNodes.length === 1 && f.firstChild?.nodeType === Node.TEXT_NODE && (f.textContent = f.textContent?.replace(/{{\s*value\s*}}/g, s == null ? "" : String(s)).replace(/{{\s*row\.([a-zA-Z0-9_]+)\s*}}/g, (b, y) => {
735
- const S = e[y];
736
- return S == null ? "" : String(S);
740
+ const f = n.__editorTemplate, p = n.editor || (f ? "template" : De(n)), w = s;
741
+ if (p === "template" && f) {
742
+ const u = f.cloneNode(!0), c = n.__compiledEditor;
743
+ c ? u.innerHTML = c({ row: e, value: s, field: n.field, column: n }) : u.querySelectorAll("*").forEach((d) => {
744
+ d.childNodes.length === 1 && d.firstChild?.nodeType === Node.TEXT_NODE && (d.textContent = d.textContent?.replace(/{{\s*value\s*}}/g, s == null ? "" : String(s)).replace(/{{\s*row\.([a-zA-Z0-9_]+)\s*}}/g, (g, m) => {
745
+ const C = e[m];
746
+ return C == null ? "" : String(C);
737
747
  }) || "");
738
748
  });
739
- const p = c.querySelector("input,textarea,select");
740
- if (p) {
741
- const f = typeof HTMLInputElement < "u";
742
- f && p instanceof HTMLInputElement && p.type === "checkbox" ? p.checked = !!s : "value" in p && (p.value = s ?? ""), p.addEventListener("blur", () => {
743
- const b = f && p instanceof HTMLInputElement && p.type === "checkbox" ? p.checked : p.value;
744
- r(b);
745
- }), p.addEventListener("keydown", (b) => {
746
- if (b.key === "Enter") {
747
- const y = f && p instanceof HTMLInputElement && p.type === "checkbox" ? p.checked : p.value;
748
- r(y);
749
+ const h = u.querySelector("input,textarea,select");
750
+ if (h) {
751
+ const d = typeof HTMLInputElement < "u";
752
+ d && h instanceof HTMLInputElement && h.type === "checkbox" ? h.checked = !!s : "value" in h && (h.value = s ?? ""), h.addEventListener("blur", () => {
753
+ const g = d && h instanceof HTMLInputElement && h.type === "checkbox" ? h.checked : h.value;
754
+ l(g);
755
+ }), h.addEventListener("keydown", (g) => {
756
+ if (g.key === "Enter") {
757
+ const m = d && h instanceof HTMLInputElement && h.type === "checkbox" ? h.checked : h.value;
758
+ l(m);
749
759
  }
750
- b.key === "Escape" && l();
751
- }), f && p instanceof HTMLInputElement && p.type === "checkbox" && p.addEventListener("change", () => {
752
- const b = p.checked;
753
- r(b);
754
- }), setTimeout(() => p.focus(), 0);
755
- }
756
- a.appendChild(c);
757
- } else if (typeof u == "string") {
758
- const c = document.createElement(u);
759
- c.value = w, c.addEventListener("change", () => r(c.value)), a.appendChild(c);
760
- } else if (typeof u == "function") {
761
- const c = u({ row: e, value: w, field: n.field, column: n, commit: r, cancel: l });
762
- typeof c == "string" ? a.innerHTML = c : a.appendChild(c);
763
- } else if (u && typeof u == "object") {
764
- const c = document.createElement("div");
765
- c.setAttribute("data-external-editor", ""), c.setAttribute("data-field", n.field), a.appendChild(c);
766
- const d = { row: e, value: w, field: n.field, column: n, commit: r, cancel: l };
767
- if (u.mount)
760
+ g.key === "Escape" && r();
761
+ }), d && h instanceof HTMLInputElement && h.type === "checkbox" && h.addEventListener("change", () => {
762
+ const g = h.checked;
763
+ l(g);
764
+ }), setTimeout(() => h.focus(), 0);
765
+ }
766
+ a.appendChild(u);
767
+ } else if (typeof p == "string") {
768
+ const u = document.createElement(p);
769
+ u.value = w, u.addEventListener("change", () => l(u.value)), a.appendChild(u);
770
+ } else if (typeof p == "function") {
771
+ const u = p({ row: e, value: w, field: n.field, column: n, commit: l, cancel: r });
772
+ typeof u == "string" ? a.innerHTML = u : a.appendChild(u);
773
+ } else if (p && typeof p == "object") {
774
+ const u = document.createElement("div");
775
+ u.setAttribute("data-external-editor", ""), u.setAttribute("data-field", n.field), a.appendChild(u);
776
+ const c = { row: e, value: w, field: n.field, column: n, commit: l, cancel: r };
777
+ if (p.mount)
768
778
  try {
769
- u.mount({ placeholder: c, context: d, spec: u });
779
+ p.mount({ placeholder: u, context: c, spec: p });
770
780
  } catch {
771
781
  }
772
782
  else
773
783
  o.dispatchEvent(
774
- new CustomEvent("mount-external-editor", { detail: { placeholder: c, spec: u, context: d } })
784
+ new CustomEvent("mount-external-editor", { detail: { placeholder: u, spec: p, context: c } })
775
785
  );
776
786
  }
777
787
  }
@@ -796,17 +806,17 @@ function V(o) {
796
806
  const i = document.createElement("div");
797
807
  i.className = "cell", B(i, "header-cell"), i.setAttribute("role", "columnheader"), i.setAttribute("aria-colindex", String(n + 1)), i.setAttribute("data-field", t.field), i.setAttribute("data-col", String(n)), t.sticky === "left" ? i.classList.add("sticky-left") : t.sticky === "right" && i.classList.add("sticky-right");
798
808
  const s = t.__headerTemplate;
799
- if (s) Array.from(s.childNodes).forEach((r) => i.appendChild(r.cloneNode(!0)));
809
+ if (s) Array.from(s.childNodes).forEach((l) => i.appendChild(l.cloneNode(!0)));
800
810
  else {
801
- const r = t.header || t.field, l = document.createElement("span");
802
- l.textContent = r, i.appendChild(l);
811
+ const l = t.header || t.field, r = document.createElement("span");
812
+ r.textContent = l, i.appendChild(r);
803
813
  }
804
814
  if (t.sortable) {
805
815
  i.classList.add("sortable"), i.tabIndex = 0;
806
- const r = document.createElement("span");
807
- B(r, "sort-indicator"), r.style.opacity = "0.6";
808
- const l = o.sortState?.field === t.field ? o.sortState.direction : 0;
809
- r.textContent = l === 1 ? "▲" : l === -1 ? "▼" : "⇅", i.appendChild(r), i.setAttribute("aria-sort", l === 0 ? "none" : l === 1 ? "ascending" : "descending"), i.addEventListener("click", (a) => {
816
+ const l = document.createElement("span");
817
+ B(l, "sort-indicator"), l.style.opacity = "0.6";
818
+ const r = o.sortState?.field === t.field ? o.sortState.direction : 0;
819
+ l.textContent = r === 1 ? "▲" : r === -1 ? "▼" : "⇅", i.appendChild(l), i.setAttribute("aria-sort", r === 0 ? "none" : r === 1 ? "ascending" : "descending"), i.addEventListener("click", (a) => {
810
820
  o.resizeController?.isResizing || o.dispatchHeaderClick?.(a, n, i) || J(o, t);
811
821
  }), i.addEventListener("keydown", (a) => {
812
822
  if (a.key === "Enter" || a.key === " ") {
@@ -817,10 +827,10 @@ function V(o) {
817
827
  }
818
828
  if (t.resizable) {
819
829
  t.sticky || (i.style.position = "relative");
820
- const r = document.createElement("div");
821
- r.className = "resize-handle", r.setAttribute("aria-hidden", "true"), r.addEventListener("mousedown", (l) => {
822
- l.stopPropagation(), l.preventDefault(), o.resizeController.start(l, n, i);
823
- }), i.appendChild(r);
830
+ const l = document.createElement("div");
831
+ l.className = "resize-handle", l.setAttribute("aria-hidden", "true"), l.addEventListener("mousedown", (r) => {
832
+ r.stopPropagation(), r.preventDefault(), o.resizeController.start(r, n, i);
833
+ }), i.appendChild(l);
824
834
  }
825
835
  e.appendChild(i);
826
836
  });
@@ -839,31 +849,31 @@ function Be(o) {
839
849
  let e = null, t = null, n = null, i = null;
840
850
  const s = (a) => {
841
851
  if (!e) return;
842
- const h = a.clientX - e.startX, u = Math.max(40, e.startWidth + h), w = o.visibleColumns[e.colIndex];
843
- w.width = u, w.__userResized = !0, w.__renderedWidth = u, t == null && (t = requestAnimationFrame(() => {
852
+ const f = a.clientX - e.startX, p = Math.max(40, e.startWidth + f), w = o.visibleColumns[e.colIndex];
853
+ w.width = p, w.__userResized = !0, w.__renderedWidth = p, t == null && (t = requestAnimationFrame(() => {
844
854
  t = null, o.updateTemplate?.();
845
855
  })), o.dispatchEvent(
846
- new CustomEvent("column-resize", { detail: { field: w.field, width: u } })
856
+ new CustomEvent("column-resize", { detail: { field: w.field, width: p } })
847
857
  );
848
858
  };
849
- let r = !1;
850
- const l = () => {
859
+ let l = !1;
860
+ const r = () => {
851
861
  const a = e !== null;
852
- a && (r = !0, requestAnimationFrame(() => {
853
- r = !1;
854
- })), window.removeEventListener("mousemove", s), window.removeEventListener("mouseup", l), n !== null && (document.documentElement.style.cursor = n, n = null), i !== null && (document.body.style.userSelect = i, i = null), e = null, a && o.requestStateChange && o.requestStateChange();
862
+ a && (l = !0, requestAnimationFrame(() => {
863
+ l = !1;
864
+ })), window.removeEventListener("mousemove", s), window.removeEventListener("mouseup", r), n !== null && (document.documentElement.style.cursor = n, n = null), i !== null && (document.body.style.userSelect = i, i = null), e = null, a && o.requestStateChange && o.requestStateChange();
855
865
  };
856
866
  return {
857
867
  get isResizing() {
858
- return e !== null || r;
868
+ return e !== null || l;
859
869
  },
860
- start(a, h, u) {
870
+ start(a, f, p) {
861
871
  a.preventDefault();
862
- const w = u.getBoundingClientRect();
863
- e = { startX: a.clientX, colIndex: h, startWidth: w.width }, window.addEventListener("mousemove", s), window.addEventListener("mouseup", l), n === null && (n = document.documentElement.style.cursor), document.documentElement.style.cursor = "e-resize", i === null && (i = document.body.style.userSelect), document.body.style.userSelect = "none";
872
+ const w = p.getBoundingClientRect();
873
+ e = { startX: a.clientX, colIndex: f, startWidth: w.width }, window.addEventListener("mousemove", s), window.addEventListener("mouseup", r), n === null && (n = document.documentElement.style.cursor), document.documentElement.style.cursor = "e-resize", i === null && (i = document.body.style.userSelect), document.body.style.userSelect = "none";
864
874
  },
865
875
  dispose() {
866
- l();
876
+ r();
867
877
  }
868
878
  };
869
879
  }
@@ -884,20 +894,20 @@ function Ke(o, e) {
884
894
  return !!(o?.header?.title || o?.header?.toolbarButtons?.length || e.toolPanels.size > 0 || e.headerContents.size > 0 || e.toolbarButtons.size > 0 || e.lightDomButtons.length > 0 || e.lightDomHeaderContent.length > 0);
885
895
  }
886
896
  function We(o, e) {
887
- const t = o?.header?.title ?? "", n = !!t, i = o?.header?.toolbarButtons ?? [], s = i.length > 0, r = e.toolbarButtons.size > 0, l = e.lightDomButtons.length > 0, a = e.toolPanels.size > 0, u = (s || r || l) && a, w = [...i].sort((f, b) => (f.order ?? 100) - (b.order ?? 100)), c = [...e.toolbarButtons.values()].sort((f, b) => (f.order ?? 100) - (b.order ?? 100)), d = [...e.toolPanels.values()].sort((f, b) => (f.order ?? 100) - (b.order ?? 100));
888
- let p = "";
889
- for (const f of w)
890
- f.icon && f.action && (p += `<button class="tbw-toolbar-btn" data-btn="${f.id}" title="${f.label}" aria-label="${f.label}"${f.disabled ? " disabled" : ""}>${f.icon}</button>`);
891
- for (const f of c)
892
- f.icon && f.action && (p += `<button class="tbw-toolbar-btn" data-btn="${f.id}" title="${f.label}" aria-label="${f.label}"${f.disabled ? " disabled" : ""}>${f.icon}</button>`);
893
- for (const f of w)
894
- (f.element || f.render) && (p += `<div class="tbw-toolbar-btn-slot" data-btn-slot="${f.id}"></div>`);
895
- for (const f of c)
896
- (f.element || f.render) && (p += `<div class="tbw-toolbar-btn-slot" data-btn-slot="${f.id}"></div>`);
897
- l && (p += '<slot name="toolbar"></slot>'), u && (p += '<div class="tbw-toolbar-separator"></div>');
898
- for (const f of d) {
899
- const b = e.activePanel === f.id;
900
- p += `<button class="tbw-toolbar-btn${b ? " active" : ""}" data-panel="${f.id}" title="${f.tooltip ?? f.title}" aria-label="${f.tooltip ?? f.title}" aria-pressed="${b}" aria-controls="tbw-panel-${f.id}">${f.icon}</button>`;
897
+ const t = o?.header?.title ?? "", n = !!t, i = o?.header?.toolbarButtons ?? [], s = i.length > 0, l = e.toolbarButtons.size > 0, r = e.lightDomButtons.length > 0, a = e.toolPanels.size > 0, p = (s || l || r) && a, w = [...i].sort((d, g) => (d.order ?? 100) - (g.order ?? 100)), u = [...e.toolbarButtons.values()].sort((d, g) => (d.order ?? 100) - (g.order ?? 100)), c = [...e.toolPanels.values()].sort((d, g) => (d.order ?? 100) - (g.order ?? 100));
898
+ let h = "";
899
+ for (const d of w)
900
+ d.icon && d.action && (h += `<button class="tbw-toolbar-btn" data-btn="${d.id}" title="${d.label}" aria-label="${d.label}"${d.disabled ? " disabled" : ""}>${d.icon}</button>`);
901
+ for (const d of u)
902
+ d.icon && d.action && (h += `<button class="tbw-toolbar-btn" data-btn="${d.id}" title="${d.label}" aria-label="${d.label}"${d.disabled ? " disabled" : ""}>${d.icon}</button>`);
903
+ for (const d of w)
904
+ (d.element || d.render) && (h += `<div class="tbw-toolbar-btn-slot" data-btn-slot="${d.id}"></div>`);
905
+ for (const d of u)
906
+ (d.element || d.render) && (h += `<div class="tbw-toolbar-btn-slot" data-btn-slot="${d.id}"></div>`);
907
+ r && (h += '<slot name="toolbar"></slot>'), p && (h += '<div class="tbw-toolbar-separator"></div>');
908
+ for (const d of c) {
909
+ const g = e.activePanel === d.id;
910
+ h += `<button class="tbw-toolbar-btn${g ? " active" : ""}" data-panel="${d.id}" title="${d.tooltip ?? d.title}" aria-label="${d.tooltip ?? d.title}" aria-pressed="${g}" aria-controls="tbw-panel-${d.id}">${d.icon}</button>`;
901
911
  }
902
912
  return `
903
913
  <div class="tbw-shell-header" part="shell-header" role="banner">
@@ -906,16 +916,16 @@ function We(o, e) {
906
916
  <slot name="header-content"></slot>
907
917
  </div>
908
918
  <div class="tbw-shell-toolbar" part="shell-toolbar" role="toolbar" aria-label="Grid tools">
909
- ${p}
919
+ ${h}
910
920
  </div>
911
921
  </div>
912
922
  `;
913
923
  }
914
924
  function Fe(o, e, t) {
915
- const n = o?.toolPanel?.position ?? "right", i = e.toolPanels.size > 0, s = e.activePanel !== null, r = e.activePanel ? e.toolPanels.get(e.activePanel) : null, l = i ? `
916
- <aside class="tbw-tool-panel${s ? " open" : ""}" part="tool-panel" data-position="${n}" role="complementary" aria-label="${r?.title ?? "Tool panel"}" id="tbw-panel-${e.activePanel ?? "closed"}">
925
+ const n = o?.toolPanel?.position ?? "right", i = e.toolPanels.size > 0, s = e.activePanel !== null, l = e.activePanel ? e.toolPanels.get(e.activePanel) : null, r = i ? `
926
+ <aside class="tbw-tool-panel${s ? " open" : ""}" part="tool-panel" data-position="${n}" role="complementary" aria-label="${l?.title ?? "Tool panel"}" id="tbw-panel-${e.activePanel ?? "closed"}">
917
927
  <div class="tbw-tool-panel-header">
918
- <span class="tbw-tool-panel-title">${r?.title ?? ""}</span>
928
+ <span class="tbw-tool-panel-title">${l?.title ?? ""}</span>
919
929
  <button class="tbw-tool-panel-close" aria-label="Close panel">✕</button>
920
930
  </div>
921
931
  <div class="tbw-tool-panel-content" role="region"></div>
@@ -923,7 +933,7 @@ function Fe(o, e, t) {
923
933
  ` : "";
924
934
  return n === "left" ? `
925
935
  <div class="tbw-shell-body">
926
- ${l}
936
+ ${r}
927
937
  <div class="tbw-grid-content">
928
938
  ${t}
929
939
  </div>
@@ -933,7 +943,7 @@ function Fe(o, e, t) {
933
943
  <div class="tbw-grid-content">
934
944
  ${t}
935
945
  </div>
936
- ${l}
946
+ ${r}
937
947
  </div>
938
948
  `;
939
949
  }
@@ -942,30 +952,30 @@ function ee(o, e) {
942
952
  if (!t) return;
943
953
  t.style.display = "none";
944
954
  const n = t.querySelectorAll("tbw-grid-header-content");
945
- e.lightDomHeaderContent = Array.from(n), e.lightDomHeaderContent.forEach((s, r) => {
955
+ e.lightDomHeaderContent = Array.from(n), e.lightDomHeaderContent.forEach((s, l) => {
946
956
  s.setAttribute("slot", "header-content");
947
957
  });
948
958
  const i = t.querySelectorAll("tbw-grid-tool-button");
949
- e.lightDomButtons = Array.from(i), e.lightDomButtons.sort((s, r) => {
950
- const l = parseInt(s.getAttribute("order") ?? "100", 10), a = parseInt(r.getAttribute("order") ?? "100", 10);
951
- return l - a;
959
+ e.lightDomButtons = Array.from(i), e.lightDomButtons.sort((s, l) => {
960
+ const r = parseInt(s.getAttribute("order") ?? "100", 10), a = parseInt(l.getAttribute("order") ?? "100", 10);
961
+ return r - a;
952
962
  }), e.lightDomButtons.forEach((s) => {
953
963
  s.setAttribute("slot", "toolbar");
954
964
  });
955
965
  }
956
966
  function Ve(o, e, t, n) {
957
967
  const i = o.querySelector(".tbw-shell-toolbar");
958
- i && i.addEventListener("click", (r) => {
959
- const l = r.target, a = l.closest("[data-panel]");
968
+ i && i.addEventListener("click", (l) => {
969
+ const r = l.target, a = r.closest("[data-panel]");
960
970
  if (a) {
961
- const u = a.getAttribute("data-panel");
962
- u && n.onPanelToggle(u);
971
+ const p = a.getAttribute("data-panel");
972
+ p && n.onPanelToggle(p);
963
973
  return;
964
974
  }
965
- const h = l.closest("[data-btn]");
966
- if (h) {
967
- const u = h.getAttribute("data-btn");
968
- u && n.onToolbarButtonClick(u);
975
+ const f = r.closest("[data-btn]");
976
+ if (f) {
977
+ const p = f.getAttribute("data-btn");
978
+ p && n.onToolbarButtonClick(p);
969
979
  }
970
980
  });
971
981
  const s = o.querySelector(".tbw-tool-panel-close");
@@ -978,25 +988,25 @@ function Ge(o, e, t) {
978
988
  for (const i of n) {
979
989
  const s = o.querySelector(`[data-btn-slot="${i.id}"]`);
980
990
  if (!s) continue;
981
- const r = t.toolbarButtonCleanups.get(i.id);
982
- if (r && (r(), t.toolbarButtonCleanups.delete(i.id)), i.element)
991
+ const l = t.toolbarButtonCleanups.get(i.id);
992
+ if (l && (l(), t.toolbarButtonCleanups.delete(i.id)), i.element)
983
993
  s.appendChild(i.element);
984
994
  else if (i.render) {
985
- const l = i.render(s);
986
- l && t.toolbarButtonCleanups.set(i.id, l);
995
+ const r = i.render(s);
996
+ r && t.toolbarButtonCleanups.set(i.id, r);
987
997
  }
988
998
  }
989
999
  }
990
1000
  function te(o, e) {
991
1001
  const t = o.querySelector(".tbw-shell-content");
992
1002
  if (!t) return;
993
- const n = [...e.headerContents.values()].sort((s, r) => (s.order ?? 100) - (r.order ?? 100)), i = t.querySelector('slot[name="header-content"]');
1003
+ const n = [...e.headerContents.values()].sort((s, l) => (s.order ?? 100) - (l.order ?? 100)), i = t.querySelector('slot[name="header-content"]');
994
1004
  for (const s of n) {
995
- const r = e.headerContentCleanups.get(s.id);
996
- r && (r(), e.headerContentCleanups.delete(s.id));
997
- let l = t.querySelector(`[data-header-content="${s.id}"]`);
998
- l || (l = document.createElement("div"), l.setAttribute("data-header-content", s.id), i ? t.insertBefore(l, i) : t.appendChild(l));
999
- const a = s.render(l);
1005
+ const l = e.headerContentCleanups.get(s.id);
1006
+ l && (l(), e.headerContentCleanups.delete(s.id));
1007
+ let r = t.querySelector(`[data-header-content="${s.id}"]`);
1008
+ r || (r = document.createElement("div"), r.setAttribute("data-header-content", s.id), i ? t.insertBefore(r, i) : t.appendChild(r));
1009
+ const a = s.render(r);
1000
1010
  a && e.headerContentCleanups.set(s.id, a);
1001
1011
  }
1002
1012
  }
@@ -1194,6 +1204,14 @@ class Ye {
1194
1204
  for (const e of this.plugins)
1195
1205
  e.afterRender?.();
1196
1206
  }
1207
+ /**
1208
+ * Execute onScrollRender hook on all plugins.
1209
+ * Called after scroll-triggered row rendering for lightweight visual state updates.
1210
+ */
1211
+ onScrollRender() {
1212
+ for (const e of this.plugins)
1213
+ e.onScrollRender?.();
1214
+ }
1197
1215
  /**
1198
1216
  * Execute renderRow hook on all plugins.
1199
1217
  * Returns true if any plugin handled the row.
@@ -1321,44 +1339,45 @@ class Ye {
1321
1339
  class q extends HTMLElement {
1322
1340
  // TODO: Rename to 'data-grid' when migration is complete
1323
1341
  static tagName = "tbw-grid";
1324
- #t;
1325
- #S = !1;
1342
+ #o;
1343
+ #i = !1;
1326
1344
  // ---------------- Ready Promise ----------------
1327
- #D;
1328
1345
  #H;
1346
+ #z;
1329
1347
  // ================== INPUT PROPERTIES ==================
1330
1348
  // These backing fields store raw user input. They are merged into
1331
1349
  // #effectiveConfig by #mergeEffectiveConfig(). Never read directly
1332
1350
  // for rendering logic - always use effectiveConfig or derived state.
1333
- #s = [];
1351
+ #l = [];
1334
1352
  #r;
1335
- #b;
1336
- #v;
1337
- #C;
1353
+ #p;
1354
+ #g;
1355
+ #m;
1338
1356
  // ================== SINGLE SOURCE OF TRUTH ==================
1339
1357
  // All input sources converge here. This is the canonical config
1340
1358
  // that all rendering and logic should read from.
1341
1359
  #n = {};
1342
- #h = !1;
1343
- #x = 0;
1344
- #y = null;
1345
- #E = !1;
1360
+ #f = !1;
1361
+ #T = 0;
1362
+ #v = null;
1363
+ #C = !1;
1346
1364
  // Cached flag for plugin scroll handlers
1347
- #T;
1365
+ #L;
1348
1366
  // Cached hook to avoid closures
1349
- #u;
1350
- #f;
1351
- #R = !1;
1352
- #p;
1353
- #w;
1367
+ #y = !1;
1368
+ #E = null;
1369
+ #R = null;
1370
+ #_ = null;
1371
+ #A = null;
1372
+ #a;
1354
1373
  // ---------------- Plugin System ----------------
1355
- #o;
1374
+ #t;
1356
1375
  // ---------------- Column State ----------------
1357
- #L;
1358
- #c;
1376
+ #k;
1377
+ #h;
1359
1378
  // ---------------- Shell State ----------------
1360
1379
  #e = $e();
1361
- #l = !1;
1380
+ #c = !1;
1362
1381
  // ================== DERIVED STATE ==================
1363
1382
  // _rows: result of applying plugin processRows hooks
1364
1383
  _rows = [];
@@ -1418,43 +1437,43 @@ class q extends HTMLElement {
1418
1437
  return this._rows;
1419
1438
  }
1420
1439
  set rows(e) {
1421
- const t = this.#s;
1422
- this.#s = e, t !== e && this.#j();
1440
+ const t = this.#l;
1441
+ this.#l = e, t !== e && this.#Y();
1423
1442
  }
1424
1443
  /**
1425
1444
  * Get the original unfiltered/unprocessed rows.
1426
1445
  * Use this when you need access to all source data regardless of active filters.
1427
1446
  */
1428
1447
  get sourceRows() {
1429
- return this.#s;
1448
+ return this.#l;
1430
1449
  }
1431
1450
  get columns() {
1432
1451
  return [...this._columns];
1433
1452
  }
1434
1453
  set columns(e) {
1435
1454
  const t = this.#r;
1436
- this.#r = e, t !== e && this.#Y();
1455
+ this.#r = e, t !== e && this.#Z();
1437
1456
  }
1438
1457
  get gridConfig() {
1439
1458
  return this.#n;
1440
1459
  }
1441
1460
  set gridConfig(e) {
1442
- const t = this.#b;
1443
- this.#b = e, t !== e && this.#Z();
1461
+ const t = this.#p;
1462
+ this.#p = e, t !== e && this.#J();
1444
1463
  }
1445
1464
  get fitMode() {
1446
1465
  return this.#n.fitMode ?? "stretch";
1447
1466
  }
1448
1467
  set fitMode(e) {
1449
- const t = this.#v;
1450
- this.#v = e, t !== e && this.#U();
1468
+ const t = this.#g;
1469
+ this.#g = e, t !== e && this.#X();
1451
1470
  }
1452
1471
  get editOn() {
1453
1472
  return this.#n.editOn;
1454
1473
  }
1455
1474
  set editOn(e) {
1456
- const t = this.#C;
1457
- this.#C = e, t !== e && this.#X();
1475
+ const t = this.#m;
1476
+ this.#m = e, t !== e && this.#j();
1458
1477
  }
1459
1478
  // Effective config accessor for internal modules and plugins
1460
1479
  // Returns the merged config (single source of truth) before plugin processing
@@ -1462,12 +1481,22 @@ class q extends HTMLElement {
1462
1481
  get effectiveConfig() {
1463
1482
  return this.#n;
1464
1483
  }
1484
+ /**
1485
+ * Get the disconnect signal for event listener cleanup.
1486
+ * This signal is aborted when the grid disconnects from the DOM.
1487
+ * Plugins and internal code can use this for automatic listener cleanup.
1488
+ * @example
1489
+ * element.addEventListener('click', handler, { signal: this.grid.disconnectSignal });
1490
+ */
1491
+ get disconnectSignal() {
1492
+ return this.#a || (this.#a = new AbortController()), this.#a.signal;
1493
+ }
1465
1494
  constructor() {
1466
- super(), this.#t = this.attachShadow({ mode: "open" }), this.#W(), this.#D = new Promise((e) => this.#H = e);
1495
+ super(), this.#o = this.attachShadow({ mode: "open" }), this.#F(), this.#H = new Promise((e) => this.#z = e);
1467
1496
  }
1468
- #W() {
1497
+ #F() {
1469
1498
  const e = new CSSStyleSheet();
1470
- e.replaceSync(we), this.#t.adoptedStyleSheets = [e];
1499
+ e.replaceSync(we), this.#o.adoptedStyleSheets = [e];
1471
1500
  }
1472
1501
  // ---------------- Plugin System ----------------
1473
1502
  /**
@@ -1475,14 +1504,14 @@ class q extends HTMLElement {
1475
1504
  * Used by plugins for inter-plugin communication.
1476
1505
  */
1477
1506
  getPlugin(e) {
1478
- return this.#o?.getPlugin(e);
1507
+ return this.#t?.getPlugin(e);
1479
1508
  }
1480
1509
  /**
1481
1510
  * Get a plugin instance by its name.
1482
1511
  * Used for loose coupling between plugins (avoids static imports).
1483
1512
  */
1484
1513
  getPluginByName(e) {
1485
- return this.#o?.getPluginByName(e);
1514
+ return this.#t?.getPluginByName(e);
1486
1515
  }
1487
1516
  /**
1488
1517
  * Request a full re-render of the grid.
@@ -1490,7 +1519,7 @@ class q extends HTMLElement {
1490
1519
  * Note: This does NOT reset plugin state - just re-processes rows/columns and renders.
1491
1520
  */
1492
1521
  requestRender() {
1493
- this.#A(), this.#k(), this.#_(), this.updateTemplate(), this.refreshVirtualWindow(!0);
1522
+ this.#x(), this.#P(), this.#S(), this.updateTemplate(), this.refreshVirtualWindow(!0);
1494
1523
  }
1495
1524
  /**
1496
1525
  * Request a lightweight style update without rebuilding DOM.
@@ -1498,186 +1527,217 @@ class q extends HTMLElement {
1498
1527
  * This runs all plugin afterRender hooks without rebuilding row/column DOM.
1499
1528
  */
1500
1529
  requestAfterRender() {
1501
- this.#g();
1530
+ this.#w();
1502
1531
  }
1503
1532
  /**
1504
1533
  * Initialize plugin system with instances from config.
1505
1534
  * Plugins are class instances passed in gridConfig.plugins[].
1506
1535
  */
1507
- #z() {
1508
- this.#o = new Ye(this);
1536
+ #N() {
1537
+ this.#t = new Ye(this);
1509
1538
  const e = this.#n?.plugins, t = Array.isArray(e) ? e : [];
1510
- this.#o.attachAll(t);
1539
+ this.#t.attachAll(t);
1511
1540
  }
1512
1541
  /**
1513
1542
  * Inject all plugin styles into the shadow DOM.
1514
1543
  * Must be called after #render() since innerHTML wipes existing content.
1515
1544
  */
1516
- #N() {
1517
- const e = this.#o?.getAllStyles() ?? "";
1545
+ #q() {
1546
+ const e = this.#t?.getAllStyles() ?? "";
1518
1547
  if (e) {
1519
1548
  const t = document.createElement("style");
1520
- t.setAttribute("data-plugin", "all"), t.textContent = e, this.#t.appendChild(t);
1549
+ t.setAttribute("data-plugin", "all"), t.textContent = e, this.#o.appendChild(t);
1521
1550
  }
1522
1551
  }
1523
1552
  /**
1524
1553
  * Update plugins when grid config changes.
1525
1554
  * With class-based plugins, we need to detach old and attach new.
1526
1555
  */
1527
- #q() {
1528
- this.#o && this.#o.detachAll(), this.#z(), this.#N(), this.#E = this.#o?.getAll().some((e) => e.onScroll) ?? !1;
1556
+ #I() {
1557
+ this.#t && this.#t.detachAll(), this.#N(), this.#q(), this.#C = this.#t?.getAll().some((e) => e.onScroll) ?? !1;
1529
1558
  }
1530
1559
  /**
1531
1560
  * Clean up plugin states when grid disconnects.
1532
1561
  */
1533
- #F() {
1534
- this.#o?.detachAll();
1562
+ #V() {
1563
+ this.#t?.detachAll();
1535
1564
  }
1536
1565
  /**
1537
1566
  * Collect tool panels and header content from all plugins.
1538
1567
  * Called after plugins are attached but before render.
1539
1568
  */
1540
- #V() {
1541
- if (!this.#o) return;
1542
- const e = this.#o.getToolPanels();
1569
+ #G() {
1570
+ if (!this.#t) return;
1571
+ const e = this.#t.getToolPanels();
1543
1572
  for (const { panel: n } of e)
1544
1573
  this.#e.toolPanels.has(n.id) || this.#e.toolPanels.set(n.id, n);
1545
- const t = this.#o.getHeaderContents();
1574
+ const t = this.#t.getHeaderContents();
1546
1575
  for (const { content: n } of t)
1547
1576
  this.#e.headerContents.has(n.id) || this.#e.headerContents.set(n.id, n);
1548
1577
  }
1549
1578
  // ---------------- Lifecycle ----------------
1550
1579
  connectedCallback() {
1551
- this.hasAttribute("tabindex") || (this.tabIndex = 0), this._rows = Array.isArray(this.#s) ? [...this.#s] : [], this.#d(), this.#z(), this.#V(), this.#S || (this.#K(), this.#N(), this.#S = !0), this.#I();
1580
+ this.hasAttribute("tabindex") || (this.tabIndex = 0), this._rows = Array.isArray(this.#l) ? [...this.#l] : [], this.#a?.abort(), this.#a = new AbortController(), this.#u(), this.#N(), this.#G(), this.#i || (this.#W(), this.#q(), this.#i = !0), this.#B();
1552
1581
  }
1553
1582
  disconnectedCallback() {
1554
- this.#F(), je(this.#e), this.#l = !1, this.#u && (document.removeEventListener("keydown", this.#u, !0), this.#u = void 0), this.#f && (document.removeEventListener("mousedown", this.#f, !1), this.#f = void 0), this.#p && (document.removeEventListener("mousemove", this.#p), this.#p = void 0), this.#w && (document.removeEventListener("mouseup", this.#w), this.#w = void 0), this.resizeController && this.resizeController.dispose(), this.#h = !1;
1583
+ this.#V(), je(this.#e), this.#c = !1, this.#a && (this.#a.abort(), this.#a = void 0), this.resizeController && this.resizeController.dispose(), this.#f = !1;
1555
1584
  }
1556
- #I() {
1557
- const t = this.#t.querySelector(".tbw-grid-content") ?? this.#t.querySelector(".tbw-grid-root");
1558
- if (this.headerRowEl = t?.querySelector(".header-row"), this.virtualization.totalHeightEl = t?.querySelector(".faux-vscroll-spacer"), this.virtualization.viewportEl = t?.querySelector(".rows-viewport"), this.bodyEl = t?.querySelector(".rows"), this.#l) {
1559
- te(this.#t, this.#e), Ge(this.#t, this.#n?.shell, this.#e);
1560
- const s = this.#n?.shell?.toolPanel?.defaultOpen;
1561
- s && this.#e.toolPanels.has(s) && this.openToolPanel(s);
1562
- }
1563
- this.setAttribute("data-upgraded", ""), this.hasAttribute("role") || this.setAttribute("role", "grid"), this.#h = !0, this.#a(), this.addEventListener("keydown", (s) => He(this, s)), this.#u || (this.#u = (s) => {
1564
- s.key === "Escape" && this.activeEditRows !== -1 && this.#O(this.activeEditRows, !0);
1565
- }, document.addEventListener("keydown", this.#u, !0)), this.#f || (this.#f = (s) => {
1566
- if (this.activeEditRows === -1) return;
1567
- const r = this.findRenderedRowElement(this.activeEditRows);
1568
- !r || (s.composedPath && s.composedPath() || []).includes(r) || this.#O(this.activeEditRows, !1);
1569
- }, document.addEventListener("mousedown", this.#f, !1));
1570
- const n = t?.querySelector(".faux-vscroll"), i = t?.querySelector(".rows");
1571
- if (this.virtualization.container = n ?? this, this.#E = this.#o?.getAll().some((s) => s.onScroll) ?? !1, n && i) {
1572
- n.addEventListener(
1585
+ #B() {
1586
+ const t = this.#o.querySelector(".tbw-grid-content") ?? this.#o.querySelector(".tbw-grid-root");
1587
+ if (this.headerRowEl = t?.querySelector(".header-row"), this.virtualization.totalHeightEl = t?.querySelector(".faux-vscroll-spacer"), this.virtualization.viewportEl = t?.querySelector(".rows-viewport"), this.bodyEl = t?.querySelector(".rows"), this.#c) {
1588
+ te(this.#o, this.#e), Ge(this.#o, this.#n?.shell, this.#e);
1589
+ const l = this.#n?.shell?.toolPanel?.defaultOpen;
1590
+ l && this.#e.toolPanels.has(l) && this.openToolPanel(l);
1591
+ }
1592
+ this.setAttribute("data-upgraded", ""), this.hasAttribute("role") || this.setAttribute("role", "grid"), this.#f = !0;
1593
+ const n = this.disconnectSignal;
1594
+ this.#d(), this.addEventListener("keydown", (l) => He(this, l), { signal: n }), document.addEventListener(
1595
+ "keydown",
1596
+ (l) => {
1597
+ l.key === "Escape" && this.activeEditRows !== -1 && this.#O(this.activeEditRows, !0);
1598
+ },
1599
+ { capture: !0, signal: n }
1600
+ ), document.addEventListener(
1601
+ "mousedown",
1602
+ (l) => {
1603
+ if (this.activeEditRows === -1) return;
1604
+ const r = this.findRenderedRowElement(this.activeEditRows);
1605
+ !r || (l.composedPath && l.composedPath() || []).includes(r) || this.#O(this.activeEditRows, !1);
1606
+ },
1607
+ { signal: n }
1608
+ );
1609
+ const i = t?.querySelector(".faux-vscroll"), s = t?.querySelector(".rows");
1610
+ if (this.virtualization.container = i ?? this, this.#C = this.#t?.getAll().some((l) => l.onScroll) ?? !1, i && s) {
1611
+ i.addEventListener(
1573
1612
  "scroll",
1574
1613
  () => {
1575
- if (!this.virtualization.enabled && !this.#E) return;
1576
- const r = n.scrollTop, l = this.virtualization.rowHeight, a = -(r % l);
1577
- i.style.transform = `translateY(${a}px)`, this.#y = r, this.#x || (this.#x = requestAnimationFrame(() => {
1578
- this.#x = 0, this.#y !== null && (this.#te(this.#y), this.#y = null);
1614
+ if (!this.virtualization.enabled && !this.#C) return;
1615
+ const a = i.scrollTop, f = this.virtualization.rowHeight, p = -(a % f);
1616
+ s.style.transform = `translateY(${p}px)`, this.#v = a, this.#T || (this.#T = requestAnimationFrame(() => {
1617
+ this.#T = 0, this.#v !== null && (this.#oe(this.#v), this.#v = null);
1579
1618
  }));
1580
1619
  },
1581
- { passive: !0 }
1620
+ { passive: !0, signal: n }
1582
1621
  );
1583
- const s = t?.querySelector(".rows-body");
1584
- s && s.addEventListener(
1622
+ const l = this.#o.querySelector(".tbw-grid-content"), r = this.#o.querySelector(".tbw-scroll-area");
1623
+ l && (l.addEventListener(
1585
1624
  "wheel",
1586
- (r) => {
1587
- r.preventDefault(), n.scrollTop += r.deltaY;
1625
+ (a) => {
1626
+ a.preventDefault(), a.shiftKey || Math.abs(a.deltaX) > Math.abs(a.deltaY) ? r && (r.scrollLeft += a.shiftKey ? a.deltaY : a.deltaX) : i.scrollTop += a.deltaY;
1588
1627
  },
1589
- { passive: !1 }
1590
- );
1628
+ { passive: !1, signal: n }
1629
+ ), l.addEventListener(
1630
+ "touchstart",
1631
+ (a) => {
1632
+ a.touches.length === 1 && (this.#E = a.touches[0].clientY, this.#R = a.touches[0].clientX, this.#_ = i.scrollTop, this.#A = r?.scrollLeft ?? 0);
1633
+ },
1634
+ { passive: !0, signal: n }
1635
+ ), l.addEventListener(
1636
+ "touchmove",
1637
+ (a) => {
1638
+ if (a.touches.length === 1 && this.#E !== null && this.#R !== null && this.#_ !== null && this.#A !== null) {
1639
+ const f = this.#E - a.touches[0].clientY, p = this.#R - a.touches[0].clientX;
1640
+ i.scrollTop = this.#_ + f, r && (r.scrollLeft = this.#A + p), a.preventDefault();
1641
+ }
1642
+ },
1643
+ { passive: !1, signal: n }
1644
+ ), l.addEventListener(
1645
+ "touchend",
1646
+ () => {
1647
+ this.#E = null, this.#R = null, this.#_ = null, this.#A = null;
1648
+ },
1649
+ { passive: !0, signal: n }
1650
+ ));
1591
1651
  }
1592
- this.resizeController = Be(this), this.#t.addEventListener("mousedown", (s) => this.#oe(s)), this.#p || (this.#p = (s) => this.#ne(s), document.addEventListener("mousemove", this.#p)), this.#w || (this.#w = (s) => this.#ie(s), document.addEventListener("mouseup", this.#w)), this.virtualization.enabled && requestAnimationFrame(() => this.refreshVirtualWindow(!0)), requestAnimationFrame(() => {
1593
- const s = this.bodyEl.querySelector(".data-grid-row");
1594
- if (s) {
1595
- const r = s.getBoundingClientRect().height;
1652
+ this.resizeController = Be(this), this.#o.addEventListener("mousedown", (l) => this.#ne(l), { signal: n }), document.addEventListener("mousemove", (l) => this.#ie(l), { signal: n }), document.addEventListener("mouseup", (l) => this.#se(l), { signal: n }), this.virtualization.enabled && requestAnimationFrame(() => this.refreshVirtualWindow(!0)), requestAnimationFrame(() => {
1653
+ const l = this.bodyEl.querySelector(".data-grid-row");
1654
+ if (l) {
1655
+ const r = l.getBoundingClientRect().height;
1596
1656
  r && Math.abs(r - this.virtualization.rowHeight) > 0.1 && (this.virtualization.rowHeight = r, this.refreshVirtualWindow(!0));
1597
1657
  }
1598
- }), queueMicrotask(() => this.#G()), requestAnimationFrame(() => requestAnimationFrame(() => this.#H?.()));
1658
+ }), queueMicrotask(() => this.#U()), requestAnimationFrame(() => requestAnimationFrame(() => this.#z?.()));
1599
1659
  }
1600
1660
  // ---------------- Event Emitters ----------------
1601
- #i(e, t) {
1661
+ #s(e, t) {
1602
1662
  this.dispatchEvent(new CustomEvent(e, { detail: t, bubbles: !0, composed: !0 }));
1603
1663
  }
1604
1664
  emitCellCommit(e) {
1605
- this.#i("cell-commit", e);
1665
+ this.#s("cell-commit", e);
1606
1666
  }
1607
1667
  emitRowCommit(e) {
1608
- this.#i("row-commit", e);
1668
+ this.#s("row-commit", e);
1609
1669
  }
1610
1670
  emitSortChange(e) {
1611
- this.#i("sort-change", e);
1671
+ this.#s("sort-change", e);
1612
1672
  }
1613
1673
  emitColumnResize(e) {
1614
- this.#i("column-resize", e);
1674
+ this.#s("column-resize", e);
1615
1675
  }
1616
1676
  emitActivateCell(e) {
1617
- this.#i("activate-cell", e);
1677
+ this.#s("activate-cell", e);
1618
1678
  }
1619
1679
  /** Update ARIA selection attributes on rendered rows/cells */
1620
- #G() {
1680
+ #U() {
1621
1681
  this.bodyEl?.querySelectorAll(".data-grid-row")?.forEach((t, n) => {
1622
1682
  const i = n === this.focusRow;
1623
- t.setAttribute("aria-selected", String(i)), t.querySelectorAll(".cell").forEach((s, r) => {
1624
- s.setAttribute("aria-selected", String(i && r === this.focusCol));
1683
+ t.setAttribute("aria-selected", String(i)), t.querySelectorAll(".cell").forEach((s, l) => {
1684
+ s.setAttribute("aria-selected", String(i && l === this.focusCol));
1625
1685
  });
1626
1686
  });
1627
1687
  }
1628
1688
  // ---------------- Watch Handlers ----------------
1629
- #U() {
1630
- if (!this.#h) return;
1631
- this.#d(), this.#n.fitMode === "fixed" ? (this.__didInitialAutoSize = !1, this.#B()) : (this._columns.forEach((t) => {
1689
+ #X() {
1690
+ if (!this.#f) return;
1691
+ this.#u(), this.#n.fitMode === "fixed" ? (this.__didInitialAutoSize = !1, this.#$()) : (this._columns.forEach((t) => {
1632
1692
  !t.__userResized && t.__autoSized && delete t.width;
1633
1693
  }), this.updateTemplate());
1634
1694
  }
1635
- #X() {
1636
- this.#h && (this.#d(), this.rowPool.length = 0, this.bodyEl && (this.bodyEl.innerHTML = ""), this.__rowRenderEpoch++, this.refreshVirtualWindow(!0));
1637
- }
1638
1695
  #j() {
1639
- this._rows = Array.isArray(this.#s) ? [...this.#s] : [], this.#A(), !this.#r || Array.isArray(this.#r) && this.#r.length === 0 ? this.#a() : this.refreshVirtualWindow(!0);
1696
+ this.#f && (this.#u(), this.rowPool.length = 0, this.bodyEl && (this.bodyEl.innerHTML = ""), this.__rowRenderEpoch++, this.refreshVirtualWindow(!0));
1640
1697
  }
1641
1698
  #Y() {
1642
- j(this), this.#h && (this.#d(), this.#a());
1699
+ this._rows = Array.isArray(this.#l) ? [...this.#l] : [], this.#x(), !this.#r || Array.isArray(this.#r) && this.#r.length === 0 ? this.#d() : this.refreshVirtualWindow(!0);
1643
1700
  }
1644
1701
  #Z() {
1645
- this.#h && (this.#d(), this.#q(), this.#A(), this.#k(), this.#_(), this.updateTemplate(), this.refreshVirtualWindow(!0));
1702
+ j(this), this.#f && (this.#u(), this.#d());
1646
1703
  }
1647
- // ---------------- Helper Wrappers ----------------
1648
1704
  #J() {
1649
- Oe(this);
1705
+ this.#f && (this.#u(), this.#I(), this.#x(), this.#P(), this.#S(), this.updateTemplate(), this.refreshVirtualWindow(!0));
1706
+ }
1707
+ // ---------------- Helper Wrappers ----------------
1708
+ #Q() {
1709
+ Me(this);
1650
1710
  }
1651
- #_() {
1711
+ #S() {
1652
1712
  V(this);
1653
1713
  }
1654
1714
  updateTemplate() {
1655
1715
  he(this);
1656
1716
  }
1657
- #B() {
1658
- Me(this);
1717
+ #$() {
1718
+ Oe(this);
1659
1719
  }
1660
- #k() {
1661
- if (this.#o) {
1662
- const e = this._columns.filter((n) => !n.hidden), t = this.#o.processColumns([...e]);
1720
+ #P() {
1721
+ if (this.#t) {
1722
+ const e = this._columns.filter((n) => !n.hidden), t = this.#t.processColumns([...e]);
1663
1723
  if (t !== e) {
1664
- const n = new Map(t.map((s, r) => [s.field, { col: s, order: r }])), i = this._columns.map((s) => {
1724
+ const n = new Map(t.map((s, l) => [s.field, { col: s, order: l }])), i = this._columns.map((s) => {
1665
1725
  if (s.hidden) return s;
1666
- const r = n.get(s.field);
1667
- return r ? r.col : s;
1726
+ const l = n.get(s.field);
1727
+ return l ? l.col : s;
1668
1728
  });
1669
1729
  this._columns = i;
1670
1730
  }
1671
1731
  }
1672
1732
  }
1673
1733
  /** Execute all plugin afterRender hooks */
1674
- #g() {
1675
- this.#o?.afterRender();
1734
+ #w() {
1735
+ this.#t?.afterRender();
1676
1736
  }
1677
1737
  /** Recompute row model via plugin hooks (grouping, tree, filtering, etc.). */
1678
- #A() {
1738
+ #x() {
1679
1739
  j(this);
1680
- const e = Array.isArray(this.#s) ? [...this.#s] : [], t = this.#o?.processRows(e) ?? e;
1740
+ const e = Array.isArray(this.#l) ? [...this.#l] : [], t = this.#t?.processRows(e) ?? e;
1681
1741
  this._rows = t;
1682
1742
  }
1683
1743
  /**
@@ -1698,8 +1758,8 @@ class q extends HTMLElement {
1698
1758
  * - `_columns` is NOT set here (done by #getColumnConfiguration + #processColumns)
1699
1759
  * - Plugins receive config via their attach() method
1700
1760
  */
1701
- #d() {
1702
- const e = this.#b ? { ...this.#b } : {};
1761
+ #u() {
1762
+ const e = this.#p ? { ...this.#p } : {};
1703
1763
  let t = Array.isArray(e.columns) ? [...e.columns] : [];
1704
1764
  const n = (this.__lightDomColumnsCache || []).map((i) => ({
1705
1765
  ...i
@@ -1707,39 +1767,39 @@ class q extends HTMLElement {
1707
1767
  if (n.length) {
1708
1768
  const i = {};
1709
1769
  t.forEach((s) => i[s.field] = s), n.forEach((s) => {
1710
- const r = i[s.field];
1711
- r ? (s.header && !r.header && (r.header = s.header), s.type && !r.type && (r.type = s.type), r.sortable = r.sortable || s.sortable, s.resizable && (r.resizable = !0), s.editable && (r.editable = !0)) : (t.push(s), i[s.field] = s);
1770
+ const l = i[s.field];
1771
+ l ? (s.header && !l.header && (l.header = s.header), s.type && !l.type && (l.type = s.type), l.sortable = l.sortable || s.sortable, s.resizable && (l.resizable = !0), s.editable && (l.editable = !0)) : (t.push(s), i[s.field] = s);
1712
1772
  });
1713
1773
  }
1714
1774
  if (this.#r && this.#r.length && (t = [...this.#r]), (!t || t.length === 0) && this._rows.length && (t = ce(this._rows).columns), t.length) {
1715
- t.forEach((r) => {
1716
- r.sortable === void 0 && (r.sortable = !0), r.resizable === void 0 && (r.resizable = !0);
1775
+ t.forEach((l) => {
1776
+ l.sortable === void 0 && (l.sortable = !0), l.resizable === void 0 && (l.resizable = !0);
1717
1777
  });
1718
1778
  const i = this.#n.columns;
1719
- i?.some((r) => r.__compiledView || r.__compiledEditor) ? e.columns = i : e.columns = t;
1779
+ i?.some((l) => l.__compiledView || l.__compiledEditor) ? e.columns = i : e.columns = t;
1720
1780
  } else {
1721
1781
  const i = this.#n.columns;
1722
1782
  i?.some((s) => s.__compiledView || s.__compiledEditor) && (e.columns = i);
1723
1783
  }
1724
- this.#v && (e.fitMode = this.#v), e.fitMode || (e.fitMode = "stretch"), this.#C && (e.editOn = this.#C), e.columnState && !this.#c && (this.#c = e.columnState), this.#n = e, e.fitMode === "fixed" && this._columns.forEach((i) => {
1784
+ this.#g && (e.fitMode = this.#g), e.fitMode || (e.fitMode = "stretch"), this.#m && (e.editOn = this.#m), e.columnState && !this.#h && (this.#h = e.columnState), this.#n = e, e.fitMode === "fixed" && this._columns.forEach((i) => {
1725
1785
  i.width == null && (i.width = 80);
1726
1786
  });
1727
1787
  }
1728
1788
  // ---------------- Delegate Wrappers ----------------
1729
- #P(e, t, n = this.__rowRenderEpoch) {
1730
- this.#T || (this.#T = (i, s, r) => this.#o?.renderRow(i, s, r) ?? !1), qe(this, e, t, n, this.#T);
1789
+ #M(e, t, n = this.__rowRenderEpoch) {
1790
+ this.#L || (this.#L = (i, s, l) => this.#t?.renderRow(i, s, l) ?? !1), qe(this, e, t, n, this.#L);
1731
1791
  }
1732
- #Q(e, t) {
1733
- A(this, e, t);
1792
+ #ee(e, t) {
1793
+ T(this, e, t);
1734
1794
  }
1735
1795
  #O(e, t) {
1736
1796
  Ie(this, e, t);
1737
1797
  }
1738
1798
  // ---------------- Core Helpers ----------------
1739
- #a() {
1799
+ #d() {
1740
1800
  if (!this.isConnected || !this.headerRowEl || !this.bodyEl)
1741
1801
  return;
1742
- const e = this.#b?.columns || this.#r || [];
1802
+ const e = this.#p?.columns || this.#r || [];
1743
1803
  if (e.length) {
1744
1804
  const n = new Map(this._columns.filter((s) => s.hidden).map((s) => [s.field, !0])), i = e.map((s) => ({
1745
1805
  ...s,
@@ -1747,26 +1807,26 @@ class q extends HTMLElement {
1747
1807
  }));
1748
1808
  this._columns = i;
1749
1809
  }
1750
- if (this.#J(), this.#d(), this.#q(), this.#A(), this.#k(), this.#c) {
1751
- const n = this.#c;
1752
- this.#c = void 0, this.#$(n);
1810
+ if (this.#Q(), this.#u(), this.#I(), this.#x(), this.#P(), this.#h) {
1811
+ const n = this.#h;
1812
+ this.#h = void 0, this.#K(n);
1753
1813
  }
1754
- this.#_(), this.updateTemplate(), this.refreshVirtualWindow(!0), this.#n.fitMode === "fixed" && !this.__didInitialAutoSize && requestAnimationFrame(() => this.#B()), this.bodyEl && (this.bodyEl.style.display = "", this.bodyEl.style.gridTemplateColumns = ""), queueMicrotask(() => this.#g());
1814
+ this.#S(), this.updateTemplate(), this.refreshVirtualWindow(!0), this.#n.fitMode === "fixed" && !this.__didInitialAutoSize && requestAnimationFrame(() => this.#$()), this.bodyEl && (this.bodyEl.style.display = "", this.bodyEl.style.gridTemplateColumns = ""), queueMicrotask(() => this.#w());
1755
1815
  }
1756
1816
  /** Internal method to apply column state without triggering setup loop */
1757
- #$(e) {
1758
- const t = this.#n.columns ?? [], n = this.#o?.getAll() ?? [];
1817
+ #K(e) {
1818
+ const t = this.#n.columns ?? [], n = this.#t?.getAll() ?? [];
1759
1819
  ge(this, e, t, n);
1760
1820
  for (const i of e.columns) {
1761
- const s = t.find((r) => r.field === i.field);
1821
+ const s = t.find((l) => l.field === i.field);
1762
1822
  s && (s.hidden = !i.visible);
1763
1823
  }
1764
1824
  }
1765
- #ee() {
1825
+ #te() {
1766
1826
  return this._rows.length <= this.virtualization.bypassThreshold;
1767
1827
  }
1768
- #te(e) {
1769
- if (this.refreshVirtualWindow(!1), this.#E) {
1828
+ #oe(e) {
1829
+ if (this.refreshVirtualWindow(!1), this.#t?.onScrollRender(), this.#C) {
1770
1830
  const t = this.virtualization.container, n = {
1771
1831
  scrollTop: e,
1772
1832
  scrollLeft: t?.scrollLeft ?? 0,
@@ -1776,11 +1836,11 @@ class q extends HTMLElement {
1776
1836
  clientWidth: t?.clientWidth ?? 0,
1777
1837
  originalEvent: new Event("scroll")
1778
1838
  };
1779
- this.#o?.onScroll(n);
1839
+ this.#t?.onScroll(n);
1780
1840
  }
1781
1841
  }
1782
1842
  findHeaderRow() {
1783
- return this.#t.querySelector(".header-row");
1843
+ return this.#o.querySelector(".header-row");
1784
1844
  }
1785
1845
  findRenderedRowElement(e) {
1786
1846
  return Array.from(this.bodyEl.querySelectorAll(".data-grid-row")).find((t) => {
@@ -1793,18 +1853,18 @@ class q extends HTMLElement {
1793
1853
  * Returns true if any plugin handled the event.
1794
1854
  */
1795
1855
  dispatchCellClick(e, t, n, i) {
1796
- const s = this._rows[t], r = this._columns[n];
1797
- if (!s || !r) return !1;
1798
- const l = {
1856
+ const s = this._rows[t], l = this._columns[n];
1857
+ if (!s || !l) return !1;
1858
+ const r = {
1799
1859
  row: s,
1800
1860
  rowIndex: t,
1801
1861
  colIndex: n,
1802
- field: r.field,
1803
- value: s[r.field],
1862
+ field: l.field,
1863
+ value: s[l.field],
1804
1864
  cellEl: i,
1805
1865
  originalEvent: e
1806
1866
  };
1807
- return this.#o?.onCellClick(l) ?? !1;
1867
+ return this.#t?.onCellClick(r) ?? !1;
1808
1868
  }
1809
1869
  /**
1810
1870
  * Dispatch a header click event to the plugin system.
@@ -1820,65 +1880,65 @@ class q extends HTMLElement {
1820
1880
  headerEl: n,
1821
1881
  originalEvent: e
1822
1882
  };
1823
- return this.#o?.onHeaderClick(s) ?? !1;
1883
+ return this.#t?.onHeaderClick(s) ?? !1;
1824
1884
  }
1825
1885
  /**
1826
1886
  * Dispatch a keyboard event to the plugin system.
1827
1887
  * Returns true if any plugin handled the event.
1828
1888
  */
1829
1889
  dispatchKeyDown(e) {
1830
- return this.#o?.onKeyDown(e) ?? !1;
1890
+ return this.#t?.onKeyDown(e) ?? !1;
1831
1891
  }
1832
1892
  /**
1833
1893
  * Build a CellMouseEvent from a native MouseEvent.
1834
1894
  * Extracts cell/row information from the event target.
1835
1895
  */
1836
- #M(e, t) {
1896
+ #D(e, t) {
1837
1897
  let n = null;
1838
1898
  const i = e.composedPath?.();
1839
- if (i && i.length > 0 ? n = i[0] : n = e.target, n && !this.#t.contains(n)) {
1840
- const p = this.#t.elementFromPoint(e.clientX, e.clientY);
1841
- p && (n = p);
1899
+ if (i && i.length > 0 ? n = i[0] : n = e.target, n && !this.#o.contains(n)) {
1900
+ const h = this.#o.elementFromPoint(e.clientX, e.clientY);
1901
+ h && (n = h);
1842
1902
  }
1843
- const s = n?.closest?.("[data-col]"), r = n?.closest?.(".data-grid-row"), l = n?.closest?.(".header-row");
1844
- let a, h, u, w, c, d;
1845
- return s && (a = parseInt(s.getAttribute("data-row") ?? "-1", 10), h = parseInt(s.getAttribute("data-col") ?? "-1", 10), a >= 0 && h >= 0 && (u = this._rows[a], d = this._columns[h], w = d?.field, c = u && w ? u[w] : void 0)), {
1903
+ const s = n?.closest?.("[data-col]"), l = n?.closest?.(".data-grid-row"), r = n?.closest?.(".header-row");
1904
+ let a, f, p, w, u, c;
1905
+ return s && (a = parseInt(s.getAttribute("data-row") ?? "-1", 10), f = parseInt(s.getAttribute("data-col") ?? "-1", 10), a >= 0 && f >= 0 && (p = this._rows[a], c = this._columns[f], w = c?.field, u = p && w ? p[w] : void 0)), {
1846
1906
  type: t,
1847
- row: u,
1907
+ row: p,
1848
1908
  rowIndex: a !== void 0 && a >= 0 ? a : void 0,
1849
- colIndex: h !== void 0 && h >= 0 ? h : void 0,
1909
+ colIndex: f !== void 0 && f >= 0 ? f : void 0,
1850
1910
  field: w,
1851
- value: c,
1852
- column: d,
1911
+ value: u,
1912
+ column: c,
1853
1913
  originalEvent: e,
1854
1914
  cellElement: s ?? void 0,
1855
- rowElement: r ?? void 0,
1856
- isHeader: !!l,
1857
- cell: a !== void 0 && h !== void 0 && a >= 0 && h >= 0 ? { row: a, col: h } : void 0
1915
+ rowElement: l ?? void 0,
1916
+ isHeader: !!r,
1917
+ cell: a !== void 0 && f !== void 0 && a >= 0 && f >= 0 ? { row: a, col: f } : void 0
1858
1918
  };
1859
1919
  }
1860
1920
  /**
1861
1921
  * Handle mousedown events and dispatch to plugin system.
1862
1922
  */
1863
- #oe(e) {
1864
- const t = this.#M(e, "mousedown");
1865
- (this.#o?.onCellMouseDown(t) ?? !1) && (this.#R = !0);
1923
+ #ne(e) {
1924
+ const t = this.#D(e, "mousedown");
1925
+ (this.#t?.onCellMouseDown(t) ?? !1) && (this.#y = !0);
1866
1926
  }
1867
1927
  /**
1868
1928
  * Handle mousemove events (only when dragging).
1869
1929
  */
1870
- #ne(e) {
1871
- if (!this.#R) return;
1872
- const t = this.#M(e, "mousemove");
1873
- this.#o?.onCellMouseMove(t);
1930
+ #ie(e) {
1931
+ if (!this.#y) return;
1932
+ const t = this.#D(e, "mousemove");
1933
+ this.#t?.onCellMouseMove(t);
1874
1934
  }
1875
1935
  /**
1876
1936
  * Handle mouseup events.
1877
1937
  */
1878
- #ie(e) {
1879
- if (!this.#R) return;
1880
- const t = this.#M(e, "mouseup");
1881
- this.#o?.onCellMouseUp(t), this.#R = !1;
1938
+ #se(e) {
1939
+ if (!this.#y) return;
1940
+ const t = this.#D(e, "mouseup");
1941
+ this.#t?.onCellMouseUp(t), this.#y = !1;
1882
1942
  }
1883
1943
  // API consumed by internal utils (rows.ts)
1884
1944
  get changedRows() {
@@ -1888,19 +1948,19 @@ class q extends HTMLElement {
1888
1948
  return Array.from(this._changedRowIndices);
1889
1949
  }
1890
1950
  async resetChangedRows(e) {
1891
- this._changedRowIndices.clear(), e || this.#i("changed-rows-reset", { rows: this.changedRows, indices: this.changedRowIndices }), this.rowPool.forEach((t) => t.classList.remove("changed"));
1951
+ this._changedRowIndices.clear(), e || this.#s("changed-rows-reset", { rows: this.changedRows, indices: this.changedRowIndices }), this.rowPool.forEach((t) => t.classList.remove("changed"));
1892
1952
  }
1893
1953
  async beginBulkEdit(e) {
1894
- this.#Q(e, this._rows[e]);
1954
+ this.#ee(e, this._rows[e]);
1895
1955
  }
1896
1956
  async commitActiveRowEdit() {
1897
1957
  this.activeEditRows !== -1 && this.#O(this.activeEditRows, !1);
1898
1958
  }
1899
1959
  async ready() {
1900
- return this.#D;
1960
+ return this.#H;
1901
1961
  }
1902
1962
  async forceLayout() {
1903
- this.#a(), await new Promise((e) => requestAnimationFrame(() => requestAnimationFrame(e)));
1963
+ this.#d(), await new Promise((e) => requestAnimationFrame(() => requestAnimationFrame(e)));
1904
1964
  }
1905
1965
  /** Public method: returns a frozen snapshot of the merged effective configuration */
1906
1966
  async getConfig() {
@@ -1914,15 +1974,15 @@ class q extends HTMLElement {
1914
1974
  * @returns True if visibility was changed, false if column not found or locked
1915
1975
  */
1916
1976
  setColumnVisible(e, t) {
1917
- const n = this.#n.columns, i = n?.find((l) => l.field === e);
1977
+ const n = this.#n.columns, i = n?.find((r) => r.field === e);
1918
1978
  if (!i || !t && i.lockVisible || !t && (n ?? []).filter((a) => !a.hidden && a.field !== e).length === 0)
1919
1979
  return !1;
1920
- const s = !!i.hidden, r = !t;
1921
- return s !== r ? (i.hidden = r, this.#i("column-visibility", {
1980
+ const s = !!i.hidden, l = !t;
1981
+ return s !== l ? (i.hidden = l, this.#s("column-visibility", {
1922
1982
  field: e,
1923
1983
  visible: t,
1924
- visibleColumns: (n ?? []).filter((l) => !l.hidden).map((l) => l.field)
1925
- }), this.rowPool.length = 0, this.bodyEl && (this.bodyEl.innerHTML = ""), this.__rowRenderEpoch++, this.#a(), this.requestStateChange(), !0) : !1;
1984
+ visibleColumns: (n ?? []).filter((r) => !r.hidden).map((r) => r.field)
1985
+ }), this.rowPool.length = 0, this.bodyEl && (this.bodyEl.innerHTML = ""), this.__rowRenderEpoch++, this.#d(), this.requestStateChange(), !0) : !1;
1926
1986
  }
1927
1987
  /**
1928
1988
  * Toggle the visibility of a column.
@@ -1949,9 +2009,9 @@ class q extends HTMLElement {
1949
2009
  const e = this.#n.columns;
1950
2010
  e?.some((n) => n.hidden) && (e?.forEach((n) => {
1951
2011
  n.hidden = !1;
1952
- }), this.#i("column-visibility", {
2012
+ }), this.#s("column-visibility", {
1953
2013
  visibleColumns: (e ?? []).map((n) => n.field)
1954
- }), this.rowPool.length = 0, this.bodyEl && (this.bodyEl.innerHTML = ""), this.__rowRenderEpoch++, this.#a(), this.requestStateChange());
2014
+ }), this.rowPool.length = 0, this.bodyEl && (this.bodyEl.innerHTML = ""), this.__rowRenderEpoch++, this.#d(), this.requestStateChange());
1955
2015
  }
1956
2016
  /**
1957
2017
  * Get list of all column fields (including hidden).
@@ -1981,7 +2041,7 @@ class q extends HTMLElement {
1981
2041
  }
1982
2042
  for (const i of t.values())
1983
2043
  n.push(i);
1984
- this._columns = n, this.#_(), this.updateTemplate(), this.refreshVirtualWindow(!0);
2044
+ this._columns = n, this.#S(), this.updateTemplate(), this.refreshVirtualWindow(!0);
1985
2045
  }
1986
2046
  /**
1987
2047
  * Get the current column order as an array of field names.
@@ -1996,7 +2056,7 @@ class q extends HTMLElement {
1996
2056
  * Returns a serializable object suitable for localStorage or database storage.
1997
2057
  */
1998
2058
  getColumnState() {
1999
- const e = this.#o?.getAll() ?? [];
2059
+ const e = this.#t?.getAll() ?? [];
2000
2060
  return ae(this, e);
2001
2061
  }
2002
2062
  /**
@@ -2004,7 +2064,7 @@ class q extends HTMLElement {
2004
2064
  * Use this to restore previously saved column state.
2005
2065
  */
2006
2066
  set columnState(e) {
2007
- e && (this.#c = e, this.#S && this.#se(e));
2067
+ e && (this.#h = e, this.#i && this.#le(e));
2008
2068
  }
2009
2069
  /**
2010
2070
  * Get the current column state.
@@ -2015,10 +2075,10 @@ class q extends HTMLElement {
2015
2075
  /**
2016
2076
  * Apply column state internally.
2017
2077
  */
2018
- #se(e) {
2078
+ #le(e) {
2019
2079
  (this.#n.columns ?? []).forEach((n) => {
2020
2080
  n.hidden = !1;
2021
- }), this.#$(e), this.#a();
2081
+ }), this.#K(e), this.#d();
2022
2082
  }
2023
2083
  /**
2024
2084
  * Request a state change event to be emitted.
@@ -2027,21 +2087,21 @@ class q extends HTMLElement {
2027
2087
  * The event is debounced to avoid excessive events during drag operations.
2028
2088
  */
2029
2089
  requestStateChange() {
2030
- this.#L || (this.#L = me(
2090
+ this.#k || (this.#k = me(
2031
2091
  this,
2032
- () => this.#o?.getAll() ?? [],
2033
- (e) => this.#i("column-state-change", e)
2034
- )), this.#L();
2092
+ () => this.#t?.getAll() ?? [],
2093
+ (e) => this.#s("column-state-change", e)
2094
+ )), this.#k();
2035
2095
  }
2036
2096
  /**
2037
2097
  * Reset column state to initial configuration.
2038
2098
  * Clears all user modifications (order, width, visibility, sort).
2039
2099
  */
2040
2100
  resetColumnState() {
2041
- this.#c = void 0, (this.#n.columns ?? []).forEach((n) => {
2101
+ this.#h = void 0, (this.#n.columns ?? []).forEach((n) => {
2042
2102
  n.hidden = !1;
2043
- }), this.sortState = null, this.__originalOrder = [], this.#d(), this.#a();
2044
- const t = this.#o?.getAll() ?? [];
2103
+ }), this.sortState = null, this.__originalOrder = [], this.#u(), this.#d();
2104
+ const t = this.#t?.getAll() ?? [];
2045
2105
  for (const n of t)
2046
2106
  if (n.applyColumnState)
2047
2107
  for (const i of this._columns)
@@ -2068,7 +2128,7 @@ class q extends HTMLElement {
2068
2128
  console.warn(`[tbw-grid] Tool panel "${e}" not found`);
2069
2129
  return;
2070
2130
  }
2071
- this.#e.activePanel && this.#e.activePanel !== e && this.closeToolPanel(), this.#e.activePanel = e, oe(this.#t, this.#e), ne(this.#t, this.#e), Ue(this.#t, this.#e), this.#i("tool-panel-open", { id: e });
2131
+ this.#e.activePanel && this.#e.activePanel !== e && this.closeToolPanel(), this.#e.activePanel = e, oe(this.#o, this.#e), ne(this.#o, this.#e), Ue(this.#o, this.#e), this.#s("tool-panel-open", { id: e });
2072
2132
  }
2073
2133
  /**
2074
2134
  * Close the currently open tool panel.
@@ -2076,7 +2136,7 @@ class q extends HTMLElement {
2076
2136
  closeToolPanel() {
2077
2137
  if (!this.#e.activePanel) return;
2078
2138
  const e = this.#e.activePanel, t = this.#e.toolPanels.get(e);
2079
- this.#e.activePanelCleanup && (this.#e.activePanelCleanup(), this.#e.activePanelCleanup = null), t?.onClose?.(), this.#e.activePanel = null, oe(this.#t, this.#e), ne(this.#t, this.#e), this.#i("tool-panel-close", { id: e });
2139
+ this.#e.activePanelCleanup && (this.#e.activePanelCleanup(), this.#e.activePanelCleanup = null), t?.onClose?.(), this.#e.activePanel = null, oe(this.#o, this.#e), ne(this.#o, this.#e), this.#s("tool-panel-close", { id: e });
2080
2140
  }
2081
2141
  /**
2082
2142
  * Toggle a tool panel open/closed.
@@ -2098,13 +2158,13 @@ class q extends HTMLElement {
2098
2158
  console.warn(`[tbw-grid] Tool panel "${e.id}" already registered`);
2099
2159
  return;
2100
2160
  }
2101
- this.#e.toolPanels.set(e.id, e), this.#l && this.#m();
2161
+ this.#e.toolPanels.set(e.id, e), this.#c && this.#b();
2102
2162
  }
2103
2163
  /**
2104
2164
  * Unregister a custom tool panel.
2105
2165
  */
2106
2166
  unregisterToolPanel(e) {
2107
- this.#e.activePanel === e && this.closeToolPanel(), this.#e.toolPanels.delete(e), this.#l && this.#m();
2167
+ this.#e.activePanel === e && this.closeToolPanel(), this.#e.toolPanels.delete(e), this.#c && this.#b();
2108
2168
  }
2109
2169
  /**
2110
2170
  * Get registered header content definitions.
@@ -2120,14 +2180,14 @@ class q extends HTMLElement {
2120
2180
  console.warn(`[tbw-grid] Header content "${e.id}" already registered`);
2121
2181
  return;
2122
2182
  }
2123
- this.#e.headerContents.set(e.id, e), this.#l && te(this.#t, this.#e);
2183
+ this.#e.headerContents.set(e.id, e), this.#c && te(this.#o, this.#e);
2124
2184
  }
2125
2185
  /**
2126
2186
  * Unregister custom header content.
2127
2187
  */
2128
2188
  unregisterHeaderContent(e) {
2129
2189
  const t = this.#e.headerContentCleanups.get(e);
2130
- t && (t(), this.#e.headerContentCleanups.delete(e)), this.#e.headerContents.get(e)?.onDestroy?.(), this.#e.headerContents.delete(e), this.#t.querySelector(`[data-header-content="${e}"]`)?.remove();
2190
+ t && (t(), this.#e.headerContentCleanups.delete(e)), this.#e.headerContents.get(e)?.onDestroy?.(), this.#e.headerContents.delete(e), this.#o.querySelector(`[data-header-content="${e}"]`)?.remove();
2131
2191
  }
2132
2192
  /**
2133
2193
  * Get all registered toolbar buttons.
@@ -2143,14 +2203,14 @@ class q extends HTMLElement {
2143
2203
  console.warn(`[tbw-grid] Toolbar button "${e.id}" already registered`);
2144
2204
  return;
2145
2205
  }
2146
- this.#e.toolbarButtons.set(e.id, e), this.#l && this.#m();
2206
+ this.#e.toolbarButtons.set(e.id, e), this.#c && this.#b();
2147
2207
  }
2148
2208
  /**
2149
2209
  * Unregister a custom toolbar button.
2150
2210
  */
2151
2211
  unregisterToolbarButton(e) {
2152
2212
  const t = this.#e.toolbarButtonCleanups.get(e);
2153
- t && (t(), this.#e.toolbarButtonCleanups.delete(e)), this.#e.toolbarButtons.delete(e), this.#l && this.#m();
2213
+ t && (t(), this.#e.toolbarButtonCleanups.delete(e)), this.#e.toolbarButtons.delete(e), this.#c && this.#b();
2154
2214
  }
2155
2215
  /**
2156
2216
  * Enable/disable a toolbar button by ID.
@@ -2158,7 +2218,7 @@ class q extends HTMLElement {
2158
2218
  setToolbarButtonDisabled(e, t) {
2159
2219
  const n = this.#e.toolbarButtons.get(e);
2160
2220
  n && (n.disabled = t);
2161
- const i = this.#t.querySelector(`[data-btn="${e}"]`);
2221
+ const i = this.#o.querySelector(`[data-btn="${e}"]`);
2162
2222
  i && (i.disabled = t);
2163
2223
  }
2164
2224
  /**
@@ -2166,13 +2226,13 @@ class q extends HTMLElement {
2166
2226
  * Call this after dynamically modifying <tbw-grid-header> children.
2167
2227
  */
2168
2228
  refreshShellHeader() {
2169
- this.#m();
2229
+ this.#b();
2170
2230
  }
2171
2231
  /**
2172
2232
  * Internal shell header refresh.
2173
2233
  */
2174
- #m() {
2175
- ee(this, this.#e), this.#K(), this.#I();
2234
+ #b() {
2235
+ ee(this, this.#e), this.#W(), this.#B();
2176
2236
  }
2177
2237
  // ---------------- Virtual Window ----------------
2178
2238
  /**
@@ -2183,24 +2243,24 @@ class q extends HTMLElement {
2183
2243
  if (!this.bodyEl) return;
2184
2244
  const t = this._rows.length;
2185
2245
  if (!this.virtualization.enabled) {
2186
- this.#P(0, t), this.#g();
2246
+ this.#M(0, t), this.#w();
2187
2247
  return;
2188
2248
  }
2189
- if (this.#ee()) {
2190
- this.virtualization.start = 0, this.virtualization.end = t, this.bodyEl.style.transform = "translateY(0px)", this.#P(0, t, this.__rowRenderEpoch), this.virtualization.totalHeightEl && (this.virtualization.totalHeightEl.style.height = `${t * this.virtualization.rowHeight}px`), this.setAttribute("aria-rowcount", String(t)), this.setAttribute("aria-colcount", String(this.visibleColumns.length)), this.#g();
2249
+ if (this.#te()) {
2250
+ this.virtualization.start = 0, this.virtualization.end = t, this.bodyEl.style.transform = "translateY(0px)", this.#M(0, t, this.__rowRenderEpoch), this.virtualization.totalHeightEl && (this.virtualization.totalHeightEl.style.height = `${t * this.virtualization.rowHeight}px`), this.setAttribute("aria-rowcount", String(t)), this.setAttribute("aria-colcount", String(this.visibleColumns.length)), this.#w();
2191
2251
  return;
2192
2252
  }
2193
- const n = this.virtualization.container ?? this, s = (this.virtualization.viewportEl ?? n).clientHeight, r = this.virtualization.rowHeight, l = n.scrollTop;
2194
- let a = Math.floor(l / r);
2253
+ const n = this.virtualization.container ?? this, s = (this.virtualization.viewportEl ?? n).clientHeight, l = this.virtualization.rowHeight, r = n.scrollTop;
2254
+ let a = Math.floor(r / l);
2195
2255
  a < 0 && (a = 0);
2196
- const h = Math.ceil(s / r) + 2;
2197
- let u = a + h;
2198
- u > t && (u = t), this.virtualization.start = a, this.virtualization.end = u, this.virtualization.totalHeightEl && (this.virtualization.totalHeightEl.style.height = `${t * r}px`);
2199
- const w = -(l % r);
2200
- this.bodyEl.style.transform = `translateY(${w}px)`, this.#P(a, u, e ? ++this.__rowRenderEpoch : this.__rowRenderEpoch), this.setAttribute("aria-rowcount", String(t)), this.setAttribute("aria-colcount", String(this.visibleColumns.length)), e && this.#g();
2256
+ const f = Math.ceil(s / l) + 2;
2257
+ let p = a + f;
2258
+ p > t && (p = t), this.virtualization.start = a, this.virtualization.end = p, this.virtualization.totalHeightEl && (this.virtualization.totalHeightEl.style.height = `${t * l}px`);
2259
+ const w = -(r % l);
2260
+ this.bodyEl.style.transform = `translateY(${w}px)`, this.#M(a, p, e ? ++this.__rowRenderEpoch : this.__rowRenderEpoch), this.setAttribute("aria-rowcount", String(t)), this.setAttribute("aria-colcount", String(this.visibleColumns.length)), e && this.#w();
2201
2261
  }
2202
2262
  // ---------------- Render ----------------
2203
- #K() {
2263
+ #W() {
2204
2264
  ee(this, this.#e);
2205
2265
  const e = this.#n?.shell, t = Ke(e, this.#e), n = `
2206
2266
  <div class="tbw-scroll-area">
@@ -2223,14 +2283,14 @@ class q extends HTMLElement {
2223
2283
  `;
2224
2284
  if (t) {
2225
2285
  const i = We(e, this.#e), s = Fe(e, this.#e, n);
2226
- this.#t.innerHTML = `
2286
+ this.#o.innerHTML = `
2227
2287
  <div class="tbw-grid-root has-shell">
2228
2288
  ${i}
2229
2289
  ${s}
2230
2290
  </div>
2231
- `, this.#re(), this.#l = !0;
2291
+ `, this.#re(), this.#c = !0;
2232
2292
  } else
2233
- this.#t.innerHTML = `
2293
+ this.#o.innerHTML = `
2234
2294
  <div class="tbw-grid-root">
2235
2295
  <div class="tbw-grid-content">
2236
2296
  ${n}
@@ -2242,16 +2302,16 @@ class q extends HTMLElement {
2242
2302
  * Set up shell event listeners after render.
2243
2303
  */
2244
2304
  #re() {
2245
- Ve(this.#t, this.#n?.shell, this.#e, {
2305
+ Ve(this.#o, this.#n?.shell, this.#e, {
2246
2306
  onPanelToggle: (e) => this.toggleToolPanel(e),
2247
2307
  onPanelClose: () => this.closeToolPanel(),
2248
- onToolbarButtonClick: (e) => this.#le(e)
2308
+ onToolbarButtonClick: (e) => this.#ae(e)
2249
2309
  });
2250
2310
  }
2251
2311
  /**
2252
2312
  * Handle toolbar button click (for config buttons with action).
2253
2313
  */
2254
- #le(e) {
2314
+ #ae(e) {
2255
2315
  const n = (this.#n?.shell?.header?.toolbarButtons ?? []).find((s) => s.id === e);
2256
2316
  if (n?.action) {
2257
2317
  n.action();
@@ -2361,6 +2421,26 @@ class ue {
2361
2421
  get shadowRoot() {
2362
2422
  return this.grid?.shadowRoot ?? null;
2363
2423
  }
2424
+ /**
2425
+ * Get the disconnect signal for event listener cleanup.
2426
+ * This signal is aborted when the grid disconnects from the DOM.
2427
+ * Use this when adding event listeners that should be cleaned up automatically.
2428
+ *
2429
+ * Best for:
2430
+ * - Document/window-level listeners added in attach()
2431
+ * - Listeners on the grid element itself
2432
+ * - Any listener that should persist across renders
2433
+ *
2434
+ * Not needed for:
2435
+ * - Listeners on elements created in afterRender() (removed with element)
2436
+ *
2437
+ * @example
2438
+ * element.addEventListener('click', handler, { signal: this.disconnectSignal });
2439
+ * document.addEventListener('keydown', handler, { signal: this.disconnectSignal });
2440
+ */
2441
+ get disconnectSignal() {
2442
+ return this.grid?.disconnectSignal;
2443
+ }
2364
2444
  /**
2365
2445
  * Log a warning message.
2366
2446
  */
@@ -2368,7 +2448,7 @@ class ue {
2368
2448
  console.warn(`[tbw-grid:${this.name}] ${e}`);
2369
2449
  }
2370
2450
  }
2371
- function z(o) {
2451
+ function N(o) {
2372
2452
  return {
2373
2453
  startRow: Math.min(o.startRow, o.endRow),
2374
2454
  startCol: Math.min(o.startCol, o.endCol),
@@ -2377,7 +2457,7 @@ function z(o) {
2377
2457
  };
2378
2458
  }
2379
2459
  function Ze(o) {
2380
- const e = z(o);
2460
+ const e = N(o);
2381
2461
  return {
2382
2462
  from: { row: e.startRow, col: e.startCol },
2383
2463
  to: { row: e.endRow, col: e.endCol }
@@ -2387,14 +2467,14 @@ function K(o) {
2387
2467
  return o.map(Ze);
2388
2468
  }
2389
2469
  function Je(o, e, t) {
2390
- const n = z(t);
2470
+ const n = N(t);
2391
2471
  return o >= n.startRow && o <= n.endRow && e >= n.startCol && e <= n.endCol;
2392
2472
  }
2393
2473
  function ie(o, e, t) {
2394
2474
  return t.some((n) => Je(o, e, n));
2395
2475
  }
2396
2476
  function Qe(o) {
2397
- const e = [], t = z(o);
2477
+ const e = [], t = N(o);
2398
2478
  for (let n = t.startRow; n <= t.endRow; n++)
2399
2479
  for (let i = t.startCol; i <= t.endCol; i++)
2400
2480
  e.push({ row: n, col: i });
@@ -2463,15 +2543,15 @@ class st extends ue {
2463
2543
  onCellClick(e) {
2464
2544
  const { rowIndex: t, colIndex: n, originalEvent: i } = e, { mode: s } = this.config;
2465
2545
  if (s === "cell")
2466
- return this.selectedCell = { row: t, col: n }, this.emit("selection-change", this.#t()), this.requestAfterRender(), !1;
2546
+ return this.selectedCell = { row: t, col: n }, this.emit("selection-change", this.#i()), this.requestAfterRender(), !1;
2467
2547
  if (s === "row")
2468
- return this.selected.clear(), this.selected.add(t), this.lastSelected = t, this.emit("selection-change", this.#t()), this.requestAfterRender(), !1;
2548
+ return this.selected.clear(), this.selected.add(t), this.lastSelected = t, this.emit("selection-change", this.#i()), this.requestAfterRender(), !1;
2469
2549
  if (s === "range") {
2470
- const r = i.shiftKey, l = i.ctrlKey || i.metaKey;
2471
- if (r && this.cellAnchor) {
2550
+ const l = i.shiftKey, r = i.ctrlKey || i.metaKey;
2551
+ if (l && this.cellAnchor) {
2472
2552
  const a = se(this.cellAnchor, { row: t, col: n });
2473
- l ? this.ranges.length > 0 ? this.ranges[this.ranges.length - 1] = a : this.ranges.push(a) : this.ranges = [a], this.activeRange = a;
2474
- } else if (l) {
2553
+ r ? this.ranges.length > 0 ? this.ranges[this.ranges.length - 1] = a : this.ranges.push(a) : this.ranges = [a], this.activeRange = a;
2554
+ } else if (r) {
2475
2555
  const a = {
2476
2556
  startRow: t,
2477
2557
  startCol: n,
@@ -2488,14 +2568,14 @@ class st extends ue {
2488
2568
  };
2489
2569
  this.ranges = [a], this.activeRange = a, this.cellAnchor = { row: t, col: n };
2490
2570
  }
2491
- return this.emit("selection-change", this.#t()), this.requestAfterRender(), !1;
2571
+ return this.emit("selection-change", this.#i()), this.requestAfterRender(), !1;
2492
2572
  }
2493
2573
  return !1;
2494
2574
  }
2495
2575
  onKeyDown(e) {
2496
2576
  const { mode: t } = this.config;
2497
2577
  if (e.key === "Escape")
2498
- return t === "cell" ? this.selectedCell = null : t === "row" ? (this.selected.clear(), this.anchor = null) : t === "range" && (this.ranges = [], this.activeRange = null, this.cellAnchor = null), this.emit("selection-change", this.#t()), this.requestAfterRender(), !0;
2578
+ return t === "cell" ? this.selectedCell = null : t === "row" ? (this.selected.clear(), this.anchor = null) : t === "range" && (this.ranges = [], this.activeRange = null, this.cellAnchor = null), this.emit("selection-change", this.#i()), this.requestAfterRender(), !0;
2499
2579
  if (t === "range" && e.key === "a" && (e.ctrlKey || e.metaKey)) {
2500
2580
  const n = this.rows.length, i = this.columns.length;
2501
2581
  if (n > 0 && i > 0) {
@@ -2505,7 +2585,7 @@ class st extends ue {
2505
2585
  endRow: n - 1,
2506
2586
  endCol: i - 1
2507
2587
  };
2508
- return this.ranges = [s], this.activeRange = s, this.emit("selection-change", this.#t()), this.requestAfterRender(), !0;
2588
+ return this.ranges = [s], this.activeRange = s, this.emit("selection-change", this.#i()), this.requestAfterRender(), !0;
2509
2589
  }
2510
2590
  }
2511
2591
  return !1;
@@ -2522,37 +2602,55 @@ class st extends ue {
2522
2602
  endRow: t,
2523
2603
  endCol: n
2524
2604
  };
2525
- return this.ranges.push(s), this.activeRange = s, this.emit("selection-change", this.#t()), this.requestAfterRender(), !0;
2605
+ return this.ranges.push(s), this.activeRange = s, this.emit("selection-change", this.#i()), this.requestAfterRender(), !0;
2526
2606
  }
2527
2607
  onCellMouseMove(e) {
2528
2608
  if (this.config.mode !== "range" || !this.isDragging || !this.cellAnchor || e.rowIndex === void 0 || e.colIndex === void 0 || e.rowIndex < 0) return;
2529
2609
  const t = se(this.cellAnchor, { row: e.rowIndex, col: e.colIndex });
2530
- return this.ranges.length > 0 ? this.ranges[this.ranges.length - 1] = t : this.ranges.push(t), this.activeRange = t, this.emit("selection-change", this.#t()), this.requestAfterRender(), !0;
2610
+ return this.ranges.length > 0 ? this.ranges[this.ranges.length - 1] = t : this.ranges.push(t), this.activeRange = t, this.emit("selection-change", this.#i()), this.requestAfterRender(), !0;
2531
2611
  }
2532
2612
  onCellMouseUp(e) {
2533
2613
  if (this.config.mode === "range" && this.isDragging)
2534
2614
  return this.isDragging = !1, !0;
2535
2615
  }
2536
- afterRender() {
2616
+ /**
2617
+ * Apply selection classes to visible cells/rows.
2618
+ * Shared by afterRender and onScrollRender.
2619
+ */
2620
+ #o() {
2537
2621
  const e = this.shadowRoot;
2538
2622
  if (!e) return;
2539
- const t = e.children[0], { mode: n } = this.config;
2540
- this.grid.setAttribute("data-selection-mode", n), t && t.classList.toggle("selecting", this.isDragging), e.querySelectorAll(".cell").forEach((r) => {
2541
- r.classList.remove("selected", "top", "bottom", "first", "last");
2623
+ const { mode: t } = this.config;
2624
+ e.querySelectorAll(".cell").forEach((s) => {
2625
+ s.classList.remove("selected", "top", "bottom", "first", "last");
2542
2626
  });
2543
- const s = e.querySelectorAll(".data-grid-row");
2544
- if (s.forEach((r) => {
2545
- r.classList.remove("selected");
2546
- }), n === "row" && (s.forEach((r) => r.classList.remove("row-focus")), s.forEach((r) => {
2547
- const l = r.querySelector(".cell[data-row]"), a = parseInt(l?.getAttribute("data-row") ?? "-1", 10);
2548
- a >= 0 && this.selected.has(a) && r.classList.add("selected", "row-focus");
2549
- })), n === "range" && this.ranges.length > 0) {
2550
- const r = this.activeRange ? z(this.activeRange) : null;
2551
- e.querySelectorAll(".cell[data-row][data-col]").forEach((a) => {
2552
- const h = parseInt(a.getAttribute("data-row") ?? "-1", 10), u = parseInt(a.getAttribute("data-col") ?? "-1", 10);
2553
- h >= 0 && u >= 0 && ie(h, u, this.ranges) && (a.classList.add("selected"), r && (h === r.startRow && a.classList.add("top"), h === r.endRow && a.classList.add("bottom"), u === r.startCol && a.classList.add("first"), u === r.endCol && a.classList.add("last")));
2627
+ const i = e.querySelectorAll(".data-grid-row");
2628
+ if (i.forEach((s) => {
2629
+ s.classList.remove("selected", "row-focus");
2630
+ }), t === "row" && i.forEach((s) => {
2631
+ const l = s.querySelector(".cell[data-row]"), r = parseInt(l?.getAttribute("data-row") ?? "-1", 10);
2632
+ r >= 0 && this.selected.has(r) && (s.classList.add("selected", "row-focus"), s.querySelectorAll(".cell-focus").forEach((a) => a.classList.remove("cell-focus")));
2633
+ }), t === "range" && this.ranges.length > 0) {
2634
+ const s = this.activeRange ? N(this.activeRange) : null;
2635
+ e.querySelectorAll(".cell[data-row][data-col]").forEach((r) => {
2636
+ const a = parseInt(r.getAttribute("data-row") ?? "-1", 10), f = parseInt(r.getAttribute("data-col") ?? "-1", 10);
2637
+ a >= 0 && f >= 0 && ie(a, f, this.ranges) && (r.classList.add("selected"), r.classList.remove("cell-focus"), s && (a === s.startRow && r.classList.add("top"), a === s.endRow && r.classList.add("bottom"), f === s.startCol && r.classList.add("first"), f === s.endCol && r.classList.add("last")));
2554
2638
  });
2555
2639
  }
2640
+ t === "cell" && this.selectedCell && e.querySelectorAll(".cell-focus").forEach((s) => s.classList.remove("cell-focus"));
2641
+ }
2642
+ afterRender() {
2643
+ const e = this.shadowRoot;
2644
+ if (!e) return;
2645
+ const t = e.children[0], { mode: n } = this.config;
2646
+ this.grid.setAttribute("data-selection-mode", n), t && t.classList.toggle("selecting", this.isDragging), this.#o();
2647
+ }
2648
+ /**
2649
+ * Called after scroll-triggered row rendering.
2650
+ * Reapplies selection classes to recycled DOM elements.
2651
+ */
2652
+ onScrollRender() {
2653
+ this.#o();
2556
2654
  }
2557
2655
  // ===== Public API =====
2558
2656
  /**
@@ -2606,7 +2704,7 @@ class st extends ue {
2606
2704
  }), this.requestAfterRender();
2607
2705
  }
2608
2706
  // ===== Private Helpers =====
2609
- #t() {
2707
+ #i() {
2610
2708
  return tt(
2611
2709
  this.config.mode,
2612
2710
  {
@@ -2656,35 +2754,35 @@ function G(o, e, t) {
2656
2754
  return o.id !== void 0 ? String(o.id) : t ? `${t}-${e}` : String(e);
2657
2755
  }
2658
2756
  function fe(o, e, t, n = null, i = 0) {
2659
- const s = e.childrenField ?? "children", r = [];
2660
- for (let l = 0; l < o.length; l++) {
2661
- const a = o[l], h = G(a, l, n), u = a[s], w = Array.isArray(u) && u.length > 0, c = t.has(h);
2662
- if (r.push({
2663
- key: h,
2757
+ const s = e.childrenField ?? "children", l = [];
2758
+ for (let r = 0; r < o.length; r++) {
2759
+ const a = o[r], f = G(a, r, n), p = a[s], w = Array.isArray(p) && p.length > 0, u = t.has(f);
2760
+ if (l.push({
2761
+ key: f,
2664
2762
  data: a,
2665
2763
  depth: i,
2666
2764
  hasChildren: w,
2667
- isExpanded: c,
2765
+ isExpanded: u,
2668
2766
  parentKey: n
2669
- }), w && c) {
2670
- const d = fe(u, e, t, h, i + 1);
2671
- r.push(...d);
2767
+ }), w && u) {
2768
+ const c = fe(p, e, t, f, i + 1);
2769
+ l.push(...c);
2672
2770
  }
2673
2771
  }
2674
- return r;
2772
+ return l;
2675
2773
  }
2676
- function re(o, e) {
2774
+ function le(o, e) {
2677
2775
  const t = new Set(o);
2678
2776
  return t.has(e) ? t.delete(e) : t.add(e), t;
2679
2777
  }
2680
2778
  function W(o, e, t = null, n = 0) {
2681
2779
  const i = e.childrenField ?? "children", s = /* @__PURE__ */ new Set();
2682
- for (let r = 0; r < o.length; r++) {
2683
- const l = o[r], a = G(l, r, t), h = l[i];
2684
- if (Array.isArray(h) && h.length > 0) {
2780
+ for (let l = 0; l < o.length; l++) {
2781
+ const r = o[l], a = G(r, l, t), f = r[i];
2782
+ if (Array.isArray(f) && f.length > 0) {
2685
2783
  s.add(a);
2686
- const u = W(h, e, a, n + 1);
2687
- for (const w of u) s.add(w);
2784
+ const p = W(f, e, a, n + 1);
2785
+ for (const w of p) s.add(w);
2688
2786
  }
2689
2787
  }
2690
2788
  return s;
@@ -2694,15 +2792,15 @@ function ot() {
2694
2792
  }
2695
2793
  function pe(o, e, t, n = null, i = 0) {
2696
2794
  const s = t.childrenField ?? "children";
2697
- for (let r = 0; r < o.length; r++) {
2698
- const l = o[r], a = G(l, r, n);
2795
+ for (let l = 0; l < o.length; l++) {
2796
+ const r = o[l], a = G(r, l, n);
2699
2797
  if (a === e)
2700
2798
  return [a];
2701
- const h = l[s];
2702
- if (Array.isArray(h) && h.length > 0) {
2703
- const u = pe(h, e, t, a, i + 1);
2704
- if (u)
2705
- return [a, ...u];
2799
+ const f = r[s];
2800
+ if (Array.isArray(f) && f.length > 0) {
2801
+ const p = pe(f, e, t, a, i + 1);
2802
+ if (p)
2803
+ return [a, ...p];
2706
2804
  }
2707
2805
  }
2708
2806
  return null;
@@ -2711,11 +2809,11 @@ function nt(o, e, t, n) {
2711
2809
  const i = pe(o, e, t);
2712
2810
  if (!i) return n;
2713
2811
  const s = new Set(n);
2714
- for (let r = 0; r < i.length - 1; r++)
2715
- s.add(i[r]);
2812
+ for (let l = 0; l < i.length - 1; l++)
2813
+ s.add(i[l]);
2716
2814
  return s;
2717
2815
  }
2718
- function le(o, e = "children") {
2816
+ function re(o, e = "children") {
2719
2817
  if (!Array.isArray(o) || o.length === 0) return !1;
2720
2818
  for (const t of o)
2721
2819
  if (t && Array.isArray(t[e]) && t[e].length > 0)
@@ -2733,7 +2831,7 @@ function it(o) {
2733
2831
  }
2734
2832
  return null;
2735
2833
  }
2736
- class rt extends ue {
2834
+ class lt extends ue {
2737
2835
  name = "tree";
2738
2836
  version = "1.0.0";
2739
2837
  get defaultConfig() {
@@ -2767,12 +2865,12 @@ class rt extends ue {
2767
2865
  detect(e) {
2768
2866
  if (!this.config.autoDetect) return !1;
2769
2867
  const t = this.config.childrenField ?? it(e) ?? "children";
2770
- return le(e, t);
2868
+ return re(e, t);
2771
2869
  }
2772
2870
  // ===== Data Processing =====
2773
2871
  processRows(e) {
2774
2872
  const t = this.config.childrenField ?? "children";
2775
- if (!le(e, t))
2873
+ if (!re(e, t))
2776
2874
  return this.flattenedRows = [], this.rowKeyMap.clear(), [...e];
2777
2875
  this.config.defaultExpanded && !this.initialExpansionDone && (this.expandedKeys = W(e, this.config), this.initialExpansionDone = !0), this.flattenedRows = fe(e, this.config, this.expandedKeys), this.rowKeyMap.clear();
2778
2876
  for (const n of this.flattenedRows)
@@ -2789,24 +2887,27 @@ class rt extends ue {
2789
2887
  if (this.flattenedRows.length === 0) return [...e];
2790
2888
  const t = this.config.indentWidth ?? 20, n = this.config.showExpandIcons ?? !0, i = [...e];
2791
2889
  if (i.length > 0) {
2792
- const s = { ...i[0] }, r = s.viewRenderer;
2793
- s.viewRenderer = (l) => {
2794
- const { value: a, row: h, column: u } = l, w = h.__treeDepth ?? 0, c = h.__treeHasChildren ?? !1, d = h.__treeExpanded ?? !1, p = document.createElement("span");
2795
- if (p.style.display = "flex", p.style.alignItems = "center", p.style.paddingLeft = `${w * t}px`, c && n) {
2796
- const b = document.createElement("span");
2797
- b.className = "tree-toggle", b.textContent = d ? "▼" : "▶", b.style.cursor = "pointer", b.style.marginRight = "4px", b.style.fontSize = "10px", b.setAttribute("data-tree-key", h.__treeKey), p.appendChild(b);
2890
+ const s = { ...i[0] }, l = s.viewRenderer;
2891
+ if (l?.__treeWrapped)
2892
+ return i;
2893
+ const r = (a) => {
2894
+ const { value: f, row: p, column: w } = a, u = p.__treeDepth ?? 0, c = p.__treeHasChildren ?? !1, h = p.__treeExpanded ?? !1, d = document.createElement("span");
2895
+ if (d.style.display = "flex", d.style.alignItems = "center", d.style.paddingLeft = `${u * t}px`, c && n) {
2896
+ const m = document.createElement("span");
2897
+ m.className = "tree-toggle", m.textContent = h ? "▼" : "▶", m.style.cursor = "pointer", m.style.marginRight = "4px", m.style.fontSize = "10px", m.setAttribute("data-tree-key", p.__treeKey), d.appendChild(m);
2798
2898
  } else if (n) {
2799
- const b = document.createElement("span");
2800
- b.style.width = "14px", b.style.display = "inline-block", p.appendChild(b);
2899
+ const m = document.createElement("span");
2900
+ m.style.width = "14px", m.style.display = "inline-block", d.appendChild(m);
2801
2901
  }
2802
- const f = document.createElement("span");
2803
- if (r) {
2804
- const b = r(l);
2805
- b instanceof Node ? f.appendChild(b) : f.textContent = String(b ?? a ?? "");
2902
+ const g = document.createElement("span");
2903
+ if (l) {
2904
+ const m = l(a);
2905
+ m instanceof Node ? g.appendChild(m) : g.textContent = String(m ?? f ?? "");
2806
2906
  } else
2807
- f.textContent = String(a ?? "");
2808
- return p.appendChild(f), p;
2809
- }, i[0] = s;
2907
+ g.textContent = String(f ?? "");
2908
+ return d.appendChild(g), d;
2909
+ };
2910
+ r.__treeWrapped = !0, s.viewRenderer = r, i[0] = s;
2810
2911
  }
2811
2912
  return i;
2812
2913
  }
@@ -2817,7 +2918,7 @@ class rt extends ue {
2817
2918
  const n = t.getAttribute("data-tree-key");
2818
2919
  if (!n) return !1;
2819
2920
  const i = this.rowKeyMap.get(n);
2820
- return i ? (this.expandedKeys = re(this.expandedKeys, n), this.emit("tree-expand", {
2921
+ return i ? (this.expandedKeys = le(this.expandedKeys, n), this.emit("tree-expand", {
2821
2922
  key: n,
2822
2923
  row: i.data,
2823
2924
  expanded: this.expandedKeys.has(n),
@@ -2841,7 +2942,7 @@ class rt extends ue {
2841
2942
  * Toggle the expansion state of a node.
2842
2943
  */
2843
2944
  toggle(e) {
2844
- this.expandedKeys = re(this.expandedKeys, e), this.requestRender();
2945
+ this.expandedKeys = le(this.expandedKeys, e), this.requestRender();
2845
2946
  }
2846
2947
  /**
2847
2948
  * Expand all nodes in the tree.
@@ -2897,7 +2998,7 @@ class rt extends ue {
2897
2998
  }
2898
2999
  `;
2899
3000
  }
2900
- const v = {
3001
+ const y = {
2901
3002
  // Root structure
2902
3003
  ROOT: "tbw-grid-root",
2903
3004
  HEADER: "header",
@@ -2949,23 +3050,23 @@ const v = {
2949
3050
  GROUP_KEY: "data-group-key",
2950
3051
  TREE_LEVEL: "data-tree-level",
2951
3052
  STICKY: "data-sticky"
2952
- }, lt = {
2953
- ROOT: `.${v.ROOT}`,
2954
- HEADER: `.${v.HEADER}`,
2955
- HEADER_ROW: `.${v.HEADER_ROW}`,
2956
- HEADER_CELL: `.${v.HEADER_CELL}`,
2957
- ROWS_VIEWPORT: `.${v.ROWS_VIEWPORT}`,
2958
- ROWS_CONTAINER: `.${v.ROWS_CONTAINER}`,
2959
- DATA_ROW: `.${v.DATA_ROW}`,
2960
- DATA_CELL: `.${v.DATA_CELL}`,
2961
- GROUP_ROW: `.${v.GROUP_ROW}`,
3053
+ }, rt = {
3054
+ ROOT: `.${y.ROOT}`,
3055
+ HEADER: `.${y.HEADER}`,
3056
+ HEADER_ROW: `.${y.HEADER_ROW}`,
3057
+ HEADER_CELL: `.${y.HEADER_CELL}`,
3058
+ ROWS_VIEWPORT: `.${y.ROWS_VIEWPORT}`,
3059
+ ROWS_CONTAINER: `.${y.ROWS_CONTAINER}`,
3060
+ DATA_ROW: `.${y.DATA_ROW}`,
3061
+ DATA_CELL: `.${y.DATA_CELL}`,
3062
+ GROUP_ROW: `.${y.GROUP_ROW}`,
2962
3063
  // By data attribute
2963
- ROW_BY_INDEX: (o) => `.${v.DATA_ROW}[${H.ROW_INDEX}="${o}"]`,
2964
- CELL_BY_FIELD: (o) => `.${v.DATA_CELL}[${H.FIELD}="${o}"]`,
2965
- CELL_AT: (o, e) => `.${v.DATA_ROW}[${H.ROW_INDEX}="${o}"] .${v.DATA_CELL}[${H.COL_INDEX}="${e}"]`,
3064
+ ROW_BY_INDEX: (o) => `.${y.DATA_ROW}[${H.ROW_INDEX}="${o}"]`,
3065
+ CELL_BY_FIELD: (o) => `.${y.DATA_CELL}[${H.FIELD}="${o}"]`,
3066
+ CELL_AT: (o, e) => `.${y.DATA_ROW}[${H.ROW_INDEX}="${o}"] .${y.DATA_CELL}[${H.COL_INDEX}="${e}"]`,
2966
3067
  // State selectors
2967
- SELECTED_ROWS: `.${v.DATA_ROW}.${v.SELECTED}`,
2968
- EDITING_CELL: `.${v.DATA_CELL}.${v.EDITING}`
3068
+ SELECTED_ROWS: `.${y.DATA_ROW}.${y.SELECTED}`,
3069
+ EDITING_CELL: `.${y.DATA_CELL}.${y.EDITING}`
2969
3070
  }, at = {
2970
3071
  // Colors
2971
3072
  COLOR_BG: "--tbw-color-bg",
@@ -3041,7 +3142,7 @@ const v = {
3041
3142
  max: (o, e) => Math.max(...o.map((t) => Number(t[e]) || -1 / 0)),
3042
3143
  first: (o, e) => o[0]?.[e],
3043
3144
  last: (o, e) => o[o.length - 1]?.[e]
3044
- }, P = /* @__PURE__ */ new Map(), R = {
3145
+ }, P = /* @__PURE__ */ new Map(), x = {
3045
3146
  /**
3046
3147
  * Register a custom aggregator function.
3047
3148
  */
@@ -3080,22 +3181,22 @@ const v = {
3080
3181
  list() {
3081
3182
  return [...Object.keys(I), ...P.keys()];
3082
3183
  }
3083
- }, ht = R.register.bind(R), ut = R.unregister.bind(R), ft = R.get.bind(R), pt = R.run.bind(R), wt = R.list.bind(R);
3184
+ }, ht = x.register.bind(x), ut = x.unregister.bind(x), ft = x.get.bind(x), pt = x.run.bind(x), wt = x.list.bind(x);
3084
3185
  export {
3085
3186
  ue as BaseGridPlugin,
3086
3187
  ct as DGEvents,
3087
3188
  q as DataGridElement,
3088
- O as FitModeEnum,
3189
+ M as FitModeEnum,
3089
3190
  at as GridCSSVars,
3090
- v as GridClasses,
3191
+ y as GridClasses,
3091
3192
  H as GridDataAttrs,
3092
3193
  q as GridElement,
3093
- lt as GridSelectors,
3194
+ rt as GridSelectors,
3094
3195
  dt as PluginEvents,
3095
3196
  Ye as PluginManager,
3096
3197
  st as SelectionPlugin,
3097
- rt as TreePlugin,
3098
- R as aggregatorRegistry,
3198
+ lt as TreePlugin,
3199
+ x as aggregatorRegistry,
3099
3200
  ft as getAggregator,
3100
3201
  wt as listAggregators,
3101
3202
  ht as registerAggregator,