@toolbox-web/grid 0.4.2 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (123) hide show
  1. package/README.md +2 -3
  2. package/all.js +1063 -1024
  3. package/all.js.map +1 -1
  4. package/index.js +1078 -912
  5. package/index.js.map +1 -1
  6. package/lib/core/grid.d.ts +28 -0
  7. package/lib/core/grid.d.ts.map +1 -1
  8. package/lib/core/internal/dom-builder.d.ts +2 -0
  9. package/lib/core/internal/dom-builder.d.ts.map +1 -1
  10. package/lib/core/internal/event-delegation.d.ts +21 -0
  11. package/lib/core/internal/event-delegation.d.ts.map +1 -1
  12. package/lib/core/internal/header.d.ts.map +1 -1
  13. package/lib/core/internal/resize.d.ts.map +1 -1
  14. package/lib/core/internal/rows.d.ts +1 -1
  15. package/lib/core/internal/rows.d.ts.map +1 -1
  16. package/lib/core/internal/shell.d.ts +19 -13
  17. package/lib/core/internal/shell.d.ts.map +1 -1
  18. package/lib/core/plugin/base-plugin.d.ts +13 -2
  19. package/lib/core/plugin/base-plugin.d.ts.map +1 -1
  20. package/lib/core/plugin/expander-column.d.ts.map +1 -1
  21. package/lib/core/plugin/plugin-manager.d.ts +6 -2
  22. package/lib/core/plugin/plugin-manager.d.ts.map +1 -1
  23. package/lib/core/types.d.ts +41 -3
  24. package/lib/core/types.d.ts.map +1 -1
  25. package/lib/plugins/clipboard/index.js +22 -11
  26. package/lib/plugins/clipboard/index.js.map +1 -1
  27. package/lib/plugins/column-virtualization/index.js +59 -48
  28. package/lib/plugins/column-virtualization/index.js.map +1 -1
  29. package/lib/plugins/context-menu/index.js +71 -60
  30. package/lib/plugins/context-menu/index.js.map +1 -1
  31. package/lib/plugins/editing/EditingPlugin.d.ts +1 -0
  32. package/lib/plugins/editing/EditingPlugin.d.ts.map +1 -1
  33. package/lib/plugins/editing/index.js +93 -80
  34. package/lib/plugins/editing/index.js.map +1 -1
  35. package/lib/plugins/export/index.js +29 -18
  36. package/lib/plugins/export/index.js.map +1 -1
  37. package/lib/plugins/filtering/FilteringPlugin.d.ts +9 -1
  38. package/lib/plugins/filtering/FilteringPlugin.d.ts.map +1 -1
  39. package/lib/plugins/filtering/index.js +199 -165
  40. package/lib/plugins/filtering/index.js.map +1 -1
  41. package/lib/plugins/grouping-columns/GroupingColumnsPlugin.d.ts +1 -0
  42. package/lib/plugins/grouping-columns/GroupingColumnsPlugin.d.ts.map +1 -1
  43. package/lib/plugins/grouping-columns/index.js +79 -49
  44. package/lib/plugins/grouping-columns/index.js.map +1 -1
  45. package/lib/plugins/grouping-rows/GroupingRowsPlugin.d.ts.map +1 -1
  46. package/lib/plugins/grouping-rows/index.js +98 -87
  47. package/lib/plugins/grouping-rows/index.js.map +1 -1
  48. package/lib/plugins/master-detail/index.js +70 -57
  49. package/lib/plugins/master-detail/index.js.map +1 -1
  50. package/lib/plugins/multi-sort/index.js +48 -37
  51. package/lib/plugins/multi-sort/index.js.map +1 -1
  52. package/lib/plugins/pinned-columns/PinnedColumnsPlugin.d.ts.map +1 -1
  53. package/lib/plugins/pinned-columns/index.js +71 -66
  54. package/lib/plugins/pinned-columns/index.js.map +1 -1
  55. package/lib/plugins/pinned-columns/pinned-columns.d.ts +2 -2
  56. package/lib/plugins/pinned-columns/pinned-columns.d.ts.map +1 -1
  57. package/lib/plugins/pinned-rows/PinnedRowsPlugin.d.ts.map +1 -1
  58. package/lib/plugins/pinned-rows/index.js +63 -52
  59. package/lib/plugins/pinned-rows/index.js.map +1 -1
  60. package/lib/plugins/pivot/PivotPlugin.d.ts.map +1 -1
  61. package/lib/plugins/pivot/index.js +310 -299
  62. package/lib/plugins/pivot/index.js.map +1 -1
  63. package/lib/plugins/reorder/ReorderPlugin.d.ts.map +1 -1
  64. package/lib/plugins/reorder/index.d.ts +1 -1
  65. package/lib/plugins/reorder/index.d.ts.map +1 -1
  66. package/lib/plugins/reorder/index.js +79 -68
  67. package/lib/plugins/reorder/index.js.map +1 -1
  68. package/lib/plugins/selection/SelectionPlugin.d.ts.map +1 -1
  69. package/lib/plugins/selection/index.js +115 -105
  70. package/lib/plugins/selection/index.js.map +1 -1
  71. package/lib/plugins/server-side/index.js +15 -4
  72. package/lib/plugins/server-side/index.js.map +1 -1
  73. package/lib/plugins/tree/TreePlugin.d.ts.map +1 -1
  74. package/lib/plugins/tree/index.js +41 -30
  75. package/lib/plugins/tree/index.js.map +1 -1
  76. package/lib/plugins/undo-redo/index.js +29 -18
  77. package/lib/plugins/undo-redo/index.js.map +1 -1
  78. package/lib/plugins/visibility/VisibilityPlugin.d.ts.map +1 -1
  79. package/lib/plugins/visibility/index.js +59 -47
  80. package/lib/plugins/visibility/index.js.map +1 -1
  81. package/package.json +6 -6
  82. package/public.d.ts +42 -0
  83. package/public.d.ts.map +1 -1
  84. package/themes/dg-theme-bootstrap.css +55 -53
  85. package/themes/dg-theme-contrast.css +42 -40
  86. package/themes/dg-theme-large.css +38 -37
  87. package/themes/dg-theme-material.css +54 -52
  88. package/themes/dg-theme-standard.css +19 -17
  89. package/themes/dg-theme-vibrant.css +16 -14
  90. package/umd/grid.all.umd.js +23 -22
  91. package/umd/grid.all.umd.js.map +1 -1
  92. package/umd/grid.umd.js +15 -14
  93. package/umd/grid.umd.js.map +1 -1
  94. package/umd/plugins/column-virtualization.umd.js +1 -1
  95. package/umd/plugins/column-virtualization.umd.js.map +1 -1
  96. package/umd/plugins/context-menu.umd.js +1 -1
  97. package/umd/plugins/context-menu.umd.js.map +1 -1
  98. package/umd/plugins/editing.umd.js +1 -1
  99. package/umd/plugins/editing.umd.js.map +1 -1
  100. package/umd/plugins/filtering.umd.js +1 -1
  101. package/umd/plugins/filtering.umd.js.map +1 -1
  102. package/umd/plugins/grouping-columns.umd.js +1 -1
  103. package/umd/plugins/grouping-columns.umd.js.map +1 -1
  104. package/umd/plugins/grouping-rows.umd.js +1 -1
  105. package/umd/plugins/grouping-rows.umd.js.map +1 -1
  106. package/umd/plugins/master-detail.umd.js +1 -1
  107. package/umd/plugins/master-detail.umd.js.map +1 -1
  108. package/umd/plugins/multi-sort.umd.js +1 -1
  109. package/umd/plugins/multi-sort.umd.js.map +1 -1
  110. package/umd/plugins/pinned-columns.umd.js +1 -1
  111. package/umd/plugins/pinned-columns.umd.js.map +1 -1
  112. package/umd/plugins/pinned-rows.umd.js +1 -1
  113. package/umd/plugins/pinned-rows.umd.js.map +1 -1
  114. package/umd/plugins/pivot.umd.js +1 -1
  115. package/umd/plugins/pivot.umd.js.map +1 -1
  116. package/umd/plugins/reorder.umd.js +1 -1
  117. package/umd/plugins/reorder.umd.js.map +1 -1
  118. package/umd/plugins/selection.umd.js +1 -1
  119. package/umd/plugins/selection.umd.js.map +1 -1
  120. package/umd/plugins/tree.umd.js +1 -1
  121. package/umd/plugins/tree.umd.js.map +1 -1
  122. package/umd/plugins/visibility.umd.js +1 -1
  123. package/umd/plugins/visibility.umd.js.map +1 -1
