@ixfx/components 0.10.3 → 0.10.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (102) hide show
  1. package/bundle/index.d.ts +106 -28
  2. package/bundle/index.d.ts.map +1 -1
  3. package/bundle/index.js +335 -22
  4. package/bundle/index.js.map +1 -1
  5. package/dist/ac-text.d.ts +1 -1
  6. package/dist/{ac-token-TCLAZeVg.d.ts → ac-token--_vCHXWw.d.ts} +2 -2
  7. package/dist/{ac-token-TCLAZeVg.d.ts.map → ac-token--_vCHXWw.d.ts.map} +1 -1
  8. package/dist/ac-token.d.ts +1 -1
  9. package/dist/{button-DsFbV4XD.js → button-B7mgqtxR.js} +36 -2
  10. package/dist/button-B7mgqtxR.js.map +1 -0
  11. package/dist/button-BYuf72aR.d.ts +63 -0
  12. package/dist/button-BYuf72aR.d.ts.map +1 -0
  13. package/dist/button.d.ts +2 -21
  14. package/dist/button.js +1 -1
  15. package/dist/colour-picker.d.ts +1 -1
  16. package/dist/crumbs.d.ts +1 -1
  17. package/dist/{data-grid-f9W2uzaR.d.ts → data-grid-DE1_gZNk.d.ts} +10 -5
  18. package/dist/data-grid-DE1_gZNk.d.ts.map +1 -0
  19. package/dist/data-grid.d.ts +2 -2
  20. package/dist/data-grid.js +56 -0
  21. package/dist/data-grid.js.map +1 -1
  22. package/dist/{detail-list-C3tozzBT.d.ts → detail-list-CaStSzYN.d.ts} +7 -5
  23. package/dist/detail-list-CaStSzYN.d.ts.map +1 -0
  24. package/dist/detail-list.d.ts +4 -3
  25. package/dist/detail-list.js +61 -1
  26. package/dist/detail-list.js.map +1 -1
  27. package/dist/{grid-list-CM1XhTaW.d.ts → grid-list-BJDxBL0x.d.ts} +3 -3
  28. package/dist/{grid-list-CM1XhTaW.d.ts.map → grid-list-BJDxBL0x.d.ts.map} +1 -1
  29. package/dist/{grid-list-WE92nfX5.js → grid-list-CaMcdpFJ.js} +22 -3
  30. package/dist/grid-list-CaMcdpFJ.js.map +1 -0
  31. package/dist/grid-list.d.ts +2 -2
  32. package/dist/grid-list.js +1 -1
  33. package/dist/{grouped-item-lister-CEZ72VOs.d.ts → grouped-item-lister-DETte0Dh.d.ts} +3 -3
  34. package/dist/{grouped-item-lister-CEZ72VOs.d.ts.map → grouped-item-lister-DETte0Dh.d.ts.map} +1 -1
  35. package/dist/grouped-item-lister.d.ts +1 -1
  36. package/dist/{icon-DR_3rSyZ.d.ts → icon-CDGprSdE.d.ts} +2 -2
  37. package/dist/icon-CDGprSdE.d.ts.map +1 -0
  38. package/dist/icons.d.ts +2 -2
  39. package/dist/incr-search.d.ts +1 -1
  40. package/dist/{index-C59-JEPl.d.ts → index-9AhaHIT2.d.ts} +3 -3
  41. package/dist/{index-C59-JEPl.d.ts.map → index-9AhaHIT2.d.ts.map} +1 -1
  42. package/dist/{index-garxxqgV.d.ts → index-CYndvTWH.d.ts} +2 -2
  43. package/dist/{index-garxxqgV.d.ts.map → index-CYndvTWH.d.ts.map} +1 -1
  44. package/dist/{index-BUB5SICW.d.ts → index-CoqtMSd9.d.ts} +2 -2
  45. package/dist/{index-BUB5SICW.d.ts.map → index-CoqtMSd9.d.ts.map} +1 -1
  46. package/dist/{index-BXafRK-_.d.ts → index-CsaQwNkz.d.ts} +2 -2
  47. package/dist/{index-BXafRK-_.d.ts.map → index-CsaQwNkz.d.ts.map} +1 -1
  48. package/dist/{index-CJ5fshD3.d.ts → index-UvnoZUAo.d.ts} +2 -2
  49. package/dist/{index-CJ5fshD3.d.ts.map → index-UvnoZUAo.d.ts.map} +1 -1
  50. package/dist/{index-BOUaDIW-.d.ts → index-tq6f8007.d.ts} +2 -2
  51. package/dist/{index-BOUaDIW-.d.ts.map → index-tq6f8007.d.ts.map} +1 -1
  52. package/dist/index.d.ts +22 -39
  53. package/dist/index.d.ts.map +1 -1
  54. package/dist/index.js +93 -14
  55. package/dist/index.js.map +1 -1
  56. package/dist/{labelled-input-base-Dp_9KP0G.d.ts → labelled-input-base-DiTme1JO.d.ts} +2 -2
  57. package/dist/{labelled-input-base-Dp_9KP0G.d.ts.map → labelled-input-base-DiTme1JO.d.ts.map} +1 -1
  58. package/dist/labelled-radial-input.d.ts +2 -2
  59. package/dist/labelled-radial-input.d.ts.map +1 -1
  60. package/dist/labelled-range-input.d.ts +1 -1
  61. package/dist/labelled-slider-input.d.ts +1 -1
  62. package/dist/{list-selection-types-B5ioL-dG.d.ts → list-selection-types-PjKdhF-a.d.ts} +1 -9
  63. package/dist/list-selection-types-PjKdhF-a.d.ts.map +1 -0
  64. package/dist/list-viewport-types-BRZsLcvp.d.ts +23 -0
  65. package/dist/list-viewport-types-BRZsLcvp.d.ts.map +1 -0
  66. package/dist/{menu-item-ZmkXNjek.d.ts → menu-item-CZi9vy5O.d.ts} +2 -2
  67. package/dist/{menu-item-ZmkXNjek.d.ts.map → menu-item-CZi9vy5O.d.ts.map} +1 -1
  68. package/dist/menu.d.ts +2 -2
  69. package/dist/miller.d.ts +1 -1
  70. package/dist/panel.d.ts +1 -1
  71. package/dist/{split-layout-C5SYbDrq.d.ts → split-layout-JK3xWVX2.d.ts} +2 -2
  72. package/dist/{split-layout-C5SYbDrq.d.ts.map → split-layout-JK3xWVX2.d.ts.map} +1 -1
  73. package/dist/split-layout.d.ts +1 -1
  74. package/dist/{tab-list-DbMIL520.d.ts → tab-list-pqfKaVAE.d.ts} +31 -2
  75. package/dist/tab-list-pqfKaVAE.d.ts.map +1 -0
  76. package/dist/tabs.d.ts +1 -1
  77. package/dist/tabs.js +24 -5
  78. package/dist/tabs.js.map +1 -1
  79. package/dist/{titlebar-B5zSTZnF.d.ts → titlebar-Tqu-VvMU.d.ts} +2 -2
  80. package/dist/{titlebar-B5zSTZnF.d.ts.map → titlebar-Tqu-VvMU.d.ts.map} +1 -1
  81. package/dist/titlebar.d.ts +1 -1
  82. package/dist/tree.d.ts +1 -1
  83. package/dist/{vertical-list-DdaYcvHQ.d.ts → vertical-list-DfcNsa4p.d.ts} +11 -3
  84. package/dist/vertical-list-DfcNsa4p.d.ts.map +1 -0
  85. package/dist/vertical-list.d.ts +4 -3
  86. package/dist/vertical-list.js +47 -1
  87. package/dist/vertical-list.js.map +1 -1
  88. package/docs-user/data-grid.md +9 -0
  89. package/docs-user/detail-list.md +8 -0
  90. package/docs-user/grid-list.md +1 -1
  91. package/docs-user/index.json +2 -2
  92. package/docs-user/vertical-list.md +7 -0
  93. package/package.json +1 -1
  94. package/dist/button-DsFbV4XD.js.map +0 -1
  95. package/dist/button.d.ts.map +0 -1
  96. package/dist/data-grid-f9W2uzaR.d.ts.map +0 -1
  97. package/dist/detail-list-C3tozzBT.d.ts.map +0 -1
  98. package/dist/grid-list-WE92nfX5.js.map +0 -1
  99. package/dist/icon-DR_3rSyZ.d.ts.map +0 -1
  100. package/dist/list-selection-types-B5ioL-dG.d.ts.map +0 -1
  101. package/dist/tab-list-DbMIL520.d.ts.map +0 -1
  102. package/dist/vertical-list-DdaYcvHQ.d.ts.map +0 -1
package/bundle/index.js CHANGED
@@ -5715,6 +5715,20 @@ const buttonStyles = i$3`
5715
5715
  :host([subtle]) button:focus-visible:not(:disabled) {
5716
5716
  background: color-mix(in oklch, var(--surface-4, #ccc) 70%, transparent);
5717
5717
  }
5718
+
5719
+ :host([toggleable]) button:not(:disabled) {
5720
+ opacity: 0.7;
5721
+ }
5722
+
5723
+ :host([toggleable]) button:hover:not(:disabled) {
5724
+ opacity: 0.85;
5725
+ }
5726
+
5727
+ :host([toggleable][value]) button:not(:disabled) {
5728
+ opacity: 1;
5729
+ outline: var(--ixfx-button-toggle-outline-width, 2px) solid var(--ixfx-button-toggle-outline-color, oklch(from var(--accent, #666) l c calc(h + 130)));
5730
+ outline-offset: var(--ixfx-button-toggle-outline-offset, 2px);
5731
+ }
5718
5732
  `;
5719
5733
  //#endregion
5720
5734
  //#region src/button/button.ts
@@ -5726,7 +5740,19 @@ let ButtonElement = class ButtonElement extends i {
5726
5740
  this.hideLabel = false;
5727
5741
  this.hasIcon = false;
5728
5742
  this.subtle = false;
5743
+ this.toggleable = false;
5744
+ this.value = false;
5745
+ this.#handleClick = () => {
5746
+ if (!this.toggleable || this.disabled) return;
5747
+ this.value = !this.value;
5748
+ this.dispatchEvent(new CustomEvent(`toggle`, {
5749
+ detail: { value: this.value },
5750
+ bubbles: true,
5751
+ composed: true
5752
+ }));
5753
+ };
5729
5754
  }