package/index.js CHANGED
@@ -1,11 +1,11 @@
1
- const te = ':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-cell-white-space: nowrap;--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: 6px;--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-animation-duration: .2s;--tbw-animation-easing: ease-out;--tbw-animation-enabled: 1;--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-editing-row-bg: var(--tbw-editing-bg);--tbw-editing-row-outline-color: var(--tbw-color-accent);--tbw-editing-row-outline-width: 1px;--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;opacity:.6}:host .header-row>.cell:last-child{border-right:0}:host .header-group-cell:not(:last-child),:host .header-row>.cell.grouped.group-end:not(:last-child){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;content-visibility:auto;contain-intrinsic-size:auto var(--tbw-row-height)}:host .data-grid-row:has(.editing){background:var(--tbw-editing-row-bg);outline:var(--tbw-editing-row-outline-width) solid var(--tbw-editing-row-outline-color);outline-offset:calc(-1 * var(--tbw-editing-row-outline-width))}:host .selecting .data-grid-row>.cell{user-select:none}:host .data-grid-row>.cell.selected:focus-visible,:host .data-grid-row>.cell:focus-visible:not(.cell-focus){outline:none}:host .data-grid-row>.cell{display:block;padding:var(--tbw-cell-padding, 2px 8px);border-bottom:var(--tbw-row-divider);min-height:var(--tbw-row-height);line-height:calc(var(--tbw-row-height) - 5px);border-right:1px solid var(--tbw-color-border-cell);overflow:hidden;min-width:0;white-space:var(--tbw-cell-white-space, nowrap);text-overflow:ellipsis}:host .data-grid-row>.cell>*{overflow:hidden;text-overflow:ellipsis;white-space:inherit;min-width:0}:host .data-grid-row>.cell:last-child{border-right:0}:host .data-grid-row>.cell[data-type=boolean]{text-align:center}:host .data-grid-row>.cell[data-type=boolean] input[type=checkbox]{margin:0;width:var(--tbw-checkbox-size);height:var(--tbw-checkbox-size);vertical-align:middle}:host .data-grid-row>.cell.editing{overflow:hidden;padding:0;display:flex;min-height:calc(var(--tbw-row-height) + 2px)}: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%;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 .header-row>.cell.resizable{position:relative}:host .tbw-editor-host{display:contents}: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([data-has-focus]) .cell-focus,:host([data-has-focus]) .row-focus{outline:var(--tbw-focus-outline);outline-offset:var(--tbw-focus-outline-offset)}: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)}: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: var(--tbw-animation-duration) var(--tbw-animation-easing);--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{position:relative;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;overflow-anchor:none}:host .tbw-tool-panel{position:absolute;top:0;bottom:0;right:0;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;z-index:30;box-shadow:-2px 0 8px var(--tbw-color-shadow)}:host .tbw-tool-panel[data-position=left]{right:auto;left:0;border-left:none;border-right:1px solid var(--tbw-tool-panel-border);box-shadow:2px 0 8px var(--tbw-color-shadow)}:host .tbw-tool-panel.open{width:var(--tbw-tool-panel-width)}:host .tbw-tool-panel-resize{position:absolute;top:0;bottom:0;width:6px;cursor:col-resize;background:transparent;z-index:10;transition:background var(--tbw-transition-duration) var(--tbw-transition-ease)}:host .tbw-tool-panel-resize[data-handle-position=left]{left:0}:host .tbw-tool-panel-resize[data-handle-position=right]{right:0}:host .tbw-tool-panel-resize:hover,:host .tbw-tool-panel-resize.resizing{background:var(--tbw-color-accent)}: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}:host .tbw-accordion{display:flex;flex-direction:column;gap:0}:host .tbw-accordion-section{border-bottom:1px solid var(--tbw-tool-panel-border)}:host .tbw-accordion-section:last-child{border-bottom:none}:host .tbw-accordion-header{display:flex;align-items:center;gap:8px;width:100%;padding:10px 12px;border:none;background:transparent;color:var(--tbw-color-fg);font-size:13px;font-weight:600;text-align:left;cursor:pointer;user-select:none}:host .tbw-accordion-header:hover{background:var(--tbw-color-row-hover)}:host .tbw-accordion-section.single .tbw-accordion-header{cursor:default}:host .tbw-accordion-section.single .tbw-accordion-header:hover{background:transparent}:host .tbw-accordion-chevron{display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;font-size:10px;color:var(--tbw-color-fg-muted);transition:transform .15s ease;flex-shrink:0}:host .tbw-accordion-section.expanded .tbw-accordion-chevron{transform:rotate(90deg)}:host .tbw-accordion-icon{display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;font-size:14px;flex-shrink:0}:host .tbw-accordion-title{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}:host .tbw-accordion-content{display:none}:host .tbw-accordion-section.expanded .tbw-accordion-content{display:block}@media(forced-colors:active){:host{--tbw-color-border: CanvasText;--tbw-color-border-strong: CanvasText;--tbw-color-border-cell: CanvasText;--tbw-color-border-header: CanvasText;--tbw-color-fg: CanvasText;--tbw-color-bg: Canvas;--tbw-color-panel-bg: Canvas;--tbw-color-header-bg: Canvas;--tbw-color-header-fg: CanvasText;--tbw-color-accent: Highlight;--tbw-color-accent-fg: HighlightText;--tbw-color-selection: Highlight;--tbw-color-row-hover: Highlight;--tbw-focus-outline: 2px solid Highlight;--tbw-range-border-color: Highlight}:host .cell:focus,:host .cell.active-cell{outline:2px solid Highlight!important;outline-offset:-2px}:host .data-grid-row[aria-selected=true]{background:Highlight!important;color:HighlightText!important}}@media(prefers-reduced-motion:reduce){:host([data-animation-mode="reduced-motion"]){--tbw-animation-enabled: 0;--tbw-animation-duration: 0ms}}:host([data-animation-mode="off"]){--tbw-animation-enabled: 0;--tbw-animation-duration: 0ms}:host .tbw-expanding{animation:tbw-expand var(--tbw-animation-duration) var(--tbw-animation-easing) forwards;overflow:hidden}:host .tbw-collapsing{animation:tbw-collapse var(--tbw-animation-duration) var(--tbw-animation-easing) forwards;overflow:hidden}@keyframes tbw-expand{0%{opacity:0;max-height:0;transform:translateY(-8px)}to{opacity:1;max-height:500px;transform:translateY(0)}}@keyframes tbw-collapse{0%{opacity:1;max-height:500px;transform:translateY(0)}to{opacity:0;max-height:0;transform:translateY(-8px)}}', W = {
1
+ const re = '@layer tbw-base,tbw-plugins,tbw-theme;@layer tbw-base{:root{color-scheme:light dark}tbw-grid{--tbw-base-icon-size: 1em;--tbw-base-radius: .25em;--tbw-font-size: 1em;--tbw-font-size-sm: .9285em;--tbw-font-size-xs: .7857em;--tbw-font-size-2xs: .7142em;--tbw-spacing-xs: .25em;--tbw-spacing-sm: .375em;--tbw-spacing-md: .5em;--tbw-spacing-lg: .75em;--tbw-spacing-xl: 1em;--tbw-icon-size: var(--tbw-base-icon-size);--tbw-icon-size-sm: .875em;--tbw-checkbox-size: var(--tbw-base-icon-size);--tbw-toggle-size: 1.25em;--tbw-border-radius: var(--tbw-base-radius);--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-error: light-dark(hsl(0, 65%, 51%), hsl(0, 65%, 55%));--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, #666666);--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-header: var(--tbw-font-size);--tbw-font-weight-header: bold;--tbw-cell-padding-header: var(--tbw-spacing-xs) var(--tbw-spacing-md);--tbw-cell-padding: var(--tbw-spacing-xs) var(--tbw-spacing-md);--tbw-cell-padding-input: var(--tbw-spacing-xs) var(--tbw-spacing-sm);--tbw-row-height: 1.75em;--tbw-header-height: 1.875em;--tbw-cell-white-space: nowrap;--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: var(--tbw-spacing-sm);--tbw-resize-handle-color: transparent;--tbw-resize-handle-color-hover: var(--tbw-color-accent);--tbw-resize-handle-border-radius: 0;--tbw-resize-indicator-width: 2px;--tbw-resize-indicator-color: var(--tbw-color-accent);--tbw-resize-indicator-opacity: .6;--tbw-scrollbar-thumb: var(--tbw-color-border-strong);--tbw-scrollbar-track: var(--tbw-color-bg);--tbw-transition-duration: .12s;--tbw-transition-ease: ease;--tbw-animation-duration: .2s;--tbw-animation-easing: ease-out;--tbw-animation-enabled: 1;--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-density-scale: 1;--tbw-shell-header-height: 2.75em;--tbw-shell-header-bg: var(--tbw-color-panel-bg);--tbw-shell-header-border: var(--tbw-color-border);--tbw-shell-title-font-size: var(--tbw-font-size);--tbw-shell-title-font-weight: 600;--tbw-tool-panel-width: 17.5em;--tbw-tool-panel-bg: var(--tbw-color-panel-bg);--tbw-tool-panel-border: var(--tbw-color-border);--tbw-tool-panel-header-height: 2.5em;--tbw-tool-panel-transition: var(--tbw-animation-duration) var(--tbw-animation-easing);--tbw-toolbar-button-size: 2em;--tbw-toolbar-button-gap: var(--tbw-spacing-xs);--tbw-panel-padding: var(--tbw-spacing-lg);--tbw-panel-gap: var(--tbw-spacing-md);--tbw-menu-item-padding: var(--tbw-spacing-sm) var(--tbw-spacing-lg);--tbw-menu-item-gap: var(--tbw-spacing-md);--tbw-menu-min-width: 10rem;--tbw-button-padding: var(--tbw-spacing-sm) var(--tbw-spacing-lg);--tbw-button-padding-sm: var(--tbw-spacing-xs) var(--tbw-spacing-md);--tbw-input-height: var(--tbw-row-height);--tbw-input-padding: 0 var(--tbw-spacing-md);--tbw-detail-padding: var(--tbw-spacing-xl);--tbw-detail-max-height: 31.25rem;--tbw-indicator-size: var(--tbw-spacing-sm);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;&,*{box-sizing:border-box}.header{display:block;flex-shrink:0;z-index:var(--tbw-z-layer-header, 30);background:var(--tbw-color-header-bg);overflow:visible}.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)}.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));&:not(:last-child){border-right:2px solid var(--tbw-color-border)}}.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);>.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:visible;min-width:0;>span:first-child{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}>span[part~=sort-indicator]{flex-shrink:0;opacity:.6}&:last-child{border-right:0}&.grouped.group-end:not(:last-child){border-right:2px solid var(--tbw-color-border)}&.resizable{position:relative}&.sticky-left,&.sticky-right{background:var(--tbw-color-header-bg);z-index:35}}}.tbw-grid-root{display:flex;flex-direction:column;height:100%;&.has-shell{display:flex;flex-direction:column;height:100%}}.rows-body-wrapper{flex:1;min-height:0;display:flex;flex-direction:row;width:100%;min-width:fit-content}.rows-body{flex:1;min-width:0;min-height:0;display:flex;flex-direction:column;overflow:visible}.rows-container{display:flex;flex-direction:row;flex:1;min-height:0;overflow:visible}.rows-viewport{flex:1;min-width:0;position:relative;display:block;overflow:clip;.rows{position:absolute;top:0;left:0;min-width:100%;will-change:transform;z-index:var(--tbw-z-layer-rows, 1)}}.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)}.faux-vscroll-spacer{width:1px}.data-grid-row{display:grid;grid-template-columns:var(--tbw-column-template);contain:layout style;content-visibility:auto;contain-intrinsic-size:auto var(--tbw-row-height);&:nth-child(2n){background:var(--tbw-color-row-alt)}&:hover{background:var(--tbw-color-row-hover)}>.cell{display:block;padding:var(--tbw-cell-padding, 2px 8px);border-bottom:var(--tbw-row-divider);min-height:var(--tbw-row-height);line-height:calc(var(--tbw-row-height) - 5px);border-right:1px solid var(--tbw-color-border-cell);overflow:hidden;min-width:0;white-space:var(--tbw-cell-white-space, nowrap);text-overflow:ellipsis;>*{overflow:hidden;text-overflow:ellipsis;white-space:inherit;min-width:0}&:last-child{border-right:0}&[data-type=boolean]{text-align:center;input[type=checkbox]{margin:0;width:var(--tbw-checkbox-size);height:var(--tbw-checkbox-size);vertical-align:middle}}&.selected:focus-visible,&:focus-visible:not(.cell-focus){outline:none}&.sticky-left,&.sticky-right{background:var(--tbw-color-panel-bg)}}}.selecting .data-grid-row>.cell{user-select:none}.sortable{cursor:pointer;user-select:none}.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);&:after{content:"";position:absolute;top:100%;left:50%;transform:translate(-50%);width:var(--tbw-resize-indicator-width, 2px);height:0;background:var(--tbw-resize-indicator-color, var(--tbw-color-accent));opacity:0;pointer-events:none;transition:opacity .12s ease,height 0s .12s;z-index:1000}&:hover{background:var(--tbw-resize-handle-color-hover);&:after{height:100vh;opacity:var(--tbw-resize-indicator-opacity, .6);transition:opacity .12s ease,height 0s}}}&[data-has-focus]{.cell-focus,.row-focus{outline:var(--tbw-focus-outline);outline-offset:var(--tbw-focus-outline-offset)}}.sticky-left,.sticky-right{position:sticky;z-index:25}.sticky-left{box-shadow:1px 0 0 var(--tbw-color-border)}.sticky-right{box-shadow:-1px 0 0 var(--tbw-color-border)}.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}.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}.tbw-shell-content{flex:1;display:flex;align-items:center;gap:12px;min-width:0;overflow:hidden}.tbw-shell-toolbar{display:flex;align-items:center;gap:var(--tbw-toolbar-button-gap);flex-shrink:0}.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);&:hover{background:var(--tbw-color-row-hover)}&:focus-visible{outline:var(--tbw-focus-outline);outline-offset:var(--tbw-focus-outline-offset)}&.active{background:var(--tbw-focus-background);border-color:var(--tbw-color-accent)}&:disabled{opacity:.5;cursor:not-allowed}}.tbw-toolbar-separator{width:1px;height:20px;background:var(--tbw-color-border);margin:0 4px}.tbw-shell-body{position:relative;display:flex;flex:1;min-height:0;overflow:visible}.tbw-grid-content{flex:1;min-width:0;min-height:0;display:flex;flex-direction:row;overflow:hidden}.tbw-scroll-area{flex:1;min-width:0;min-height:0;display:flex;flex-direction:column;overflow-x:auto;overflow-y:hidden;overflow-anchor:none}.tbw-tool-panel{position:absolute;top:0;bottom:0;right:0;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;z-index:30;box-shadow:-2px 0 8px var(--tbw-color-shadow);&[data-position=left]{right:auto;left:0;border-left:none;border-right:1px solid var(--tbw-tool-panel-border);box-shadow:2px 0 8px var(--tbw-color-shadow)}&.open{width:var(--tbw-tool-panel-width)}}.tbw-tool-panel-resize{position:absolute;top:0;bottom:0;width:6px;cursor:col-resize;background:transparent;z-index:10;transition:background var(--tbw-transition-duration) var(--tbw-transition-ease);&[data-handle-position=left]{left:0}&[data-handle-position=right]{right:0}&:hover,&.resizing{background:var(--tbw-color-accent)}}.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}.tbw-tool-panel-title{font-weight:600;font-size:13px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.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;&:hover{background:var(--tbw-color-row-hover);color:var(--tbw-color-fg)}}.tbw-tool-panel-content{flex:1;overflow:auto}.tbw-accordion{display:flex;flex-direction:column;gap:0}.tbw-accordion-section{border-bottom:1px solid var(--tbw-tool-panel-border);&:last-child{border-bottom:none}&.single .tbw-accordion-header{cursor:default;&:hover{background:transparent}}&.expanded{.tbw-accordion-chevron{transform:rotate(90deg)}.tbw-accordion-content{display:block}}}.tbw-accordion-header{display:flex;align-items:center;gap:8px;width:100%;padding:10px 12px;border:none;background:transparent;color:var(--tbw-color-fg);font-size:13px;font-weight:600;text-align:left;cursor:pointer;user-select:none;&:hover{background:var(--tbw-color-row-hover)}}.tbw-accordion-chevron{display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;font-size:10px;color:var(--tbw-color-fg-muted);transition:transform .15s ease;flex-shrink:0}.tbw-accordion-icon{display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;font-size:14px;flex-shrink:0}.tbw-accordion-title{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tbw-accordion-content{display:none}.tbw-expanding{animation:tbw-expand var(--tbw-animation-duration) var(--tbw-animation-easing) forwards;overflow:hidden}.tbw-collapsing{animation:tbw-collapse var(--tbw-animation-duration) var(--tbw-animation-easing) forwards;overflow:hidden}&[data-animation-mode=off]{--tbw-animation-enabled: 0;--tbw-animation-duration: 0ms}}@media(forced-colors:active){tbw-grid{--tbw-color-border: CanvasText;--tbw-color-border-strong: CanvasText;--tbw-color-border-cell: CanvasText;--tbw-color-border-header: CanvasText;--tbw-color-fg: CanvasText;--tbw-color-bg: Canvas;--tbw-color-panel-bg: Canvas;--tbw-color-header-bg: Canvas;--tbw-color-header-fg: CanvasText;--tbw-color-accent: Highlight;--tbw-color-accent-fg: HighlightText;--tbw-color-selection: Highlight;--tbw-color-row-hover: Highlight;--tbw-focus-outline: 2px solid Highlight;--tbw-range-border-color: Highlight;.cell:focus,.cell.active-cell{outline:2px solid Highlight!important;outline-offset:-2px}.data-grid-row[aria-selected=true]{background:Highlight!important;color:HighlightText!important}}}@media(prefers-reduced-motion:reduce){tbw-grid[data-animation-mode=reduced-motion]{--tbw-animation-enabled: 0;--tbw-animation-duration: 0ms}}@keyframes tbw-expand{0%{opacity:0;max-height:0;transform:translateY(-8px)}to{opacity:1;max-height:500px;transform:translateY(0)}}@keyframes tbw-collapse{0%{opacity:1;max-height:500px;transform:translateY(0)}to{opacity:0;max-height:0;transform:translateY(-8px)}}}', F = {
2
2
  STRETCH: "stretch",
3
3
  FIXED: "fixed"
4
- }, Me = {
4
+ }, Ne = {
5
5
  mode: "reduced-motion",
6
6
  duration: 200,
7
7
  easing: "ease-out"
8
- }, L = {
8
+ }, M = {
9
9
  expand: "▶",
10
10
  collapse: "▼",
11
11
  sortAsc: "▲",
@@ -15,44 +15,44 @@ const te = ':root{color-scheme:light dark}:host{--tbw-color-bg: transparent;--tb
15
15
  dragHandle: "⋮⋮",
16
16
  toolPanel: "☰"
17
17
  };
18
- function ze(t) {
18
+ function ke(t) {
19
19
  return Array.from(t.querySelectorAll("tbw-grid-column")).map((o) => {
20
20
  const i = o.getAttribute("field") || "";
21
21
  if (!i) return null;
22
- const n = o.getAttribute("type") || void 0, s = n && (/* @__PURE__ */ new Set(["number", "string", "date", "boolean", "select", "typeahead"])).has(n) ? n : void 0, l = o.getAttribute("header") || void 0, a = o.hasAttribute("sortable"), c = o.hasAttribute("editable"), h = { field: i, type: s, header: l, sortable: a, editable: c }, d = o.getAttribute("width");
22
+ const n = o.getAttribute("type") || void 0, s = n && (/* @__PURE__ */ new Set(["number", "string", "date", "boolean", "select", "typeahead"])).has(n) ? n : void 0, l = o.getAttribute("header") || void 0, a = o.hasAttribute("sortable"), c = o.hasAttribute("editable"), u = { field: i, type: s, header: l, sortable: a, editable: c }, d = o.getAttribute("width");
23
23
  if (d) {
24
- const v = parseFloat(d);
25
- !isNaN(v) && /^\d+(\.\d+)?$/.test(d.trim()) ? h.width = v : h.width = d;
24
+ const b = parseFloat(d);
25
+ !isNaN(b) && /^\d+(\.\d+)?$/.test(d.trim()) ? u.width = b : u.width = d;
26
26
  }
27
27
  const f = o.getAttribute("minWidth") || o.getAttribute("min-width");
28
28
  if (f) {
29
- const v = parseFloat(f);
30
- isNaN(v) || (h.minWidth = v);
29
+ const b = parseFloat(f);
30
+ isNaN(b) || (u.minWidth = b);
31
31
  }
32
- o.hasAttribute("resizable") && (h.resizable = !0), o.hasAttribute("sizable") && (h.resizable = !0);
33
- const p = o.getAttribute("editor"), u = o.getAttribute("renderer");
34
- p && (h.__editorName = p), u && (h.__rendererName = u);
32
+ o.hasAttribute("resizable") && (u.resizable = !0), o.hasAttribute("sizable") && (u.resizable = !0);
33
+ const p = o.getAttribute("editor"), h = o.getAttribute("renderer");
34
+ p && (u.__editorName = p), h && (u.__rendererName = h);
35
35
  const g = o.getAttribute("options");
36
- g && (h.options = g.split(",").map((v) => {
37
- const [Y, De] = v.includes(":") ? v.split(":") : [v.trim(), v.trim()];
38
- return { value: Y.trim(), label: De?.trim() || Y.trim() };
36
+ g && (u.options = g.split(",").map((b) => {
37
+ const [E, B] = b.includes(":") ? b.split(":") : [b.trim(), b.trim()];
38
+ return { value: E.trim(), label: B?.trim() || E.trim() };
39
39
  }));
40
- const m = o.querySelector("tbw-grid-column-view"), b = o.querySelector("tbw-grid-column-editor"), _ = o.querySelector("tbw-grid-column-header");
41
- m && (h.__viewTemplate = m), b && (h.__editorTemplate = b), _ && (h.__headerTemplate = _);
42
- const C = globalThis.DataGridElement?.getAdapters?.() ?? [], y = m ?? o, R = C.find((v) => v.canHandle(y));
43
- if (R) {
44
- const v = R.createRenderer(y);
45
- v && (h.viewRenderer = v);
40
+ const w = o.querySelector("tbw-grid-column-view"), _ = o.querySelector("tbw-grid-column-editor"), T = o.querySelector("tbw-grid-column-header");
41
+ w && (u.__viewTemplate = w), _ && (u.__editorTemplate = _), T && (u.__headerTemplate = T);
42
+ const m = globalThis.DataGridElement?.getAdapters?.() ?? [], y = w ?? o, S = m.find((b) => b.canHandle(y));
43
+ if (S) {
44
+ const b = S.createRenderer(y);
45
+ b && (u.viewRenderer = b);
46
46
  }
47
- const U = b ?? o, x = C.find((v) => v.canHandle(U));
48
- if (x) {
49
- const v = x.createEditor(U);
50
- v && (h.editor = v);
47
+ const C = _ ?? o, O = m.find((b) => b.canHandle(C));
48
+ if (O) {
49
+ const b = O.createEditor(C);
50
+ b && (u.editor = b);
51
51
  }
52
- return h;
52
+ return u;
53
53
  }).filter((o) => !!o);
54
54
  }
55
- function oe(t, e) {
55
+ function se(t, e) {
56
56
  if ((!t || !t.length) && (!e || !e.length)) return [];
57
57
  if (!t || !t.length) return e || [];
58
58
  if (!e || !e.length) return t;
@@ -76,7 +76,7 @@ function oe(t, e) {
76
76
  });
77
77
  return Object.keys(o).forEach((n) => i.push(o[n])), i;
78
78
  }
79
- function ie(t, e) {
79
+ function le(t, e) {
80
80
  try {
81
81
  t.part?.add?.(e);
82
82
  } catch {
@@ -84,9 +84,9 @@ function ie(t, e) {
84
84
  const o = t.getAttribute("part");
85
85
  o ? o.split(/\s+/).includes(e) || t.setAttribute("part", o + " " + e) : t.setAttribute("part", e);
86
86
  }
87
- function ne(t) {
88
- const e = t.effectiveConfig?.fitMode || t.fitMode || W.STRETCH;
89
- if (e !== W.STRETCH && e !== W.FIXED || t.__didInitialAutoSize || !t.isConnected) return;
87
+ function ae(t) {
88
+ const e = t.effectiveConfig?.fitMode || t.fitMode || F.STRETCH;
89
+ if (e !== F.STRETCH && e !== F.FIXED || t.__didInitialAutoSize || !t.isConnected) return;
90
90
  const o = Array.from(t._headerRowEl?.children || []);
91
91
  if (!o.length) return;
92
92
  let i = !1;
@@ -97,37 +97,37 @@ function ne(t) {
97
97
  for (const a of t._rowPool) {
98
98
  const c = a.children[r];
99
99
  if (c) {
100
- const h = c.scrollWidth;
101
- h > l && (l = h);
100
+ const u = c.scrollWidth;
101
+ u > l && (l = u);
102
102
  }
103
103
  }
104
104
  l > 0 && (n.width = l + 2, n.__autoSized = !0, i = !0);
105
- }), i && q(t), t.__didInitialAutoSize = !0;
105
+ }), i && $(t), t.__didInitialAutoSize = !0;
106
106
  }
107
- function q(t) {
108
- (t.effectiveConfig?.fitMode || t.fitMode || W.STRETCH) === W.STRETCH ? t._gridTemplate = t._visibleColumns.map((o) => {
107
+ function $(t) {
108
+ (t.effectiveConfig?.fitMode || t.fitMode || F.STRETCH) === F.STRETCH ? t._gridTemplate = t._visibleColumns.map((o) => {
109
109
  if (o.width) return `${o.width}px`;
110
110
  const i = o.minWidth;
111
111
  return i != null ? `minmax(${i}px, 1fr)` : "1fr";
112
112
  }).join(" ").trim() : t._gridTemplate = t._visibleColumns.map((o) => o.width ? `${o.width}px` : "max-content").join(" "), t.style.setProperty("--tbw-column-template", t._gridTemplate);
113
113
  }
114
- function Ne(t) {
114
+ function Ie(t) {
115
115
  return t == null ? "string" : typeof t == "number" ? "number" : typeof t == "boolean" ? "boolean" : t instanceof Date || typeof t == "string" && /\d{4}-\d{2}-\d{2}/.test(t) && !isNaN(Date.parse(t)) ? "date" : "string";
116
116
  }
117
- function ke(t, e) {
117
+ function qe(t, e) {
118
118
  const o = t[0] || {}, i = Object.keys(o).map((r) => {
119
- const s = o[r], l = Ne(s);
119
+ const s = o[r], l = Ie(s);
120
120
  return { field: r, header: r.charAt(0).toUpperCase() + r.slice(1), type: l };
121
121
  }), n = {};
122
122
  return i.forEach((r) => {
123
123
  n[r.field] = r.type || "string";
124
124
  }), { columns: i, typeMap: n };
125
125
  }
126
- const Ie = /{{\s*([^}]+)\s*}}/g, A = "__DG_EMPTY__", qe = /^[\w$. '?+\-*/%:()!<>=,&|]+$/, Be = /__(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/;
127
- function We(t) {
126
+ const Be = /{{\s*([^}]+)\s*}}/g, L = "__DG_EMPTY__", We = /^[\w$. '?+\-*/%:()!<>=,&|]+$/, $e = /__(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/;
127
+ function Ue(t) {
128
128
  return !t || typeof t != "string" ? "" : t.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
129
129
  }
130
- const Ue = /* @__PURE__ */ new Set([
130
+ const Fe = /* @__PURE__ */ new Set([
131
131
  "script",
132
132
  "iframe",
133
133
  "object",
@@ -152,23 +152,23 @@ const Ue = /* @__PURE__ */ new Set([
152
152
  "plaintext",
153
153
  "xmp",
154
154
  "listing"
155
- ]), re = /^on\w+$/i, $e = /* @__PURE__ */ new Set(["href", "src", "action", "formaction", "data", "srcdoc", "xlink:href", "poster", "srcset"]), Fe = /^\s*(javascript|vbscript|data|blob):/i;
156
- function G(t) {
155
+ ]), ce = /^on\w+$/i, Ve = /* @__PURE__ */ new Set(["href", "src", "action", "formaction", "data", "srcdoc", "xlink:href", "poster", "srcset"]), Ge = /^\s*(javascript|vbscript|data|blob):/i;
156
+ function j(t) {
157
157
  if (!t || typeof t != "string") return "";
158
158
  if (t.indexOf("<") === -1) return t;
159
159
  const e = document.createElement("template");
160
- return e.innerHTML = t, Ve(e.content), e.innerHTML;
160
+ return e.innerHTML = t, Xe(e.content), e.innerHTML;
161
161
  }
162
- function Ve(t) {
162
+ function Xe(t) {
163
163
  const e = [], o = t.querySelectorAll("*");
164
164
  for (const i of o) {
165
165
  const n = i.tagName.toLowerCase();
166
- if (Ue.has(n)) {
166
+ if (Fe.has(n)) {
167
167
  e.push(i);
168
168
  continue;
169
169
  }
170
170
  if ((n === "svg" || i.namespaceURI === "http://www.w3.org/2000/svg") && Array.from(i.attributes).some(
171
- (l) => re.test(l.name) || l.name === "href" || l.name === "xlink:href"
171
+ (l) => ce.test(l.name) || l.name === "href" || l.name === "xlink:href"
172
172
  )) {
173
173
  e.push(i);
174
174
  continue;
@@ -176,11 +176,11 @@ function Ve(t) {
176
176
  const r = [];
177
177
  for (const s of i.attributes) {
178
178
  const l = s.name.toLowerCase();
179
- if (re.test(l)) {
179
+ if (ce.test(l)) {
180
180
  r.push(s.name);
181
181
  continue;
182
182
  }
183
- if ($e.has(l) && Fe.test(s.value)) {
183
+ if (Ve.has(l) && Ge.test(s.value)) {
184
184
  r.push(s.name);
185
185
  continue;
186
186
  }
@@ -193,35 +193,35 @@ function Ve(t) {
193
193
  }
194
194
  e.forEach((i) => i.remove());
195
195
  }
196
- function ve(t, e) {
196
+ function _e(t, e) {
197
197
  if (!t || t.indexOf("{{") === -1) return t;
198
- const o = [], i = t.replace(Ie, (l, a) => {
199
- const c = Ge(a, e);
198
+ const o = [], i = t.replace(Be, (l, a) => {
199
+ const c = Ye(a, e);
200
200
  return o.push({ expr: a.trim(), result: c }), c;
201
- }), n = Xe(i), r = o.length && o.every((l) => l.result === "" || l.result === A);
201
+ }), n = je(i), r = o.length && o.every((l) => l.result === "" || l.result === L);
202
202
  return /Reflect\.|\bProxy\b|ownKeys\(/.test(t) || r ? "" : n;
203
203
  }
204
- function Ge(t, e) {
205
- if (t = (t || "").trim(), !t || /\b(Reflect|Proxy|ownKeys)\b/.test(t)) return A;
206
- if (t === "value") return e.value == null ? A : String(e.value);
204
+ function Ye(t, e) {
205
+ if (t = (t || "").trim(), !t || /\b(Reflect|Proxy|ownKeys)\b/.test(t)) return L;
206
+ if (t === "value") return e.value == null ? L : String(e.value);
207
207
  if (t.startsWith("row.") && !/[()?]/.test(t) && !t.includes(":")) {
208
208
  const i = t.slice(4), n = e.row ? e.row[i] : void 0;
209
- return n == null ? A : String(n);
209
+ return n == null ? L : String(n);
210
210
  }
211
- if (t.length > 80 || !qe.test(t) || Be.test(t)) return A;
211
+ if (t.length > 80 || !We.test(t) || $e.test(t)) return L;
212
212
  const o = t.match(/\./g);
213
- if (o && o.length > 1) return A;
213
+ if (o && o.length > 1) return L;
214
214
  try {
215
215
  const n = new Function("value", "row", `return (${t});`)(e.value, e.row), r = n == null ? "" : String(n);
216
- return /Reflect|Proxy|ownKeys/.test(r) ? A : r || A;
216
+ return /Reflect|Proxy|ownKeys/.test(r) ? L : r || L;
217
217
  } catch {
218
- return A;
218
+ return L;
219
219
  }
220
220
  }
221
- function Xe(t) {
222
- return t && t.replace(new RegExp(A, "g"), "").replace(/Reflect\.[^<>{}\s]+/g, "").replace(/\bProxy\b/g, "").replace(/ownKeys\([^)]*\)/g, "");
221
+ function je(t) {
222
+ return t && t.replace(new RegExp(L, "g"), "").replace(/Reflect\.[^<>{}\s]+/g, "").replace(/\bProxy\b/g, "").replace(/ownKeys\([^)]*\)/g, "");
223
223
  }
224
- function Ye(t) {
224
+ function Ke(t) {
225
225
  if (/Reflect|Proxy|ownKeys/.test(t.textContent || "")) {
226
226
  if (Array.from(t.childNodes).forEach((e) => {
227
227
  e.nodeType === Node.TEXT_NODE && /Reflect|Proxy|ownKeys/.test(e.textContent || "") && (e.textContent = "");
@@ -233,16 +233,16 @@ function Ye(t) {
233
233
  (t.textContent || "").trim().length === 0 && (t.textContent = "");
234
234
  }
235
235
  }
236
- function se(t) {
237
- const e = /Reflect\.|\bProxy\b|ownKeys\(/.test(t), o = ((i) => e ? "" : ve(t, i));
236
+ function de(t) {
237
+ const e = /Reflect\.|\bProxy\b|ownKeys\(/.test(t), o = ((i) => e ? "" : _e(t, i));
238
238
  return o.__blocked = e, o;
239
239
  }
240
- const je = 100;
241
- class Ke {
240
+ const Ze = 100;
241
+ class Je {
242
242
  // ============================================================================
243
243
  // Sources (raw input from user)
244
244
  // ============================================================================
245
- #o;
245
+ #i;
246
246
  #c;
247
247
  #f;
248
248
  #d;
@@ -269,12 +269,12 @@ class Ke {
269
269
  // ============================================================================
270
270
  #p = !0;
271
271
  #l = [];
272
- #v;
273
272
  #w;
273
+ #m;
274
274
  #b;
275
275
  #s;
276
276
  // Shell state (Light DOM title)
277
- #m;
277
+ #y;
278
278
  constructor(e) {
279
279
  this.#s = e;
280
280
  }
@@ -315,11 +315,11 @@ class Ke {
315
315
  }
316
316
  /** Get light DOM title */
317
317
  get lightDomTitle() {
318
- return this.#m;
318
+ return this.#y;
319
319
  }
320
320
  /** Set light DOM title */
321
321
  set lightDomTitle(e) {
322
- this.#m = e;
322
+ this.#y = e;
323
323
  }
324
324
  /** Get initial column state */
325
325
  get initialColumnState() {
@@ -351,11 +351,11 @@ class Ke {
351
351
  // ============================================================================
352
352
  /** Set gridConfig source */
353
353
  setGridConfig(e) {
354
- this.#o = e, this.#p = !0, this.#r = void 0;
354
+ this.#i = e, this.#p = !0, this.#r = void 0;
355
355
  }
356
356
  /** Get the raw gridConfig source */
357
357
  getGridConfig() {
358
- return this.#o;
358
+ return this.#i;
359
359
  }
360
360
  /** Set columns source */
361
361
  setColumns(e) {
@@ -404,13 +404,13 @@ class Ke {
404
404
  if (!this.#p && e)
405
405
  return;
406
406
  const o = this.#_();
407
- this.#p = !1, this.#h = o, Object.freeze(this.#h), this.#h.columns && Object.freeze(this.#h.columns), this.#u = this.#A(this.#h), this.#g();
407
+ this.#p = !1, this.#h = o, Object.freeze(this.#h), this.#h.columns && Object.freeze(this.#h.columns), this.#u = this.#g(this.#h), this.#v();
408
408
  }
409
409
  /**
410
410
  * Deep clone a config object, handling functions (renderers, editors).
411
411
  * Uses structuredClone where possible, with fallback for function properties.
412
412
  */
413
- #A(e) {
413
+ #g(e) {
414
414
  const o = { ...e };
415
415
  return e.columns && (o.columns = e.columns.map((i) => ({ ...i }))), e.shell && (o.shell = {
416
416
  ...e.shell,
@@ -424,7 +424,7 @@ class Ke {
424
424
  * Apply operations that depend on the merged effective config.
425
425
  * These were previously in grid.ts #mergeEffectiveConfig().
426
426
  */
427
- #g() {
427
+ #v() {
428
428
  const e = this.#u;
429
429
  e.rowHeight && e.rowHeight > 0 && this.#s.setRowHeight(e.rowHeight), e.fitMode === "fixed" && this.columns.forEach((i) => {
430
430
  i.width == null && (i.width = 80);
@@ -446,23 +446,23 @@ class Ke {
446
446
  * Runtime state (hidden, width) is NOT preserved here - that's in effectiveConfig.
447
447
  */
448
448
  #_() {
449
- const e = this.#o ? { ...this.#o } : {}, o = Array.isArray(e.columns) ? [...e.columns] : [], i = (this.#r ?? []).map((s) => ({
449
+ const e = this.#i ? { ...this.#i } : {}, o = Array.isArray(e.columns) ? [...e.columns] : [], i = (this.#r ?? []).map((s) => ({
450
450
  ...s
451
451
  }));
452
- let n = oe(
452
+ let n = se(
453
453
  o,
454
454
  i
455
455
  );
456
- this.#c && this.#c.length && (n = oe(
456
+ this.#c && this.#c.length && (n = se(
457
457
  this.#c,
458
458
  i
459
459
  ));
460
460
  const r = this.#s.getRows();
461
- return n.length === 0 && r.length && (n = ke(r).columns), n.length && (n.forEach((s) => {
461
+ return n.length === 0 && r.length && (n = qe(r).columns), n.length && (n.forEach((s) => {
462
462
  s.sortable === void 0 && (s.sortable = !0), s.resizable === void 0 && (s.resizable = !0), s.__originalWidth === void 0 && typeof s.width == "number" && (s.__originalWidth = s.width);
463
463
  }), n.forEach((s) => {
464
- s.__viewTemplate && !s.__compiledView && (s.__compiledView = se(s.__viewTemplate.innerHTML)), s.__editorTemplate && !s.__compiledEditor && (s.__compiledEditor = se(s.__editorTemplate.innerHTML));
465
- }), e.columns = n), this.#f && (e.fitMode = this.#f), e.fitMode || (e.fitMode = "stretch"), this.#d && (e.editOn = this.#d), this.#y(e), e.columnState && !this.#b && (this.#b = e.columnState), e;
464
+ s.__viewTemplate && !s.__compiledView && (s.__compiledView = de(s.__viewTemplate.innerHTML)), s.__editorTemplate && !s.__compiledEditor && (s.__compiledEditor = de(s.__editorTemplate.innerHTML));
465
+ }), e.columns = n), this.#f && (e.fitMode = this.#f), e.fitMode || (e.fitMode = "stretch"), this.#d && (e.editOn = this.#d), this.#C(e), e.columnState && !this.#b && (this.#b = e.columnState), e;
466
466
  }
467
467
  /**
468
468
  * Merge shell state into base config's shell property.
@@ -471,10 +471,10 @@ class Ke {
471
471
  * IMPORTANT: This method must NOT mutate the original gridConfig.
472
472
  * We shallow-clone the shell hierarchy to avoid side effects.
473
473
  */
474
- #y(e) {
474
+ #C(e) {
475
475
  e.shell = e.shell ? { ...e.shell } : {}, e.shell.header = e.shell.header ? { ...e.shell.header } : {};
476
476
  const o = this.#s.getShellLightDomTitle();
477
- o && (this.#m = o), this.#m && !e.shell.header.title && (e.shell.header.title = this.#m);
477
+ o && (this.#y = o), this.#y && !e.shell.header.title && (e.shell.header.title = this.#y);
478
478
  const i = this.#s.getShellLightDomHeaderContent();
479
479
  i?.length > 0 && (e.shell.header.lightDomContent = i), this.#s.getShellHasToolButtonsContainer() && (e.shell.header.hasToolButtonsContainer = !0);
480
480
  const n = this.#s.getShellToolPanels();
@@ -487,10 +487,10 @@ class Ke {
487
487
  const d = Array.from(r.values());
488
488
  d.sort((f, p) => (f.order ?? 100) - (p.order ?? 100)), e.shell.headerContents = d;
489
489
  }
490
- const s = this.#s.getShellToolbarButtons(), l = Array.from(s.values()), a = this.#o?.shell?.header?.toolbarButtons ?? [], c = new Set(a.map((d) => d.id)), h = [...a];
490
+ const s = this.#s.getShellToolbarButtons(), l = Array.from(s.values()), a = this.#i?.shell?.header?.toolbarButtons ?? [], c = new Set(a.map((d) => d.id)), u = [...a];
491
491
  for (const d of l)
492
- c.has(d.id) || h.push(d);
493
- h.sort((d, f) => (d.order ?? 100) - (f.order ?? 100)), e.shell.header.toolbarButtons = h;
492
+ c.has(d.id) || u.push(d);
493
+ u.sort((d, f) => (d.order ?? 100) - (f.order ?? 100)), e.shell.header.toolbarButtons = u;
494
494
  }
495
495
  // ============================================================================
496
496
  // State Persistence (Replaces column-state.ts)
@@ -500,7 +500,7 @@ class Ke {
500
500
  * Returns only the changes from the original configuration.
501
501
  */
502
502
  collectState(e) {
503
- const o = this.columns, i = this.#C();
503
+ const o = this.columns, i = this.#z();
504
504
  return {
505
505
  columns: o.map((n, r) => {
506
506
  const s = {
@@ -513,8 +513,8 @@ class Ke {
513
513
  a && (s.sort = a);
514
514
  for (const c of e)
515
515
  if (c.getColumnState) {
516
- const h = c.getColumnState(n.field);
517
- h && Object.assign(s, h);
516
+ const u = c.getColumnState(n.field);
517
+ u && Object.assign(s, u);
518
518
  }
519
519
  return s;
520
520
  })
@@ -532,8 +532,8 @@ class Ke {
532
532
  return a.width !== void 0 && (c.width = a.width, c.__renderedWidth = a.width), a.visible !== void 0 && (c.hidden = !a.visible), c;
533
533
  });
534
534
  r.sort((l, a) => {
535
- const c = n.get(l.field)?.order ?? 1 / 0, h = n.get(a.field)?.order ?? 1 / 0;
536
- return c - h;
535
+ const c = n.get(l.field)?.order ?? 1 / 0, u = n.get(a.field)?.order ?? 1 / 0;
536
+ return c - u;
537
537
  }), this.columns = r;
538
538
  const s = e.columns.filter((l) => l.sort !== void 0).sort((l, a) => (l.sort?.priority ?? 0) - (a.sort?.priority ?? 0));
539
539
  if (s.length > 0) {
@@ -557,7 +557,7 @@ class Ke {
557
557
  * the state to what was compiled from sources.
558
558
  */
559
559
  resetState(e) {
560
- this.#b = void 0, this.#s.setSortState(null), this.#u = this.#A(this.#h), this.#g();
560
+ this.#b = void 0, this.#s.setSortState(null), this.#u = this.#g(this.#h), this.#v();
561
561
  for (const o of e)
562
562
  if (o.applyColumnState)
563
563
  for (const i of this.columns)
@@ -571,7 +571,7 @@ class Ke {
571
571
  /**
572
572
  * Get sort state as a map.
573
573
  */
574
- #C() {
574
+ #z() {
575
575
  const e = /* @__PURE__ */ new Map(), o = this.#s.getSortState();
576
576
  return o && e.set(o.field, {
577
577
  direction: o.direction === 1 ? "asc" : "desc",
@@ -582,11 +582,11 @@ class Ke {
582
582
  * Request a debounced state change event.
583
583
  */
584
584
  requestStateChange(e) {
585
- this.#w && clearTimeout(this.#w), this.#w = setTimeout(() => {
586
- this.#w = void 0;
585
+ this.#m && clearTimeout(this.#m), this.#m = setTimeout(() => {
586
+ this.#m = void 0;
587
587
  const o = this.collectState(e);
588
588
  this.#s.emit("column-state-change", o);
589
- }, je);
589
+ }, Ze);
590
590
  }
591
591
  // ============================================================================
592
592
  // Column Visibility API
@@ -665,7 +665,7 @@ class Ke {
665
665
  * Parse light DOM columns from host element.
666
666
  */
667
667
  parseLightDomColumns(e) {
668
- this.#r || (this.#n = Array.from(e.querySelectorAll("tbw-grid-column")), this.#r = this.#n.length ? ze(e) : []);
668
+ this.#r || (this.#n = Array.from(e.querySelectorAll("tbw-grid-column")), this.#r = this.#n.length ? ke(e) : []);
669
669
  }
670
670
  /**
671
671
  * Clear the light DOM columns cache.
@@ -680,7 +680,7 @@ class Ke {
680
680
  * This is a generic mechanism - plugins (or future ShellPlugin) register
681
681
  * what elements they care about and handle parsing themselves.
682
682
  */
683
- #S = /* @__PURE__ */ new Map();
683
+ #o = /* @__PURE__ */ new Map();
684
684
  /**
685
685
  * Register a handler for Light DOM element changes.
686
686
  * When elements matching the tag name are added/removed/changed,
@@ -690,13 +690,13 @@ class Ke {
690
690
  * @param callback - Called when matching elements change
691
691
  */
692
692
  registerLightDomHandler(e, o) {
693
- this.#S.set(e.toLowerCase(), o);
693
+ this.#o.set(e.toLowerCase(), o);
694
694
  }
695
695
  /**
696
696
  * Unregister a Light DOM element handler.
697
697
  */
698
698
  unregisterLightDomHandler(e) {
699
- this.#S.delete(e.toLowerCase());
699
+ this.#o.delete(e.toLowerCase());
700
700
  }
701
701
  /**
702
702
  * Set up MutationObserver to watch for Light DOM changes.
@@ -713,29 +713,29 @@ class Ke {
713
713
  * @param host - The host element to observe (the grid element)
714
714
  */
715
715
  observeLightDOM(e) {
716
- this.#v && this.#v.disconnect();
716
+ this.#w && this.#w.disconnect();
717
717
  const o = /* @__PURE__ */ new Set();
718
718
  let i = null;
719
719
  const n = () => {
720
720
  i = null;
721
721
  for (const r of o)
722
- this.#S.get(r)?.();
722
+ this.#o.get(r)?.();
723
723
  o.clear();
724
724
  };
725
- this.#v = new MutationObserver((r) => {
725
+ this.#w = new MutationObserver((r) => {
726
726
  for (const s of r) {
727
727
  for (const l of s.addedNodes) {
728
728
  if (l.nodeType !== Node.ELEMENT_NODE) continue;
729
729
  const c = l.tagName.toLowerCase();
730
- this.#S.has(c) && o.add(c);
730
+ this.#o.has(c) && o.add(c);
731
731
  }
732
732
  if (s.type === "attributes" && s.target.nodeType === Node.ELEMENT_NODE) {
733
733
  const a = s.target.tagName.toLowerCase();
734
- this.#S.has(a) && o.add(a);
734
+ this.#o.has(a) && o.add(a);
735
735
  }
736
736
  }
737
737
  o.size > 0 && !i && (i = setTimeout(n, 0));
738
- }), this.#v.observe(e, {
738
+ }), this.#w.observe(e, {
739
739
  childList: !0,
740
740
  subtree: !0,
741
741
  attributes: !0,
@@ -765,13 +765,13 @@ class Ke {
765
765
  * Dispose of the ConfigManager and clean up resources.
766
766
  */
767
767
  dispose() {
768
- this.#v?.disconnect(), this.#l = [], this.#w && clearTimeout(this.#w);
768
+ this.#w?.disconnect(), this.#l = [], this.#m && clearTimeout(this.#m);
769
769
  }
770
770
  }
771
- function Ce(t) {
771
+ function Ee(t) {
772
772
  return `<span role="checkbox" aria-checked="${t}" aria-label="${t}">${t ? "&#x1F5F9;" : "&#9744;"}</span>`;
773
773
  }
774
- function _e(t) {
774
+ function Se(t) {
775
775
  if (t == null || t === "") return "";
776
776
  if (t instanceof Date)
777
777
  return isNaN(t.getTime()) ? "" : t.toLocaleDateString();
@@ -781,7 +781,7 @@ function _e(t) {
781
781
  }
782
782
  return "";
783
783
  }
784
- function ye(t) {
784
+ function Te(t) {
785
785
  if (!t) return -1;
786
786
  const e = t.getAttribute("data-row");
787
787
  if (e) return parseInt(e, 10);
@@ -794,136 +794,40 @@ function ye(t) {
794
794
  if (n[r] === o) return r;
795
795
  return -1;
796
796
  }
797
- function Ze(t) {
797
+ function Qe(t) {
798
798
  if (!t) return -1;
799
799
  const e = t.getAttribute("data-col");
800
800
  return e ? parseInt(e, 10) : -1;
801
801
  }
802
- function ee(t) {
802
+ function ie(t) {
803
803
  t && t.querySelectorAll(".cell-focus").forEach((e) => e.classList.remove("cell-focus"));
804
804
  }
805
- function Je(t, e) {
806
- const o = ye(e), i = Ze(e);
807
- o < 0 || i < 0 || (t._focusRow = o, t._focusCol = i, ee(t._bodyEl), e.classList.add("cell-focus"), e.setAttribute("aria-selected", "true"));
808
- }
809
- function Qe(t, e, o) {
810
- e.addEventListener(
811
- "mousedown",
812
- (i) => {
813
- const n = i.target.closest(".cell[data-col]");
814
- n && (n.classList.contains("editing") || Je(t, n));
815
- },
816
- { signal: o }
817
- );
818
- }
819
- function et(t, e) {
820
- return t == null && e == null ? 0 : t == null ? -1 : e == null || t > e ? 1 : t < e ? -1 : 0;
821
- }
822
- function tt(t, e, o) {
823
- const n = o.find((l) => l.field === e.field)?.sortComparator ?? et, { field: r, direction: s } = e;
824
- return [...t].sort((l, a) => n(l[r], a[r], l, a) * s);
825
- }
826
- function le(t, e, o, i) {
827
- t._rows = e, t.__rowRenderEpoch++, t._rowPool.forEach((n) => n.__epoch = -1), X(t), t.refreshVirtualWindow(!0), t.dispatchEvent(
828
- new CustomEvent("sort-change", { detail: { field: o.field, direction: i } })
829
- ), t.requestStateChange?.();
830
- }
831
- function ae(t, e) {
832
- !t._sortState || t._sortState.field !== e.field ? (t._sortState || (t.__originalOrder = t._rows.slice()), ce(t, e, 1)) : t._sortState.direction === 1 ? ce(t, e, -1) : (t._sortState = null, t.__rowRenderEpoch++, t._rowPool.forEach((i) => i.__epoch = -1), t._rows = t.__originalOrder.slice(), X(t), t._headerRowEl?.querySelectorAll('[role="columnheader"].sortable')?.forEach((i) => {
833
- i.getAttribute("aria-sort") ? (i.getAttribute("aria-sort") === "ascending" || i.getAttribute("aria-sort") === "descending") && (t._sortState || i.setAttribute("aria-sort", "none")) : i.setAttribute("aria-sort", "none");
834
- }), t.refreshVirtualWindow(!0), t.dispatchEvent(
835
- new CustomEvent("sort-change", { detail: { field: e.field, direction: 0 } })
836
- ), t.requestStateChange?.());
837
- }
838
- function ce(t, e, o) {
839
- t._sortState = { field: e.field, direction: o };
840
- const i = { field: e.field, direction: o }, n = t._columns, s = (t.effectiveConfig?.sortHandler ?? tt)(t._rows, i, n);
841
- s && typeof s.then == "function" ? s.then((l) => {
842
- le(t, l, e, o);
843
- }) : le(t, s, e, o);
844
- }
845
- function ot(t, e) {
846
- typeof e == "string" ? t.textContent = e : e instanceof HTMLElement && (t.innerHTML = "", t.appendChild(e.cloneNode(!0)));
847
- }
848
- function X(t) {
849
- t._headerRowEl = t.findHeaderRow();
850
- const e = t._headerRowEl;
851
- e.innerHTML = "", t._visibleColumns.forEach((o, i) => {
852
- const n = document.createElement("div");
853
- n.className = "cell", ie(n, "header-cell"), n.setAttribute("role", "columnheader"), n.setAttribute("aria-colindex", String(i + 1)), n.setAttribute("data-field", o.field), n.setAttribute("data-col", String(i));
854
- const r = o.__headerTemplate;
855
- if (r) Array.from(r.childNodes).forEach((s) => n.appendChild(s.cloneNode(!0)));
856
- else {
857
- const s = o.header || o.field, l = document.createElement("span");
858
- l.textContent = s, n.appendChild(l);
859
- }
860
- if (o.sortable) {
861
- n.classList.add("sortable"), n.tabIndex = 0;
862
- const s = document.createElement("span");
863
- ie(s, "sort-indicator");
864
- const l = t._sortState?.field === o.field ? t._sortState.direction : 0, a = { ...L, ...t.icons }, c = l === 1 ? a.sortAsc : l === -1 ? a.sortDesc : a.sortNone;
865
- ot(s, c), n.appendChild(s), n.setAttribute("aria-sort", l === 0 ? "none" : l === 1 ? "ascending" : "descending"), n.addEventListener("click", (h) => {
866
- t._resizeController?.isResizing || t._dispatchHeaderClick?.(h, i, n) || ae(t, o);
867
- }), n.addEventListener("keydown", (h) => {
868
- if (h.key === "Enter" || h.key === " ") {
869
- if (h.preventDefault(), t._dispatchHeaderClick?.(h, i, n)) return;
870
- ae(t, o);
871
- }
872
- });
873
- }
874
- if (o.resizable) {
875
- n.classList.add("resizable");
876
- const s = document.createElement("div");
877
- s.className = "resize-handle", s.setAttribute("aria-hidden", "true"), s.addEventListener("mousedown", (l) => {
878
- l.stopPropagation(), l.preventDefault(), t._resizeController.start(l, i, n);
879
- }), s.addEventListener("dblclick", (l) => {
880
- l.stopPropagation(), l.preventDefault(), t._resizeController.resetColumn(i);
881
- }), n.appendChild(s);
882
- }
883
- e.appendChild(n);
884
- }), e.querySelectorAll(".cell.sortable").forEach((o) => {
885
- o.getAttribute("aria-sort") || o.setAttribute("aria-sort", "none");
886
- }), e.children.length > 0 ? (e.setAttribute("role", "row"), e.setAttribute("aria-rowindex", "1")) : (e.removeAttribute("role"), e.removeAttribute("aria-rowindex"));
887
- }
888
- const Ee = typeof requestIdleCallback == "function";
889
- function it(t, e) {
890
- return Ee ? requestIdleCallback(t, e) : window.setTimeout(() => {
891
- const o = Date.now();
892
- t({
893
- didTimeout: !1,
894
- timeRemaining: () => Math.max(0, 50 - (Date.now() - o))
895
- });
896
- }, 1);
897
- }
898
- function de(t) {
899
- Ee ? cancelIdleCallback(t) : clearTimeout(t);
900
- }
901
- const Se = 'input,select,textarea,[contenteditable="true"],[contenteditable=""],[tabindex]:not([tabindex="-1"])';
902
- function j(t) {
805
+ const Re = 'input,select,textarea,[contenteditable="true"],[contenteditable=""],[tabindex]:not([tabindex="-1"])';
806
+ function J(t) {
903
807
  return (t.__editingCellCount ?? 0) > 0;
904
808
  }
905
- function K(t) {
809
+ function Q(t) {
906
810
  t.__editingCellCount = 0, t.removeAttribute("data-has-editing"), t.querySelectorAll(".cell.editing").forEach((o) => o.classList.remove("editing"));
907
811
  }
908
- const Re = document.createElement("template");
909
- Re.innerHTML = '<div class="cell" role="gridcell" part="cell"></div>';
910
- const Te = document.createElement("template");
911
- Te.innerHTML = '<div class="data-grid-row" role="row" part="row"></div>';
912
- function nt() {
913
- return Re.content.firstElementChild.cloneNode(!0);
812
+ const xe = document.createElement("template");
813
+ xe.innerHTML = '<div class="cell" role="gridcell" part="cell"></div>';
814
+ const Ae = document.createElement("template");
815
+ Ae.innerHTML = '<div class="data-grid-row" role="row" part="row"></div>';
816
+ function et() {
817
+ return xe.content.firstElementChild.cloneNode(!0);
914
818
  }
915
- function rt() {
916
- return Te.content.firstElementChild.cloneNode(!0);
819
+ function tt() {
820
+ return Ae.content.firstElementChild.cloneNode(!0);
917
821
  }
918
- function $(t) {
822
+ function G(t) {
919
823
  t.__cellDisplayCache = void 0, t.__cellCacheEpoch = void 0, t.__hasSpecialColumns = void 0;
920
824
  }
921
- function st(t, e, o, i, n) {
825
+ function ot(t, e, o, i, n) {
922
826
  const r = Math.max(0, o - e), s = t._bodyEl, l = t._visibleColumns, a = l.length;
923
827
  let c = t.__cachedHeaderRowCount;
924
- for (c === void 0 && (c = t.shadowRoot?.querySelector(".header-group-row") ? 2 : 1, t.__cachedHeaderRowCount = c); t._rowPool.length < r; ) {
925
- const d = rt();
926
- d.addEventListener("click", (f) => he(t, f, d)), d.addEventListener("dblclick", (f) => he(t, f, d)), t._rowPool.push(d);
828
+ for (c === void 0 && (c = t.querySelector(".header-group-row") ? 2 : 1, t.__cachedHeaderRowCount = c); t._rowPool.length < r; ) {
829
+ const d = tt();
830
+ t._rowPool.push(d);
927
831
  }
928
832
  if (t._rowPool.length > r) {
929
833
  for (let d = r; d < t._rowPool.length; d++) {
@@ -932,44 +836,60 @@ function st(t, e, o, i, n) {
932
836
  }
933
837
  t._rowPool.length = r;
934
838
  }
935
- const h = n && t.__hasRenderRowPlugins !== !1;
839
+ const u = n && t.__hasRenderRowPlugins !== !1;
936
840
  for (let d = 0; d < r; d++) {
937
- const f = e + d, p = t._rows[f], u = t._rowPool[d];
938
- if (u.setAttribute("aria-rowindex", String(f + c + 1)), h && n(p, u, f)) {
939
- u.__epoch = i, u.__rowDataRef = p, u.parentNode !== s && s.appendChild(u);
841
+ const f = e + d, p = t._rows[f], h = t._rowPool[d];
842
+ if (h.setAttribute("aria-rowindex", String(f + c + 1)), u && n(p, h, f)) {
843
+ h.__epoch = i, h.__rowDataRef = p, h.parentNode !== s && s.appendChild(h);
940
844
  continue;
941
845
  }
942
- const g = u.__epoch, m = u.__rowDataRef, b = u.children.length, w = g === i && b === a, C = m !== p;
846
+ const g = h.__epoch, w = h.__rowDataRef, _ = h.children.length, v = g === i && _ === a, m = w !== p;
943
847
  let y = !1;
944
- if (w && C) {
945
- for (let x = 0; x < a; x++)
946
- if (l[x].externalView && !u.querySelector(`.cell[data-col="${x}"] [data-external-view]`)) {
848
+ if (v && m) {
849
+ for (let b = 0; b < a; b++)
850
+ if (l[b].externalView && !h.querySelector(`.cell[data-col="${b}"] [data-external-view]`)) {
947
851
  y = !0;
948
852
  break;
949
853
  }
950
854
  }
951
- if (!w || y) {
952
- const x = j(u), v = t._activeEditRows === f;
953
- x && !v ? (u.__isCustomRow && (u.className = "data-grid-row", u.setAttribute("role", "row"), u.__isCustomRow = !1), K(u), B(t, u, p, f), u.__epoch = i, u.__rowDataRef = p) : x && v ? (Z(t, u, p, f), u.__rowDataRef = p) : (u.__isCustomRow && (u.className = "data-grid-row", u.setAttribute("role", "row"), u.__isCustomRow = !1), B(t, u, p, f), u.__epoch = i, u.__rowDataRef = p);
954
- } else if (C) {
955
- const x = j(u), v = t._activeEditRows === f;
956
- x && !v ? (K(u), B(t, u, p, f), u.__epoch = i, u.__rowDataRef = p) : (Z(t, u, p, f), u.__rowDataRef = p);
855
+ if (!v || y) {
856
+ const b = J(h), E = t._activeEditRows === f;
857
+ b && !E ? (h.__isCustomRow && (h.className = "data-grid-row", h.setAttribute("role", "row"), h.__isCustomRow = !1), Q(h), U(t, h, p, f), h.__epoch = i, h.__rowDataRef = p) : b && E ? (ee(t, h, p, f), h.__rowDataRef = p) : (h.__isCustomRow && (h.className = "data-grid-row", h.setAttribute("role", "row"), h.__isCustomRow = !1), U(t, h, p, f), h.__epoch = i, h.__rowDataRef = p);
858
+ } else if (m) {
859
+ const b = J(h), E = t._activeEditRows === f;
860
+ b && !E ? (Q(h), U(t, h, p, f), h.__epoch = i, h.__rowDataRef = p) : (ee(t, h, p, f), h.__rowDataRef = p);
957
861
  } else {
958
- const x = j(u), v = t._activeEditRows === f;
959
- x && !v ? (K(u), B(t, u, p, f), u.__epoch = i, u.__rowDataRef = p) : Z(t, u, p, f);
862
+ const b = J(h), E = t._activeEditRows === f;
863
+ b && !E ? (Q(h), U(t, h, p, f), h.__epoch = i, h.__rowDataRef = p) : ee(t, h, p, f);
960
864
  }
961
- const R = t._changedRowIndices?.has(f) ?? !1, U = u.classList.contains("changed");
962
- R !== U && u.classList.toggle("changed", R), u.parentNode !== s && s.appendChild(u);
865
+ const S = t._changedRowIndices?.has(f) ?? !1, C = h.classList.contains("changed");
866
+ S !== C && h.classList.toggle("changed", S);
867
+ const O = t.effectiveConfig?.rowClass;
868
+ if (O) {
869
+ const b = h.getAttribute("data-dynamic-classes");
870
+ b && b.split(" ").forEach((E) => E && h.classList.remove(E));
871
+ try {
872
+ const E = O(p);
873
+ if (E && E.length > 0) {
874
+ const B = E.filter((V) => V && typeof V == "string");
875
+ B.forEach((V) => h.classList.add(V)), h.setAttribute("data-dynamic-classes", B.join(" "));
876
+ } else
877
+ h.removeAttribute("data-dynamic-classes");
878
+ } catch (E) {
879
+ console.warn("[tbw-grid] rowClass callback error:", E), h.removeAttribute("data-dynamic-classes");
880
+ }
881
+ }
882
+ h.parentNode !== s && s.appendChild(h);
963
883
  }
964
884
  }
965
- function Z(t, e, o, i) {
966
- const n = e.children, r = t._visibleColumns, s = r.length, l = n.length, a = s < l ? s : l, c = t._focusRow, h = t._focusCol;
885
+ function ee(t, e, o, i) {
886
+ const n = e.children, r = t._visibleColumns, s = r.length, l = n.length, a = s < l ? s : l, c = t._focusRow, u = t._focusCol;
967
887
  let d = t.__hasSpecialColumns;
968
888
  if (d === void 0) {
969
889
  d = !1;
970
890
  for (let p = 0; p < s; p++) {
971
- const u = r[p];
972
- if (u.__viewTemplate || u.__compiledView || u.renderer || u.viewRenderer || u.externalView || u.format || u.type === "date" || u.type === "boolean") {
891
+ const h = r[p];
892
+ if (h.__viewTemplate || h.__compiledView || h.renderer || h.viewRenderer || h.externalView || h.format || h.type === "date" || h.type === "boolean") {
973
893
  d = !0;
974
894
  break;
975
895
  }
@@ -979,70 +899,88 @@ function Z(t, e, o, i) {
979
899
  const f = String(i);
980
900
  if (!d) {
981
901
  for (let p = 0; p < a; p++) {
982
- const u = n[p], g = o[r[p].field];
983
- u.textContent = g == null ? "" : String(g), u.getAttribute("data-row") !== f && u.setAttribute("data-row", f);
984
- const m = c === i && h === p, b = u.classList.contains("cell-focus");
985
- m !== b && (u.classList.toggle("cell-focus", m), u.setAttribute("aria-selected", String(m)));
902
+ const h = n[p];
903
+ if (h.classList.contains("editing")) continue;
904
+ const g = o[r[p].field];
905
+ h.textContent = g == null ? "" : String(g), h.getAttribute("data-row") !== f && h.setAttribute("data-row", f);
906
+ const w = c === i && u === p, _ = h.classList.contains("cell-focus");
907
+ w !== _ && (h.classList.toggle("cell-focus", w), h.setAttribute("aria-selected", String(w)));
986
908
  }
987
909
  return;
988
910
  }
989
911
  for (let p = 0; p < a; p++)
990
912
  if (r[p].externalView && !n[p].querySelector("[data-external-view]")) {
991
- B(t, e, o, i);
913
+ U(t, e, o, i);
992
914
  return;
993
915
  }
994
916
  for (let p = 0; p < a; p++) {
995
- const u = r[p], g = n[p];
917
+ const h = r[p], g = n[p];
996
918
  g.getAttribute("data-row") !== f && g.setAttribute("data-row", f);
997
- const m = c === i && h === p, b = g.classList.contains("cell-focus");
998
- if (m !== b && (g.classList.toggle("cell-focus", m), g.setAttribute("aria-selected", String(m))), g.classList.contains("editing")) continue;
999
- const _ = u.renderer || u.viewRenderer;
1000
- if (_) {
1001
- const y = o[u.field], R = _({ row: o, value: y, field: u.field, column: u, cellEl: g });
1002
- typeof R == "string" ? g.innerHTML = G(R) : R instanceof Node ? R.parentElement !== g && (g.innerHTML = "", g.appendChild(R)) : R == null && (g.textContent = y == null ? "" : String(y));
919
+ const w = c === i && u === p, _ = g.classList.contains("cell-focus");
920
+ w !== _ && (g.classList.toggle("cell-focus", w), g.setAttribute("aria-selected", String(w)));
921
+ const T = h.cellClass;
922
+ if (T) {
923
+ const S = g.getAttribute("data-dynamic-classes");
924
+ S && S.split(" ").forEach((C) => C && g.classList.remove(C));
925
+ try {
926
+ const C = o[h.field], O = T(C, o, h);
927
+ if (O && O.length > 0) {
928
+ const b = O.filter((E) => E && typeof E == "string");
929
+ b.forEach((E) => g.classList.add(E)), g.setAttribute("data-dynamic-classes", b.join(" "));
930
+ } else
931
+ g.removeAttribute("data-dynamic-classes");
932
+ } catch (C) {
933
+ console.warn(`[tbw-grid] cellClass callback error for column '${h.field}':`, C), g.removeAttribute("data-dynamic-classes");
934
+ }
935
+ }
936
+ if (g.classList.contains("editing")) continue;
937
+ const v = h.renderer || h.viewRenderer;
938
+ if (v) {
939
+ const S = o[h.field], C = v({ row: o, value: S, field: h.field, column: h, cellEl: g });
940
+ typeof C == "string" ? g.innerHTML = j(C) : C instanceof Node ? C.parentElement !== g && (g.innerHTML = "", g.appendChild(C)) : C == null && (g.textContent = S == null ? "" : String(S));
1003
941
  continue;
1004
942
  }
1005
- if (u.__viewTemplate || u.__compiledView || u.externalView)
943
+ if (h.__viewTemplate || h.__compiledView || h.externalView)
1006
944
  continue;
1007
- const w = o[u.field];
1008
- let C;
1009
- if (u.format)
945
+ const m = o[h.field];
946
+ let y;
947
+ if (h.format)
1010
948
  try {
1011
- const y = u.format(w, o);
1012
- C = y == null ? "" : String(y);
1013
- } catch (y) {
1014
- console.warn(`[tbw-grid] Format error in column '${u.field}':`, y), C = w == null ? "" : String(w);
949
+ const S = h.format(m, o);
950
+ y = S == null ? "" : String(S);
951
+ } catch (S) {
952
+ console.warn(`[tbw-grid] Format error in column '${h.field}':`, S), y = m == null ? "" : String(m);
1015
953
  }
1016
- else u.type === "date" ? (C = _e(w), g.textContent = C) : u.type === "boolean" ? g.innerHTML = Ce(!!w) : (C = w == null ? "" : String(w), g.textContent = C);
954
+ else h.type === "date" ? (y = Se(m), g.textContent = y) : h.type === "boolean" ? g.innerHTML = Ee(!!m) : (y = m == null ? "" : String(m), g.textContent = y);
1017
955
  }
1018
956
  }
1019
- function B(t, e, o, i) {
957
+ function U(t, e, o, i) {
1020
958
  e.innerHTML = "";
1021
959
  const n = t._visibleColumns, r = n.length, s = t._focusRow, l = t._focusCol, a = t, c = document.createDocumentFragment();
1022
- for (let h = 0; h < r; h++) {
1023
- const d = n[h], f = nt();
1024
- f.setAttribute("aria-colindex", String(h + 1)), f.setAttribute("data-col", String(h)), f.setAttribute("data-row", String(i)), f.setAttribute("data-field", d.field), d.type && f.setAttribute("data-type", d.type);
960
+ for (let u = 0; u < r; u++) {
961
+ const d = n[u], f = et();
962
+ f.setAttribute("aria-colindex", String(u + 1)), f.setAttribute("data-col", String(u)), f.setAttribute("data-row", String(i)), f.setAttribute("data-field", d.field), d.type && f.setAttribute("data-type", d.type);
1025
963
  let p = o[d.field];
1026
964
  if (d.format)
1027
965
  try {
1028
966
  p = d.format(p, o);
1029
- } catch (w) {
1030
- console.warn(`[tbw-grid] Format error in column '${d.field}':`, w);
967
+ } catch (m) {
968
+ console.warn(`[tbw-grid] Format error in column '${d.field}':`, m);
1031
969
  }
1032
- const u = d.__compiledView, g = d.__viewTemplate, m = d.renderer || d.viewRenderer, b = d.externalView;
1033
- let _ = !1;
1034
- if (m) {
1035
- const w = m({ row: o, value: p, field: d.field, column: d, cellEl: f });
1036
- typeof w == "string" ? (f.innerHTML = G(w), _ = !0) : w instanceof Node ? w.parentElement !== f && (f.textContent = "", f.appendChild(w)) : w == null && (f.textContent = p == null ? "" : String(p));
1037
- } else if (b) {
1038
- const w = b, C = document.createElement("div");
1039
- C.setAttribute("data-external-view", ""), C.setAttribute("data-field", d.field), f.appendChild(C);
1040
- const y = { row: o, value: p, field: d.field, column: d };
1041
- if (w.mount)
970
+ const h = d.__compiledView, g = d.__viewTemplate, w = d.renderer || d.viewRenderer, _ = d.externalView;
971
+ let T = !1;
972
+ if (w) {
973
+ const m = w({ row: o, value: p, field: d.field, column: d, cellEl: f });
974
+ typeof m == "string" ? (f.innerHTML = j(m), T = !0) : m instanceof Node ? m.parentElement !== f && (f.textContent = "", f.appendChild(m)) : m == null && (f.textContent = p == null ? "" : String(p));
975
+ } else if (_) {
976
+ const m = _, y = document.createElement("div");
977
+ y.setAttribute("data-external-view", ""), y.setAttribute("data-field", d.field), f.appendChild(y);
978
+ const S = { row: o, value: p, field: d.field, column: d };
979
+ if (m.mount)
1042
980
  try {
1043
- w.mount({ placeholder: C, context: y, spec: w });
1044
- } catch (R) {
1045
- console.warn(`[tbw-grid] External view mount error for column '${d.field}':`, R);
981
+ m.mount({ placeholder: y, context: S, spec: m });
982
+ } catch (C) {
983
+ console.warn(`[tbw-grid] External view mount error for column '${d.field}':`, C);
1046
984
  }
1047
985
  else
1048
986
  queueMicrotask(() => {
@@ -1051,70 +989,82 @@ function B(t, e, o, i) {
1051
989
  new CustomEvent("mount-external-view", {
1052
990
  bubbles: !0,
1053
991
  composed: !0,
1054
- detail: { placeholder: C, spec: w, context: y }
992
+ detail: { placeholder: y, spec: m, context: S }
1055
993
  })
1056
994
  );
1057
- } catch (R) {
1058
- console.warn(`[tbw-grid] External view event dispatch error for column '${d.field}':`, R);
995
+ } catch (C) {
996
+ console.warn(`[tbw-grid] External view event dispatch error for column '${d.field}':`, C);
1059
997
  }
1060
998
  });
1061
- C.setAttribute("data-mounted", "");
1062
- } else if (u) {
1063
- const w = u({ row: o, value: p, field: d.field, column: d }), C = u.__blocked;
1064
- f.innerHTML = C ? "" : G(w), _ = !0, C && (f.textContent = "", f.setAttribute("data-blocked-template", ""));
999
+ y.setAttribute("data-mounted", "");
1000
+ } else if (h) {
1001
+ const m = h({ row: o, value: p, field: d.field, column: d }), y = h.__blocked;
1002
+ f.innerHTML = y ? "" : j(m), T = !0, y && (f.textContent = "", f.setAttribute("data-blocked-template", ""));
1065
1003
  } else if (g) {
1066
- const w = g.innerHTML;
1067
- /Reflect\.|\bProxy\b|ownKeys\(/.test(w) ? (f.textContent = "", f.setAttribute("data-blocked-template", "")) : (f.innerHTML = G(ve(w, { row: o, value: p })), _ = !0);
1004
+ const m = g.innerHTML;
1005
+ /Reflect\.|\bProxy\b|ownKeys\(/.test(m) ? (f.textContent = "", f.setAttribute("data-blocked-template", "")) : (f.innerHTML = j(_e(m, { row: o, value: p })), T = !0);
1068
1006
  } else
1069
- d.type === "date" ? f.textContent = _e(p) : d.type === "boolean" ? f.innerHTML = Ce(!!p) : f.textContent = p == null ? "" : String(p);
1070
- if (_) {
1071
- Ye(f);
1072
- const w = f.textContent || "";
1073
- /Proxy|Reflect\.ownKeys/.test(w) && (f.textContent = w.replace(/Proxy|Reflect\.ownKeys/g, "").trim(), /Proxy|Reflect\.ownKeys/.test(f.textContent || "") && (f.textContent = ""));
1007
+ d.type === "date" ? f.textContent = Se(p) : d.type === "boolean" ? f.innerHTML = Ee(!!p) : f.textContent = p == null ? "" : String(p);
1008
+ if (T) {
1009
+ Ke(f);
1010
+ const m = f.textContent || "";
1011
+ /Proxy|Reflect\.ownKeys/.test(m) && (f.textContent = m.replace(/Proxy|Reflect\.ownKeys/g, "").trim(), /Proxy|Reflect\.ownKeys/.test(f.textContent || "") && (f.textContent = ""));
1074
1012
  }
1075
- f.hasAttribute("data-blocked-template") && (f.textContent || "").trim().length && (f.textContent = ""), d.editable ? f.tabIndex = 0 : d.type === "boolean" && (f.hasAttribute("tabindex") || (f.tabIndex = 0)), s === i && l === h ? (f.classList.add("cell-focus"), f.setAttribute("aria-selected", "true")) : f.setAttribute("aria-selected", "false"), c.appendChild(f);
1013
+ f.hasAttribute("data-blocked-template") && (f.textContent || "").trim().length && (f.textContent = ""), d.editable ? f.tabIndex = 0 : d.type === "boolean" && (f.hasAttribute("tabindex") || (f.tabIndex = 0)), s === i && l === u ? (f.classList.add("cell-focus"), f.setAttribute("aria-selected", "true")) : f.setAttribute("aria-selected", "false");
1014
+ const v = d.cellClass;
1015
+ if (v)
1016
+ try {
1017
+ const m = o[d.field], y = v(m, o, d);
1018
+ if (y && y.length > 0) {
1019
+ const S = y.filter((C) => C && typeof C == "string");
1020
+ S.forEach((C) => f.classList.add(C)), f.setAttribute("data-dynamic-classes", S.join(" "));
1021
+ }
1022
+ } catch (m) {
1023
+ console.warn(`[tbw-grid] cellClass callback error for column '${d.field}':`, m);
1024
+ }
1025
+ c.appendChild(f);
1076
1026
  }
1077
1027
  e.appendChild(c);
1078
1028
  }
1079
- function he(t, e, o, i) {
1029
+ function he(t, e, o) {
1080
1030
  if (e.target?.closest(".resize-handle")) return;
1081
- const n = o.querySelector(".cell[data-row]"), r = ye(n);
1082
- if (r < 0) return;
1083
- const s = t._rows[r];
1084
- if (!s || t._dispatchRowClick?.(e, r, s, o))
1031
+ const i = o.querySelector(".cell[data-row]"), n = Te(i);
1032
+ if (n < 0) return;
1033
+ const r = t._rows[n];
1034
+ if (!r || t._dispatchRowClick?.(e, n, r, o))
1085
1035
  return;
1086
- const l = e.target?.closest(".cell[data-col]");
1087
- if (l) {
1088
- const a = Number(l.getAttribute("data-col"));
1089
- if (!isNaN(a)) {
1090
- if (t._dispatchCellClick?.(e, r, a, l))
1036
+ const s = e.target?.closest(".cell[data-col]");
1037
+ if (s) {
1038
+ const l = Number(s.getAttribute("data-col"));
1039
+ if (!isNaN(l)) {
1040
+ if (t._dispatchCellClick?.(e, n, l, s))
1091
1041
  return;
1092
- const c = t._focusRow !== r || t._focusCol !== a;
1093
- if (t._focusRow = r, t._focusCol = a, l.classList.contains("editing")) {
1094
- c && (ee(t.shadowRoot ?? t._bodyEl), l.classList.add("cell-focus"));
1095
- const h = l.querySelector(Se);
1042
+ const a = t._focusRow !== n || t._focusCol !== l;
1043
+ if (t._focusRow = n, t._focusCol = l, s.classList.contains("editing")) {
1044
+ a && (ie(t._bodyEl ?? t), s.classList.add("cell-focus"));
1045
+ const c = s.querySelector(Re);
1096
1046
  try {
1097
- h?.focus({ preventScroll: !0 });
1047
+ c?.focus({ preventScroll: !0 });
1098
1048
  } catch {
1099
1049
  }
1100
1050
  return;
1101
1051
  }
1102
- k(t);
1052
+ q(t);
1103
1053
  }
1104
1054
  }
1105
1055
  }
1106
- function lt(t, e) {
1056
+ function it(t, e) {
1107
1057
  if (t._dispatchKeyDown?.(e))
1108
1058
  return;
1109
- const o = t._rows.length - 1, i = t._visibleColumns.length - 1, n = t._activeEditRows !== void 0 && t._activeEditRows !== -1, s = t._visibleColumns[t._focusCol]?.type, l = e.composedPath?.() ?? [], a = l.length ? l[0] : e.target, c = (h) => {
1110
- if (!h) return !1;
1111
- const d = h.tagName;
1112
- return !!(d === "INPUT" || d === "SELECT" || d === "TEXTAREA" || h.isContentEditable);
1059
+ const o = t._rows.length - 1, i = t._visibleColumns.length - 1, n = t._activeEditRows !== void 0 && t._activeEditRows !== -1, s = t._visibleColumns[t._focusCol]?.type, l = e.composedPath?.() ?? [], a = l.length ? l[0] : e.target, c = (u) => {
1060
+ if (!u) return !1;
1061
+ const d = u.tagName;
1062
+ return !!(d === "INPUT" || d === "SELECT" || d === "TEXTAREA" || u.isContentEditable);
1113
1063
  };
1114
1064
  if (!(c(a) && (e.key === "Home" || e.key === "End")) && !(c(a) && (e.key === "ArrowUp" || e.key === "ArrowDown") && a.tagName === "INPUT" && a.type === "number") && !(c(a) && (e.key === "ArrowLeft" || e.key === "ArrowRight")) && !(c(a) && (e.key === "Enter" || e.key === "Escape")) && !(n && (s === "select" || s === "typeahead") && (e.key === "ArrowDown" || e.key === "ArrowUp"))) {
1115
1065
  switch (e.key) {
1116
1066
  case "Tab": {
1117
- e.preventDefault(), !e.shiftKey ? t._focusCol < i ? t._focusCol += 1 : (typeof t.commitActiveRowEdit == "function" && t.commitActiveRowEdit(), t._focusRow < o && (t._focusRow += 1, t._focusCol = 0)) : t._focusCol > 0 ? t._focusCol -= 1 : t._focusRow > 0 && (typeof t.commitActiveRowEdit == "function" && t._activeEditRows === t._focusRow && t.commitActiveRowEdit(), t._focusRow -= 1, t._focusCol = i), k(t);
1067
+ e.preventDefault(), !e.shiftKey ? t._focusCol < i ? t._focusCol += 1 : (typeof t.commitActiveRowEdit == "function" && t.commitActiveRowEdit(), t._focusRow < o && (t._focusRow += 1, t._focusCol = 0)) : t._focusCol > 0 ? t._focusCol -= 1 : t._focusRow > 0 && (typeof t.commitActiveRowEdit == "function" && t._activeEditRows === t._focusRow && t.commitActiveRowEdit(), t._focusRow -= 1, t._focusCol = i), q(t);
1118
1068
  return;
1119
1069
  }
1120
1070
  case "ArrowDown":
@@ -1130,10 +1080,10 @@ function lt(t, e) {
1130
1080
  t._focusCol = Math.max(0, t._focusCol - 1), e.preventDefault();
1131
1081
  break;
1132
1082
  case "Home":
1133
- (e.ctrlKey || e.metaKey) && (n && typeof t.commitActiveRowEdit == "function" && t.commitActiveRowEdit(), t._focusRow = 0), t._focusCol = 0, e.preventDefault(), k(t, { forceScrollLeft: !0 });
1083
+ (e.ctrlKey || e.metaKey) && (n && typeof t.commitActiveRowEdit == "function" && t.commitActiveRowEdit(), t._focusRow = 0), t._focusCol = 0, e.preventDefault(), q(t, { forceScrollLeft: !0 });
1134
1084
  return;
1135
1085
  case "End":
1136
- (e.ctrlKey || e.metaKey) && (n && typeof t.commitActiveRowEdit == "function" && t.commitActiveRowEdit(), t._focusRow = o), t._focusCol = i, e.preventDefault(), k(t, { forceScrollRight: !0 });
1086
+ (e.ctrlKey || e.metaKey) && (n && typeof t.commitActiveRowEdit == "function" && t.commitActiveRowEdit(), t._focusRow = o), t._focusCol = i, e.preventDefault(), q(t, { forceScrollRight: !0 });
1137
1087
  return;
1138
1088
  case "PageDown":
1139
1089
  t._focusRow = Math.min(o, t._focusRow + 20), e.preventDefault();
@@ -1144,11 +1094,11 @@ function lt(t, e) {
1144
1094
  // NOTE: Enter key is handled by EditingPlugin. If no plugin handles it,
1145
1095
  // we dispatch a cancelable activate-cell event for custom handling.
1146
1096
  case "Enter": {
1147
- const h = new CustomEvent("activate-cell", {
1097
+ const u = new CustomEvent("activate-cell", {
1148
1098
  cancelable: !0,
1149
1099
  detail: { row: t._focusRow, col: t._focusCol }
1150
1100
  });
1151
- if (t.dispatchEvent(h), h.defaultPrevented) {
1101
+ if (t.dispatchEvent(u), u.defaultPrevented) {
1152
1102
  e.preventDefault();
1153
1103
  return;
1154
1104
  }
@@ -1157,19 +1107,19 @@ function lt(t, e) {
1157
1107
  default:
1158
1108
  return;
1159
1109
  }
1160
- k(t);
1110
+ q(t);
1161
1111
  }
1162
1112
  }
1163
- function k(t, e) {
1113
+ function q(t, e) {
1164
1114
  if (t._virtualization?.enabled) {
1165
- const { rowHeight: s, container: l, viewportEl: a } = t._virtualization, c = l, h = a?.clientHeight ?? c?.clientHeight ?? 0;
1166
- if (c && h > 0) {
1115
+ const { rowHeight: s, container: l, viewportEl: a } = t._virtualization, c = l, u = a?.clientHeight ?? c?.clientHeight ?? 0;
1116
+ if (c && u > 0) {
1167
1117
  const d = t._focusRow * s;
1168
- d < c.scrollTop ? c.scrollTop = d : d + s > c.scrollTop + h && (c.scrollTop = d - h + s);
1118
+ d < c.scrollTop ? c.scrollTop = d : d + s > c.scrollTop + u && (c.scrollTop = d - u + s);
1169
1119
  }
1170
1120
  }
1171
1121
  const o = t._activeEditRows !== void 0 && t._activeEditRows !== -1;
1172
- o || t.refreshVirtualWindow(!1), ee(t._bodyEl), Array.from(t._bodyEl.querySelectorAll('[aria-selected="true"]')).forEach((s) => {
1122
+ o || t.refreshVirtualWindow(!1), ie(t._bodyEl), Array.from(t._bodyEl.querySelectorAll('[aria-selected="true"]')).forEach((s) => {
1173
1123
  s.setAttribute("aria-selected", "false");
1174
1124
  });
1175
1125
  const i = t._focusRow, n = t._virtualization.start ?? 0, r = t._virtualization.end ?? t._rows.length;
@@ -1178,7 +1128,7 @@ function k(t, e) {
1178
1128
  let l = s?.children[t._focusCol];
1179
1129
  if ((!l || !l.classList?.contains("cell")) && (l = s?.querySelector(`.cell[data-col="${t._focusCol}"]`) ?? s?.querySelector(".cell[data-col]")), l) {
1180
1130
  l.classList.add("cell-focus"), l.setAttribute("aria-selected", "true");
1181
- const a = t.shadowRoot?.querySelector(".tbw-scroll-area");
1131
+ const a = t.querySelector(".tbw-scroll-area");
1182
1132
  if (a && l && !o)
1183
1133
  if (e?.forceScrollLeft)
1184
1134
  a.scrollLeft = 0;
@@ -1187,12 +1137,12 @@ function k(t, e) {
1187
1137
  else {
1188
1138
  const c = t._getHorizontalScrollOffsets?.(s ?? void 0, l) ?? { left: 0, right: 0 };
1189
1139
  if (!c.skipScroll) {
1190
- const h = l.getBoundingClientRect(), d = a.getBoundingClientRect(), f = h.left - d.left + a.scrollLeft, p = f + h.width, u = a.scrollLeft + c.left, g = a.scrollLeft + a.clientWidth - c.right;
1191
- f < u ? a.scrollLeft = f - c.left : p > g && (a.scrollLeft = p - a.clientWidth + c.right);
1140
+ const u = l.getBoundingClientRect(), d = a.getBoundingClientRect(), f = u.left - d.left + a.scrollLeft, p = f + u.width, h = a.scrollLeft + c.left, g = a.scrollLeft + a.clientWidth - c.right;
1141
+ f < h ? a.scrollLeft = f - c.left : p > g && (a.scrollLeft = p - a.clientWidth + c.right);
1192
1142
  }
1193
1143
  }
1194
1144
  if (t._activeEditRows !== void 0 && t._activeEditRows !== -1 && l.classList.contains("editing")) {
1195
- const c = l.querySelector(Se);
1145
+ const c = l.querySelector(Re);
1196
1146
  if (c && document.activeElement !== c)
1197
1147
  try {
1198
1148
  c.focus({ preventScroll: !0 });
@@ -1208,9 +1158,161 @@ function k(t, e) {
1208
1158
  }
1209
1159
  }
1210
1160
  }
1211
- var S = /* @__PURE__ */ ((t) => (t[t.STYLE = 1] = "STYLE", t[t.VIRTUALIZATION = 2] = "VIRTUALIZATION", t[t.HEADER = 3] = "HEADER", t[t.ROWS = 4] = "ROWS", t[t.COLUMNS = 5] = "COLUMNS", t[t.FULL = 6] = "FULL", t))(S || {});
1212
- class at {
1213
- #o;
1161
+ const K = /* @__PURE__ */ new WeakMap();
1162
+ function nt(t, e) {
1163
+ const o = Te(e), i = Qe(e);
1164
+ o < 0 || i < 0 || (t._focusRow = o, t._focusCol = i, ie(t._bodyEl), e.classList.add("cell-focus"), e.setAttribute("aria-selected", "true"));
1165
+ }
1166
+ function ne(t, e, o, i) {
1167
+ let n = null;
1168
+ const r = o.composedPath?.();
1169
+ if (r && r.length > 0 ? n = r[0] : n = o.target, n && !e.contains(n)) {
1170
+ const g = document.elementFromPoint(o.clientX, o.clientY);
1171
+ g && (n = g);
1172
+ }
1173
+ const s = n?.closest?.("[data-col]"), l = n?.closest?.(".data-grid-row"), a = n?.closest?.(".header-row");
1174
+ let c, u, d, f, p, h;
1175
+ return s && (c = parseInt(s.getAttribute("data-row") ?? "-1", 10), u = parseInt(s.getAttribute("data-col") ?? "-1", 10), c >= 0 && u >= 0 && (d = t._rows[c], h = t._columns[u], f = h?.field, p = d && f ? d[f] : void 0)), {
1176
+ type: i,
1177
+ row: d,
1178
+ rowIndex: c !== void 0 && c >= 0 ? c : void 0,
1179
+ colIndex: u !== void 0 && u >= 0 ? u : void 0,
1180
+ field: f,
1181
+ value: p,
1182
+ column: h,
1183
+ originalEvent: o,
1184
+ cellElement: s ?? void 0,
1185
+ rowElement: l ?? void 0,
1186
+ isHeader: !!a,
1187
+ cell: c !== void 0 && u !== void 0 && c >= 0 && u >= 0 ? { row: c, col: u } : void 0
1188
+ };
1189
+ }
1190
+ function rt(t, e, o) {
1191
+ const i = ne(t, e, o, "mousedown");
1192
+ (t._dispatchCellMouseDown?.(i) ?? !1) && K.set(t, !0);
1193
+ }
1194
+ function st(t, e, o) {
1195
+ if (!K.get(t)) return;
1196
+ const i = ne(t, e, o, "mousemove");
1197
+ t._dispatchCellMouseMove?.(i);
1198
+ }
1199
+ function lt(t, e, o) {
1200
+ if (!K.get(t)) return;
1201
+ const i = ne(t, e, o, "mouseup");
1202
+ t._dispatchCellMouseUp?.(i), K.set(t, !1);
1203
+ }
1204
+ function at(t, e, o) {
1205
+ e.addEventListener(
1206
+ "mousedown",
1207
+ (i) => {
1208
+ const n = i.target.closest(".cell[data-col]");
1209
+ n && (n.classList.contains("editing") || nt(t, n));
1210
+ },
1211
+ { signal: o }
1212
+ ), e.addEventListener(
1213
+ "click",
1214
+ (i) => {
1215
+ const n = i.target.closest(".data-grid-row");
1216
+ n && he(t, i, n);
1217
+ },
1218
+ { signal: o }
1219
+ ), e.addEventListener(
1220
+ "dblclick",
1221
+ (i) => {
1222
+ const n = i.target.closest(".data-grid-row");
1223
+ n && he(t, i, n);
1224
+ },
1225
+ { signal: o }
1226
+ );
1227
+ }
1228
+ function ct(t, e, o, i) {
1229
+ e.addEventListener("keydown", (n) => it(t, n), { signal: i }), o.addEventListener("mousedown", (n) => rt(t, o, n), { signal: i }), document.addEventListener("mousemove", (n) => st(t, o, n), { signal: i }), document.addEventListener("mouseup", (n) => lt(t, o, n), { signal: i });
1230
+ }
1231
+ function dt(t, e) {
1232
+ return t == null && e == null ? 0 : t == null ? -1 : e == null || t > e ? 1 : t < e ? -1 : 0;
1233
+ }
1234
+ function ht(t, e, o) {
1235
+ const n = o.find((l) => l.field === e.field)?.sortComparator ?? dt, { field: r, direction: s } = e;
1236
+ return [...t].sort((l, a) => n(l[r], a[r], l, a) * s);
1237
+ }
1238
+ function ue(t, e, o, i) {
1239
+ t._rows = e, t.__rowRenderEpoch++, t._rowPool.forEach((n) => n.__epoch = -1), Z(t), t.refreshVirtualWindow(!0), t.dispatchEvent(
1240
+ new CustomEvent("sort-change", { detail: { field: o.field, direction: i } })
1241
+ ), t.requestStateChange?.();
1242
+ }
1243
+ function fe(t, e) {
1244
+ !t._sortState || t._sortState.field !== e.field ? (t._sortState || (t.__originalOrder = t._rows.slice()), pe(t, e, 1)) : t._sortState.direction === 1 ? pe(t, e, -1) : (t._sortState = null, t.__rowRenderEpoch++, t._rowPool.forEach((i) => i.__epoch = -1), t._rows = t.__originalOrder.slice(), Z(t), t._headerRowEl?.querySelectorAll('[role="columnheader"].sortable')?.forEach((i) => {
1245
+ i.getAttribute("aria-sort") ? (i.getAttribute("aria-sort") === "ascending" || i.getAttribute("aria-sort") === "descending") && (t._sortState || i.setAttribute("aria-sort", "none")) : i.setAttribute("aria-sort", "none");
1246
+ }), t.refreshVirtualWindow(!0), t.dispatchEvent(
1247
+ new CustomEvent("sort-change", { detail: { field: e.field, direction: 0 } })
1248
+ ), t.requestStateChange?.());
1249
+ }
1250
+ function pe(t, e, o) {
1251
+ t._sortState = { field: e.field, direction: o };
1252
+ const i = { field: e.field, direction: o }, n = t._columns, s = (t.effectiveConfig?.sortHandler ?? ht)(t._rows, i, n);
1253
+ s && typeof s.then == "function" ? s.then((l) => {
1254
+ ue(t, l, e, o);
1255
+ }) : ue(t, s, e, o);
1256
+ }
1257
+ function ut(t, e) {
1258
+ typeof e == "string" ? t.textContent = e : e instanceof HTMLElement && (t.innerHTML = "", t.appendChild(e.cloneNode(!0)));
1259
+ }
1260
+ function Z(t) {
1261
+ t._headerRowEl = t.findHeaderRow();
1262
+ const e = t._headerRowEl;
1263
+ e && (e.innerHTML = "", t._visibleColumns.forEach((o, i) => {
1264
+ const n = document.createElement("div");
1265
+ n.className = "cell", le(n, "header-cell"), n.setAttribute("role", "columnheader"), n.setAttribute("aria-colindex", String(i + 1)), n.setAttribute("data-field", o.field), n.setAttribute("data-col", String(i));
1266
+ const r = o.__headerTemplate;
1267
+ if (r) Array.from(r.childNodes).forEach((s) => n.appendChild(s.cloneNode(!0)));
1268
+ else {
1269
+ const s = o.header ?? o.field, l = document.createElement("span");
1270
+ l.textContent = s, n.appendChild(l);
1271
+ }
1272
+ if (o.sortable) {
1273
+ n.classList.add("sortable"), n.tabIndex = 0;
1274
+ const s = document.createElement("span");
1275
+ le(s, "sort-indicator");
1276
+ const l = t._sortState?.field === o.field ? t._sortState.direction : 0, a = { ...M, ...t.icons }, c = l === 1 ? a.sortAsc : l === -1 ? a.sortDesc : a.sortNone;
1277
+ ut(s, c), n.appendChild(s), n.setAttribute("aria-sort", l === 0 ? "none" : l === 1 ? "ascending" : "descending"), n.addEventListener("click", (u) => {
1278
+ t._resizeController?.isResizing || t._dispatchHeaderClick?.(u, i, n) || fe(t, o);
1279
+ }), n.addEventListener("keydown", (u) => {
1280
+ if (u.key === "Enter" || u.key === " ") {
1281
+ if (u.preventDefault(), t._dispatchHeaderClick?.(u, i, n)) return;
1282
+ fe(t, o);
1283
+ }
1284
+ });
1285
+ }
1286
+ if (o.resizable) {
1287
+ n.classList.add("resizable");
1288
+ const s = document.createElement("div");
1289
+ s.className = "resize-handle", s.setAttribute("aria-hidden", "true"), s.addEventListener("mousedown", (l) => {
1290
+ l.stopPropagation(), l.preventDefault(), t._resizeController.start(l, i, n);
1291
+ }), s.addEventListener("dblclick", (l) => {
1292
+ l.stopPropagation(), l.preventDefault(), t._resizeController.resetColumn(i);
1293
+ }), n.appendChild(s);
1294
+ }
1295
+ e.appendChild(n);
1296
+ }), e.querySelectorAll(".cell.sortable").forEach((o) => {
1297
+ o.getAttribute("aria-sort") || o.setAttribute("aria-sort", "none");
1298
+ }), e.children.length > 0 ? (e.setAttribute("role", "row"), e.setAttribute("aria-rowindex", "1")) : (e.removeAttribute("role"), e.removeAttribute("aria-rowindex")));
1299
+ }
1300
+ const Pe = typeof requestIdleCallback == "function";
1301
+ function ft(t, e) {
1302
+ return Pe ? requestIdleCallback(t, e) : window.setTimeout(() => {
1303
+ const o = Date.now();
1304
+ t({
1305
+ didTimeout: !1,
1306
+ timeRemaining: () => Math.max(0, 50 - (Date.now() - o))
1307
+ });
1308
+ }, 1);
1309
+ }
1310
+ function ge(t) {
1311
+ Pe ? cancelIdleCallback(t) : clearTimeout(t);
1312
+ }
1313
+ var x = /* @__PURE__ */ ((t) => (t[t.STYLE = 1] = "STYLE", t[t.VIRTUALIZATION = 2] = "VIRTUALIZATION", t[t.HEADER = 3] = "HEADER", t[t.ROWS = 4] = "ROWS", t[t.COLUMNS = 5] = "COLUMNS", t[t.FULL = 6] = "FULL", t))(x || {});
1314
+ class pt {
1315
+ #i;
1214
1316
  /** Current pending phase (0 = none pending) */
1215
1317
  #c = 0;
1216
1318
  /** RAF handle for cancellation */
@@ -1222,7 +1324,7 @@ class at {
1222
1324
  #n = null;
1223
1325
  #h = !1;
1224
1326
  constructor(e) {
1225
- this.#o = e;
1327
+ this.#i = e;
1226
1328
  }
1227
1329
  /**
1228
1330
  * Request a render at the specified phase.
@@ -1280,23 +1382,23 @@ class at {
1280
1382
  * This is the single RAF callback that does all rendering.
1281
1383
  */
1282
1384
  #p() {
1283
- if (this.#f = 0, !this.#o.isConnected()) {
1385
+ if (this.#f = 0, !this.#i.isConnected()) {
1284
1386
  this.#c = 0, this.#r && (this.#r(), this.#r = null, this.#d = null);
1285
1387
  return;
1286
1388
  }
1287
1389
  const e = this.#c;
1288
- this.#c = 0, e >= 5 && this.#o.mergeConfig(), e >= 4 && this.#o.processRows(), e >= 5 && (this.#o.processColumns(), this.#o.updateTemplate()), e >= 3 && this.#o.renderHeader(), e >= 2 && this.#o.renderVirtualWindow(), e >= 1 && this.#o.afterRender(), !this.#h && this.#n && (this.#h = !0, this.#n()), this.#r && (this.#r(), this.#r = null, this.#d = null);
1390
+ this.#c = 0, e >= 5 && this.#i.mergeConfig(), e >= 4 && this.#i.processRows(), e >= 5 && (this.#i.processColumns(), this.#i.updateTemplate()), e >= 3 && this.#i.renderHeader(), e >= 2 && this.#i.renderVirtualWindow(), e >= 1 && this.#i.afterRender(), !this.#h && this.#n && (this.#h = !0, this.#n()), this.#r && (this.#r(), this.#r = null, this.#d = null);
1289
1391
  }
1290
1392
  }
1291
- function ct(t) {
1393
+ function gt(t) {
1292
1394
  let e = null, o = null, i = null, n = null;
1293
1395
  const r = (a) => {
1294
1396
  if (!e) return;
1295
- const c = a.clientX - e.startX, h = Math.max(40, e.startWidth + c), d = t._visibleColumns[e.colIndex];
1296
- d.width = h, d.__userResized = !0, d.__renderedWidth = h, o == null && (o = requestAnimationFrame(() => {
1397
+ const c = a.clientX - e.startX, u = Math.max(40, e.startWidth + c), d = t._visibleColumns[e.colIndex];
1398
+ d.width = u, d.__userResized = !0, d.__renderedWidth = u, o == null && (o = requestAnimationFrame(() => {
1297
1399
  o = null, t.updateTemplate?.();
1298
1400
  })), t.dispatchEvent(
1299
- new CustomEvent("column-resize", { detail: { field: d.field, width: h } })
1401
+ new CustomEvent("column-resize", { detail: { field: d.field, width: u } })
1300
1402
  );
1301
1403
  };
1302
1404
  let s = !1;
@@ -1310,10 +1412,10 @@ function ct(t) {
1310
1412
  get isResizing() {
1311
1413
  return e !== null || s;
1312
1414
  },
1313
- start(a, c, h) {
1415
+ start(a, c, u) {
1314
1416
  a.preventDefault();
1315
- const d = h.getBoundingClientRect();
1316
- e = { startX: a.clientX, colIndex: c, startWidth: d.width }, window.addEventListener("mousemove", r), window.addEventListener("mouseup", l), i === null && (i = document.documentElement.style.cursor), document.documentElement.style.cursor = "e-resize", n === null && (n = document.body.style.userSelect), document.body.style.userSelect = "none";
1417
+ const d = t._visibleColumns[c], f = typeof d?.width == "number" ? d.width : void 0, p = d?.__renderedWidth ?? f ?? u.getBoundingClientRect().width;
1418
+ e = { startX: a.clientX, colIndex: c, startWidth: p }, window.addEventListener("mousemove", r), window.addEventListener("mouseup", l), i === null && (i = document.documentElement.style.cursor), document.documentElement.style.cursor = "e-resize", n === null && (n = document.body.style.userSelect), document.body.style.userSelect = "none";
1317
1419
  },
1318
1420
  resetColumn(a) {
1319
1421
  const c = t._visibleColumns[a];
@@ -1326,7 +1428,7 @@ function ct(t) {
1326
1428
  }
1327
1429
  };
1328
1430
  }
1329
- function F(t, e, o) {
1431
+ function X(t, e, o) {
1330
1432
  const i = document.createElement(t);
1331
1433
  if (e)
1332
1434
  for (const n in e) {
@@ -1335,7 +1437,7 @@ function F(t, e, o) {
1335
1437
  }
1336
1438
  return i;
1337
1439
  }
1338
- function T(t, e) {
1440
+ function A(t, e) {
1339
1441
  const o = document.createElement("div");
1340
1442
  if (t && (o.className = t), e)
1341
1443
  for (const i in e) {
@@ -1344,7 +1446,7 @@ function T(t, e) {
1344
1446
  }
1345
1447
  return o;
1346
1448
  }
1347
- function xe(t, e, o) {
1449
+ function Le(t, e, o) {
1348
1450
  const i = document.createElement("button");
1349
1451
  if (t && (i.className = t), e)
1350
1452
  for (const n in e) {
@@ -1353,12 +1455,8 @@ function xe(t, e, o) {
1353
1455
  }
1354
1456
  return i;
1355
1457
  }
1356
- function ue(t) {
1357
- const e = document.createElement("slot");
1358
- return t && (e.name = t), e;
1359
- }
1360
- const Ae = document.createElement("template");
1361
- Ae.innerHTML = `
1458
+ const He = document.createElement("template");
1459
+ He.innerHTML = `
1362
1460
  <div class="tbw-scroll-area">
1363
1461
  <div class="rows-body-wrapper">
1364
1462
  <div class="rows-body" role="grid">
@@ -1377,34 +1475,38 @@ Ae.innerHTML = `
1377
1475
  <div class="faux-vscroll-spacer"></div>
1378
1476
  </div>
1379
1477
  `;
1380
- function Pe() {
1381
- return Ae.content.cloneNode(!0);
1478
+ function Oe() {
1479
+ return He.content.cloneNode(!0);
1382
1480
  }
1383
- function fe(t) {
1384
- const e = document.createDocumentFragment(), o = T(t.hasShell ? "tbw-grid-root has-shell" : "tbw-grid-root");
1481
+ function me(t) {
1482
+ const e = document.createDocumentFragment(), o = A(t.hasShell ? "tbw-grid-root has-shell" : "tbw-grid-root");
1385
1483
  if (t.hasShell && t.shellHeader && t.shellBody)
1386
1484
  o.appendChild(t.shellHeader), o.appendChild(t.shellBody);
1387
1485
  else {
1388
- const i = T("tbw-grid-content");
1389
- i.appendChild(Pe()), o.appendChild(i);
1486
+ const i = A("tbw-grid-content");
1487
+ i.appendChild(Oe()), o.appendChild(i);
1390
1488
  }
1391
1489
  return e.appendChild(o), e;
1392
1490
  }
1393
- function dt(t) {
1394
- const e = T("tbw-shell-header", { part: "shell-header", role: "presentation" });
1491
+ function mt(t) {
1492
+ const e = A("tbw-shell-header", { part: "shell-header", role: "presentation" });
1395
1493
  if (t.title) {
1396
- const r = T("tbw-shell-title");
1494
+ const r = A("tbw-shell-title");
1397
1495
  r.textContent = t.title, e.appendChild(r);
1398
1496
  }
1399
- const o = T("tbw-shell-content", { part: "shell-content", role: "presentation" });
1400
- o.appendChild(ue("header-content")), e.appendChild(o);
1401
- const i = T("tbw-shell-toolbar", { part: "shell-toolbar", role: "presentation" });
1497
+ const o = A("tbw-shell-content", {
1498
+ part: "shell-content",
1499
+ role: "presentation",
1500
+ "data-light-dom-header-content": ""
1501
+ });
1502
+ e.appendChild(o);
1503
+ const i = A("tbw-shell-toolbar", { part: "shell-toolbar", role: "presentation" });
1402
1504
  for (const r of t.configButtons)
1403
- (r.hasElement || r.hasRender) && i.appendChild(T("tbw-toolbar-btn-slot", { "data-btn-slot": r.id }));
1505
+ (r.hasElement || r.hasRender) && i.appendChild(A("tbw-toolbar-btn-slot", { "data-btn-slot": r.id }));
1404
1506
  for (const r of t.apiButtons)
1405
- (r.hasElement || r.hasRender) && i.appendChild(T("tbw-toolbar-btn-slot", { "data-btn-slot": r.id }));
1406
- if (i.appendChild(ue("toolbar")), (t.configButtons.some((r) => r.hasElement || r.hasRender) || t.apiButtons.some((r) => r.hasElement || r.hasRender)) && t.hasPanels && i.appendChild(T("tbw-toolbar-separator")), t.hasPanels) {
1407
- const r = xe(t.isPanelOpen ? "tbw-toolbar-btn active" : "tbw-toolbar-btn", {
1507
+ (r.hasElement || r.hasRender) && i.appendChild(A("tbw-toolbar-btn-slot", { "data-btn-slot": r.id }));
1508
+ if (i.appendChild(A("tbw-toolbar-light-dom", { "data-light-dom-toolbar": "" })), (t.configButtons.some((r) => r.hasElement || r.hasRender) || t.apiButtons.some((r) => r.hasElement || r.hasRender)) && t.hasPanels && i.appendChild(A("tbw-toolbar-separator")), t.hasPanels) {
1509
+ const r = Le(t.isPanelOpen ? "tbw-toolbar-btn active" : "tbw-toolbar-btn", {
1408
1510
  "data-panel-toggle": "",
1409
1511
  title: "Settings",
1410
1512
  "aria-label": "Toggle settings panel",
@@ -1415,12 +1517,12 @@ function dt(t) {
1415
1517
  }
1416
1518
  return e.appendChild(i), e;
1417
1519
  }
1418
- function ht(t) {
1419
- const e = T("tbw-shell-body"), o = t.panels.length > 0, i = t.panels.length === 1, n = T("tbw-grid-content");
1420
- n.appendChild(Pe());
1520
+ function bt(t) {
1521
+ const e = A("tbw-shell-body"), o = t.panels.length > 0, i = t.panels.length === 1, n = A("tbw-grid-content");
1522
+ n.appendChild(Oe());
1421
1523
  let r = null;
1422
1524
  if (o) {
1423
- r = F("aside", {
1525
+ r = X("aside", {
1424
1526
  class: t.isPanelOpen ? "tbw-tool-panel open" : "tbw-tool-panel",
1425
1527
  part: "tool-panel",
1426
1528
  "data-position": t.position,
@@ -1429,29 +1531,29 @@ function ht(t) {
1429
1531
  });
1430
1532
  const s = t.position === "left" ? "right" : "left";
1431
1533
  r.appendChild(
1432
- T("tbw-tool-panel-resize", {
1534
+ A("tbw-tool-panel-resize", {
1433
1535
  "data-resize-handle": "",
1434
1536
  "data-handle-position": s,
1435
1537
  "aria-hidden": "true"
1436
1538
  })
1437
1539
  );
1438
- const l = T("tbw-tool-panel-content", { role: "presentation" }), a = T("tbw-accordion");
1540
+ const l = A("tbw-tool-panel-content", { role: "presentation" }), a = A("tbw-accordion");
1439
1541
  for (const c of t.panels) {
1440
- const h = `tbw-accordion-section${c.isExpanded ? " expanded" : ""}${i ? " single" : ""}`, d = T(h, { "data-section": c.id }), f = xe("tbw-accordion-header", {
1542
+ const u = `tbw-accordion-section${c.isExpanded ? " expanded" : ""}${i ? " single" : ""}`, d = A(u, { "data-section": c.id }), f = Le("tbw-accordion-header", {
1441
1543
  "aria-expanded": String(c.isExpanded),
1442
1544
  "aria-controls": `tbw-section-${c.id}`
1443
1545
  });
1444
1546
  if (i && f.setAttribute("aria-disabled", "true"), c.icon) {
1445
- const u = F("span", { class: "tbw-accordion-icon" });
1446
- u.innerHTML = c.icon, f.appendChild(u);
1547
+ const h = X("span", { class: "tbw-accordion-icon" });
1548
+ h.innerHTML = c.icon, f.appendChild(h);
1447
1549
  }
1448
- const p = F("span", { class: "tbw-accordion-title" });
1550
+ const p = X("span", { class: "tbw-accordion-title" });
1449
1551
  if (p.textContent = c.title, f.appendChild(p), !i) {
1450
- const u = F("span", { class: "tbw-accordion-chevron" });
1451
- u.innerHTML = c.isExpanded ? t.collapseIcon : t.expandIcon, f.appendChild(u);
1552
+ const h = X("span", { class: "tbw-accordion-chevron" });
1553
+ h.innerHTML = c.isExpanded ? t.collapseIcon : t.expandIcon, f.appendChild(h);
1452
1554
  }
1453
1555
  d.appendChild(f), d.appendChild(
1454
- T("tbw-accordion-content", {
1556
+ A("tbw-accordion-content", {
1455
1557
  id: `tbw-section-${c.id}`,
1456
1558
  role: "presentation"
1457
1559
  })
@@ -1461,10 +1563,10 @@ function ht(t) {
1461
1563
  }
1462
1564
  return t.position === "left" && r ? (e.appendChild(r), e.appendChild(n)) : (e.appendChild(n), r && e.appendChild(r)), e;
1463
1565
  }
1464
- function O(t) {
1566
+ function z(t) {
1465
1567
  return t ? typeof t == "string" ? t : t.outerHTML : "";
1466
1568
  }
1467
- function ut() {
1569
+ function wt() {
1468
1570
  return {
1469
1571
  toolPanels: /* @__PURE__ */ new Map(),
1470
1572
  headerContents: /* @__PURE__ */ new Map(),
@@ -1478,36 +1580,36 @@ function ut() {
1478
1580
  expandedSections: /* @__PURE__ */ new Set(),
1479
1581
  headerContentCleanups: /* @__PURE__ */ new Map(),
1480
1582
  panelCleanups: /* @__PURE__ */ new Map(),
1481
- toolbarButtonCleanups: /* @__PURE__ */ new Map()
1583
+ toolbarButtonCleanups: /* @__PURE__ */ new Map(),
1584
+ lightDomContentMoved: !1,
1585
+ lightDomToolButtonsMoved: !1
1482
1586
  };
1483
1587
  }
1484
- function Le(t) {
1588
+ function Me(t) {
1485
1589
  return !!(t?.header?.title || t?.header?.toolbarButtons?.length || t?.toolPanels?.length || t?.headerContents?.length || t?.header?.lightDomContent?.length || t?.header?.hasToolButtonsContainer);
1486
1590
  }
1487
- function pe(t, e, o = "☰") {
1488
- const i = t?.header?.title ?? e.lightDomTitle ?? "", n = !!i, r = O(o), s = t?.header?.toolbarButtons ?? [], l = s.some((g) => g.element || g.render), a = [...e.toolbarButtons.values()].some((g) => g.element || g.render), c = e.toolPanels.size > 0, d = (l || a) && c, f = [...s].sort((g, m) => (g.order ?? 100) - (m.order ?? 100)), p = [...e.toolbarButtons.values()].sort((g, m) => (g.order ?? 100) - (m.order ?? 100));
1489
- let u = "";
1591
+ function be(t, e, o = "☰") {
1592
+ const i = t?.header?.title ?? e.lightDomTitle ?? "", n = !!i, r = z(o), s = t?.header?.toolbarButtons ?? [], l = s.some((g) => g.element || g.render), a = [...e.toolbarButtons.values()].some((g) => g.element || g.render), c = e.toolPanels.size > 0, d = (l || a) && c, f = [...s].sort((g, w) => (g.order ?? 100) - (w.order ?? 100)), p = [...e.toolbarButtons.values()].sort((g, w) => (g.order ?? 100) - (w.order ?? 100));
1593
+ let h = "";
1490
1594
  for (const g of f)
1491
- (g.element || g.render) && (u += `<div class="tbw-toolbar-btn-slot" data-btn-slot="${g.id}"></div>`);
1595
+ (g.element || g.render) && (h += `<div class="tbw-toolbar-btn-slot" data-btn-slot="${g.id}"></div>`);
1492
1596
  for (const g of p)
1493
- (g.element || g.render) && (u += `<div class="tbw-toolbar-btn-slot" data-btn-slot="${g.id}"></div>`);
1494
- if (u += '<slot name="toolbar"></slot>', d && (u += '<div class="tbw-toolbar-separator"></div>'), c) {
1597
+ (g.element || g.render) && (h += `<div class="tbw-toolbar-btn-slot" data-btn-slot="${g.id}"></div>`);
1598
+ if (h += '<div class="tbw-toolbar-light-dom" data-light-dom-toolbar></div>', d && (h += '<div class="tbw-toolbar-separator"></div>'), c) {
1495
1599
  const g = e.isPanelOpen;
1496
- u += `<button class="${g ? "tbw-toolbar-btn active" : "tbw-toolbar-btn"}" data-panel-toggle title="Settings" aria-label="Toggle settings panel" aria-pressed="${g}" aria-controls="tbw-tool-panel">${r}</button>`;
1600
+ h += `<button class="${g ? "tbw-toolbar-btn active" : "tbw-toolbar-btn"}" data-panel-toggle title="Settings" aria-label="Toggle settings panel" aria-pressed="${g}" aria-controls="tbw-tool-panel">${r}</button>`;
1497
1601
  }
1498
1602
  return `
1499
1603
  <div class="tbw-shell-header" part="shell-header" role="presentation">
1500
- ${n ? `<div class="tbw-shell-title">${We(i)}</div>` : ""}
1501
- <div class="tbw-shell-content" part="shell-content" role="presentation">
1502
- <slot name="header-content"></slot>
1503
- </div>
1604
+ ${n ? `<div class="tbw-shell-title">${Ue(i)}</div>` : ""}
1605
+ <div class="tbw-shell-content" part="shell-content" role="presentation" data-light-dom-header-content></div>
1504
1606
  <div class="tbw-shell-toolbar" part="shell-toolbar" role="presentation">
1505
- ${u}
1607
+ ${h}
1506
1608
  </div>
1507
1609
  </div>
1508
1610
  `;
1509
1611
  }
1510
- function M(t, e) {
1612
+ function N(t, e) {
1511
1613
  const o = t.querySelector("tbw-grid-header");
1512
1614
  if (!o) return;
1513
1615
  if (!e.lightDomTitle) {
@@ -1515,15 +1617,13 @@ function M(t, e) {
1515
1617
  n && (e.lightDomTitle = n);
1516
1618
  }
1517
1619
  const i = o.querySelectorAll("tbw-grid-header-content");
1518
- i.length > 0 && e.lightDomHeaderContent.length === 0 && (e.lightDomHeaderContent = Array.from(i), e.lightDomHeaderContent.forEach((n) => {
1519
- n.setAttribute("slot", "header-content");
1520
- })), o.style.display = "none";
1620
+ i.length > 0 && e.lightDomHeaderContent.length === 0 && (e.lightDomHeaderContent = Array.from(i)), o.style.display = "none";
1521
1621
  }
1522
- function z(t, e) {
1622
+ function k(t, e) {
1523
1623
  const o = t.querySelector(":scope > tbw-grid-tool-buttons");
1524
- o && (e.hasToolButtonsContainer = !0, o.setAttribute("slot", "toolbar"));
1624
+ o && (e.hasToolButtonsContainer = !0, o.style.display = "none");
1525
1625
  }
1526
- function N(t, e, o) {
1626
+ function I(t, e, o) {
1527
1627
  t.querySelectorAll(":scope > tbw-grid-tool-panel").forEach((n) => {
1528
1628
  const r = n, s = r.getAttribute("id"), l = r.getAttribute("title");
1529
1629
  if (!s || !l) {
@@ -1532,39 +1632,39 @@ function N(t, e, o) {
1532
1632
  );
1533
1633
  return;
1534
1634
  }
1535
- const a = r.getAttribute("icon") ?? void 0, c = r.getAttribute("tooltip") ?? void 0, h = parseInt(r.getAttribute("order") ?? "100", 10);
1635
+ const a = r.getAttribute("icon") ?? void 0, c = r.getAttribute("tooltip") ?? void 0, u = parseInt(r.getAttribute("order") ?? "100", 10);
1536
1636
  let d;
1537
1637
  const f = o?.(r);
1538
1638
  if (f)
1539
1639
  d = f;
1540
1640
  else {
1541
1641
  const g = r.innerHTML.trim();
1542
- d = (m) => {
1543
- const b = document.createElement("div");
1544
- return b.innerHTML = g, m.appendChild(b), () => b.remove();
1642
+ d = (w) => {
1643
+ const _ = document.createElement("div");
1644
+ return _.innerHTML = g, w.appendChild(_), () => _.remove();
1545
1645
  };
1546
1646
  }
1547
1647
  const p = e.toolPanels.get(s);
1548
1648
  if (p) {
1549
1649
  if (f) {
1550
- p.render = d, p.order = h, p.icon = a, p.tooltip = c;
1650
+ p.render = d, p.order = u, p.icon = a, p.tooltip = c;
1551
1651
  const g = e.panelCleanups.get(s);
1552
1652
  g && (g(), e.panelCleanups.delete(s));
1553
1653
  }
1554
1654
  return;
1555
1655
  }
1556
- const u = {
1656
+ const h = {
1557
1657
  id: s,
1558
1658
  title: l,
1559
1659
  icon: a,
1560
1660
  tooltip: c,
1561
- order: h,
1661
+ order: u,
1562
1662
  render: d
1563
1663
  };
1564
- e.toolPanels.set(s, u), e.lightDomToolPanelIds.add(s), r.style.display = "none";
1664
+ e.toolPanels.set(s, h), e.lightDomToolPanelIds.add(s), r.style.display = "none";
1565
1665
  });
1566
1666
  }
1567
- function ft(t, e, o, i) {
1667
+ function vt(t, e, o, i) {
1568
1668
  const n = t.querySelector(".tbw-shell-toolbar");
1569
1669
  n && n.addEventListener("click", (s) => {
1570
1670
  const l = s.target;
@@ -1574,79 +1674,95 @@ function ft(t, e, o, i) {
1574
1674
  }
1575
1675
  const c = l.closest("[data-btn]");
1576
1676
  if (c) {
1577
- const h = c.getAttribute("data-btn");
1578
- h && i.onToolbarButtonClick(h);
1677
+ const u = c.getAttribute("data-btn");
1678
+ u && i.onToolbarButtonClick(u);
1579
1679
  }
1580
1680
  });
1581
1681
  const r = t.querySelector(".tbw-accordion");
1582
1682
  r && r.addEventListener("click", (s) => {
1583
1683
  const a = s.target.closest(".tbw-accordion-header");
1584
1684
  if (a) {
1585
- const h = a.closest("[data-section]")?.getAttribute("data-section");
1586
- h && i.onSectionToggle(h);
1685
+ const u = a.closest("[data-section]")?.getAttribute("data-section");
1686
+ u && i.onSectionToggle(u);
1587
1687
  }
1588
1688
  });
1589
1689
  }
1590
- function pt(t, e, o) {
1690
+ function Ct(t, e, o) {
1591
1691
  const i = t.querySelector(".tbw-tool-panel"), n = t.querySelector("[data-resize-handle]"), r = t.querySelector(".tbw-shell-body");
1592
1692
  if (!i || !n || !r)
1593
1693
  return () => {
1594
1694
  };
1595
1695
  const s = e?.toolPanel?.position ?? "right", l = 200;
1596
- let a = 0, c = 0, h = 0, d = !1;
1696
+ let a = 0, c = 0, u = 0, d = !1;
1597
1697
  const f = (g) => {
1598
1698
  if (!d) return;
1599
1699
  g.preventDefault();
1600
- const m = s === "left" ? g.clientX - a : a - g.clientX, b = Math.min(h, Math.max(l, c + m));
1601
- i.style.width = `${b}px`;
1700
+ const w = s === "left" ? g.clientX - a : a - g.clientX, _ = Math.min(u, Math.max(l, c + w));
1701
+ i.style.width = `${_}px`;
1602
1702
  }, p = () => {
1603
1703
  if (!d) return;
1604
1704
  d = !1, n.classList.remove("resizing"), i.style.transition = "", document.body.style.cursor = "", document.body.style.userSelect = "";
1605
1705
  const g = i.getBoundingClientRect().width;
1606
1706
  o(g), document.removeEventListener("mousemove", f), document.removeEventListener("mouseup", p);
1607
- }, u = (g) => {
1608
- g.preventDefault(), d = !0, a = g.clientX, c = i.getBoundingClientRect().width, h = r.getBoundingClientRect().width - 20, n.classList.add("resizing"), i.style.transition = "none", document.body.style.cursor = "col-resize", document.body.style.userSelect = "none", document.addEventListener("mousemove", f), document.addEventListener("mouseup", p);
1707
+ }, h = (g) => {
1708
+ g.preventDefault(), d = !0, a = g.clientX, c = i.getBoundingClientRect().width, u = r.getBoundingClientRect().width - 20, n.classList.add("resizing"), i.style.transition = "none", document.body.style.cursor = "col-resize", document.body.style.userSelect = "none", document.addEventListener("mousemove", f), document.addEventListener("mouseup", p);
1609
1709
  };
1610
- return n.addEventListener("mousedown", u), () => {
1611
- n.removeEventListener("mousedown", u), document.removeEventListener("mousemove", f), document.removeEventListener("mouseup", p);
1710
+ return n.addEventListener("mousedown", h), () => {
1711
+ n.removeEventListener("mousedown", h), document.removeEventListener("mousemove", f), document.removeEventListener("mouseup", p);
1612
1712
  };
1613
1713
  }
1614
- function gt(t, e, o) {
1615
- const i = [...e?.header?.toolbarButtons ?? [], ...o.toolbarButtons.values()];
1616
- for (const n of i) {
1617
- const r = t.querySelector(`[data-btn-slot="${n.id}"]`);
1618
- if (!r) continue;
1619
- const s = o.toolbarButtonCleanups.get(n.id);
1620
- if (s && (s(), o.toolbarButtonCleanups.delete(n.id)), n.element)
1621
- r.appendChild(n.element);
1622
- else if (n.render) {
1623
- const l = n.render(r);
1624
- l && o.toolbarButtonCleanups.set(n.id, l);
1714
+ function yt(t, e, o, i) {
1715
+ const n = [...e?.header?.toolbarButtons ?? [], ...o.toolbarButtons.values()];
1716
+ for (const r of n) {
1717
+ if (r.element?.parentNode || o.toolbarButtonCleanups.has(r.id)) continue;
1718
+ const s = t.querySelector(`[data-btn-slot="${r.id}"]`);
1719
+ if (s) {
1720
+ if (r.element)
1721
+ s.appendChild(r.element);
1722
+ else if (r.render) {
1723
+ const l = r.render(s);
1724
+ l && o.toolbarButtonCleanups.set(r.id, l);
1725
+ }
1726
+ }
1727
+ }
1728
+ if (i && o.hasToolButtonsContainer && !o.lightDomToolButtonsMoved) {
1729
+ const r = t.querySelector("[data-light-dom-toolbar]"), s = i.querySelector(":scope > tbw-grid-tool-buttons");
1730
+ if (r && s && s.firstChild) {
1731
+ for (; s.firstChild; )
1732
+ r.appendChild(s.firstChild);
1733
+ o.lightDomToolButtonsMoved = !0;
1625
1734
  }
1626
1735
  }
1627
1736
  }
1628
- function He(t, e) {
1629
- const o = t.querySelector(".tbw-shell-content");
1630
- if (!o) return;
1631
- const i = [...e.headerContents.values()].sort((r, s) => (r.order ?? 100) - (s.order ?? 100)), n = o.querySelector('slot[name="header-content"]');
1632
- for (const r of i) {
1633
- const s = e.headerContentCleanups.get(r.id);
1634
- s && (s(), e.headerContentCleanups.delete(r.id));
1635
- let l = o.querySelector(`[data-header-content="${r.id}"]`);
1636
- l || (l = document.createElement("div"), l.setAttribute("data-header-content", r.id), n ? o.insertBefore(l, n) : o.appendChild(l));
1637
- const a = r.render(l);
1638
- a && e.headerContentCleanups.set(r.id, a);
1737
+ function De(t, e) {
1738
+ const o = e.lightDomHeaderContent.length > 0 && !e.lightDomContentMoved, i = e.headerContents.size > 0;
1739
+ if (!o && !i) return;
1740
+ const n = t.querySelector(".tbw-shell-content");
1741
+ if (!n) return;
1742
+ if (o) {
1743
+ for (const s of e.lightDomHeaderContent)
1744
+ s.style.display = "", n.appendChild(s);
1745
+ e.lightDomContentMoved = !0;
1746
+ }
1747
+ const r = [...e.headerContents.values()].sort((s, l) => (s.order ?? 100) - (l.order ?? 100));
1748
+ for (const s of r) {
1749
+ const l = e.headerContentCleanups.get(s.id);
1750
+ l && (l(), e.headerContentCleanups.delete(s.id));
1751
+ let a = n.querySelector(`[data-header-content="${s.id}"]`);
1752
+ a || (a = document.createElement("div"), a.setAttribute("data-header-content", s.id), n.appendChild(a));
1753
+ const c = s.render(a);
1754
+ c && e.headerContentCleanups.set(s.id, c);
1639
1755
  }
1640
1756
  }
1641
- function wt(t, e, o) {
1757
+ function _t(t, e, o) {
1642
1758
  if (!e.isPanelOpen) return;
1643
- const i = O(o?.expand ?? L.expand), n = O(o?.collapse ?? L.collapse);
1759
+ const i = z(o?.expand ?? M.expand), n = z(o?.collapse ?? M.collapse);
1644
1760
  for (const [r, s] of e.toolPanels) {
1645
1761
  const l = e.expandedSections.has(r), a = t.querySelector(`[data-section="${r}"]`), c = a?.querySelector(".tbw-accordion-content");
1646
1762
  if (!a || !c) continue;
1647
1763
  a.classList.toggle("expanded", l);
1648
- const h = a.querySelector(".tbw-accordion-header");
1649
- h && h.setAttribute("aria-expanded", String(l));
1764
+ const u = a.querySelector(".tbw-accordion-header");
1765
+ u && u.setAttribute("aria-expanded", String(l));
1650
1766
  const d = a.querySelector(".tbw-accordion-chevron");
1651
1767
  if (d && (d.innerHTML = l ? n : i), l) {
1652
1768
  if (c.children.length === 0) {
@@ -1659,15 +1775,15 @@ function wt(t, e, o) {
1659
1775
  }
1660
1776
  }
1661
1777
  }
1662
- function ge(t, e) {
1778
+ function we(t, e) {
1663
1779
  const o = t.querySelector("[data-panel-toggle]");
1664
1780
  o && (o.classList.toggle("active", e.isPanelOpen), o.setAttribute("aria-pressed", String(e.isPanelOpen)));
1665
1781
  }
1666
- function we(t, e) {
1782
+ function ve(t, e) {
1667
1783
  const o = t.querySelector(".tbw-tool-panel");
1668
1784
  o && (o.classList.toggle("open", e.isPanelOpen), e.isPanelOpen || (o.style.width = ""));
1669
1785
  }
1670
- function bt(t, e) {
1786
+ function Et(t, e) {
1671
1787
  const o = [];
1672
1788
  for (const i of t?.header?.toolbarButtons ?? [])
1673
1789
  o.push({
@@ -1690,7 +1806,7 @@ function bt(t, e) {
1690
1806
  });
1691
1807
  return o;
1692
1808
  }
1693
- function mt(t) {
1809
+ function St(t) {
1694
1810
  for (const e of t.headerContentCleanups.values())
1695
1811
  e();
1696
1812
  t.headerContentCleanups.clear();
@@ -1702,9 +1818,9 @@ function mt(t) {
1702
1818
  if (t.toolbarButtonCleanups.clear(), t.isPanelOpen)
1703
1819
  for (const e of t.expandedSections)
1704
1820
  t.toolPanels.get(e)?.onClose?.();
1705
- t.isPanelOpen = !1, t.expandedSections.clear(), t.toolPanels.clear(), t.headerContents.clear(), t.toolbarButtons.clear(), t.lightDomHeaderContent = [];
1821
+ t.isPanelOpen = !1, t.expandedSections.clear(), t.toolPanels.clear(), t.headerContents.clear(), t.toolbarButtons.clear(), t.lightDomHeaderContent = [], t.lightDomContentMoved = !1, t.lightDomToolButtonsMoved = !1;
1706
1822
  }
1707
- function vt(t, e) {
1823
+ function Tt(t, e) {
1708
1824
  let o = !1;
1709
1825
  const i = {
1710
1826
  get isInitialized() {
@@ -1733,7 +1849,7 @@ function vt(t, e) {
1733
1849
  s && t.expandedSections.add(s.id);
1734
1850
  }
1735
1851
  const n = e.getShadow();
1736
- ge(n, t), we(n, t), wt(n, t, e.getAccordionIcons()), e.emit("tool-panel-open", { sections: i.expandedSections });
1852
+ we(n, t), ve(n, t), _t(n, t, e.getAccordionIcons()), e.emit("tool-panel-open", { sections: i.expandedSections });
1737
1853
  },
1738
1854
  closeToolPanel() {
1739
1855
  if (!t.isPanelOpen) return;
@@ -1744,7 +1860,7 @@ function vt(t, e) {
1744
1860
  r.onClose?.();
1745
1861
  t.isPanelOpen = !1;
1746
1862
  const n = e.getShadow();
1747
- ge(n, t), we(n, t), e.emit("tool-panel-close", {});
1863
+ we(n, t), ve(n, t), e.emit("tool-panel-close", {});
1748
1864
  },
1749
1865
  toggleToolPanel() {
1750
1866
  t.isPanelOpen ? i.closeToolPanel() : i.openToolPanel();
@@ -1760,16 +1876,16 @@ function vt(t, e) {
1760
1876
  const s = e.getShadow(), l = t.expandedSections.has(n);
1761
1877
  if (l) {
1762
1878
  const a = t.panelCleanups.get(n);
1763
- a && (a(), t.panelCleanups.delete(n)), r.onClose?.(), t.expandedSections.delete(n), J(s, n, !1);
1879
+ a && (a(), t.panelCleanups.delete(n)), r.onClose?.(), t.expandedSections.delete(n), te(s, n, !1);
1764
1880
  } else {
1765
1881
  for (const [a, c] of t.toolPanels)
1766
1882
  if (a !== n && t.expandedSections.has(a)) {
1767
- const h = t.panelCleanups.get(a);
1768
- h && (h(), t.panelCleanups.delete(a)), c.onClose?.(), t.expandedSections.delete(a), J(s, a, !1);
1883
+ const u = t.panelCleanups.get(a);
1884
+ u && (u(), t.panelCleanups.delete(a)), c.onClose?.(), t.expandedSections.delete(a), te(s, a, !1);
1769
1885
  const d = s.querySelector(`[data-section="${a}"] .tbw-accordion-content`);
1770
1886
  d && (d.innerHTML = "");
1771
1887
  }
1772
- t.expandedSections.add(n), J(s, n, !0), Ct(s, t, n);
1888
+ t.expandedSections.add(n), te(s, n, !0), Rt(s, t, n);
1773
1889
  }
1774
1890
  e.emit("tool-panel-section-toggle", { id: n, expanded: !l });
1775
1891
  },
@@ -1798,14 +1914,14 @@ function vt(t, e) {
1798
1914
  console.warn(`[tbw-grid] Header content "${n.id}" already registered`);
1799
1915
  return;
1800
1916
  }
1801
- t.headerContents.set(n.id, n), o && He(e.getShadow(), t);
1917
+ t.headerContents.set(n.id, n), o && De(e.getShadow(), t);
1802
1918
  },
1803
1919
  unregisterHeaderContent(n) {
1804
1920
  const r = t.headerContentCleanups.get(n);
1805
1921
  r && (r(), t.headerContentCleanups.delete(n)), t.headerContents.get(n)?.onDestroy?.(), t.headerContents.delete(n), e.getShadow().querySelector(`[data-header-content="${n}"]`)?.remove();
1806
1922
  },
1807
1923
  getToolbarButtons() {
1808
- return bt(e.getShellConfig(), t);
1924
+ return Et(e.getShellConfig(), t);
1809
1925
  },
1810
1926
  registerToolbarButton(n) {
1811
1927
  if (t.toolbarButtons.has(n.id)) {
@@ -1829,11 +1945,11 @@ function vt(t, e) {
1829
1945
  };
1830
1946
  return i;
1831
1947
  }
1832
- function J(t, e, o) {
1948
+ function te(t, e, o) {
1833
1949
  const i = t.querySelector(`[data-section="${e}"]`);
1834
1950
  i && i.classList.toggle("expanded", o);
1835
1951
  }
1836
- function Ct(t, e, o) {
1952
+ function Rt(t, e, o) {
1837
1953
  const i = e.toolPanels.get(o);
1838
1954
  if (!i?.render) return;
1839
1955
  const n = t.querySelector(`[data-section="${o}"] .tbw-accordion-content`);
@@ -1841,46 +1957,51 @@ function Ct(t, e, o) {
1841
1957
  const r = i.render(n);
1842
1958
  r && e.panelCleanups.set(o, r);
1843
1959
  }
1844
- function _t(t, e, o, i) {
1845
- const n = Le(e);
1846
- if (t.replaceChildren(), n) {
1847
- const r = O(i?.toolPanel ?? L.toolPanel), s = O(i?.expand ?? L.expand), l = O(i?.collapse ?? L.collapse), c = [...e?.header?.toolbarButtons ?? []].sort((b, _) => (b.order ?? 100) - (_.order ?? 100)), d = [...e?.toolPanels ?? []].sort((b, _) => (b.order ?? 100) - (_.order ?? 100)), f = {
1960
+ function xt(t, e, o, i) {
1961
+ const n = Me(e), r = [], s = ["tbw-grid-header", "tbw-grid-tool-buttons", "tbw-grid-tool-panel", "tbw-grid-column"];
1962
+ for (const l of s)
1963
+ t.querySelectorAll(`:scope > ${l}`).forEach((c) => r.push(c));
1964
+ t.replaceChildren();
1965
+ for (const l of r)
1966
+ t.appendChild(l);
1967
+ if (n) {
1968
+ const l = z(i?.toolPanel ?? M.toolPanel), a = z(i?.expand ?? M.expand), c = z(i?.collapse ?? M.collapse), d = [...e?.header?.toolbarButtons ?? []].sort((v, m) => (v.order ?? 100) - (m.order ?? 100)), p = [...e?.toolPanels ?? []].sort((v, m) => (v.order ?? 100) - (m.order ?? 100)), h = {
1848
1969
  title: e?.header?.title ?? void 0,
1849
- hasPanels: d.length > 0,
1970
+ hasPanels: p.length > 0,
1850
1971
  isPanelOpen: o.isPanelOpen,
1851
- toolPanelIcon: r,
1972
+ toolPanelIcon: l,
1852
1973
  // All buttons are now in config (no more separate config vs API distinction for rendering)
1853
- configButtons: c.map((b) => ({
1854
- id: b.id,
1855
- hasElement: !!b.element,
1856
- hasRender: !!b.render
1974
+ configButtons: d.map((v) => ({
1975
+ id: v.id,
1976
+ hasElement: !!v.element,
1977
+ hasRender: !!v.render
1857
1978
  })),
1858
1979
  apiButtons: []
1859
1980
  // No longer needed - all buttons merged into configButtons
1860
- }, p = {
1981
+ }, g = {
1861
1982
  position: e?.toolPanel?.position ?? "right",
1862
1983
  isPanelOpen: o.isPanelOpen,
1863
- expandIcon: s,
1864
- collapseIcon: l,
1865
- panels: d.map((b) => ({
1866
- id: b.id,
1867
- title: b.title,
1868
- icon: O(b.icon),
1869
- isExpanded: o.expandedSections.has(b.id)
1984
+ expandIcon: a,
1985
+ collapseIcon: c,
1986
+ panels: p.map((v) => ({
1987
+ id: v.id,
1988
+ title: v.title,
1989
+ icon: z(v.icon),
1990
+ isExpanded: o.expandedSections.has(v.id)
1870
1991
  }))
1871
- }, u = dt(f), g = ht(p), m = fe({
1992
+ }, w = mt(h), _ = bt(g), T = me({
1872
1993
  hasShell: !0,
1873
- shellHeader: u,
1874
- shellBody: g
1994
+ shellHeader: w,
1995
+ shellBody: _
1875
1996
  });
1876
- t.appendChild(m);
1997
+ t.appendChild(T);
1877
1998
  } else {
1878
- const r = fe({ hasShell: !1 });
1879
- t.appendChild(r);
1999
+ const l = me({ hasShell: !1 });
2000
+ t.appendChild(l);
1880
2001
  }
1881
2002
  return n;
1882
2003
  }
1883
- function yt() {
2004
+ function At() {
1884
2005
  return {
1885
2006
  startY: null,
1886
2007
  startX: null,
@@ -1894,19 +2015,19 @@ function yt() {
1894
2015
  momentumRaf: 0
1895
2016
  };
1896
2017
  }
1897
- function Et(t) {
2018
+ function Pt(t) {
1898
2019
  t.startY = null, t.startX = null, t.scrollTop = null, t.scrollLeft = null, t.lastY = null, t.lastX = null, t.lastTime = null;
1899
2020
  }
1900
- function Oe(t) {
2021
+ function ze(t) {
1901
2022
  t.momentumRaf && (cancelAnimationFrame(t.momentumRaf), t.momentumRaf = 0);
1902
2023
  }
1903
- function St(t, e, o) {
2024
+ function Lt(t, e, o) {
1904
2025
  if (t.touches.length !== 1) return;
1905
- Oe(e);
2026
+ ze(e);
1906
2027
  const i = t.touches[0];
1907
2028
  e.startY = i.clientY, e.startX = i.clientX, e.lastY = i.clientY, e.lastX = i.clientX, e.lastTime = performance.now(), e.scrollTop = o.fauxScrollbar.scrollTop, e.scrollLeft = o.scrollArea?.scrollLeft ?? 0, e.velocityY = 0, e.velocityX = 0;
1908
2029
  }
1909
- function Rt(t, e, o) {
2030
+ function Ht(t, e, o) {
1910
2031
  if (t.touches.length !== 1 || e.startY === null || e.startX === null || e.scrollTop === null || e.scrollLeft === null)
1911
2032
  return !1;
1912
2033
  const i = t.touches[0], n = i.clientY, r = i.clientX, s = performance.now(), l = e.startY - n, a = e.startX - r;
@@ -1915,18 +2036,18 @@ function Rt(t, e, o) {
1915
2036
  g > 0 && (e.velocityY = (e.lastY - n) / g, e.velocityX = (e.lastX - r) / g);
1916
2037
  }
1917
2038
  e.lastY = n, e.lastX = r, e.lastTime = s;
1918
- const { scrollTop: c, scrollHeight: h, clientHeight: d } = o.fauxScrollbar, f = h - d, p = l > 0 && c < f || l < 0 && c > 0;
1919
- let u = !1;
2039
+ const { scrollTop: c, scrollHeight: u, clientHeight: d } = o.fauxScrollbar, f = u - d, p = l > 0 && c < f || l < 0 && c > 0;
2040
+ let h = !1;
1920
2041
  if (o.scrollArea) {
1921
- const { scrollLeft: g, scrollWidth: m, clientWidth: b } = o.scrollArea, _ = m - b;
1922
- u = a > 0 && g < _ || a < 0 && g > 0;
2042
+ const { scrollLeft: g, scrollWidth: w, clientWidth: _ } = o.scrollArea, T = w - _;
2043
+ h = a > 0 && g < T || a < 0 && g > 0;
1923
2044
  }
1924
- return p && (o.fauxScrollbar.scrollTop = e.scrollTop + l), u && o.scrollArea && (o.scrollArea.scrollLeft = e.scrollLeft + a), p || u;
2045
+ return p && (o.fauxScrollbar.scrollTop = e.scrollTop + l), h && o.scrollArea && (o.scrollArea.scrollLeft = e.scrollLeft + a), p || h;
1925
2046
  }
1926
- function Tt(t, e) {
1927
- (Math.abs(t.velocityY) > 0.1 || Math.abs(t.velocityX) > 0.1) && xt(t, e), Et(t);
2047
+ function Ot(t, e) {
2048
+ (Math.abs(t.velocityY) > 0.1 || Math.abs(t.velocityX) > 0.1) && Mt(t, e), Pt(t);
1928
2049
  }
1929
- function xt(t, e) {
2050
+ function Mt(t, e) {
1930
2051
  const n = () => {
1931
2052
  t.velocityY *= 0.95, t.velocityX *= 0.95;
1932
2053
  const r = t.velocityY * 16, s = t.velocityX * 16;
@@ -1934,19 +2055,19 @@ function xt(t, e) {
1934
2055
  };
1935
2056
  t.momentumRaf = requestAnimationFrame(n);
1936
2057
  }
1937
- function At(t, e, o, i) {
1938
- t.addEventListener("touchstart", (n) => St(n, e, o), {
2058
+ function Dt(t, e, o, i) {
2059
+ t.addEventListener("touchstart", (n) => Lt(n, e, o), {
1939
2060
  passive: !0,
1940
2061
  signal: i
1941
2062
  }), t.addEventListener(
1942
2063
  "touchmove",
1943
2064
  (n) => {
1944
- Rt(n, e, o) && n.preventDefault();
2065
+ Ht(n, e, o) && n.preventDefault();
1945
2066
  },
1946
2067
  { passive: !1, signal: i }
1947
- ), t.addEventListener("touchend", () => Tt(e, o), { passive: !0, signal: i });
2068
+ ), t.addEventListener("touchend", () => Ot(e, o), { passive: !0, signal: i });
1948
2069
  }
1949
- const Pt = [
2070
+ const zt = [
1950
2071
  // EditingPlugin
1951
2072
  {
1952
2073
  property: "editable",
@@ -1976,7 +2097,7 @@ const Pt = [
1976
2097
  importHint: "import { PinnedColumnsPlugin } from '@toolbox-web/grid/plugins/pinned-columns';",
1977
2098
  isUsed: (t) => t === "left" || t === "right"
1978
2099
  }
1979
- ], Lt = [
2100
+ ], Nt = [
1980
2101
  // GroupingColumnsPlugin
1981
2102
  {
1982
2103
  property: "columnGroups",
@@ -1986,37 +2107,37 @@ const Pt = [
1986
2107
  isUsed: (t) => Array.isArray(t) && t.length > 0
1987
2108
  }
1988
2109
  ];
1989
- function H(t) {
2110
+ function D(t) {
1990
2111
  return t.charAt(0).toUpperCase() + t.slice(1);
1991
2112
  }
1992
- function be(t, e) {
2113
+ function Ce(t, e) {
1993
2114
  return t.some((o) => o.name === e);
1994
2115
  }
1995
- function Ht(t, e) {
2116
+ function kt(t, e) {
1996
2117
  const o = /* @__PURE__ */ new Map();
1997
2118
  function i(r, s, l, a, c = !1) {
1998
2119
  o.has(r) || o.set(r, { description: s, importHint: l, fields: [], isConfigProperty: c });
1999
- const h = o.get(r);
2000
- h.fields.includes(a) || h.fields.push(a);
2120
+ const u = o.get(r);
2121
+ u.fields.includes(a) || u.fields.push(a);
2001
2122
  }
2002
- for (const r of Lt) {
2123
+ for (const r of Nt) {
2003
2124
  const s = t[r.property];
2004
- (r.isUsed ? r.isUsed(s) : s !== void 0) && !be(e, r.pluginName) && i(r.pluginName, r.description, r.importHint, r.property, !0);
2125
+ (r.isUsed ? r.isUsed(s) : s !== void 0) && !Ce(e, r.pluginName) && i(r.pluginName, r.description, r.importHint, r.property, !0);
2005
2126
  }
2006
2127
  const n = t.columns;
2007
2128
  if (n && n.length > 0)
2008
2129
  for (const r of n)
2009
- for (const s of Pt) {
2130
+ for (const s of zt) {
2010
2131
  const l = r[s.property];
2011
- if ((s.isUsed ? s.isUsed(l) : l !== void 0) && !be(e, s.pluginName)) {
2132
+ if ((s.isUsed ? s.isUsed(l) : l !== void 0) && !Ce(e, s.pluginName)) {
2012
2133
  const c = r.field || "<unknown>";
2013
2134
  i(s.pluginName, s.description, s.importHint, c);
2014
2135
  }
2015
2136
  }
2016
2137
  if (o.size > 0) {
2017
2138
  const r = [];
2018
- for (const [s, { description: l, importHint: a, fields: c, isConfigProperty: h }] of o)
2019
- if (h)
2139
+ for (const [s, { description: l, importHint: a, fields: c, isConfigProperty: u }] of o)
2140
+ if (u)
2020
2141
  r.push(
2021
2142
  `Config uses ${l}, but the required plugin is not loaded.
2022
2143
  → Add the plugin to your gridConfig.plugins array:
@@ -2043,7 +2164,7 @@ This validation helps catch misconfigurations early. The properties listed above
2043
2164
  );
2044
2165
  }
2045
2166
  }
2046
- const Ot = {
2167
+ const It = {
2047
2168
  editing: "import { EditingPlugin } from '@toolbox-web/grid/plugins/editing';",
2048
2169
  selection: "import { SelectionPlugin } from '@toolbox-web/grid/plugins/selection';",
2049
2170
  reorder: "import { ReorderPlugin } from '@toolbox-web/grid/plugins/reorder';",
@@ -2064,32 +2185,32 @@ const Ot = {
2064
2185
  serverSide: "import { ServerSidePlugin } from '@toolbox-web/grid/plugins/server-side';",
2065
2186
  columnVirtualization: "import { ColumnVirtualizationPlugin } from '@toolbox-web/grid/plugins/column-virtualization';"
2066
2187
  };
2067
- function Dt(t) {
2068
- return Ot[t] ?? `import { ${H(t)}Plugin } from '@toolbox-web/grid/plugins/${t}';`;
2188
+ function qt(t) {
2189
+ return It[t] ?? `import { ${D(t)}Plugin } from '@toolbox-web/grid/plugins/${t}';`;
2069
2190
  }
2070
- function Mt(t, e) {
2191
+ function Bt(t, e) {
2071
2192
  const o = t.name, n = t.constructor.dependencies ?? [];
2072
2193
  for (const r of n) {
2073
2194
  const s = r.name, l = r.required ?? !0, a = r.reason;
2074
- if (!e.some((h) => h.name === s)) {
2075
- const h = a ?? `${H(o)}Plugin requires ${H(s)}Plugin`, d = Dt(s);
2195
+ if (!e.some((u) => u.name === s)) {
2196
+ const u = a ?? `${D(o)}Plugin requires ${D(s)}Plugin`, d = qt(s);
2076
2197
  if (l)
2077
2198
  throw new Error(
2078
2199
  `[tbw-grid] Plugin dependency error:
2079
2200
 
2080
- ${h}.
2201
+ ${u}.
2081
2202
 
2082
- → Add the plugin to your gridConfig.plugins array BEFORE ${H(o)}Plugin:
2203
+ → Add the plugin to your gridConfig.plugins array BEFORE ${D(o)}Plugin:
2083
2204
  ${d}
2084
- plugins: [new ${H(s)}Plugin(), new ${H(o)}Plugin()]`
2205
+ plugins: [new ${D(s)}Plugin(), new ${D(o)}Plugin()]`
2085
2206
  );
2086
2207
  console.info(
2087
- `[tbw-grid] ${H(o)}Plugin: Optional "${s}" plugin not found. Some features may be unavailable.`
2208
+ `[tbw-grid] ${D(o)}Plugin: Optional "${s}" plugin not found. Some features may be unavailable.`
2088
2209
  );
2089
2210
  }
2090
2211
  }
2091
2212
  }
2092
- class zt {
2213
+ class Wt {
2093
2214
  constructor(e) {
2094
2215
  this.grid = e;
2095
2216
  }
@@ -2119,7 +2240,7 @@ class zt {
2119
2240
  * Validates dependencies and notifies other plugins of the new attachment.
2120
2241
  */
2121
2242
  attach(e) {
2122
- if (Mt(e, this.plugins), this.pluginMap.set(e.constructor, e), this.plugins.push(e), e.cellRenderers)
2243
+ if (Bt(e, this.plugins), this.pluginMap.set(e.constructor, e), this.plugins.push(e), e.cellRenderers)
2123
2244
  for (const [o, i] of Object.entries(e.cellRenderers))
2124
2245
  this.cellRenderers.set(o, i);
2125
2246
  if (e.headerRenderers)
@@ -2193,11 +2314,11 @@ class zt {
2193
2314
  return this.cellEditors.get(e);
2194
2315
  }
2195
2316
  /**
2196
- * Get all CSS styles from all plugins.
2317
+ * Get all CSS styles from all plugins as structured data.
2318
+ * Returns an array of { name, styles } for each plugin with styles.
2197
2319
  */
2198
- getAllStyles() {
2199
- return this.plugins.filter((e) => e.styles).map((e) => e.styles).join(`
2200
- `);
2320
+ getPluginStyles() {
2321
+ return this.plugins.filter((e) => e.styles).map((e) => ({ name: e.name, styles: e.styles }));
2201
2322
  }
2202
2323
  // #region Hook execution methods
2203
2324
  /**
@@ -2423,10 +2544,10 @@ class zt {
2423
2544
  }
2424
2545
  // #endregion
2425
2546
  }
2426
- class D extends HTMLElement {
2547
+ class P extends HTMLElement {
2427
2548
  // TODO: Rename to 'data-grid' when migration is complete
2428
2549
  static tagName = "tbw-grid";
2429
- static version = "0.4.2";
2550
+ static version = "0.6.0";
2430
2551
  // ---------------- Framework Adapters ----------------
2431
2552
  /**
2432
2553
  * Registry of framework adapters that handle converting light DOM elements
@@ -2467,7 +2588,26 @@ class D extends HTMLElement {
2467
2588
  static get observedAttributes() {
2468
2589
  return ["rows", "columns", "grid-config", "fit-mode", "edit-on"];
2469
2590
  }
2470
- #o;
2591
+ /**
2592
+ * The render root for the grid. Without Shadow DOM, this is the element itself.
2593
+ * This abstraction allows internal code to work the same way regardless of DOM mode.
2594
+ */
2595
+ get #i() {
2596
+ return this;
2597
+ }
2598
+ /**
2599
+ * Access the grid's ShadowRoot.
2600
+ *
2601
+ * Note: The grid renders into its light DOM and does not attach a shadow root,
2602
+ * so this getter returns `null`. Use `grid.querySelector()` directly for DOM queries.
2603
+ *
2604
+ * @deprecated This property returns `null` since Shadow DOM was removed.
2605
+ * Use `grid.querySelector()` or `grid.querySelectorAll()` directly.
2606
+ * @returns null (no shadow root is attached)
2607
+ */
2608
+ get shadowRoot() {
2609
+ return super.shadowRoot;
2610
+ }
2471
2611
  #c = !1;
2472
2612
  // ---------------- Ready Promise ----------------
2473
2613
  #f;
@@ -2497,22 +2637,21 @@ class D extends HTMLElement {
2497
2637
  // ---------------- Render Scheduler ----------------
2498
2638
  // Centralizes all rendering through a single RAF-based pipeline
2499
2639
  #l;
2500
- #v = 0;
2501
- #w = null;
2640
+ #w = 0;
2641
+ #m = null;
2502
2642
  #b = !1;
2503
2643
  // Cached flag for plugin scroll handlers
2504
2644
  #s;
2505
2645
  // Cached hook to avoid closures
2506
- #m = !1;
2507
- #A = yt();
2646
+ #y = At();
2508
2647
  #g;
2648
+ #v;
2509
2649
  #_;
2510
- #y;
2511
2650
  // Watches first row for size changes (CSS loading, custom renderers)
2512
2651
  #C;
2513
2652
  // Handle for cancelling deferred idle work
2514
2653
  // Pooled scroll event object (reused to avoid GC pressure during scroll)
2515
- #S = {
2654
+ #z = {
2516
2655
  scrollTop: 0,
2517
2656
  scrollLeft: 0,
2518
2657
  scrollHeight: 0,
@@ -2521,22 +2660,22 @@ class D extends HTMLElement {
2521
2660
  clientWidth: 0
2522
2661
  };
2523
2662
  // ---------------- Plugin System ----------------
2524
- #i;
2663
+ #o;
2525
2664
  #E;
2526
2665
  // Track last attached plugins to avoid unnecessary re-initialization
2527
2666
  // ---------------- Event Listeners ----------------
2528
- #O = !1;
2667
+ #L = !1;
2529
2668
  // Guard against adding duplicate component-level listeners
2530
- #P;
2669
+ #x;
2531
2670
  // Separate controller for DOM scroll listeners (recreated on DOM changes)
2532
2671
  // ---------------- Column State ----------------
2533
- #L;
2672
+ #A;
2534
2673
  // ---------------- Config Manager ----------------
2535
2674
  #t;
2536
2675
  // ---------------- Shell State ----------------
2537
- #e = ut();
2676
+ #e = wt();
2538
2677
  #a;
2539
- #D;
2678
+ #H;
2540
2679
  // #endregion
2541
2680
  // #region Derived State
2542
2681
  // _rows: result of applying plugin processRows hooks
@@ -2622,7 +2761,7 @@ class D extends HTMLElement {
2622
2761
  }
2623
2762
  set rows(e) {
2624
2763
  const o = this.#r;
2625
- this.#r = e, o !== e && this.#H("rows");
2764
+ this.#r = e, o !== e && this.#P("rows");
2626
2765
  }
2627
2766
  /**
2628
2767
  * Get the original unfiltered/unprocessed rows.
@@ -2636,28 +2775,28 @@ class D extends HTMLElement {
2636
2775
  }
2637
2776
  set columns(e) {
2638
2777
  const o = this.#t?.getColumns();
2639
- this.#t?.setColumns(e), o !== e && this.#H("columns");
2778
+ this.#t?.setColumns(e), o !== e && this.#P("columns");
2640
2779
  }
2641
2780
  get gridConfig() {
2642
2781
  return this.#n;
2643
2782
  }
2644
2783
  set gridConfig(e) {
2645
2784
  const o = this.#t?.getGridConfig();
2646
- this.#t?.setGridConfig(e), o !== e && (this.#t.clearLightDomCache(), this.#H("gridConfig"));
2785
+ this.#t?.setGridConfig(e), o !== e && (this.#t.clearLightDomCache(), this.#P("gridConfig"));
2647
2786
  }
2648
2787
  get fitMode() {
2649
2788
  return this.#n.fitMode ?? "stretch";
2650
2789
  }
2651
2790
  set fitMode(e) {
2652
2791
  const o = this.#t?.getFitMode();
2653
- this.#t?.setFitMode(e), o !== e && this.#H("fitMode");
2792
+ this.#t?.setFitMode(e), o !== e && this.#P("fitMode");
2654
2793
  }
2655
2794
  get editOn() {
2656
2795
  return this.#n.editOn;
2657
2796
  }
2658
2797
  set editOn(e) {
2659
2798
  const o = this.#t?.getEditOn();
2660
- this.#t?.setEditOn(e), o !== e && this.#H("editMode");
2799
+ this.#t?.setEditOn(e), o !== e && this.#P("editMode");
2661
2800
  }
2662
2801
  /**
2663
2802
  * Effective config accessor for internal modules and plugins.
@@ -2681,50 +2820,50 @@ class D extends HTMLElement {
2681
2820
  }
2682
2821
  // #endregion
2683
2822
  constructor() {
2684
- super(), this.#o = this.attachShadow({ mode: "open" }), this.#J(), this.#f = new Promise((e) => this.#d = e), this.#l = new at({
2823
+ super(), this.#te(), this.#f = new Promise((e) => this.#d = e), this.#l = new pt({
2685
2824
  mergeConfig: () => {
2686
- this.#t.parseLightDomColumns(this), this.#t.merge(), this.#G(), Ht(this.#n, this.#i?.getPlugins() ?? []), this.#N = [...this._columns];
2825
+ this.#t.parseLightDomColumns(this), this.#t.merge(), this.#Y(), kt(this.#n, this.#o?.getPlugins() ?? []), this.#N = [...this._columns];
2687
2826
  },
2688
- processColumns: () => this.#de(),
2689
- processRows: () => this.#he(),
2690
- renderHeader: () => X(this),
2691
- updateTemplate: () => q(this),
2827
+ processColumns: () => this.#fe(),
2828
+ processRows: () => this.#pe(),
2829
+ renderHeader: () => Z(this),
2830
+ updateTemplate: () => $(this),
2692
2831
  renderVirtualWindow: () => this.refreshVirtualWindow(!0),
2693
2832
  afterRender: () => {
2694
- this.#i?.afterRender(), this.#n.fitMode === "fixed" && !this.__didInitialAutoSize && (this.__didInitialAutoSize = !0, ne(this)), this._restoreFocusAfterRender && (this._restoreFocusAfterRender = !1, k(this)), this._virtualization.enabled && !this.#z && this.#te();
2833
+ this.#o?.afterRender(), this.#n.fitMode === "fixed" && !this.__didInitialAutoSize && (this.__didInitialAutoSize = !0, ae(this)), this._restoreFocusAfterRender && (this._restoreFocusAfterRender = !1, q(this)), this._virtualization.enabled && !this.#D && this.#ne();
2695
2834
  },
2696
2835
  isConnected: () => this.isConnected && this.#h
2697
- }), this.#l.setInitialReadyResolver(() => this.#d?.()), this.#a = vt(this.#e, {
2698
- getShadow: () => this.#o,
2836
+ }), this.#l.setInitialReadyResolver(() => this.#d?.()), this.#a = Tt(this.#e, {
2837
+ getShadow: () => this.#i,
2699
2838
  getShellConfig: () => this.#n?.shell,
2700
2839
  getAccordionIcons: () => ({
2701
- expand: this.#n?.icons?.expand ?? L.expand,
2702
- collapse: this.#n?.icons?.collapse ?? L.collapse
2840
+ expand: this.#n?.icons?.expand ?? M.expand,
2841
+ collapse: this.#n?.icons?.collapse ?? M.collapse
2703
2842
  }),
2704
- emit: (e, o) => this.#Y(e, o),
2843
+ emit: (e, o) => this.#K(e, o),
2705
2844
  refreshShellHeader: () => this.refreshShellHeader()
2706
- }), this.#t = new Ke({
2845
+ }), this.#t = new Je({
2707
2846
  getRows: () => this.#r,
2708
2847
  getSortState: () => this._sortState,
2709
2848
  setSortState: (e) => {
2710
2849
  this._sortState = e;
2711
2850
  },
2712
2851
  onConfigChange: () => {
2713
- this.#l.requestPhase(S.FULL, "configChange");
2852
+ this.#l.requestPhase(x.FULL, "configChange");
2714
2853
  },
2715
- emit: (e, o) => this.#Y(e, o),
2854
+ emit: (e, o) => this.#K(e, o),
2716
2855
  clearRowPool: () => {
2717
2856
  this._rowPool.length = 0, this._bodyEl && (this._bodyEl.innerHTML = ""), this.__rowRenderEpoch++;
2718
2857
  },
2719
- setup: () => this.#T(),
2720
- renderHeader: () => X(this),
2721
- updateTemplate: () => q(this),
2722
- refreshVirtualWindow: () => this.#l.requestPhase(S.VIRTUALIZATION, "configManager"),
2858
+ setup: () => this.#R(),
2859
+ renderHeader: () => Z(this),
2860
+ updateTemplate: () => $(this),
2861
+ refreshVirtualWindow: () => this.#l.requestPhase(x.VIRTUALIZATION, "configManager"),
2723
2862
  getVirtualization: () => this._virtualization,
2724
2863
  setRowHeight: (e) => {
2725
2864
  this._virtualization.rowHeight = e;
2726
2865
  },
2727
- applyAnimationConfig: (e) => this.#ue(e),
2866
+ applyAnimationConfig: (e) => this.#ge(e),
2728
2867
  getShellLightDomTitle: () => this.#e.lightDomTitle,
2729
2868
  getShellToolPanels: () => this.#e.toolPanels,
2730
2869
  getShellHeaderContents: () => this.#e.headerContents,
@@ -2733,33 +2872,64 @@ class D extends HTMLElement {
2733
2872
  getShellHasToolButtonsContainer: () => this.#e.hasToolButtonsContainer
2734
2873
  });
2735
2874
  }
2736
- async #J() {
2737
- const e = new CSSStyleSheet();
2738
- if (te.length > 0) {
2739
- e.replaceSync(te), this.#o.adoptedStyleSheets = [e];
2740
- return;
2741
- }
2742
- await new Promise((o) => setTimeout(o, 50));
2743
- try {
2744
- let o = "";
2745
- for (const i of Array.from(document.styleSheets))
2746
- try {
2747
- const r = Array.from(i.cssRules || []).map((s) => s.cssText).join(`
2875
+ /** ID for the consolidated grid stylesheet in document.head */
2876
+ static #G = "tbw-grid-styles";
2877
+ /** Track injected base styles CSS text */
2878
+ static #O = "";
2879
+ /** Track injected plugin styles by plugin name (accumulates across all grid instances) */
2880
+ static #k = /* @__PURE__ */ new Map();
2881
+ /**
2882
+ * Get or create the consolidated style element in document.head.
2883
+ * All grid and plugin styles are combined into this single element.
2884
+ */
2885
+ static #ee() {
2886
+ let e = document.getElementById(this.#G);
2887
+ return e || (e = document.createElement("style"), e.id = this.#G, e.setAttribute("data-tbw-grid", "true"), document.head.appendChild(e)), e;
2888
+ }
2889
+ /**
2890
+ * Update the consolidated stylesheet with current base + plugin styles.
2891
+ */
2892
+ static #I() {
2893
+ const e = this.#ee(), o = Array.from(this.#k.values()).join(`
2894
+ `);
2895
+ e.textContent = `${this.#O}
2896
+
2897
+ /* Plugin Styles */
2898
+ ${o}`;
2899
+ }
2900
+ /**
2901
+ * Inject grid styles into the document.
2902
+ * All styles go into a single <style id="tbw-grid-styles"> element in document.head.
2903
+ * Uses a singleton pattern to avoid duplicate injection across multiple grid instances.
2904
+ */
2905
+ async #te() {
2906
+ if (!P.#O) {
2907
+ if (re.length > 0) {
2908
+ P.#O = re, P.#I();
2909
+ return;
2910
+ }
2911
+ await new Promise((e) => setTimeout(e, 50));
2912
+ try {
2913
+ let e = "";
2914
+ for (const o of Array.from(document.styleSheets))
2915
+ try {
2916
+ const n = Array.from(o.cssRules || []).map((r) => r.cssText).join(`
2748
2917
  `);
2749
- if (r.includes(".tbw-grid-root") && r.includes(":host")) {
2750
- o = r;
2751
- break;
2918
+ if (n.includes(".tbw-grid-root") && n.includes("tbw-grid")) {
2919
+ e = n;
2920
+ break;
2921
+ }
2922
+ } catch {
2923
+ continue;
2752
2924
  }
2753
- } catch {
2754
- continue;
2755
- }
2756
- o ? (e.replaceSync(o), this.#o.adoptedStyleSheets = [e]) : (typeof process > "u" || process.env?.NODE_ENV !== "test") && console.warn(
2757
- "[tbw-grid] Could not find grid.css in document.styleSheets. Grid styling will not work.",
2758
- "Available stylesheets:",
2759
- Array.from(document.styleSheets).map((i) => i.href || "(inline)")
2760
- );
2761
- } catch (o) {
2762
- console.warn("[tbw-grid] Failed to extract grid.css from document stylesheets:", o);
2925
+ e ? (P.#O = e, P.#I()) : (typeof process > "u" || process.env?.NODE_ENV !== "test") && console.warn(
2926
+ "[tbw-grid] Could not find grid.css in document.styleSheets. Grid styling will not work.",
2927
+ "Available stylesheets:",
2928
+ Array.from(document.styleSheets).map((o) => o.href || "(inline)")
2929
+ );
2930
+ } catch (e) {
2931
+ console.warn("[tbw-grid] Failed to extract grid.css from document stylesheets:", e);
2932
+ }
2763
2933
  }
2764
2934
  }
2765
2935
  // ---------------- Plugin System ----------------
@@ -2769,7 +2939,7 @@ class D extends HTMLElement {
2769
2939
  * @internal Plugin API
2770
2940
  */
2771
2941
  getPlugin(e) {
2772
- return this.#i?.getPlugin(e);
2942
+ return this.#o?.getPlugin(e);
2773
2943
  }
2774
2944
  /**
2775
2945
  * Get a plugin instance by its name.
@@ -2777,7 +2947,7 @@ class D extends HTMLElement {
2777
2947
  * @internal Plugin API
2778
2948
  */
2779
2949
  getPluginByName(e) {
2780
- return this.#i?.getPluginByName(e);
2950
+ return this.#o?.getPluginByName(e);
2781
2951
  }
2782
2952
  /**
2783
2953
  * Request a full re-render of the grid.
@@ -2786,7 +2956,7 @@ class D extends HTMLElement {
2786
2956
  * @internal Plugin API
2787
2957
  */
2788
2958
  requestRender() {
2789
- this.#l.requestPhase(S.ROWS, "plugin:requestRender");
2959
+ this.#l.requestPhase(x.ROWS, "plugin:requestRender");
2790
2960
  }
2791
2961
  /**
2792
2962
  * Request a full re-render and restore focus styling afterward.
@@ -2795,7 +2965,7 @@ class D extends HTMLElement {
2795
2965
  * @internal Plugin API
2796
2966
  */
2797
2967
  requestRenderWithFocus() {
2798
- this._restoreFocusAfterRender = !0, this.#l.requestPhase(S.ROWS, "plugin:requestRenderWithFocus");
2968
+ this._restoreFocusAfterRender = !0, this.#l.requestPhase(x.ROWS, "plugin:requestRenderWithFocus");
2799
2969
  }
2800
2970
  /**
2801
2971
  * Update the grid's column template CSS.
@@ -2803,7 +2973,7 @@ class D extends HTMLElement {
2803
2973
  * @internal
2804
2974
  */
2805
2975
  updateTemplate() {
2806
- q(this);
2976
+ $(this);
2807
2977
  }
2808
2978
  /**
2809
2979
  * Request a lightweight style update without rebuilding DOM.
@@ -2812,41 +2982,42 @@ class D extends HTMLElement {
2812
2982
  * @internal Plugin API
2813
2983
  */
2814
2984
  requestAfterRender() {
2815
- this.#l.requestPhase(S.STYLE, "plugin:requestAfterRender");
2985
+ this.#l.requestPhase(x.STYLE, "plugin:requestAfterRender");
2816
2986
  }
2817
2987
  /**
2818
2988
  * Initialize plugin system with instances from config.
2819
2989
  * Plugins are class instances passed in gridConfig.plugins[].
2820
2990
  */
2821
- #V() {
2822
- this.#i = new zt(this);
2991
+ #X() {
2992
+ this.#o = new Wt(this);
2823
2993
  const e = this.#n?.plugins, o = Array.isArray(e) ? e : [];
2824
- this.#i.attachAll(o);
2994
+ this.#o.attachAll(o);
2825
2995
  }
2826
2996
  /**
2827
- * Inject all plugin styles into the shadow DOM.
2828
- * Must be called after #render() since innerHTML wipes existing content.
2997
+ * Inject all plugin styles into the consolidated style element.
2998
+ * Plugin styles are appended after base grid styles in the same <style> element.
2999
+ * Uses a Map to accumulate styles from all grid instances on the page.
2829
3000
  */
2830
3001
  #M() {
2831
- const e = this.#i?.getAllStyles() ?? "";
2832
- if (e) {
2833
- const o = document.createElement("style");
2834
- o.setAttribute("data-plugin", "all"), o.textContent = e, this.#o.appendChild(o);
2835
- }
3002
+ const e = this.#o?.getPluginStyles() ?? [];
3003
+ let o = !1;
3004
+ for (const { name: i, styles: n } of e)
3005
+ P.#k.has(i) || (P.#k.set(i, n), o = !0);
3006
+ o && P.#I();
2836
3007
  }
2837
3008
  /**
2838
3009
  * Update plugins when grid config changes.
2839
3010
  * With class-based plugins, we need to detach old and attach new.
2840
3011
  * Skips re-initialization if the plugins array hasn't changed.
2841
3012
  */
2842
- #G() {
3013
+ #Y() {
2843
3014
  const e = this.#n?.plugins, o = Array.isArray(e) ? e : [];
2844
3015
  if (this.#E !== o) {
2845
3016
  if (this.#E && this.#E.length === o.length && this.#E.every((i, n) => i === o[n])) {
2846
3017
  this.#E = o;
2847
3018
  return;
2848
3019
  }
2849
- this.#i && this.#i.detachAll();
3020
+ this.#o && this.#o.detachAll();
2850
3021
  for (const i of this.#e.toolPanels.keys()) {
2851
3022
  const n = this.#e.lightDomToolPanelIds.has(i), r = this.#e.apiToolPanelIds.has(i);
2852
3023
  if (!n && !r) {
@@ -2858,25 +3029,25 @@ class D extends HTMLElement {
2858
3029
  const n = this.#e.headerContentCleanups.get(i);
2859
3030
  n && (n(), this.#e.headerContentCleanups.delete(i)), this.#e.headerContents.delete(i);
2860
3031
  }
2861
- this.#V(), this.#M(), this.#E = o, this.#X(), this.#b = this.#i?.getAll().some((i) => i.onScroll) ?? !1;
3032
+ this.#X(), this.#M(), this.#E = o, this.#j(), this.#b = this.#o?.getAll().some((i) => i.onScroll) ?? !1;
2862
3033
  }
2863
3034
  }
2864
3035
  /**
2865
3036
  * Clean up plugin states when grid disconnects.
2866
3037
  */
2867
- #Q() {
2868
- this.#i?.detachAll();
3038
+ #oe() {
3039
+ this.#o?.detachAll();
2869
3040
  }
2870
3041
  /**
2871
3042
  * Collect tool panels and header content from all plugins.
2872
3043
  * Called after plugins are attached but before render.
2873
3044
  */
2874
- #X() {
2875
- if (!this.#i) return;
2876
- const e = this.#i.getToolPanels();
3045
+ #j() {
3046
+ if (!this.#o) return;
3047
+ const e = this.#o.getToolPanels();
2877
3048
  for (const { panel: i } of e)
2878
3049
  this.#e.toolPanels.has(i.id) || this.#e.toolPanels.set(i.id, i);
2879
- const o = this.#i.getHeaderContents();
3050
+ const o = this.#o.getHeaderContents();
2880
3051
  for (const { content: i } of o)
2881
3052
  this.#e.headerContents.has(i.id) || this.#e.headerContents.set(i.id, i);
2882
3053
  }
@@ -2884,8 +3055,8 @@ class D extends HTMLElement {
2884
3055
  * Gets a renderer factory for tool panels from registered framework adapters.
2885
3056
  * Returns a factory function that tries each adapter in order until one handles the element.
2886
3057
  */
2887
- #R() {
2888
- const e = D.getAdapters();
3058
+ #T() {
3059
+ const e = P.getAdapters();
2889
3060
  if (e.length === 0 && !this.__frameworkAdapter) return;
2890
3061
  const o = this.__frameworkAdapter;
2891
3062
  return (i) => {
@@ -2902,17 +3073,17 @@ class D extends HTMLElement {
2902
3073
  }
2903
3074
  // ---------------- Lifecycle ----------------
2904
3075
  connectedCallback() {
2905
- this.hasAttribute("tabindex") || (this.tabIndex = 0), this.hasAttribute("version") || this.setAttribute("version", D.version), this._rows = Array.isArray(this.#r) ? [...this.#r] : [], this.#g && (this.#g.abort(), this.#O = !1), this.#g = new AbortController(), this.#C && (de(this.#C), this.#C = void 0), M(this, this.#e), z(this, this.#e), N(this, this.#e, this.#R()), this.#t.parseLightDomColumns(this), this.#t.merge(), this.#V();
3076
+ this.hasAttribute("tabindex") || (this.tabIndex = 0), this.hasAttribute("version") || this.setAttribute("version", P.version), this._rows = Array.isArray(this.#r) ? [...this.#r] : [], this.#g && (this.#g.abort(), this.#L = !1), this.#g = new AbortController(), this.#C && (ge(this.#C), this.#C = void 0), N(this, this.#e), k(this, this.#e), I(this, this.#e, this.#T()), this.#t.parseLightDomColumns(this), this.#t.merge(), this.#X();
2906
3077
  const e = this.#n?.plugins;
2907
- this.#E = Array.isArray(e) ? e : [], this.#X(), this.#c || (this.#$(), this.#M(), this.#c = !0), this.#k(), this.#C = it(
3078
+ this.#E = Array.isArray(e) ? e : [], this.#j(), this.#c || (this.#F(), this.#M(), this.#c = !0), this.#q(), this.#C = ft(
2908
3079
  () => {
2909
- this.#me();
3080
+ this.#we();
2910
3081
  },
2911
3082
  { timeout: 100 }
2912
3083
  );
2913
3084
  }
2914
3085
  disconnectedCallback() {
2915
- this.#C && (de(this.#C), this.#C = void 0), this.#Q(), mt(this.#e), this.#a.setInitialized(!1), this.#D?.(), this.#D = void 0, Oe(this.#A), this.#g && (this.#g.abort(), this.#g = void 0), this.#P?.abort(), this.#P = void 0, this.#O = !1, this._resizeController && this._resizeController.dispose(), this.#_ && (this.#_.disconnect(), this.#_ = void 0), this.#y && (this.#y.disconnect(), this.#y = void 0, this.#z = !1), $(this), this.#x.clear(), this.#E = void 0;
3086
+ this.#C && (ge(this.#C), this.#C = void 0), this.#oe(), St(this.#e), this.#a.setInitialized(!1), this.#H?.(), this.#H = void 0, ze(this.#y), this.#g && (this.#g.abort(), this.#g = void 0), this.#x?.abort(), this.#x = void 0, this.#L = !1, this._resizeController && this._resizeController.dispose(), this.#v && (this.#v.disconnect(), this.#v = void 0), this.#_ && (this.#_.disconnect(), this.#_ = void 0, this.#D = !1), G(this), this.#S.clear(), this.#E = void 0;
2916
3087
  for (const e of this._rowPool)
2917
3088
  e.remove();
2918
3089
  this._rowPool.length = 0, this.__rowsBodyEl = null, this.#h = !1;
@@ -2933,26 +3104,26 @@ class D extends HTMLElement {
2933
3104
  }
2934
3105
  else e === "fit-mode" ? this.fitMode = i : e === "edit-on" && (this.editOn = i);
2935
3106
  }
2936
- #k() {
2937
- const o = this.#o.querySelector(".tbw-grid-content") ?? this.#o.querySelector(".tbw-grid-root");
3107
+ #q() {
3108
+ const o = this.#i.querySelector(".tbw-grid-content") ?? this.#i.querySelector(".tbw-grid-root");
2938
3109
  if (this._headerRowEl = o?.querySelector(".header-row"), this._virtualization.totalHeightEl = o?.querySelector(".faux-vscroll-spacer"), this._virtualization.viewportEl = o?.querySelector(".rows-viewport"), this._bodyEl = o?.querySelector(".rows"), this.__rowsBodyEl = o?.querySelector(".rows-body"), this.#a.isInitialized) {
2939
- He(this.#o, this.#e), gt(this.#o, this.#n?.shell, this.#e);
3110
+ De(this.#i, this.#e), yt(this.#i, this.#n?.shell, this.#e, this);
2940
3111
  const r = this.#n?.shell?.toolPanel?.defaultOpen;
2941
3112
  r && this.#e.toolPanels.has(r) && (this.openToolPanel(), this.#e.expandedSections.add(r));
2942
3113
  }
2943
- if (this.setAttribute("data-upgraded", ""), this.#h = !0, this._resizeController = ct(this), this.#T(), this.#ee(o), this.#O)
3114
+ if (this.setAttribute("data-upgraded", ""), this.#h = !0, this._resizeController = gt(this), this.#R(), this.#ie(o), this.#L)
2944
3115
  return;
2945
- this.#O = !0;
3116
+ this.#L = !0;
2946
3117
  const i = this.disconnectSignal;
2947
- this.addEventListener("keydown", (r) => lt(this, r), { signal: i }), this.#o.addEventListener("mousedown", (r) => this.#pe(r), { signal: i }), document.addEventListener("mousemove", (r) => this.#ge(r), { signal: i }), document.addEventListener("mouseup", (r) => this.#we(r), { signal: i });
3118
+ ct(this, this, this.#i, i);
2948
3119
  const n = this.#n.rowHeight;
2949
- n && n > 0 ? this._virtualization.rowHeight = n : requestAnimationFrame(() => this.#I()), queueMicrotask(() => this.#oe()), this.#l.requestPhase(S.FULL, "afterConnect");
3120
+ n && n > 0 ? this._virtualization.rowHeight = n : requestAnimationFrame(() => this.#B()), queueMicrotask(() => this.#re()), this.#l.requestPhase(x.FULL, "afterConnect");
2950
3121
  }
2951
3122
  /**
2952
3123
  * Measure actual row height from DOM.
2953
3124
  * Finds the tallest cell to account for custom renderers that may push height.
2954
3125
  */
2955
- #I() {
3126
+ #B() {
2956
3127
  const e = this._bodyEl?.querySelector(".data-grid-row");
2957
3128
  if (!e) return;
2958
3129
  const o = e.querySelectorAll(".cell");
@@ -2962,17 +3133,17 @@ class D extends HTMLElement {
2962
3133
  l > i && (i = l);
2963
3134
  });
2964
3135
  const n = e.getBoundingClientRect(), r = Math.max(n.height, i);
2965
- r > 0 && r !== this._virtualization.rowHeight && (this._virtualization.rowHeight = r, this.#l.requestPhase(S.VIRTUALIZATION, "measureRowHeight"));
3136
+ r > 0 && r !== this._virtualization.rowHeight && (this._virtualization.rowHeight = r, this.#l.requestPhase(x.VIRTUALIZATION, "measureRowHeight"));
2966
3137
  }
2967
3138
  /**
2968
3139
  * Set up scroll-related event listeners on DOM elements.
2969
3140
  * These need to be re-attached when the DOM is recreated (e.g., shell toggle).
2970
3141
  * Uses a separate AbortController that is recreated each time.
2971
3142
  */
2972
- #ee(e) {
2973
- this.#P?.abort(), this.#P = new AbortController();
2974
- const o = this.#P.signal, i = e?.querySelector(".faux-vscroll"), n = e?.querySelector(".rows");
2975
- if (this._virtualization.container = i ?? this, this.#b = this.#i?.getAll().some((r) => r.onScroll) ?? !1, i && n) {
3143
+ #ie(e) {
3144
+ this.#x?.abort(), this.#x = new AbortController();
3145
+ const o = this.#x.signal, i = e?.querySelector(".faux-vscroll"), n = e?.querySelector(".rows");
3146
+ if (this._virtualization.container = i ?? this, this.#b = this.#o?.getAll().some((r) => r.onScroll) ?? !1, i && n) {
2976
3147
  i.addEventListener(
2977
3148
  "scroll",
2978
3149
  () => {
@@ -2981,44 +3152,44 @@ class D extends HTMLElement {
2981
3152
  if (this._rows.length <= this._virtualization.bypassThreshold)
2982
3153
  n.style.transform = `translateY(${-l}px)`;
2983
3154
  else {
2984
- const c = Math.floor(l / a), h = c - c % 2, d = -(l - h * a);
3155
+ const c = Math.floor(l / a), u = c - c % 2, d = -(l - u * a);
2985
3156
  n.style.transform = `translateY(${d}px)`;
2986
3157
  }
2987
- this.#w = l, this.#v || (this.#v = requestAnimationFrame(() => {
2988
- this.#v = 0, this.#w !== null && (this.#fe(this.#w), this.#w = null);
3158
+ this.#m = l, this.#w || (this.#w = requestAnimationFrame(() => {
3159
+ this.#w = 0, this.#m !== null && (this.#me(this.#m), this.#m = null);
2989
3160
  }));
2990
3161
  },
2991
3162
  { passive: !0, signal: o }
2992
3163
  );
2993
- const r = this.#o.querySelector(".tbw-grid-content"), s = this.#o.querySelector(".tbw-scroll-area");
3164
+ const r = this.#i.querySelector(".tbw-grid-content"), s = this.#i.querySelector(".tbw-scroll-area");
2994
3165
  r && (r.addEventListener(
2995
3166
  "wheel",
2996
3167
  (l) => {
2997
3168
  const a = l.shiftKey || Math.abs(l.deltaX) > Math.abs(l.deltaY);
2998
3169
  if (a && s) {
2999
- const c = l.shiftKey ? l.deltaY : l.deltaX, { scrollLeft: h, scrollWidth: d, clientWidth: f } = s;
3000
- (c > 0 && h < d - f || c < 0 && h > 0) && (l.preventDefault(), s.scrollLeft += c);
3170
+ const c = l.shiftKey ? l.deltaY : l.deltaX, { scrollLeft: u, scrollWidth: d, clientWidth: f } = s;
3171
+ (c > 0 && u < d - f || c < 0 && u > 0) && (l.preventDefault(), s.scrollLeft += c);
3001
3172
  } else if (!a) {
3002
- const { scrollTop: c, scrollHeight: h, clientHeight: d } = i;
3003
- (l.deltaY > 0 && c < h - d || l.deltaY < 0 && c > 0) && (l.preventDefault(), i.scrollTop += l.deltaY);
3173
+ const { scrollTop: c, scrollHeight: u, clientHeight: d } = i;
3174
+ (l.deltaY > 0 && c < u - d || l.deltaY < 0 && c > 0) && (l.preventDefault(), i.scrollTop += l.deltaY);
3004
3175
  }
3005
3176
  },
3006
3177
  { passive: !1, signal: o }
3007
- ), At(r, this.#A, { fauxScrollbar: i, scrollArea: s }, o));
3178
+ ), Dt(r, this.#y, { fauxScrollbar: i, scrollArea: s }, o));
3008
3179
  }
3009
- this._bodyEl && Qe(this, this._bodyEl, o), this.#_?.disconnect(), this._virtualization.viewportEl && (this.#_ = new ResizeObserver(() => {
3010
- this.#l.requestPhase(S.VIRTUALIZATION, "resize-observer");
3011
- }), this.#_.observe(this._virtualization.viewportEl)), this._virtualization.enabled && this.#l.requestPhase(S.VIRTUALIZATION, "init-virtualization"), this.#o.addEventListener(
3180
+ this._bodyEl && at(this, this._bodyEl, o), this.#v?.disconnect(), this._virtualization.viewportEl && (this.#v = new ResizeObserver(() => {
3181
+ this.#l.requestPhase(x.VIRTUALIZATION, "resize-observer");
3182
+ }), this.#v.observe(this._virtualization.viewportEl)), this._virtualization.enabled && this.#l.requestPhase(x.VIRTUALIZATION, "init-virtualization"), this.#i.addEventListener(
3012
3183
  "focusin",
3013
3184
  () => {
3014
3185
  this.dataset.hasFocus = "";
3015
3186
  },
3016
3187
  { signal: o }
3017
- ), this.#o.addEventListener(
3188
+ ), this.#i.addEventListener(
3018
3189
  "focusout",
3019
3190
  (r) => {
3020
3191
  const s = r.relatedTarget;
3021
- (!s || !this.#o.contains(s)) && delete this.dataset.hasFocus;
3192
+ (!s || !this.#i.contains(s)) && delete this.dataset.hasFocus;
3022
3193
  },
3023
3194
  { signal: o }
3024
3195
  );
@@ -3028,23 +3199,23 @@ class D extends HTMLElement {
3028
3199
  * Called after rows are rendered to observe the actual content.
3029
3200
  * Handles dynamic CSS loading, lazy images, font loading, column virtualization, etc.
3030
3201
  */
3031
- #z = !1;
3202
+ #D = !1;
3032
3203
  // Only set up once per lifecycle
3033
- #te() {
3034
- if (this.#z) return;
3204
+ #ne() {
3205
+ if (this.#D) return;
3035
3206
  const e = this._bodyEl?.querySelector(".data-grid-row");
3036
- e && (this.#z = !0, this.#y?.disconnect(), this.#y = new ResizeObserver(() => {
3037
- this.#I();
3038
- }), this.#y.observe(e), requestAnimationFrame(() => {
3039
- this.#I();
3207
+ e && (this.#D = !0, this.#_?.disconnect(), this.#_ = new ResizeObserver(() => {
3208
+ this.#B();
3209
+ }), this.#_.observe(e), requestAnimationFrame(() => {
3210
+ this.#B();
3040
3211
  }));
3041
3212
  }
3042
3213
  // ---------------- Event Emitters ----------------
3043
- #Y(e, o) {
3214
+ #K(e, o) {
3044
3215
  this.dispatchEvent(new CustomEvent(e, { detail: o, bubbles: !0, composed: !0 }));
3045
3216
  }
3046
3217
  /** Update ARIA selection attributes on rendered rows/cells */
3047
- #oe() {
3218
+ #re() {
3048
3219
  this._bodyEl?.querySelectorAll(".data-grid-row")?.forEach((o, i) => {
3049
3220
  const n = i === this._focusRow;
3050
3221
  o.setAttribute("aria-selected", String(n)), o.querySelectorAll(".cell").forEach((r, s) => {
@@ -3059,14 +3230,14 @@ class D extends HTMLElement {
3059
3230
  * Queue an update for a specific property type.
3060
3231
  * All updates queued within the same microtask are batched together.
3061
3232
  */
3062
- #H(e) {
3063
- this.#p[e] = !0, !this.#u && (this.#u = !0, queueMicrotask(() => this.#ie()));
3233
+ #P(e) {
3234
+ this.#p[e] = !0, !this.#u && (this.#u = !0, queueMicrotask(() => this.#se()));
3064
3235
  }
3065
3236
  /**
3066
3237
  * Process all pending updates in optimal order.
3067
3238
  * Priority: gridConfig first (may affect all), then columns, rows, fitMode, editMode
3068
3239
  */
3069
- #ie() {
3240
+ #se() {
3070
3241
  if (!this.#u || !this.#h) {
3071
3242
  this.#u = !1;
3072
3243
  return;
@@ -3079,43 +3250,43 @@ class D extends HTMLElement {
3079
3250
  fitMode: !1,
3080
3251
  editMode: !1
3081
3252
  }, e.gridConfig) {
3082
- this.#ae();
3253
+ this.#he();
3083
3254
  return;
3084
3255
  }
3085
- e.columns && this.#re(), e.rows && this.#ne(), e.fitMode && this.#se(), e.editMode && this.#le();
3256
+ e.columns && this.#ae(), e.rows && this.#le(), e.fitMode && this.#ce(), e.editMode && this.#de();
3086
3257
  }
3087
3258
  // Individual update applicators - these do the actual work
3088
- #ne() {
3089
- this._rows = Array.isArray(this.#r) ? [...this.#r] : [], this.#l.requestPhase(S.ROWS, "applyRowsUpdate");
3259
+ #le() {
3260
+ this._rows = Array.isArray(this.#r) ? [...this.#r] : [], this.#l.requestPhase(x.ROWS, "applyRowsUpdate");
3090
3261
  }
3091
- #re() {
3092
- $(this), this.#t.merge(), this.#T();
3262
+ #ae() {
3263
+ G(this), this.#t.merge(), this.#R();
3093
3264
  }
3094
- #se() {
3095
- this.#t.merge(), this.#n.fitMode === "fixed" ? (this.__didInitialAutoSize = !1, ne(this)) : (this._columns.forEach((o) => {
3265
+ #ce() {
3266
+ this.#t.merge(), this.#n.fitMode === "fixed" ? (this.__didInitialAutoSize = !1, ae(this)) : (this._columns.forEach((o) => {
3096
3267
  !o.__userResized && o.__autoSized && delete o.width;
3097
- }), q(this));
3268
+ }), $(this));
3098
3269
  }
3099
- #le() {
3100
- this.#t.merge(), this._rowPool.length = 0, this._bodyEl && (this._bodyEl.innerHTML = ""), this.__rowRenderEpoch++, this.#l.requestPhase(S.VIRTUALIZATION, "applyEditModeUpdate");
3270
+ #de() {
3271
+ this.#t.merge(), this._rowPool.length = 0, this._bodyEl && (this._bodyEl.innerHTML = ""), this.__rowRenderEpoch++, this.#l.requestPhase(x.VIRTUALIZATION, "applyEditModeUpdate");
3101
3272
  }
3102
- #ae() {
3103
- M(this, this.#e), z(this, this.#e);
3104
- const e = !!this.#o.querySelector(".has-shell"), o = !!this.#o.querySelector(".tbw-tool-panel"), i = this.#o.querySelectorAll(".tbw-accordion-section").length;
3105
- this.#t.parseLightDomColumns(this), this.#t.merge(), this.#G(), N(this, this.#e, this.#R()), this.#t.markSourcesChanged(), this.#t.merge();
3106
- const n = Le(this.#n?.shell), r = (this.#n?.shell?.toolPanels?.length ?? 0) > 0, s = (this.#n?.shell?.toolPanels?.length ?? 0) !== i;
3273
+ #he() {
3274
+ N(this, this.#e), k(this, this.#e);
3275
+ const e = !!this.#i.querySelector(".has-shell"), o = !!this.#i.querySelector(".tbw-tool-panel"), i = this.#i.querySelectorAll(".tbw-accordion-section").length;
3276
+ this.#t.parseLightDomColumns(this), this.#t.merge(), this.#Y(), I(this, this.#e, this.#T()), this.#t.markSourcesChanged(), this.#t.merge();
3277
+ const n = Me(this.#n?.shell), r = (this.#n?.shell?.toolPanels?.length ?? 0) > 0, s = (this.#n?.shell?.toolPanels?.length ?? 0) !== i;
3107
3278
  if (e !== n || !e && n || !o && r || o && s) {
3108
- this.#$(), this.#M(), this.#k();
3279
+ this.#F(), this.#M(), this.#q();
3109
3280
  return;
3110
3281
  }
3111
- e && this.#ce(), this.#l.requestPhase(S.COLUMNS, "applyGridConfigUpdate");
3282
+ e && this.#ue(), this.#l.requestPhase(x.COLUMNS, "applyGridConfigUpdate");
3112
3283
  }
3113
3284
  /**
3114
3285
  * Update the shell header DOM in place without a full re-render.
3115
3286
  * Handles title, toolbar buttons, and other shell header changes.
3116
3287
  */
3117
- #ce() {
3118
- const e = this.#o.querySelector(".tbw-shell-header");
3288
+ #ue() {
3289
+ const e = this.#i.querySelector(".tbw-shell-header");
3119
3290
  if (!e) return;
3120
3291
  const o = this.#n.shell?.header?.title ?? this.#e.lightDomTitle;
3121
3292
  let i = e.querySelector(".tbw-shell-title");
@@ -3125,9 +3296,9 @@ class D extends HTMLElement {
3125
3296
  // The #queueUpdate() method schedules updates which are processed by #flushPendingUpdates()
3126
3297
  // and individual #apply*Update() methods. This coalesces rapid property changes
3127
3298
  // (e.g., setting rows, columns, gridConfig in quick succession) into a single update cycle.
3128
- #de() {
3129
- if (this.#i) {
3130
- const e = this.#N.length > 0 ? this.#N : this._columns, o = e.filter((r) => !r.hidden), i = e.filter((r) => r.hidden), n = this.#i.processColumns([...o]);
3299
+ #fe() {
3300
+ if (this.#o) {
3301
+ const e = this.#N.length > 0 ? this.#N : this._columns, o = e.filter((r) => !r.hidden), i = e.filter((r) => r.hidden), n = this.#o.processColumns([...o]);
3131
3302
  if (n !== o) {
3132
3303
  new Set(o.map((l) => l.field));
3133
3304
  const r = new Set(n.map((l) => l.field));
@@ -3137,9 +3308,9 @@ class D extends HTMLElement {
3137
3308
  }
3138
3309
  }
3139
3310
  /** Recompute row model via plugin hooks. */
3140
- #he() {
3141
- $(this);
3142
- const e = Array.isArray(this.#r) ? [...this.#r] : [], o = this.#i?.processRows(e) ?? e;
3311
+ #pe() {
3312
+ G(this);
3313
+ const e = Array.isArray(this.#r) ? [...this.#r] : [], o = this.#o?.processRows(e) ?? e;
3143
3314
  this._rows = o;
3144
3315
  }
3145
3316
  /**
@@ -3147,31 +3318,31 @@ class D extends HTMLElement {
3147
3318
  * This makes the grid's animation settings available to plugins via CSS variables.
3148
3319
  * Called by ConfigManager after merge.
3149
3320
  */
3150
- #ue(e) {
3321
+ #ge(e) {
3151
3322
  const o = {
3152
- ...Me,
3323
+ ...Ne,
3153
3324
  ...e.animation
3154
3325
  }, i = o.mode ?? "reduced-motion";
3155
3326
  let n = 1;
3156
3327
  i === !1 || i === "off" ? n = 0 : (i === !0 || i === "on") && (n = 1), this.style.setProperty("--tbw-animation-duration", `${o.duration}ms`), this.style.setProperty("--tbw-animation-easing", o.easing ?? "ease-out"), this.style.setProperty("--tbw-animation-enabled", String(n)), this.dataset.animationMode = typeof i == "boolean" ? i ? "on" : "off" : i;
3157
3328
  }
3158
3329
  // ---------------- Delegate Wrappers ----------------
3159
- #q(e, o, i = this.__rowRenderEpoch) {
3160
- this.#s || (this.#s = (n, r, s) => this.#i?.renderRow(n, r, s) ?? !1), st(this, e, o, i, this.#s);
3330
+ #W(e, o, i = this.__rowRenderEpoch) {
3331
+ this.#s || (this.#s = (n, r, s) => this.#o?.renderRow(n, r, s) ?? !1), ot(this, e, o, i, this.#s);
3161
3332
  }
3162
3333
  // Cache for ARIA counts to avoid redundant DOM writes on scroll (hot path)
3163
- #B = -1;
3164
- #j = -1;
3334
+ #$ = -1;
3335
+ #Z = -1;
3165
3336
  /**
3166
3337
  * Updates ARIA row/col counts on the grid container.
3167
3338
  * Also sets role="rowgroup" on .rows container only when there are rows.
3168
3339
  * Uses caching to avoid redundant DOM writes on every scroll frame.
3169
3340
  */
3170
- #K(e, o) {
3171
- if (e === this.#B && o === this.#j)
3341
+ #J(e, o) {
3342
+ if (e === this.#$ && o === this.#Z)
3172
3343
  return;
3173
- const i = this.#B;
3174
- this.#B = e, this.#j = o, this.__rowsBodyEl && (this.__rowsBodyEl.setAttribute("aria-rowcount", String(e)), this.__rowsBodyEl.setAttribute("aria-colcount", String(o))), e !== i && this._bodyEl && (e > 0 ? this._bodyEl.setAttribute("role", "rowgroup") : this._bodyEl.removeAttribute("role"));
3344
+ const i = this.#$;
3345
+ this.#$ = e, this.#Z = o, this.__rowsBodyEl && (this.__rowsBodyEl.setAttribute("aria-rowcount", String(e)), this.__rowsBodyEl.setAttribute("aria-colcount", String(o))), e !== i && this._bodyEl && (e > 0 ? this._bodyEl.setAttribute("role", "rowgroup") : this._bodyEl.removeAttribute("role"));
3175
3346
  }
3176
3347
  // ---------------- Core Helpers ----------------
3177
3348
  /**
@@ -3182,21 +3353,21 @@ class D extends HTMLElement {
3182
3353
  * Previously this method executed rendering synchronously, but that caused race
3183
3354
  * conditions with framework adapters that also schedule their own render work.
3184
3355
  */
3185
- #T() {
3356
+ #R() {
3186
3357
  if (this.isConnected && !(!this._headerRowEl || !this._bodyEl)) {
3187
- if (this.#t.parseLightDomColumns(this), this.#L) {
3188
- const e = this.#L;
3189
- this.#L = void 0, this.#t.merge();
3190
- const o = this.#i?.getAll() ?? [];
3358
+ if (this.#t.parseLightDomColumns(this), this.#A) {
3359
+ const e = this.#A;
3360
+ this.#A = void 0, this.#t.merge();
3361
+ const o = this.#o?.getAll() ?? [];
3191
3362
  this.#t.applyState(e, o);
3192
3363
  }
3193
- this._bodyEl && (this._bodyEl.style.display = "", this._bodyEl.style.gridTemplateColumns = ""), this.#l.requestPhase(S.FULL, "setup");
3364
+ this._bodyEl && (this._bodyEl.style.display = "", this._bodyEl.style.gridTemplateColumns = ""), this.#l.requestPhase(x.FULL, "setup");
3194
3365
  }
3195
3366
  }
3196
- #fe(e) {
3197
- if (this.refreshVirtualWindow(!1), this.#i?.onScrollRender(), this.#b) {
3198
- const o = this._virtualization.container, i = this.#S;
3199
- i.scrollTop = e, i.scrollLeft = o?.scrollLeft ?? 0, i.scrollHeight = o?.scrollHeight ?? 0, i.scrollWidth = o?.scrollWidth ?? 0, i.clientHeight = o?.clientHeight ?? 0, i.clientWidth = o?.clientWidth ?? 0, this.#i?.onScroll(i);
3367
+ #me(e) {
3368
+ if (this.refreshVirtualWindow(!1), this.#o?.onScrollRender(), this.#b) {
3369
+ const o = this._virtualization.container, i = this.#z;
3370
+ i.scrollTop = e, i.scrollLeft = o?.scrollLeft ?? 0, i.scrollHeight = o?.scrollHeight ?? 0, i.scrollWidth = o?.scrollWidth ?? 0, i.clientHeight = o?.clientHeight ?? 0, i.clientWidth = o?.clientWidth ?? 0, this.#o?.onScroll(i);
3200
3371
  }
3201
3372
  }
3202
3373
  /**
@@ -3205,7 +3376,7 @@ class D extends HTMLElement {
3205
3376
  * @internal Plugin API
3206
3377
  */
3207
3378
  findHeaderRow() {
3208
- return this.#o.querySelector(".header-row");
3379
+ return this.#i.querySelector(".header-row");
3209
3380
  }
3210
3381
  /**
3211
3382
  * Find a rendered row element by its data row index.
@@ -3236,7 +3407,7 @@ class D extends HTMLElement {
3236
3407
  cellEl: n,
3237
3408
  originalEvent: e
3238
3409
  };
3239
- return this.#i?.onCellClick(l) ?? !1;
3410
+ return this.#o?.onCellClick(l) ?? !1;
3240
3411
  }
3241
3412
  /**
3242
3413
  * Dispatch a row click event to the plugin system.
@@ -3250,7 +3421,7 @@ class D extends HTMLElement {
3250
3421
  rowEl: n,
3251
3422
  originalEvent: e
3252
3423
  };
3253
- return this.#i?.onRowClick(r) ?? !1;
3424
+ return this.#o?.onRowClick(r) ?? !1;
3254
3425
  }
3255
3426
  /**
3256
3427
  * Dispatch a header click event to the plugin system.
@@ -3266,14 +3437,14 @@ class D extends HTMLElement {
3266
3437
  headerEl: i,
3267
3438
  originalEvent: e
3268
3439
  };
3269
- return this.#i?.onHeaderClick(r) ?? !1;
3440
+ return this.#o?.onHeaderClick(r) ?? !1;
3270
3441
  }
3271
3442
  /**
3272
3443
  * Dispatch a keyboard event to the plugin system.
3273
3444
  * Returns true if any plugin handled the event.
3274
3445
  */
3275
3446
  _dispatchKeyDown(e) {
3276
- return this.#i?.onKeyDown(e) ?? !1;
3447
+ return this.#o?.onKeyDown(e) ?? !1;
3277
3448
  }
3278
3449
  /**
3279
3450
  * Get horizontal scroll boundary offsets from plugins.
@@ -3281,7 +3452,7 @@ class D extends HTMLElement {
3281
3452
  * when plugins like pinned columns obscure part of the scroll area.
3282
3453
  */
3283
3454
  _getHorizontalScrollOffsets(e, o) {
3284
- return this.#i?.getHorizontalScrollOffsets(e, o) ?? { left: 0, right: 0 };
3455
+ return this.#o?.getHorizontalScrollOffsets(e, o) ?? { left: 0, right: 0 };
3285
3456
  }
3286
3457
  /**
3287
3458
  * Query all plugins with a generic query and collect responses.
@@ -3294,64 +3465,35 @@ class D extends HTMLElement {
3294
3465
  * const canMove = !responses.includes(false);
3295
3466
  */
3296
3467
  queryPlugins(e) {
3297
- return this.#i?.queryPlugins(e) ?? [];
3468
+ return this.#o?.queryPlugins(e) ?? [];
3298
3469
  }
3299
3470
  /**
3300
- * Build a CellMouseEvent from a native MouseEvent.
3301
- * Extracts cell/row information from the event target.
3471
+ * Dispatch cell mouse events for drag operations.
3472
+ * Returns true if any plugin started a drag.
3473
+ * @internal Plugin API - called by event-delegation.ts
3302
3474
  */
3303
- #W(e, o) {
3304
- let i = null;
3305
- const n = e.composedPath?.();
3306
- if (n && n.length > 0 ? i = n[0] : i = e.target, i && !this.#o.contains(i)) {
3307
- const u = this.#o.elementFromPoint(e.clientX, e.clientY);
3308
- u && (i = u);
3309
- }
3310
- const r = i?.closest?.("[data-col]"), s = i?.closest?.(".data-grid-row"), l = i?.closest?.(".header-row");
3311
- let a, c, h, d, f, p;
3312
- return r && (a = parseInt(r.getAttribute("data-row") ?? "-1", 10), c = parseInt(r.getAttribute("data-col") ?? "-1", 10), a >= 0 && c >= 0 && (h = this._rows[a], p = this._columns[c], d = p?.field, f = h && d ? h[d] : void 0)), {
3313
- type: o,
3314
- row: h,
3315
- rowIndex: a !== void 0 && a >= 0 ? a : void 0,
3316
- colIndex: c !== void 0 && c >= 0 ? c : void 0,
3317
- field: d,
3318
- value: f,
3319
- column: p,
3320
- originalEvent: e,
3321
- cellElement: r ?? void 0,
3322
- rowElement: s ?? void 0,
3323
- isHeader: !!l,
3324
- cell: a !== void 0 && c !== void 0 && a >= 0 && c >= 0 ? { row: a, col: c } : void 0
3325
- };
3475
+ _dispatchCellMouseDown(e) {
3476
+ return this.#o?.onCellMouseDown(e) ?? !1;
3326
3477
  }
3327
3478
  /**
3328
- * Handle mousedown events and dispatch to plugin system.
3479
+ * Dispatch cell mouse move during drag.
3480
+ * @internal Plugin API - called by event-delegation.ts
3329
3481
  */
3330
- #pe(e) {
3331
- const o = this.#W(e, "mousedown");
3332
- (this.#i?.onCellMouseDown(o) ?? !1) && (this.#m = !0);
3482
+ _dispatchCellMouseMove(e) {
3483
+ this.#o?.onCellMouseMove(e);
3333
3484
  }
3334
3485
  /**
3335
- * Handle mousemove events (only when dragging).
3486
+ * Dispatch cell mouse up to end drag.
3487
+ * @internal Plugin API - called by event-delegation.ts
3336
3488
  */
3337
- #ge(e) {
3338
- if (!this.#m) return;
3339
- const o = this.#W(e, "mousemove");
3340
- this.#i?.onCellMouseMove(o);
3341
- }
3342
- /**
3343
- * Handle mouseup events.
3344
- */
3345
- #we(e) {
3346
- if (!this.#m) return;
3347
- const o = this.#W(e, "mouseup");
3348
- this.#i?.onCellMouseUp(o), this.#m = !1;
3489
+ _dispatchCellMouseUp(e) {
3490
+ this.#o?.onCellMouseUp(e);
3349
3491
  }
3350
3492
  async ready() {
3351
3493
  return this.#f;
3352
3494
  }
3353
3495
  async forceLayout() {
3354
- return this.#l.requestPhase(S.FULL, "forceLayout"), this.#l.whenReady();
3496
+ return this.#l.requestPhase(x.FULL, "forceLayout"), this.#l.whenReady();
3355
3497
  }
3356
3498
  /**
3357
3499
  * Trim the internal row pool to match the current visible window size.
@@ -3395,7 +3537,7 @@ class D extends HTMLElement {
3395
3537
  * Returns a serializable object suitable for localStorage or database storage.
3396
3538
  */
3397
3539
  getColumnState() {
3398
- const e = this.#i?.getAll() ?? [];
3540
+ const e = this.#o?.getAll() ?? [];
3399
3541
  return this.#t.collectState(e);
3400
3542
  }
3401
3543
  /**
@@ -3403,7 +3545,7 @@ class D extends HTMLElement {
3403
3545
  * Use this to restore previously saved column state.
3404
3546
  */
3405
3547
  set columnState(e) {
3406
- e && (this.#L = e, this.#t.initialColumnState = e, this.#c && this.#be(e));
3548
+ e && (this.#A = e, this.#t.initialColumnState = e, this.#c && this.#be(e));
3407
3549
  }
3408
3550
  /**
3409
3551
  * Get the current column state.
@@ -3415,8 +3557,8 @@ class D extends HTMLElement {
3415
3557
  * Apply column state internally.
3416
3558
  */
3417
3559
  #be(e) {
3418
- const o = this.#i?.getAll() ?? [];
3419
- this.#t.applyState(e, o), this.#T();
3560
+ const o = this.#o?.getAll() ?? [];
3561
+ this.#t.applyState(e, o), this.#R();
3420
3562
  }
3421
3563
  /**
3422
3564
  * Request a state change event to be emitted.
@@ -3426,7 +3568,7 @@ class D extends HTMLElement {
3426
3568
  * @internal Plugin API
3427
3569
  */
3428
3570
  requestStateChange() {
3429
- const e = this.#i?.getAll() ?? [];
3571
+ const e = this.#o?.getAll() ?? [];
3430
3572
  this.#t.requestStateChange(e);
3431
3573
  }
3432
3574
  /**
@@ -3434,9 +3576,9 @@ class D extends HTMLElement {
3434
3576
  * Clears all user modifications (order, width, visibility, sort).
3435
3577
  */
3436
3578
  resetColumnState() {
3437
- this.#L = void 0, this.__originalOrder = [];
3438
- const e = this.#i?.getAll() ?? [];
3439
- this.#t.resetState(e), this.#t.merge(), this.#T();
3579
+ this.#A = void 0, this.__originalOrder = [];
3580
+ const e = this.#o?.getAll() ?? [];
3581
+ this.#t.resetState(e), this.#t.merge(), this.#R();
3440
3582
  }
3441
3583
  // ---------------- Shell / Tool Panel API ----------------
3442
3584
  // These methods delegate to ShellController for implementation.
@@ -3518,11 +3660,11 @@ class D extends HTMLElement {
3518
3660
  * Call this after dynamically modifying <tbw-grid-header> children.
3519
3661
  */
3520
3662
  refreshShellHeader() {
3521
- M(this, this.#e), z(this, this.#e), N(this, this.#e, this.#R()), this.#t.markSourcesChanged(), this.#t.merge(), this.#$(), this.#M(), this.#k();
3663
+ N(this, this.#e), k(this, this.#e), I(this, this.#e, this.#T()), this.#t.markSourcesChanged(), this.#t.merge(), this.#F(), this.#M(), this.#q();
3522
3664
  }
3523
3665
  // #region Custom Styles API
3524
3666
  /** Map of registered custom stylesheets by ID - uses adoptedStyleSheets which survive DOM rebuilds */
3525
- #x = /* @__PURE__ */ new Map();
3667
+ #S = /* @__PURE__ */ new Map();
3526
3668
  /**
3527
3669
  * Register custom CSS styles to be injected into the grid's shadow DOM.
3528
3670
  * Use this to style custom cell renderers, editors, or detail panels.
@@ -3548,28 +3690,31 @@ class D extends HTMLElement {
3548
3690
  * ```
3549
3691
  */
3550
3692
  registerStyles(e, o) {
3551
- let i = this.#x.get(e);
3552
- i || (i = new CSSStyleSheet(), this.#x.set(e, i)), i.replaceSync(o), this.#Z();
3693
+ let i = this.#S.get(e);
3694
+ i || (i = new CSSStyleSheet(), this.#S.set(e, i)), i.replaceSync(o), this.#Q();
3553
3695
  }
3554
3696
  /**
3555
3697
  * Remove previously registered custom styles.
3556
3698
  * @param id - The ID used when registering the styles
3557
3699
  */
3558
3700
  unregisterStyles(e) {
3559
- this.#x.delete(e) && this.#Z();
3701
+ this.#S.delete(e) && this.#Q();
3560
3702
  }
3561
3703
  /**
3562
3704
  * Get list of registered custom style IDs.
3563
3705
  */
3564
3706
  getRegisteredStyles() {
3565
- return Array.from(this.#x.keys());
3707
+ return Array.from(this.#S.keys());
3566
3708
  }
3567
3709
  /**
3568
- * Update the shadow root's adoptedStyleSheets to include base + custom sheets.
3710
+ * Update document.adoptedStyleSheets to include custom sheets.
3711
+ * Without Shadow DOM, all custom styles go into the document.
3569
3712
  */
3570
- #Z() {
3571
- const e = this.#o.adoptedStyleSheets[0], o = Array.from(this.#x.values());
3572
- this.#o.adoptedStyleSheets = e ? [e, ...o] : o;
3713
+ #Q() {
3714
+ const e = Array.from(this.#S.values()), o = document.adoptedStyleSheets.filter(
3715
+ (i) => !Array.from(this.#S.values()).includes(i)
3716
+ );
3717
+ document.adoptedStyleSheets = [...o, ...e];
3573
3718
  }
3574
3719
  // #endregion
3575
3720
  /**
@@ -3582,27 +3727,27 @@ class D extends HTMLElement {
3582
3727
  * This separation allows plugins to register their own Light DOM elements
3583
3728
  * and handle parsing themselves.
3584
3729
  */
3585
- #me() {
3730
+ #we() {
3586
3731
  const e = () => {
3587
3732
  const i = this.#e.lightDomTitle, n = this.#e.hasToolButtonsContainer;
3588
- M(this, this.#e), z(this, this.#e), N(this, this.#e, this.#R());
3733
+ N(this, this.#e), k(this, this.#e), I(this, this.#e, this.#T());
3589
3734
  const r = this.#e.lightDomTitle, s = this.#e.hasToolButtonsContainer;
3590
3735
  if (r && !i || s && !n) {
3591
3736
  this.#t.markSourcesChanged(), this.#t.merge();
3592
- const l = this.#o.querySelector(".tbw-shell-header");
3737
+ const l = this.#i.querySelector(".tbw-shell-header");
3593
3738
  if (l) {
3594
- const a = pe(
3739
+ const a = be(
3595
3740
  this.#n.shell,
3596
3741
  this.#e,
3597
3742
  this.#n.icons?.toolPanel
3598
3743
  ), c = document.createElement("div");
3599
3744
  c.innerHTML = a;
3600
- const h = c.firstElementChild;
3601
- h && (l.replaceWith(h), this.#F());
3745
+ const u = c.firstElementChild;
3746
+ u && (l.replaceWith(u), this.#V());
3602
3747
  }
3603
3748
  }
3604
3749
  }, o = () => {
3605
- this.__lightDomColumnsCache = void 0, this.#T();
3750
+ this.__lightDomColumnsCache = void 0, this.#R();
3606
3751
  };
3607
3752
  this.#t.registerLightDomHandler("tbw-grid-header", e), this.#t.registerLightDomHandler("tbw-grid-tool-buttons", e), this.#t.registerLightDomHandler("tbw-grid-tool-panel", e), this.#t.registerLightDomHandler("tbw-grid-column", o), this.#t.registerLightDomHandler("tbw-grid-detail", o), this.#t.observeLightDOM(this);
3608
3753
  }
@@ -3613,25 +3758,25 @@ class D extends HTMLElement {
3613
3758
  * @internal Used by framework integration libraries (Angular, React, Vue)
3614
3759
  */
3615
3760
  refreshColumns() {
3616
- this.__lightDomColumnsCache = void 0, $(this), this.#t.parseLightDomColumns(this);
3761
+ this.__lightDomColumnsCache = void 0, G(this), this.#t.parseLightDomColumns(this);
3617
3762
  const e = this.#e.lightDomTitle, o = this.#e.hasToolButtonsContainer;
3618
- M(this, this.#e), z(this, this.#e), N(this, this.#e, this.#R());
3763
+ N(this, this.#e), k(this, this.#e), I(this, this.#e, this.#T());
3619
3764
  const i = this.#e.lightDomTitle, n = this.#e.hasToolButtonsContainer;
3620
3765
  if (i && !e || n && !o) {
3621
3766
  this.#t.markSourcesChanged(), this.#t.merge();
3622
- const s = this.#o.querySelector(".tbw-shell-header");
3767
+ const s = this.#i.querySelector(".tbw-shell-header");
3623
3768
  if (s) {
3624
- const l = pe(
3769
+ const l = be(
3625
3770
  this.#n.shell,
3626
3771
  this.#e,
3627
3772
  this.#n.icons?.toolPanel
3628
3773
  ), a = document.createElement("div");
3629
3774
  a.innerHTML = l;
3630
3775
  const c = a.firstElementChild;
3631
- c && (s.replaceWith(c), this.#F());
3776
+ c && (s.replaceWith(c), this.#V());
3632
3777
  }
3633
3778
  }
3634
- this.#l.requestPhase(S.COLUMNS, "refreshColumns");
3779
+ this.#l.requestPhase(x.COLUMNS, "refreshColumns");
3635
3780
  }
3636
3781
  // ---------------- Virtual Window ----------------
3637
3782
  /**
@@ -3639,7 +3784,7 @@ class D extends HTMLElement {
3639
3784
  * Used by both bypass and virtualized rendering paths to ensure consistent scroll behavior.
3640
3785
  */
3641
3786
  #U(e) {
3642
- const o = this._virtualization.rowHeight, i = this._virtualization.container ?? this, n = this._virtualization.viewportEl ?? i, r = i.clientHeight, s = n.clientHeight, a = this.shadowRoot?.querySelector(".tbw-scroll-area"), c = a ? a.clientHeight : r, d = c - s, f = this.#i?.getExtraHeight() ?? 0, p = Math.max(0, r - c);
3787
+ const o = this._virtualization.rowHeight, i = this._virtualization.container ?? this, n = this._virtualization.viewportEl ?? i, r = i.clientHeight, s = n.clientHeight, a = this.shadowRoot?.querySelector(".tbw-scroll-area"), c = a ? a.clientHeight : r, d = c - s, f = this.#o?.getExtraHeight() ?? 0, p = Math.max(0, r - c);
3643
3788
  return e * o + d + f + p;
3644
3789
  }
3645
3790
  /**
@@ -3651,60 +3796,60 @@ class D extends HTMLElement {
3651
3796
  if (!this._bodyEl) return;
3652
3797
  const o = this._rows.length;
3653
3798
  if (!this._virtualization.enabled) {
3654
- this.#q(0, o), this.#i?.afterRender();
3799
+ this.#W(0, o), this.#o?.afterRender();
3655
3800
  return;
3656
3801
  }
3657
3802
  if (this._rows.length <= this._virtualization.bypassThreshold) {
3658
- this._virtualization.start = 0, this._virtualization.end = o, e && (this._bodyEl.style.transform = "translateY(0px)"), this.#q(0, o, e ? ++this.__rowRenderEpoch : this.__rowRenderEpoch), this._virtualization.totalHeightEl && (this._virtualization.totalHeightEl.style.height = `${this.#U(o)}px`), this.#K(o, this._visibleColumns.length), this.#i?.afterRender();
3803
+ this._virtualization.start = 0, this._virtualization.end = o, e && (this._bodyEl.style.transform = "translateY(0px)"), this.#W(0, o, e ? ++this.__rowRenderEpoch : this.__rowRenderEpoch), this._virtualization.totalHeightEl && (this._virtualization.totalHeightEl.style.height = `${this.#U(o)}px`), this.#J(o, this._visibleColumns.length), this.#o?.afterRender();
3659
3804
  return;
3660
3805
  }
3661
3806
  const i = this._virtualization.container ?? this, n = this._virtualization.viewportEl ?? i, r = n.clientHeight, s = this._virtualization.rowHeight, l = i.scrollTop;
3662
3807
  let a = Math.floor(l / s), c = 0;
3663
- const h = 10;
3664
- for (; c < h; ) {
3665
- const _ = this.#i?.getExtraHeightBefore?.(a) ?? 0, w = Math.floor((l - _) / s);
3666
- if (w >= a || w < 0) break;
3667
- a = w, c++;
3808
+ const u = 10;
3809
+ for (; c < u; ) {
3810
+ const T = this.#o?.getExtraHeightBefore?.(a) ?? 0, v = Math.floor((l - T) / s);
3811
+ if (v >= a || v < 0) break;
3812
+ a = v, c++;
3668
3813
  }
3669
3814
  a = a - a % 2, a < 0 && (a = 0);
3670
- const d = this.#i?.adjustVirtualStart(a, l, s);
3815
+ const d = this.#o?.adjustVirtualStart(a, l, s);
3671
3816
  d !== void 0 && d < a && (a = d, a = a - a % 2, a < 0 && (a = 0));
3672
3817
  const f = Math.ceil(r / s) + 3;
3673
3818
  let p = a + f;
3674
3819
  if (p > o && (p = o), this._virtualization.start = a, this._virtualization.end = p, i.clientHeight === 0 && r > 0) {
3675
- this.#l.requestPhase(S.VIRTUALIZATION, "stale-refs-retry");
3820
+ this.#l.requestPhase(x.VIRTUALIZATION, "stale-refs-retry");
3676
3821
  return;
3677
3822
  }
3678
3823
  const g = this.#U(o);
3679
3824
  this._virtualization.totalHeightEl && (this._virtualization.totalHeightEl.style.height = `${g}px`);
3680
- const m = this.#i?.getExtraHeightBefore?.(a) ?? 0, b = -(l - a * s - m);
3681
- this._bodyEl.style.transform = `translateY(${b}px)`, this.#q(a, p, e ? ++this.__rowRenderEpoch : this.__rowRenderEpoch), this.#K(o, this._visibleColumns.length), e && (this.#i?.afterRender(), queueMicrotask(() => {
3682
- const _ = i.clientHeight, w = n.clientHeight;
3683
- if (_ === 0 && w > 0) return;
3684
- const C = this.#U(o);
3685
- this._virtualization.totalHeightEl && (this._virtualization.totalHeightEl.style.height = `${C}px`);
3825
+ const w = this.#o?.getExtraHeightBefore?.(a) ?? 0, _ = -(l - a * s - w);
3826
+ this._bodyEl.style.transform = `translateY(${_}px)`, this.#W(a, p, e ? ++this.__rowRenderEpoch : this.__rowRenderEpoch), this.#J(o, this._visibleColumns.length), e && (this.#o?.afterRender(), queueMicrotask(() => {
3827
+ const T = i.clientHeight, v = n.clientHeight;
3828
+ if (T === 0 && v > 0) return;
3829
+ const m = this.#U(o);
3830
+ this._virtualization.totalHeightEl && (this._virtualization.totalHeightEl.style.height = `${m}px`);
3686
3831
  }));
3687
3832
  }
3688
3833
  // ---------------- Render ----------------
3689
- #$() {
3690
- M(this, this.#e), z(this, this.#e), N(this, this.#e, this.#R()), this.#t.markSourcesChanged(), this.#t.merge();
3834
+ #F() {
3835
+ N(this, this.#e), k(this, this.#e), I(this, this.#e, this.#T()), this.#t.markSourcesChanged(), this.#t.merge();
3691
3836
  const e = this.#n?.shell;
3692
- _t(
3693
- this.#o,
3837
+ xt(
3838
+ this.#i,
3694
3839
  e,
3695
3840
  { isPanelOpen: this.#e.isPanelOpen, expandedSections: this.#e.expandedSections },
3696
3841
  this.#n?.icons
3697
- ) && (this.#F(), this.#a.setInitialized(!0));
3842
+ ) && (this.#V(), this.#a.setInitialized(!0));
3698
3843
  }
3699
3844
  /**
3700
3845
  * Set up shell event listeners after render.
3701
3846
  */
3702
- #F() {
3703
- ft(this.#o, this.#n?.shell, this.#e, {
3847
+ #V() {
3848
+ vt(this.#i, this.#n?.shell, this.#e, {
3704
3849
  onPanelToggle: () => this.toggleToolPanel(),
3705
3850
  onSectionToggle: (e) => this.toggleToolPanelSection(e),
3706
3851
  onToolbarButtonClick: (e) => this.#ve(e)
3707
- }), this.#D?.(), this.#D = pt(this.#o, this.#n?.shell, (e) => {
3852
+ }), this.#H?.(), this.#H = Ct(this.#i, this.#n?.shell, (e) => {
3708
3853
  this.style.setProperty("--tbw-tool-panel-width", `${e}px`);
3709
3854
  });
3710
3855
  }
@@ -3717,15 +3862,15 @@ class D extends HTMLElement {
3717
3862
  #ve(e) {
3718
3863
  }
3719
3864
  }
3720
- customElements.get(D.tagName) || customElements.define(D.tagName, D);
3721
- globalThis.DataGridElement = D;
3722
- const kt = {
3865
+ customElements.get(P.tagName) || customElements.define(P.tagName, P);
3866
+ globalThis.DataGridElement = P;
3867
+ const Ut = {
3723
3868
  /** Ask if a column can be moved. Context: ColumnConfig. Response: boolean | undefined */
3724
3869
  CAN_MOVE_COLUMN: "canMoveColumn",
3725
3870
  /** Get context menu items. Context: ContextMenuParams. Response: ContextMenuItem[] */
3726
3871
  GET_CONTEXT_MENU_ITEMS: "getContextMenuItems"
3727
3872
  };
3728
- class It {
3873
+ class Ft {
3729
3874
  /**
3730
3875
  * Plugin dependencies - declare other plugins this one requires.
3731
3876
  *
@@ -3746,7 +3891,7 @@ class It {
3746
3891
  * Plugin version - defaults to grid version for built-in plugins.
3747
3892
  * Third-party plugins can override with their own semver.
3748
3893
  */
3749
- version = "0.4.2";
3894
+ version = "0.6.0";
3750
3895
  /** CSS styles to inject into the grid's shadow DOM */
3751
3896
  styles;
3752
3897
  /** Custom cell renderers keyed by type name */
@@ -3766,7 +3911,7 @@ class It {
3766
3911
  * Created fresh in attach(), aborted in detach().
3767
3912
  * This ensures event listeners are properly cleaned up when plugins are re-attached.
3768
3913
  */
3769
- #o;
3914
+ #i;
3770
3915
  /**
3771
3916
  * Default configuration - subclasses should override this getter.
3772
3917
  * Note: This must be a getter (not property initializer) for proper inheritance
@@ -3794,7 +3939,7 @@ class It {
3794
3939
  * ```
3795
3940
  */
3796
3941
  attach(e) {
3797
- this.#o?.abort(), this.#o = new AbortController(), this.grid = e, this.config = { ...this.defaultConfig, ...this.userConfig };
3942
+ this.#i?.abort(), this.#i = new AbortController(), this.grid = e, this.config = { ...this.defaultConfig, ...this.userConfig };
3798
3943
  }
3799
3944
  /**
3800
3945
  * Called when the plugin is detached from a grid.
@@ -3810,7 +3955,7 @@ class It {
3810
3955
  * ```
3811
3956
  */
3812
3957
  detach() {
3813
- this.#o?.abort(), this.#o = void 0;
3958
+ this.#i?.abort(), this.#i = void 0;
3814
3959
  }
3815
3960
  /**
3816
3961
  * Get another plugin instance from the same grid.
@@ -3902,10 +4047,21 @@ class It {
3902
4047
  return this.grid;
3903
4048
  }
3904
4049
  /**
3905
- * Get the shadow root of the grid.
4050
+ * Get the render root of the grid for DOM queries.
4051
+ * @deprecated Use `gridElement` instead. This getter exists only for backward compatibility.
4052
+ *
4053
+ * With Shadow DOM removed, the grid element itself is the render root.
4054
+ * All new code should use `this.gridElement` for DOM queries.
4055
+ *
4056
+ * @example
4057
+ * // OLD (deprecated)
4058
+ * const rows = this.shadowRoot?.querySelector('.rows');
4059
+ *
4060
+ * // NEW (preferred)
4061
+ * const rows = this.gridElement.querySelector('.rows');
3906
4062
  */
3907
4063
  get shadowRoot() {
3908
- return this.grid?.shadowRoot ?? null;
4064
+ return this.gridElement;
3909
4065
  }
3910
4066
  /**
3911
4067
  * Get the disconnect signal for event listener cleanup.
@@ -3925,7 +4081,7 @@ class It {
3925
4081
  * document.addEventListener('keydown', handler, { signal: this.disconnectSignal });
3926
4082
  */
3927
4083
  get disconnectSignal() {
3928
- return this.#o?.signal ?? this.grid?.disconnectSignal;
4084
+ return this.#i?.signal ?? this.grid?.disconnectSignal;
3929
4085
  }
3930
4086
  /**
3931
4087
  * Get the grid-level icons configuration.
@@ -3933,7 +4089,7 @@ class It {
3933
4089
  */
3934
4090
  get gridIcons() {
3935
4091
  const e = this.grid?.gridConfig?.icons ?? {};
3936
- return { ...L, ...e };
4092
+ return { ...M, ...e };
3937
4093
  }
3938
4094
  // #region Animation Helpers
3939
4095
  /**
@@ -3956,7 +4112,7 @@ class It {
3956
4112
  const e = this.grid?.effectiveConfig?.animation?.mode ?? "reduced-motion";
3957
4113
  if (e === !1 || e === "off") return !1;
3958
4114
  if (e === !0 || e === "on") return !0;
3959
- const o = this.shadowRoot?.host;
4115
+ const o = this.gridElement;
3960
4116
  return o ? getComputedStyle(o).getPropertyValue("--tbw-animation-enabled").trim() !== "0" : !0;
3961
4117
  }
3962
4118
  /**
@@ -3972,7 +4128,7 @@ class It {
3972
4128
  * ```
3973
4129
  */
3974
4130
  get animationDuration() {
3975
- const e = this.shadowRoot?.host;
4131
+ const e = this.gridElement;
3976
4132
  if (e) {
3977
4133
  const o = getComputedStyle(e).getPropertyValue("--tbw-animation-duration").trim(), i = parseInt(o, 10);
3978
4134
  if (!isNaN(i)) return i;
@@ -4009,7 +4165,7 @@ class It {
4009
4165
  }
4010
4166
  // #endregion
4011
4167
  }
4012
- const E = {
4168
+ const R = {
4013
4169
  // ─── Core Structure ───────────────────────────────────────────────
4014
4170
  ROOT: "tbw-grid-root",
4015
4171
  HEADER: "header",
@@ -4057,7 +4213,7 @@ const E = {
4057
4213
  // Selection (SelectionPlugin applies, core CSS styles)
4058
4214
  RANGE_SELECTION: "range-selection",
4059
4215
  SELECTION_OVERLAY: "selection-overlay"
4060
- }, V = {
4216
+ }, Y = {
4061
4217
  // ─── Core Attributes ──────────────────────────────────────────────
4062
4218
  ROW_INDEX: "data-row-index",
4063
4219
  COL_INDEX: "data-col-index",
@@ -4069,24 +4225,24 @@ const E = {
4069
4225
  // TreePlugin
4070
4226
  STICKY: "data-sticky"
4071
4227
  // PinnedColumnsPlugin
4072
- }, qt = {
4073
- ROOT: `.${E.ROOT}`,
4074
- HEADER: `.${E.HEADER}`,
4075
- HEADER_ROW: `.${E.HEADER_ROW}`,
4076
- HEADER_CELL: `.${E.HEADER_CELL}`,
4077
- ROWS_VIEWPORT: `.${E.ROWS_VIEWPORT}`,
4078
- ROWS_CONTAINER: `.${E.ROWS_CONTAINER}`,
4079
- DATA_ROW: `.${E.DATA_ROW}`,
4080
- DATA_CELL: `.${E.DATA_CELL}`,
4081
- GROUP_ROW: `.${E.GROUP_ROW}`,
4228
+ }, Vt = {
4229
+ ROOT: `.${R.ROOT}`,
4230
+ HEADER: `.${R.HEADER}`,
4231
+ HEADER_ROW: `.${R.HEADER_ROW}`,
4232
+ HEADER_CELL: `.${R.HEADER_CELL}`,
4233
+ ROWS_VIEWPORT: `.${R.ROWS_VIEWPORT}`,
4234
+ ROWS_CONTAINER: `.${R.ROWS_CONTAINER}`,
4235
+ DATA_ROW: `.${R.DATA_ROW}`,
4236
+ DATA_CELL: `.${R.DATA_CELL}`,
4237
+ GROUP_ROW: `.${R.GROUP_ROW}`,
4082
4238
  // By data attribute
4083
- ROW_BY_INDEX: (t) => `.${E.DATA_ROW}[${V.ROW_INDEX}="${t}"]`,
4084
- CELL_BY_FIELD: (t) => `.${E.DATA_CELL}[${V.FIELD}="${t}"]`,
4085
- CELL_AT: (t, e) => `.${E.DATA_ROW}[${V.ROW_INDEX}="${t}"] .${E.DATA_CELL}[${V.COL_INDEX}="${e}"]`,
4239
+ ROW_BY_INDEX: (t) => `.${R.DATA_ROW}[${Y.ROW_INDEX}="${t}"]`,
4240
+ CELL_BY_FIELD: (t) => `.${R.DATA_CELL}[${Y.FIELD}="${t}"]`,
4241
+ CELL_AT: (t, e) => `.${R.DATA_ROW}[${Y.ROW_INDEX}="${t}"] .${R.DATA_CELL}[${Y.COL_INDEX}="${e}"]`,
4086
4242
  // State selectors
4087
- SELECTED_ROWS: `.${E.DATA_ROW}.${E.SELECTED}`,
4088
- EDITING_CELL: `.${E.DATA_CELL}.${E.EDITING}`
4089
- }, Bt = {
4243
+ SELECTED_ROWS: `.${R.DATA_ROW}.${R.SELECTED}`,
4244
+ EDITING_CELL: `.${R.DATA_CELL}.${R.EDITING}`
4245
+ }, Gt = {
4090
4246
  // Colors
4091
4247
  COLOR_BG: "--tbw-color-bg",
4092
4248
  COLOR_FG: "--tbw-color-fg",
@@ -4108,7 +4264,15 @@ const E = {
4108
4264
  // Borders
4109
4265
  BORDER_RADIUS: "--tbw-border-radius",
4110
4266
  FOCUS_OUTLINE: "--tbw-focus-outline"
4111
- }, Wt = {
4267
+ };
4268
+ function Xt(t) {
4269
+ const e = document.createElement("tbw-grid");
4270
+ return t && (e.gridConfig = t), e;
4271
+ }
4272
+ function Yt(t, e = document) {
4273
+ return e.querySelector(t);
4274
+ }
4275
+ const jt = {
4112
4276
  CELL_COMMIT: "cell-commit",
4113
4277
  ROW_COMMIT: "row-commit",
4114
4278
  CHANGED_ROWS_RESET: "changed-rows-reset",
@@ -4119,7 +4283,7 @@ const E = {
4119
4283
  ACTIVATE_CELL: "activate-cell",
4120
4284
  GROUP_TOGGLE: "group-toggle",
4121
4285
  COLUMN_STATE_CHANGE: "column-state-change"
4122
- }, Ut = {
4286
+ }, Kt = {
4123
4287
  // Selection plugin
4124
4288
  SELECTION_CHANGE: "selection-change",
4125
4289
  // Tree plugin
@@ -4150,7 +4314,7 @@ const E = {
4150
4314
  DETAIL_EXPAND: "detail-expand",
4151
4315
  // Grouping rows plugin
4152
4316
  GROUP_EXPAND: "group-expand"
4153
- }, Q = {
4317
+ }, oe = {
4154
4318
  sum: (t, e) => t.reduce((o, i) => o + (Number(i[e]) || 0), 0),
4155
4319
  avg: (t, e) => {
4156
4320
  const o = t.reduce((i, n) => i + (Number(n[e]) || 0), 0);
@@ -4161,25 +4325,25 @@ const E = {
4161
4325
  max: (t, e) => Math.max(...t.map((o) => Number(o[e]) || -1 / 0)),
4162
4326
  first: (t, e) => t[0]?.[e],
4163
4327
  last: (t, e) => t[t.length - 1]?.[e]
4164
- }, I = /* @__PURE__ */ new Map(), P = {
4328
+ }, W = /* @__PURE__ */ new Map(), H = {
4165
4329
  /**
4166
4330
  * Register a custom aggregator function.
4167
4331
  */
4168
4332
  register(t, e) {
4169
- I.set(t, e);
4333
+ W.set(t, e);
4170
4334
  },
4171
4335
  /**
4172
4336
  * Unregister a custom aggregator function.
4173
4337
  */
4174
4338
  unregister(t) {
4175
- I.delete(t);
4339
+ W.delete(t);
4176
4340
  },
4177
4341
  /**
4178
4342
  * Get an aggregator function by reference.
4179
4343
  */
4180
4344
  get(t) {
4181
4345
  if (t !== void 0)
4182
- return typeof t == "function" ? t : I.get(t) ?? Q[t];
4346
+ return typeof t == "function" ? t : W.get(t) ?? oe[t];
4183
4347
  },
4184
4348
  /**
4185
4349
  * Run an aggregator on a set of rows.
@@ -4192,15 +4356,15 @@ const E = {
4192
4356
  * Check if an aggregator exists.
4193
4357
  */
4194
4358
  has(t) {
4195
- return I.has(t) || t in Q;
4359
+ return W.has(t) || t in oe;
4196
4360
  },
4197
4361
  /**
4198
4362
  * List all available aggregator names.
4199
4363
  */
4200
4364
  list() {
4201
- return [...Object.keys(Q), ...I.keys()];
4365
+ return [...Object.keys(oe), ...W.keys()];
4202
4366
  }
4203
- }, me = {
4367
+ }, ye = {
4204
4368
  sum: (t) => t.reduce((e, o) => e + o, 0),
4205
4369
  avg: (t) => t.length ? t.reduce((e, o) => e + o, 0) / t.length : 0,
4206
4370
  count: (t) => t.length,
@@ -4209,43 +4373,45 @@ const E = {
4209
4373
  first: (t) => t[0] ?? 0,
4210
4374
  last: (t) => t[t.length - 1] ?? 0
4211
4375
  };
4212
- function Nt(t) {
4213
- return me[t] ?? me.sum;
4376
+ function $t(t) {
4377
+ return ye[t] ?? ye.sum;
4214
4378
  }
4215
- function $t(t, e) {
4216
- return Nt(t)(e);
4379
+ function Zt(t, e) {
4380
+ return $t(t)(e);
4217
4381
  }
4218
- const Ft = P.register.bind(P), Vt = P.unregister.bind(P), Gt = P.get.bind(P), Xt = P.run.bind(P), Yt = P.list.bind(P);
4382
+ const Jt = H.register.bind(H), Qt = H.unregister.bind(H), eo = H.get.bind(H), to = H.run.bind(H), oo = H.list.bind(H);
4219
4383
  export {
4220
- It as BaseGridPlugin,
4221
- Me as DEFAULT_ANIMATION_CONFIG,
4222
- L as DEFAULT_GRID_ICONS,
4223
- Wt as DGEvents,
4224
- D as DataGridElement,
4225
- W as FitModeEnum,
4226
- Bt as GridCSSVars,
4227
- E as GridClasses,
4228
- V as GridDataAttrs,
4229
- D as GridElement,
4230
- qt as GridSelectors,
4231
- kt as PLUGIN_QUERIES,
4232
- Ut as PluginEvents,
4233
- zt as PluginManager,
4234
- S as RenderPhase,
4235
- k as a,
4236
- P as aggregatorRegistry,
4237
- tt as builtInSort,
4238
- ee as c,
4239
- et as defaultComparator,
4240
- ve as e,
4241
- ye as g,
4242
- Gt as getAggregator,
4243
- Nt as getValueAggregator,
4244
- Yt as listAggregators,
4245
- Ft as registerAggregator,
4246
- Xt as runAggregator,
4247
- $t as runValueAggregator,
4248
- G as s,
4249
- Vt as unregisterAggregator
4384
+ Ft as BaseGridPlugin,
4385
+ Ne as DEFAULT_ANIMATION_CONFIG,
4386
+ M as DEFAULT_GRID_ICONS,
4387
+ jt as DGEvents,
4388
+ P as DataGridElement,
4389
+ F as FitModeEnum,
4390
+ Gt as GridCSSVars,
4391
+ R as GridClasses,
4392
+ Y as GridDataAttrs,
4393
+ P as GridElement,
4394
+ Vt as GridSelectors,
4395
+ Ut as PLUGIN_QUERIES,
4396
+ Kt as PluginEvents,
4397
+ Wt as PluginManager,
4398
+ x as RenderPhase,
4399
+ q as a,
4400
+ H as aggregatorRegistry,
4401
+ ht as builtInSort,
4402
+ ie as c,
4403
+ Xt as createGrid,
4404
+ dt as defaultComparator,
4405
+ _e as e,
4406
+ Te as g,
4407
+ eo as getAggregator,
4408
+ $t as getValueAggregator,
4409
+ oo as listAggregators,
4410
+ Yt as queryGrid,
4411
+ Jt as registerAggregator,
4412
+ to as runAggregator,
4413
+ Zt as runValueAggregator,
4414
+ j as s,
4415
+ Qt as unregisterAggregator
4250
4416
  };
4251
4417
  //# sourceMappingURL=index.js.map