5755
+ #handleClick;
5730
5756
  _renderIcon() {
5731
5757
  if (this.hideIcon || !this.icon) return A;
5732
5758
  if (this.icon.startsWith(`<svg`)) return b`<span class="button-icon">${unsafeHTML(this.icon)}</span>`;
@@ -5736,7 +5762,7 @@ let ButtonElement = class ButtonElement extends i {
5736
5762
  render() {
5737
5763
  this.hasIcon = !this.hideIcon && !!this.icon;
5738
5764
  const label = this.hideLabel ? A : b`<span class="button-label"><slot></slot></span>`;
5739
- return b`<button ?disabled=${this.disabled}>${this._renderIcon()}${label}</button>`;
5765
+ return b`<button ?disabled=${this.disabled} @click=${this.#handleClick}>${this._renderIcon()}${label}</button>`;
5740
5766
  }
5741
5767
  static {
5742
5768
  this.styles = [prominenceStyles, buttonStyles];
@@ -5763,6 +5789,14 @@ __decorate([property({
5763
5789
  type: Boolean,
5764
5790
  reflect: true
5765
5791
  })], ButtonElement.prototype, "subtle", void 0);
5792
+ __decorate([property({
5793
+ type: Boolean,
5794
+ reflect: true
5795
+ })], ButtonElement.prototype, "toggleable", void 0);
5796
+ __decorate([property({
5797
+ type: Boolean,
5798
+ reflect: true
5799
+ })], ButtonElement.prototype, "value", void 0);
5766
5800
  ButtonElement = __decorate([safeCustomElement(`ixfx-button`)], ButtonElement);
5767
5801
  //#endregion
5768
5802
  //#region src/button/radio-group.ts
@@ -14627,6 +14661,12 @@ __decorate([query(`.text`)], PanTextElement.prototype, "_textEl", void 0);
14627
14661
  PanTextElement = __decorate([safeCustomElement(`ixfx-pan-text`)], PanTextElement);
14628
14662
  //#endregion
14629
14663
  //#region src/data-grid/data-grid.ts
14664
+ /** Shallow key-array equality, treating `undefined` (never dispatched) as different. */
14665
+ function sameKeys$3(a, b) {
14666
+ if (a === void 0 || a.length !== b.length) return false;
14667
+ for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return false;
14668
+ return true;
14669
+ }
14630
14670
  let DataGridElement = class DataGridElement extends i {
14631
14671
  constructor(..._args) {
14632
14672
  super(..._args);
@@ -14719,6 +14759,7 @@ let DataGridElement = class DataGridElement extends i {
14719
14759
  this._colOffsets = [];
14720
14760
  this._colWidthSum = 0;
14721
14761
  this._raf = 0;
14762
+ this.#viewportChangeRaf = 0;
14722
14763
  this.#appendInProgress = false;
14723
14764
  this.#resortRaf = 0;
14724
14765
  this._drag = null;
@@ -14740,6 +14781,9 @@ let DataGridElement = class DataGridElement extends i {
14740
14781
  this._scrollLeft = el.scrollLeft;
14741
14782
  if (this._headerScrollEl) this._headerScrollEl.scrollLeft = el.scrollLeft;
14742
14783
  this.requestUpdate();
14784
+ cancelAnimationFrame(this.#viewportChangeRaf);
14785
+ this.#viewportChangeRaf = 0;
14786
+ this.#emitViewportChangeIfChanged();
14743
14787
  });
14744
14788
  };
14745
14789
  this._onKeyDown = (e) => {
@@ -15173,6 +15217,10 @@ let DataGridElement = class DataGridElement extends i {
15173
15217
  #enteringRowKeys;
15174
15218
  #rowReflowTimer;
15175
15219
  #dataGridRenderedOnce;
15220
+ #viewportChangeRaf;
15221
+ /** Key sets as of the last `datagrid-viewport-change` dispatch, for dedupe. */
15222
+ #lastViewportRenderedKeys;
15223
+ #lastViewportVisibleKeys;
15176
15224
  #appendInProgress;
15177
15225
  #resortRaf;
15178
15226
  connectedCallback() {
@@ -15188,6 +15236,8 @@ let DataGridElement = class DataGridElement extends i {
15188
15236
  this.removeEventListener(`keydown`, this._onKeyDown);
15189
15237
  this.removeEventListener(`focusout`, this._onFocusOut);
15190
15238
  cancelAnimationFrame(this._raf);
15239
+ cancelAnimationFrame(this.#viewportChangeRaf);
15240
+ this.#viewportChangeRaf = 0;
15191
15241
  this.#unregisterSearchCommands?.();
15192
15242
  this.#unregisterSearchCommands = void 0;
15193
15243
  this.#searchRegistry = void 0;
@@ -15228,6 +15278,7 @@ let DataGridElement = class DataGridElement extends i {
15228
15278
  if (w === this._viewportW && h === this._viewportH) return;
15229
15279
  this._viewportW = w;
15230
15280
  this._viewportH = h;
15281
+ this.#scheduleViewportChangeEmit();
15231
15282
  }
15232
15283
  /**
15233
15284
  * Force a fresh re-measure of the viewport and re-render. Normally
@@ -15242,6 +15293,7 @@ let DataGridElement = class DataGridElement extends i {
15242
15293
  }
15243
15294
  updated(changed) {
15244
15295
  super.updated(changed);
15296
+ if (changed.has(`rows`) || changed.has(`sortState`) || changed.has(`columns`) || changed.has(`groupBy`) || changed.has(`groupLabel`) || changed.has(`filterPredicate`) || changed.has(`rowHeight`)) this.#scheduleViewportChangeEmit();
15245
15297
  if (changed.has(`_editing`) || changed.has(`_editingRow`)) requestAnimationFrame(() => {
15246
15298
  let sel = null;
15247
15299
  if (this._editing) sel = `.row[data-key="${this._editing.rowKey}"] .cell[data-col="${this._editing.colKey}"] input, .row[data-key="${this._editing.rowKey}"] .cell[data-col="${this._editing.colKey}"] select`;
@@ -16021,6 +16073,44 @@ let DataGridElement = class DataGridElement extends i {
16021
16073
  const { startRow, endRow } = this.getVisibleRange();
16022
16074
  return this._flat.slice(startRow, endRow).filter((f) => f.type === `row`).map((f) => f.key);
16023
16075
  }
16076
+ /**
16077
+ * Row keys strictly intersecting the viewport (no overscan), mirroring
16078
+ * `ixfx-grid-list.visibleKeys()` for the `datagrid-viewport-change` detail.
16079
+ */
16080
+ #visibleKeys() {
16081
+ const rh = this.rowHeight;
16082
+ const startRow = Math.max(0, Math.floor(this._scrollTop / rh));
16083
+ const endRow = Math.min(this._flat.length, Math.ceil((this._scrollTop + this._viewportH) / rh));
16084
+ return this._flat.slice(startRow, endRow).filter((f) => f.type === `row`).map((f) => f.key);
16085
+ }
16086
+ /** Coalesce viewport-change dispatches to at most one per animation frame. */
16087
+ #scheduleViewportChangeEmit() {
16088
+ if (this.#viewportChangeRaf !== 0) return;
16089
+ this.#viewportChangeRaf = requestAnimationFrame(() => {
16090
+ this.#viewportChangeRaf = 0;
16091
+ this.#emitViewportChangeIfChanged();
16092
+ });
16093
+ }
16094
+ /**
16095
+ * Dispatch `datagrid-viewport-change` with the current key sets — unless
16096
+ * neither set changed since the last dispatch, so coalesced frames and
16097
+ * no-op scrolls stay silent.
16098
+ */
16099
+ #emitViewportChangeIfChanged() {
16100
+ const renderedKeys = this.renderedKeys();
16101
+ const visibleKeys = this.#visibleKeys();
16102
+ if (sameKeys$3(this.#lastViewportRenderedKeys, renderedKeys) && sameKeys$3(this.#lastViewportVisibleKeys, visibleKeys)) return;
16103
+ this.#lastViewportRenderedKeys = renderedKeys;
16104
+ this.#lastViewportVisibleKeys = visibleKeys;
16105
+ this.dispatchEvent(new CustomEvent(`datagrid-viewport-change`, {
16106
+ detail: {
16107
+ renderedKeys,
16108
+ visibleKeys
16109
+ },
16110
+ bubbles: true,
16111
+ composed: true
16112
+ }));
16113
+ }
16024
16114
  _findFirstVisibleCol(scrollLeft) {
16025
16115
  let lo = 0;
16026
16116
  let hi = this._colOffsets.length - 1;
@@ -16619,6 +16709,12 @@ DataTableElement = __decorate([safeCustomElement(`ixfx-data-table`)], DataTableE
16619
16709
  const ITEM_SELECTOR$3 = `:scope > li`;
16620
16710
  const SEARCH_HIGHLIGHT_KEY = `detail-list-search`;
16621
16711
  const LABEL_SPAN_CSS = `overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0`;
16712
+ /** Shallow key-array equality, treating `undefined` (never dispatched) as different. */
16713
+ function sameKeys$2(a, b) {
16714
+ if (a === void 0 || a.length !== b.length) return false;
16715
+ for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return false;
16716
+ return true;
16717
+ }
16622
16718
  let DetailListElement = class DetailListElement extends i {
16623
16719
  constructor(..._args) {
16624
16720
  super(..._args);
@@ -16637,6 +16733,7 @@ let DetailListElement = class DetailListElement extends i {
16637
16733
  this.#positions = /* @__PURE__ */ new Map();
16638
16734
  this.#geometryScheduled = false;
16639
16735
  this.#sortRaf = 0;
16736
+ this.#viewportScrollRaf = 0;
16640
16737
  this.#animatedItems = /* @__PURE__ */ new WeakSet();
16641
16738
  this.#builtFromProvider = [];
16642
16739
  this.#providerBuilt = 0;
@@ -16730,6 +16827,13 @@ let DetailListElement = class DetailListElement extends i {
16730
16827
  getLabel: (el) => el.getAttribute(`data-search-label`) ?? el.textContent?.trim() ?? ``,
16731
16828
  highlightKey: SEARCH_HIGHLIGHT_KEY
16732
16829
  }) });
16830
+ this.#onListScroll = () => {
16831
+ if (this.#viewportScrollRaf !== 0) return;
16832
+ this.#viewportScrollRaf = requestAnimationFrame(() => {
16833
+ this.#viewportScrollRaf = 0;
16834
+ this.#emitViewportChangeIfChanged();
16835
+ });
16836
+ };
16733
16837
  this._onPointerOver = (e) => {
16734
16838
  const item = this._findListItem(e.composedPath());
16735
16839
  if (item) this.tickled.handlePointerEnter(item);
@@ -16821,6 +16925,10 @@ let DetailListElement = class DetailListElement extends i {
16821
16925
  #positions;
16822
16926
  #geometryScheduled;
16823
16927
  #sortRaf;
16928
+ #viewportScrollRaf;
16929
+ /** Key sets as of the last viewport-change dispatch, for dedupe. */
16930
+ #lastViewportRenderedKeys;
16931
+ #lastViewportVisibleKeys;
16824
16932
  #resizeObserver;
16825
16933
  #mutationObserver;
16826
16934
  /** Items that have already played (or been skipped for) their enter animation. */
@@ -16960,6 +17068,8 @@ let DetailListElement = class DetailListElement extends i {
16960
17068
  this.removeEventListener(`dblclick`, this._onDblClick);
16961
17069
  this.removeEventListener(`wheel`, this._onWheel);
16962
17070
  cancelAnimationFrame(this.#sortRaf);
17071
+ cancelAnimationFrame(this.#viewportScrollRaf);
17072
+ this.#viewportScrollRaf = 0;
16963
17073
  this.#resizeObserver?.disconnect();
16964
17074
  this.#resizeObserver = void 0;
16965
17075
  this.#mutationObserver?.disconnect();
@@ -17312,6 +17422,7 @@ let DetailListElement = class DetailListElement extends i {
17312
17422
  col: colIdx,
17313
17423
  row: rowIdx
17314
17424
  })));
17425
+ this.#scheduleViewportChangeEmit();
17315
17426
  }
17316
17427
  #positionOf(el) {
17317
17428
  let pos = this.#positions.get(el);
@@ -17603,6 +17714,45 @@ let DetailListElement = class DetailListElement extends i {
17603
17714
  cancelable: true
17604
17715
  }));
17605
17716
  }
17717
+ /** Scroll on the `part="list"` element — rAF-coalesced viewport-change check. */
17718
+ #onListScroll;
17719
+ /** Coalesce non-scroll viewport checks to at most one per animation frame. */
17720
+ #scheduleViewportChangeEmit() {
17721
+ if (this.#viewportScrollRaf !== 0) return;
17722
+ this.#viewportScrollRaf = requestAnimationFrame(() => {
17723
+ this.#viewportScrollRaf = 0;
17724
+ this.#emitViewportChangeIfChanged();
17725
+ });
17726
+ }
17727
+ /**
17728
+ * Keys of everything currently rendered. The list has no virtual window —
17729
+ * every non-hidden item is in the DOM — so this is all keyed items, mirroring
17730
+ * `ixfx-vertical-list.renderedKeys()` in its non-virtualized mode.
17731
+ */
17732
+ #renderedKeys() {
17733
+ const out = [];
17734
+ for (const el of this._getVisibleItems()) {
17735
+ const key = keyForElement(el);
17736
+ if (key !== void 0) out.push(key);
17737
+ }
17738
+ return out;
17739
+ }
17740
+ /**
17741
+ * Dispatch `detail-list-viewport-change` with the current key sets — unless
17742
+ * neither set changed since the last dispatch, so coalesced frames and
17743
+ * no-op scrolls stay silent.
17744
+ */
17745
+ #emitViewportChangeIfChanged() {
17746
+ const renderedKeys = this.#renderedKeys();
17747
+ const visibleKeys = this.visibleKeys();
17748
+ if (sameKeys$2(this.#lastViewportRenderedKeys, renderedKeys) && sameKeys$2(this.#lastViewportVisibleKeys, visibleKeys)) return;
17749
+ this.#lastViewportRenderedKeys = renderedKeys;
17750
+ this.#lastViewportVisibleKeys = visibleKeys;
17751
+ this._dispatch(`detail-list-viewport-change`, {
17752
+ renderedKeys,
17753
+ visibleKeys
17754
+ });
17755
+ }
17606
17756
  _activateItem(item) {
17607
17757
  if (this.interactionMode !== `manual`) this.selection.replace(item);
17608
17758
  this._dispatch(`list-activate`, { item });
@@ -17761,7 +17911,7 @@ let DetailListElement = class DetailListElement extends i {
17761
17911
  const progress = this.#data.progress;
17762
17912
  return b`
17763
17913
  <div class="container">
17764
- <ul part="list" class="scroll-fade-x">
17914
+ <ul part="list" class="scroll-fade-x" @scroll=${this.#onListScroll}>
17765
17915
  <slot></slot>
17766
17916
  </ul>
17767
17917
  ${this.#marqueeRect ? b`<div class="marquee" part="marquee" style=${this.#marqueeStyle(this.#marqueeRect)}></div>` : ``}
@@ -19573,6 +19723,7 @@ let TabListElement = class TabListElement extends i {
19573
19723
  this.flip = false;
19574
19724
  this.scrollable = false;
19575
19725
  this.hideLabels = false;
19726
+ this.labelNogrow = false;
19576
19727
  this.shrink = false;
19577
19728
  this.dragMode = `off`;
19578
19729
  this.#items = [];
@@ -19580,9 +19731,10 @@ let TabListElement = class TabListElement extends i {
19580
19731
  this.#suppressNextClick = false;
19581
19732
  this.#onSlotChange = () => {
19582
19733
  this.updateComplete.then(() => {
19583
- this.#items = (this.shadowRoot?.querySelector(`slot:not([name])`))?.assignedElements({ flatten: true }) ?? [];
19734
+ this.#refreshItems();
19584
19735
  this.#syncIndicatorColors();
19585
19736
  this.#syncHideLabels();
19737
+ this.#syncLabelNogrow();
19586
19738
  });
19587
19739
  };
19588
19740
  this.#onToolbarSlotChange = () => {
@@ -19741,13 +19893,21 @@ let TabListElement = class TabListElement extends i {
19741
19893
  </div>`;
19742
19894
  }
19743
19895
  #onSlotChange;
19896
+ /**
19897
+ * Re-read the assigned tab items. Some environments do not fire slotchange
19898
+ * for a slot's initial assignment, so firstUpdated also calls this before
19899
+ * syncing item attributes.
19900
+ */
19901
+ #refreshItems() {
19902
+ this.#items = (this.shadowRoot?.querySelector(`slot:not([name])`))?.assignedElements({ flatten: true }) ?? [];
19903
+ }
19744
19904
  #onToolbarSlotChange;
19745
19905
  firstUpdated() {
19746
19906
  this.updateComplete.then(() => {
19747
- if (this.#items.length > 0) {
19748
- this.#syncIndicatorColors();
19749
- this.#syncHideLabels();
19750
- }
19907
+ this.#refreshItems();
19908
+ this.#syncIndicatorColors();
19909
+ this.#syncHideLabels();
19910
+ this.#syncLabelNogrow();
19751
19911
  this.#onToolbarSlotChange();
19752
19912
  });
19753
19913
  }
@@ -19756,11 +19916,16 @@ let TabListElement = class TabListElement extends i {
19756
19916
  this.classList.toggle(`scrollable`, this.scrollable);
19757
19917
  if (changedProperties.has(`dragMode`)) this.toggleAttribute(`drag-mode`, this.dragMode !== `off`);
19758
19918
  if (changedProperties.has(`hideLabels`)) this.#syncHideLabels();
19919
+ if (changedProperties.has(`labelNogrow`)) this.#syncLabelNogrow();
19759
19920
  }
19760
19921
  #syncHideLabels() {
19761
19922
  for (const item of this.#items) if (this.hideLabels) item.setAttribute(`hide-labels`, ``);
19762
19923
  else item.removeAttribute(`hide-labels`);
19763
19924
  }
19925
+ #syncLabelNogrow() {
19926
+ for (const item of this.#items) if (this.labelNogrow) item.setAttribute(`label-nogrow`, ``);
19927
+ else item.removeAttribute(`label-nogrow`);
19928
+ }
19764
19929
  #syncIndicatorColors() {
19765
19930
  for (const item of this.#items) {
19766
19931
  item.style.setProperty(`--indicator-color-bottom`, `transparent`);
@@ -20179,6 +20344,10 @@ __decorate([property({
20179
20344
  type: Boolean,
20180
20345
  attribute: `hide-labels`
20181
20346
  })], TabListElement.prototype, "hideLabels", void 0);
20347
+ __decorate([property({
20348
+ type: Boolean,
20349
+ attribute: `label-nogrow`
20350
+ })], TabListElement.prototype, "labelNogrow", void 0);
20182
20351
  __decorate([property({
20183
20352
  type: Boolean,
20184
20353
  reflect: true
@@ -20195,16 +20364,21 @@ let TabListItemElement = class TabListItemElement extends i {
20195
20364
  super(..._args);
20196
20365
  this.closeable = false;
20197
20366
  this.hideLabels = false;
20367
+ this.labelNogrow = false;
20198
20368
  this.iconName = void 0;
20199
20369
  this.description = void 0;
20200
20370
  this.commandActive = void 0;
20201
20371
  this.registry = void 0;
20202
20372
  this._compact = false;
20203
20373
  this._hasToolbarContent = false;
20374
+ this._hasStatusContent = false;
20204
20375
  this._labelObserver = null;
20205
20376
  this._onToolbarSlotChange = () => {
20206
20377
  this._updateToolbarContent();
20207
20378
  };
20379
+ this._onStatusSlotChange = () => {
20380
+ this._updateStatusContent();
20381
+ };
20208
20382
  this._onLabelSlotChange = () => {
20209
20383
  this._syncLabelSizer();
20210
20384
  };
@@ -20215,13 +20389,18 @@ let TabListItemElement = class TabListItemElement extends i {
20215
20389
  this._compact = entry.contentRect.width < 64;
20216
20390
  });
20217
20391
  this._resizeObserver.observe(this);
20218
- (this.shadowRoot?.querySelector(`slot[name="toolbar"]`))?.addEventListener(`slotchange`, this._onToolbarSlotChange);
20219
- (this.shadowRoot?.querySelector(`slot:not([name])`))?.addEventListener(`slotchange`, this._onLabelSlotChange);
20220
- this._labelObserver = new MutationObserver(() => this._syncLabelSizer());
20392
+ this._wireSlotListeners();
20393
+ this._labelObserver = new MutationObserver(() => {
20394
+ this._syncLabelSizer();
20395
+ this._updateToolbarContent();
20396
+ this._updateStatusContent();
20397
+ });
20221
20398
  this._labelObserver.observe(this, {
20222
20399
  childList: true,
20223
20400
  characterData: true,
20224
- subtree: true
20401
+ subtree: true,
20402
+ attributes: true,
20403
+ attributeFilter: [`slot`]
20225
20404
  });
20226
20405
  }
20227
20406
  disconnectedCallback() {
@@ -20232,8 +20411,7 @@ let TabListItemElement = class TabListItemElement extends i {
20232
20411
  this._commandCleanup = void 0;
20233
20412
  this._labelObserver?.disconnect();
20234
20413
  this._labelObserver = null;
20235
- (this.shadowRoot?.querySelector(`slot[name="toolbar"]`))?.removeEventListener(`slotchange`, this._onToolbarSlotChange);
20236
- (this.shadowRoot?.querySelector(`slot:not([name])`))?.removeEventListener(`slotchange`, this._onLabelSlotChange);
20414
+ this._unwireSlotListeners();
20237
20415
  }
20238
20416
  updated(changed) {
20239
20417
  super.updated(changed);
@@ -20257,6 +20435,22 @@ let TabListItemElement = class TabListItemElement extends i {
20257
20435
  });
20258
20436
  }
20259
20437
  /**
20438
+ * Attach slotchange listeners. The shadow root is empty during the first
20439
+ * connectedCallback (the template only exists once rendered), so this is
20440
+ * called again from firstUpdated. addEventListener dedupes identical
20441
+ * listener registrations, so double-wiring is harmless.
20442
+ */
20443
+ _wireSlotListeners() {
20444
+ (this.shadowRoot?.querySelector(`slot[name="toolbar"]`))?.addEventListener(`slotchange`, this._onToolbarSlotChange);
20445
+ (this.shadowRoot?.querySelector(`slot[name="status"]`))?.addEventListener(`slotchange`, this._onStatusSlotChange);
20446
+ (this.shadowRoot?.querySelector(`slot:not([name])`))?.addEventListener(`slotchange`, this._onLabelSlotChange);
20447
+ }
20448
+ _unwireSlotListeners() {
20449
+ (this.shadowRoot?.querySelector(`slot[name="toolbar"]`))?.removeEventListener(`slotchange`, this._onToolbarSlotChange);
20450
+ (this.shadowRoot?.querySelector(`slot[name="status"]`))?.removeEventListener(`slotchange`, this._onStatusSlotChange);
20451
+ (this.shadowRoot?.querySelector(`slot:not([name])`))?.removeEventListener(`slotchange`, this._onLabelSlotChange);
20452
+ }
20453
+ /**
20260
20454
  * Mirror the default-slot text into `.label[data-label]` for the `::after`
20261
20455
  * width sizer. Slotted toolbar content is excluded.
20262
20456
  */
@@ -20269,11 +20463,20 @@ let TabListItemElement = class TabListItemElement extends i {
20269
20463
  else label.removeAttribute(`data-label`);
20270
20464
  }
20271
20465
  _updateToolbarContent() {
20272
- const slot = this.shadowRoot?.querySelector(`slot[name="toolbar"]`);
20273
- this._hasToolbarContent = (slot?.assignedElements().length ?? 0) > 0;
20466
+ this._hasToolbarContent = Array.from(this.children).some((child) => child.getAttribute(`slot`) === `toolbar`);
20467
+ }
20468
+ /**
20469
+ * Named slots only render once content has been detected, so reading
20470
+ * assignedElements() cannot bootstrap detection. Direct light-DOM children
20471
+ * are exactly what a slot assigns, so scan those instead.
20472
+ */
20473
+ _updateStatusContent() {
20474
+ this._hasStatusContent = Array.from(this.children).some((child) => child.getAttribute(`slot`) === `status`);
20274
20475
  }
20275
20476
  firstUpdated() {
20477
+ this._wireSlotListeners();
20276
20478
  this._updateToolbarContent();
20479
+ this._updateStatusContent();
20277
20480
  this._syncLabelSizer();
20278
20481
  }
20279
20482
  render() {
@@ -20283,6 +20486,7 @@ let TabListItemElement = class TabListItemElement extends i {
20283
20486
  <div>
20284
20487
  ${this.iconName ? b`<ixfx-icon name="${this.iconName}"></ixfx-icon>` : A}
20285
20488
  ${showLabel ? b`<span class="label"><slot></slot></span>` : A}
20489
+ ${this._hasStatusContent ? b`<div class="status"><slot name="status"></slot></div>` : A}
20286
20490
  ${hasActions ? b`
20287
20491
  <div class="actions">
20288
20492
  <div class="toolbar"><slot name="toolbar"></slot></div>
@@ -20435,6 +20639,28 @@ let TabListItemElement = class TabListItemElement extends i {
20435
20639
  display: contents;
20436
20640
  }
20437
20641
 
20642
+ /* Persistent status slot (e.g. an ixfx-led). Unlike .toolbar it is
20643
+ always visible, selection or not, and keeps its own size however
20644
+ much the label truncates. --size inherits through slotted content,
20645
+ so bare and button-wrapped LEDs both render smaller; consumers can
20646
+ override per element. */
20647
+ .status {
20648
+ display: flex;
20649
+ align-items: center;
20650
+ flex-shrink: 0;
20651
+ --size: 0.75ex;
20652
+ }
20653
+
20654
+ slot[name="status"] {
20655
+ display: contents;
20656
+ }
20657
+
20658
+ /* With label-nogrow, the label keeps its intrinsic width so status
20659
+ content lands next to the label text instead of the far edge. */
20660
+ :host([label-nogrow]) .label {
20661
+ flex: 0 0 auto;
20662
+ }
20663
+
20438
20664
  /* Slotted buttons inherit these through the shadow boundary; keeps a
20439
20665
  toolbar button from inflating the strip height. */
20440
20666
  .toolbar ::slotted(ixfx-button) {
@@ -20478,6 +20704,10 @@ __decorate([property({
20478
20704
  type: Boolean,
20479
20705
  attribute: `hide-labels`
20480
20706
  })], TabListItemElement.prototype, "hideLabels", void 0);
20707
+ __decorate([property({
20708
+ type: Boolean,
20709
+ attribute: `label-nogrow`
20710
+ })], TabListItemElement.prototype, "labelNogrow", void 0);
20481
20711
  __decorate([property({
20482
20712
  type: String,
20483
20713
  attribute: `icon-name`
@@ -20490,6 +20720,7 @@ __decorate([property({
20490
20720
  __decorate([property({ attribute: false })], TabListItemElement.prototype, "registry", void 0);
20491
20721
  __decorate([state()], TabListItemElement.prototype, "_compact", void 0);
20492
20722
  __decorate([state()], TabListItemElement.prototype, "_hasToolbarContent", void 0);
20723
+ __decorate([state()], TabListItemElement.prototype, "_hasStatusContent", void 0);
20493
20724
  TabListItemElement = __decorate([safeCustomElement(`ixfx-tab-list-item`)], TabListItemElement);
20494
20725
  //#endregion
20495
20726
  //#region src/dock/dock-panel.ts
@@ -23629,6 +23860,12 @@ function columnOf(index, cols) {
23629
23860
  function rowOf(index, cols) {
23630
23861
  return cols <= 1 ? index : Math.floor(index / cols);
23631
23862
  }
23863
+ /** Shallow key-array equality, treating `undefined` (never dispatched) as different. */
23864
+ function sameKeys$1(a, b) {
23865
+ if (a === void 0 || a.length !== b.length) return false;
23866
+ for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return false;
23867
+ return true;
23868
+ }
23632
23869
  let GridListElement = class GridListElement extends i {
23633
23870
  constructor(..._args) {
23634
23871
  super(..._args);
@@ -24523,10 +24760,23 @@ let GridListElement = class GridListElement extends i {
24523
24760
  this.requestUpdate();
24524
24761
  }, REFLOW_WINDOW_MS);
24525
24762
  }
24763
+ /** Key sets as of the last `grid-list-viewport-change` dispatch, for dedupe. */
24764
+ #lastViewportRenderedKeys;
24765
+ #lastViewportVisibleKeys;
24766
+ /**
24767
+ * Dispatch `grid-list-viewport-change` with the current key sets — unless
24768
+ * neither set changed since the last dispatch, so coalesced frames and
24769
+ * no-op scrolls stay silent.
24770
+ */
24526
24771
  #emitViewportChange() {
24772
+ const renderedKeys = this.renderedKeys();
24773
+ const visibleKeys = this.visibleKeys();
24774
+ if (sameKeys$1(this.#lastViewportRenderedKeys, renderedKeys) && sameKeys$1(this.#lastViewportVisibleKeys, visibleKeys)) return;
24775
+ this.#lastViewportRenderedKeys = renderedKeys;
24776
+ this.#lastViewportVisibleKeys = visibleKeys;
24527
24777
  this._dispatch(`grid-list-viewport-change`, {
24528
- renderedKeys: this.renderedKeys(),
24529
- visibleKeys: this.visibleKeys()
24778
+ renderedKeys,
24779
+ visibleKeys
24530
24780
  });
24531
24781
  }
24532
24782
  firstUpdated() {
@@ -28257,6 +28507,12 @@ const ITEM_SELECTOR = `li:not([data-virtual-spacer]), [data-list-item]:not([data
28257
28507
  * vertical rows are shorter relative to the viewport, so 3.
28258
28508
  */
28259
28509
  const VIRTUAL_OVERSCAN = 3;
28510
+ /** Shallow key-array equality, treating `undefined` (never dispatched) as different. */
28511
+ function sameKeys(a, b) {
28512
+ if (a === void 0 || a.length !== b.length) return false;
28513
+ for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return false;
28514
+ return true;
28515
+ }
28260
28516
  let VerticalListElement = class VerticalListElement extends i {
28261
28517
  constructor(..._args) {
28262
28518
  super(..._args);
@@ -28371,11 +28627,11 @@ let VerticalListElement = class VerticalListElement extends i {
28371
28627
  highlightKey: `vertical-list-search`
28372
28628
  }) });
28373
28629
  this.#onScroll = () => {
28374
- if (!this.#virtualActive()) return;
28375
28630
  if (this.#scrollRaf !== 0) return;
28376
28631
  this.#scrollRaf = requestAnimationFrame(() => {
28377
28632
  this.#scrollRaf = 0;
28378
28633
  this.#syncVirtualWindow();
28634
+ this.#emitViewportChangeIfChanged();
28379
28635
  });
28380
28636
  };
28381
28637
  this._onPointerOver = (e) => {
@@ -28468,6 +28724,9 @@ let VerticalListElement = class VerticalListElement extends i {
28468
28724
  #suspendAdapterRebuild;
28469
28725
  #scrollRaf;
28470
28726
  #resizeObserver;
28727
+ /** Key sets as of the last viewport-change dispatch, for dedupe. */
28728
+ #lastViewportRenderedKeys;
28729
+ #lastViewportVisibleKeys;
28471
28730
  #topSpacer;
28472
28731
  #bottomSpacer;
28473
28732
  /** Last measured viewport height — kept so a 0 read can't collapse the window. */
@@ -28595,6 +28854,14 @@ let VerticalListElement = class VerticalListElement extends i {
28595
28854
  }
28596
28855
  }
28597
28856
  /**
28857
+ * The shadow scroll list only exists after the first render; start
28858
+ * watching it so resizes move the window (virtualized) and the visible
28859
+ * set (plain) too.
28860
+ */
28861
+ firstUpdated() {
28862
+ this.#ensureResizeObserved();
28863
+ }
28864
+ /**
28598
28865
  * Animate in items appended to the light DOM (however they got there —
28599
28866
  * {@link addItem}, direct `appendChild`, a framework binding). A bulk populate
28600
28867
  * (roughly everything at once) is left alone, as are the wrapper `<li>`s the
@@ -28604,6 +28871,7 @@ let VerticalListElement = class VerticalListElement extends i {
28604
28871
  if (!this.isConnected) return;
28605
28872
  if (this.#virtualActive()) {
28606
28873
  this.#syncVirtualWindow(this.#reconcileRecords(records));
28874
+ this.#scheduleViewportChangeEmit();
28607
28875
  return;
28608
28876
  }
28609
28877
  const fresh = [];
@@ -28614,6 +28882,7 @@ let VerticalListElement = class VerticalListElement extends i {
28614
28882
  this.#animatedItems.add(node);
28615
28883
  fresh.push(node);
28616
28884
  }
28885
+ this.#scheduleViewportChangeEmit();
28617
28886
  if (fresh.length === 0) return;
28618
28887
  if (this.#isBulkPopulate(fresh.length)) return;
28619
28888
  for (const el of fresh) animateListItemIn(el);
@@ -29167,6 +29436,7 @@ let VerticalListElement = class VerticalListElement extends i {
29167
29436
  if (!ul) return;
29168
29437
  this.#resizeObserver ??= new ResizeObserver(() => {
29169
29438
  this.#syncVirtualWindow();
29439
+ this.#scheduleViewportChangeEmit();
29170
29440
  });
29171
29441
  this.#resizeObserver.observe(ul);
29172
29442
  }
@@ -29246,6 +29516,32 @@ let VerticalListElement = class VerticalListElement extends i {
29246
29516
  this._syncItemStates();
29247
29517
  this._syncNativeDraggable();
29248
29518
  this.#nativeDrag.refreshDraggable();
29519
+ this.#scheduleViewportChangeEmit();
29520
+ }
29521
+ /** Coalesce content/layout viewport checks to at most one animation frame. */
29522
+ #scheduleViewportChangeEmit() {
29523
+ if (this.#scrollRaf !== 0) return;
29524
+ this.#scrollRaf = requestAnimationFrame(() => {
29525
+ this.#scrollRaf = 0;
29526
+ this.#syncVirtualWindow();
29527
+ this.#emitViewportChangeIfChanged();
29528
+ });
29529
+ }
29530
+ /**
29531
+ * Dispatch `vertical-list-viewport-change` with the current key sets — unless
29532
+ * neither set changed since the last dispatch, so coalesced frames and
29533
+ * no-op scrolls stay silent.
29534
+ */
29535
+ #emitViewportChangeIfChanged() {
29536
+ const renderedKeys = this.renderedKeys();
29537
+ const visibleKeys = this.visibleKeys();
29538
+ if (sameKeys(this.#lastViewportRenderedKeys, renderedKeys) && sameKeys(this.#lastViewportVisibleKeys, visibleKeys)) return;
29539
+ this.#lastViewportRenderedKeys = renderedKeys;
29540
+ this.#lastViewportVisibleKeys = visibleKeys;
29541
+ this._dispatch(`vertical-list-viewport-change`, {
29542
+ renderedKeys,
29543
+ visibleKeys
29544
+ });
29249
29545
  }
29250
29546
  _getVisibleItems() {
29251
29547
  return Array.from(this.querySelectorAll(ITEM_SELECTOR)).filter((el) => {
@@ -46598,6 +46894,7 @@ let ToolbarElement = class ToolbarElement extends i {
46598
46894
  this.invisibleGroups = false;
46599
46895
  this.allowReorder = false;
46600
46896
  this._overflowCount = 0;
46897
+ this._popoverOpen = false;
46601
46898
  this._ro = null;
46602
46899
  this._anchor = `--toolbar-${_ToolbarElement._cnt++}`;
46603
46900
  this._sizes = /* @__PURE__ */ new WeakMap();
@@ -46723,11 +47020,11 @@ let ToolbarElement = class ToolbarElement extends i {
46723
47020
  .overflow-btn[hidden] { display: none; }
46724
47021
  .overflow-popover {
46725
47022
  position: fixed;
46726
- top: anchor(bottom);
46727
- left: anchor(right);
47023
+ inset: auto;
47024
+ margin: 0;
46728
47025
  position-anchor: var(--anchor-name);
46729
47026
  position-try-fallbacks: flip-block, flip-inline, flip-block flip-inline;
46730
- margin: 8px;
47027
+ position-visibility: anchors-visible;
46731
47028
  max-height: min(60vh, 400px);
46732
47029
  max-width: min(90vw, 320px);
46733
47030
  overflow: auto;
@@ -46737,6 +47034,18 @@ let ToolbarElement = class ToolbarElement extends i {
46737
47034
  flex-direction: column;
46738
47035
  gap: var(--space-s);
46739
47036
  }
47037
+ :host([orientation="horizontal"]) .overflow-popover {
47038
+ position-area: bottom span-left;
47039
+ margin-top: var(--toolbar-overflow-gap, 8px);
47040
+ }
47041
+ :host([orientation="vertical-left"]) .overflow-popover {
47042
+ position-area: right span-bottom;
47043
+ margin-left: var(--toolbar-overflow-gap, 8px);
47044
+ }
47045
+ :host([orientation="vertical-right"]) .overflow-popover {
47046
+ position-area: left span-bottom;
47047
+ margin-right: var(--toolbar-overflow-gap, 8px);
47048
+ }
46740
47049
  .overflow-popover:popover-open { display: flex; }
46741
47050
  .overflow-popover ::slotted(*) { writing-mode: horizontal-tb; text-orientation: mixed; }
46742
47051
 
@@ -46775,6 +47084,9 @@ let ToolbarElement = class ToolbarElement extends i {
46775
47084
  });
46776
47085
  this._ro = new ResizeObserver(() => this._scheduleMeasure());
46777
47086
  this._ro.observe(this._inner);
47087
+ this._popover.addEventListener(`toggle`, () => {
47088
+ this._popoverOpen = this._popover.matches(`:popover-open`);
47089
+ });
46778
47090
  this._scheduleMeasure();
46779
47091
  this._updateGroups();
46780
47092
  }
@@ -47115,7 +47427,7 @@ let ToolbarElement = class ToolbarElement extends i {
47115
47427
  return b`
47116
47428
  <div class="inner" role="toolbar" aria-orientation=${this.orientation}>
47117
47429
  <slot @pointerdown=${this._onPointerDown} @keydown=${this._onKeyDown}></slot>
47118
- <ixfx-button class="overflow-btn" ?hidden=${!hasOverflow} @click=${this._toggleOverflow} aria-label="More" aria-haspopup="true" aria-expanded=${this._popover?.matches(`:popover-open`) ?? false}>⋯</ixfx-button>
47430
+ <ixfx-button class="overflow-btn" ?hidden=${!hasOverflow} @click=${this._toggleOverflow} aria-label="More" aria-haspopup="true" aria-expanded=${this._popoverOpen}>⋯</ixfx-button>
47119
47431
  </div>
47120
47432
  <div class="overflow-popover popup-surface" popover="auto" @click=${(e) => e.stopPropagation()}>
47121
47433
  <slot name="overflow"></slot>
@@ -47158,6 +47470,7 @@ __decorate([property({
47158
47470
  reflect: true
47159
47471
  })], ToolbarElement.prototype, "allowReorder", void 0);
47160
47472
  __decorate([state()], ToolbarElement.prototype, "_overflowCount", void 0);
47473
+ __decorate([state()], ToolbarElement.prototype, "_popoverOpen", void 0);
47161
47474
  __decorate([query(`.inner`)], ToolbarElement.prototype, "_inner", void 0);
47162
47475
  __decorate([query(`.overflow-popover`)], ToolbarElement.prototype, "_popover", void 0);
47163
47476
  __decorate([query(`slot`)], ToolbarElement.prototype, "_slot", void 0);