@ixfx/components 0.10.3 → 0.10.4
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.
- package/bundle/index.d.ts +76 -28
- package/bundle/index.d.ts.map +1 -1
- package/bundle/index.js +220 -5
- package/bundle/index.js.map +1 -1
- package/dist/ac-text.d.ts +1 -1
- package/dist/{ac-token-TCLAZeVg.d.ts → ac-token--_vCHXWw.d.ts} +2 -2
- package/dist/{ac-token-TCLAZeVg.d.ts.map → ac-token--_vCHXWw.d.ts.map} +1 -1
- package/dist/ac-token.d.ts +1 -1
- package/dist/{button-DsFbV4XD.js → button-B7mgqtxR.js} +36 -2
- package/dist/button-B7mgqtxR.js.map +1 -0
- package/dist/button-BYuf72aR.d.ts +63 -0
- package/dist/button-BYuf72aR.d.ts.map +1 -0
- package/dist/button.d.ts +2 -21
- package/dist/button.js +1 -1
- package/dist/colour-picker.d.ts +1 -1
- package/dist/crumbs.d.ts +1 -1
- package/dist/{data-grid-f9W2uzaR.d.ts → data-grid-DE1_gZNk.d.ts} +10 -5
- package/dist/data-grid-DE1_gZNk.d.ts.map +1 -0
- package/dist/data-grid.d.ts +2 -2
- package/dist/data-grid.js +56 -0
- package/dist/data-grid.js.map +1 -1
- package/dist/{detail-list-C3tozzBT.d.ts → detail-list-CaStSzYN.d.ts} +7 -5
- package/dist/detail-list-CaStSzYN.d.ts.map +1 -0
- package/dist/detail-list.d.ts +4 -3
- package/dist/detail-list.js +61 -1
- package/dist/detail-list.js.map +1 -1
- package/dist/{grid-list-CM1XhTaW.d.ts → grid-list-BJDxBL0x.d.ts} +3 -3
- package/dist/{grid-list-CM1XhTaW.d.ts.map → grid-list-BJDxBL0x.d.ts.map} +1 -1
- package/dist/{grid-list-WE92nfX5.js → grid-list-CaMcdpFJ.js} +22 -3
- package/dist/grid-list-CaMcdpFJ.js.map +1 -0
- package/dist/grid-list.d.ts +2 -2
- package/dist/grid-list.js +1 -1
- package/dist/{grouped-item-lister-CEZ72VOs.d.ts → grouped-item-lister-DETte0Dh.d.ts} +3 -3
- package/dist/{grouped-item-lister-CEZ72VOs.d.ts.map → grouped-item-lister-DETte0Dh.d.ts.map} +1 -1
- package/dist/grouped-item-lister.d.ts +1 -1
- package/dist/{icon-DR_3rSyZ.d.ts → icon-CDGprSdE.d.ts} +2 -2
- package/dist/icon-CDGprSdE.d.ts.map +1 -0
- package/dist/icons.d.ts +2 -2
- package/dist/incr-search.d.ts +1 -1
- package/dist/{index-C59-JEPl.d.ts → index-9AhaHIT2.d.ts} +3 -3
- package/dist/{index-C59-JEPl.d.ts.map → index-9AhaHIT2.d.ts.map} +1 -1
- package/dist/{index-garxxqgV.d.ts → index-CYndvTWH.d.ts} +2 -2
- package/dist/{index-garxxqgV.d.ts.map → index-CYndvTWH.d.ts.map} +1 -1
- package/dist/{index-BUB5SICW.d.ts → index-CoqtMSd9.d.ts} +2 -2
- package/dist/{index-BUB5SICW.d.ts.map → index-CoqtMSd9.d.ts.map} +1 -1
- package/dist/{index-BXafRK-_.d.ts → index-CsaQwNkz.d.ts} +2 -2
- package/dist/{index-BXafRK-_.d.ts.map → index-CsaQwNkz.d.ts.map} +1 -1
- package/dist/{index-CJ5fshD3.d.ts → index-UvnoZUAo.d.ts} +2 -2
- package/dist/{index-CJ5fshD3.d.ts.map → index-UvnoZUAo.d.ts.map} +1 -1
- package/dist/{index-BOUaDIW-.d.ts → index-tq6f8007.d.ts} +2 -2
- package/dist/{index-BOUaDIW-.d.ts.map → index-tq6f8007.d.ts.map} +1 -1
- package/dist/index.d.ts +21 -39
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/{labelled-input-base-Dp_9KP0G.d.ts → labelled-input-base-DiTme1JO.d.ts} +2 -2
- package/dist/{labelled-input-base-Dp_9KP0G.d.ts.map → labelled-input-base-DiTme1JO.d.ts.map} +1 -1
- package/dist/labelled-radial-input.d.ts +2 -2
- package/dist/labelled-radial-input.d.ts.map +1 -1
- package/dist/labelled-range-input.d.ts +1 -1
- package/dist/labelled-slider-input.d.ts +1 -1
- package/dist/{list-selection-types-B5ioL-dG.d.ts → list-selection-types-PjKdhF-a.d.ts} +1 -9
- package/dist/list-selection-types-PjKdhF-a.d.ts.map +1 -0
- package/dist/list-viewport-types-BRZsLcvp.d.ts +23 -0
- package/dist/list-viewport-types-BRZsLcvp.d.ts.map +1 -0
- package/dist/{menu-item-ZmkXNjek.d.ts → menu-item-CZi9vy5O.d.ts} +2 -2
- package/dist/{menu-item-ZmkXNjek.d.ts.map → menu-item-CZi9vy5O.d.ts.map} +1 -1
- package/dist/menu.d.ts +2 -2
- package/dist/miller.d.ts +1 -1
- package/dist/panel.d.ts +1 -1
- package/dist/{split-layout-C5SYbDrq.d.ts → split-layout-JK3xWVX2.d.ts} +2 -2
- package/dist/{split-layout-C5SYbDrq.d.ts.map → split-layout-JK3xWVX2.d.ts.map} +1 -1
- package/dist/split-layout.d.ts +1 -1
- package/dist/{tab-list-DbMIL520.d.ts → tab-list-CGyPt07Z.d.ts} +2 -2
- package/dist/{tab-list-DbMIL520.d.ts.map → tab-list-CGyPt07Z.d.ts.map} +1 -1
- package/dist/tabs.d.ts +1 -1
- package/dist/{titlebar-B5zSTZnF.d.ts → titlebar-Tqu-VvMU.d.ts} +2 -2
- package/dist/{titlebar-B5zSTZnF.d.ts.map → titlebar-Tqu-VvMU.d.ts.map} +1 -1
- package/dist/titlebar.d.ts +1 -1
- package/dist/tree.d.ts +1 -1
- package/dist/{vertical-list-DdaYcvHQ.d.ts → vertical-list-DfcNsa4p.d.ts} +11 -3
- package/dist/vertical-list-DfcNsa4p.d.ts.map +1 -0
- package/dist/vertical-list.d.ts +4 -3
- package/dist/vertical-list.js +47 -1
- package/dist/vertical-list.js.map +1 -1
- package/docs-user/data-grid.md +9 -0
- package/docs-user/detail-list.md +8 -0
- package/docs-user/grid-list.md +1 -1
- package/docs-user/index.json +2 -2
- package/docs-user/vertical-list.md +7 -0
- package/package.json +1 -1
- package/dist/button-DsFbV4XD.js.map +0 -1
- package/dist/button.d.ts.map +0 -1
- package/dist/data-grid-f9W2uzaR.d.ts.map +0 -1
- package/dist/detail-list-C3tozzBT.d.ts.map +0 -1
- package/dist/grid-list-WE92nfX5.js.map +0 -1
- package/dist/icon-DR_3rSyZ.d.ts.map +0 -1
- package/dist/list-selection-types-B5ioL-dG.d.ts.map +0 -1
- 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>` : ``}
|
|
@@ -23629,6 +23779,12 @@ function columnOf(index, cols) {
|
|
|
23629
23779
|
function rowOf(index, cols) {
|
|
23630
23780
|
return cols <= 1 ? index : Math.floor(index / cols);
|
|
23631
23781
|
}
|
|
23782
|
+
/** Shallow key-array equality, treating `undefined` (never dispatched) as different. */
|
|
23783
|
+
function sameKeys$1(a, b) {
|
|
23784
|
+
if (a === void 0 || a.length !== b.length) return false;
|
|
23785
|
+
for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return false;
|
|
23786
|
+
return true;
|
|
23787
|
+
}
|
|
23632
23788
|
let GridListElement = class GridListElement extends i {
|
|
23633
23789
|
constructor(..._args) {
|
|
23634
23790
|
super(..._args);
|
|
@@ -24523,10 +24679,23 @@ let GridListElement = class GridListElement extends i {
|
|
|
24523
24679
|
this.requestUpdate();
|
|
24524
24680
|
}, REFLOW_WINDOW_MS);
|
|
24525
24681
|
}
|
|
24682
|
+
/** Key sets as of the last `grid-list-viewport-change` dispatch, for dedupe. */
|
|
24683
|
+
#lastViewportRenderedKeys;
|
|
24684
|
+
#lastViewportVisibleKeys;
|
|
24685
|
+
/**
|
|
24686
|
+
* Dispatch `grid-list-viewport-change` with the current key sets — unless
|
|
24687
|
+
* neither set changed since the last dispatch, so coalesced frames and
|
|
24688
|
+
* no-op scrolls stay silent.
|
|
24689
|
+
*/
|
|
24526
24690
|
#emitViewportChange() {
|
|
24691
|
+
const renderedKeys = this.renderedKeys();
|
|
24692
|
+
const visibleKeys = this.visibleKeys();
|
|
24693
|
+
if (sameKeys$1(this.#lastViewportRenderedKeys, renderedKeys) && sameKeys$1(this.#lastViewportVisibleKeys, visibleKeys)) return;
|
|
24694
|
+
this.#lastViewportRenderedKeys = renderedKeys;
|
|
24695
|
+
this.#lastViewportVisibleKeys = visibleKeys;
|
|
24527
24696
|
this._dispatch(`grid-list-viewport-change`, {
|
|
24528
|
-
renderedKeys
|
|
24529
|
-
visibleKeys
|
|
24697
|
+
renderedKeys,
|
|
24698
|
+
visibleKeys
|
|
24530
24699
|
});
|
|
24531
24700
|
}
|
|
24532
24701
|
firstUpdated() {
|
|
@@ -28257,6 +28426,12 @@ const ITEM_SELECTOR = `li:not([data-virtual-spacer]), [data-list-item]:not([data
|
|
|
28257
28426
|
* vertical rows are shorter relative to the viewport, so 3.
|
|
28258
28427
|
*/
|
|
28259
28428
|
const VIRTUAL_OVERSCAN = 3;
|
|
28429
|
+
/** Shallow key-array equality, treating `undefined` (never dispatched) as different. */
|
|
28430
|
+
function sameKeys(a, b) {
|
|
28431
|
+
if (a === void 0 || a.length !== b.length) return false;
|
|
28432
|
+
for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return false;
|
|
28433
|
+
return true;
|
|
28434
|
+
}
|
|
28260
28435
|
let VerticalListElement = class VerticalListElement extends i {
|
|
28261
28436
|
constructor(..._args) {
|
|
28262
28437
|
super(..._args);
|
|
@@ -28371,11 +28546,11 @@ let VerticalListElement = class VerticalListElement extends i {
|
|
|
28371
28546
|
highlightKey: `vertical-list-search`
|
|
28372
28547
|
}) });
|
|
28373
28548
|
this.#onScroll = () => {
|
|
28374
|
-
if (!this.#virtualActive()) return;
|
|
28375
28549
|
if (this.#scrollRaf !== 0) return;
|
|
28376
28550
|
this.#scrollRaf = requestAnimationFrame(() => {
|
|
28377
28551
|
this.#scrollRaf = 0;
|
|
28378
28552
|
this.#syncVirtualWindow();
|
|
28553
|
+
this.#emitViewportChangeIfChanged();
|
|
28379
28554
|
});
|
|
28380
28555
|
};
|
|
28381
28556
|
this._onPointerOver = (e) => {
|
|
@@ -28468,6 +28643,9 @@ let VerticalListElement = class VerticalListElement extends i {
|
|
|
28468
28643
|
#suspendAdapterRebuild;
|
|
28469
28644
|
#scrollRaf;
|
|
28470
28645
|
#resizeObserver;
|
|
28646
|
+
/** Key sets as of the last viewport-change dispatch, for dedupe. */
|
|
28647
|
+
#lastViewportRenderedKeys;
|
|
28648
|
+
#lastViewportVisibleKeys;
|
|
28471
28649
|
#topSpacer;
|
|
28472
28650
|
#bottomSpacer;
|
|
28473
28651
|
/** Last measured viewport height — kept so a 0 read can't collapse the window. */
|
|
@@ -28595,6 +28773,14 @@ let VerticalListElement = class VerticalListElement extends i {
|
|
|
28595
28773
|
}
|
|
28596
28774
|
}
|
|
28597
28775
|
/**
|
|
28776
|
+
* The shadow scroll list only exists after the first render; start
|
|
28777
|
+
* watching it so resizes move the window (virtualized) and the visible
|
|
28778
|
+
* set (plain) too.
|
|
28779
|
+
*/
|
|
28780
|
+
firstUpdated() {
|
|
28781
|
+
this.#ensureResizeObserved();
|
|
28782
|
+
}
|
|
28783
|
+
/**
|
|
28598
28784
|
* Animate in items appended to the light DOM (however they got there —
|
|
28599
28785
|
* {@link addItem}, direct `appendChild`, a framework binding). A bulk populate
|
|
28600
28786
|
* (roughly everything at once) is left alone, as are the wrapper `<li>`s the
|
|
@@ -28604,6 +28790,7 @@ let VerticalListElement = class VerticalListElement extends i {
|
|
|
28604
28790
|
if (!this.isConnected) return;
|
|
28605
28791
|
if (this.#virtualActive()) {
|
|
28606
28792
|
this.#syncVirtualWindow(this.#reconcileRecords(records));
|
|
28793
|
+
this.#scheduleViewportChangeEmit();
|
|
28607
28794
|
return;
|
|
28608
28795
|
}
|
|
28609
28796
|
const fresh = [];
|
|
@@ -28614,6 +28801,7 @@ let VerticalListElement = class VerticalListElement extends i {
|
|
|
28614
28801
|
this.#animatedItems.add(node);
|
|
28615
28802
|
fresh.push(node);
|
|
28616
28803
|
}
|
|
28804
|
+
this.#scheduleViewportChangeEmit();
|
|
28617
28805
|
if (fresh.length === 0) return;
|
|
28618
28806
|
if (this.#isBulkPopulate(fresh.length)) return;
|
|
28619
28807
|
for (const el of fresh) animateListItemIn(el);
|
|
@@ -29167,6 +29355,7 @@ let VerticalListElement = class VerticalListElement extends i {
|
|
|
29167
29355
|
if (!ul) return;
|
|
29168
29356
|
this.#resizeObserver ??= new ResizeObserver(() => {
|
|
29169
29357
|
this.#syncVirtualWindow();
|
|
29358
|
+
this.#scheduleViewportChangeEmit();
|
|
29170
29359
|
});
|
|
29171
29360
|
this.#resizeObserver.observe(ul);
|
|
29172
29361
|
}
|
|
@@ -29246,6 +29435,32 @@ let VerticalListElement = class VerticalListElement extends i {
|
|
|
29246
29435
|
this._syncItemStates();
|
|
29247
29436
|
this._syncNativeDraggable();
|
|
29248
29437
|
this.#nativeDrag.refreshDraggable();
|
|
29438
|
+
this.#scheduleViewportChangeEmit();
|
|
29439
|
+
}
|
|
29440
|
+
/** Coalesce content/layout viewport checks to at most one animation frame. */
|
|
29441
|
+
#scheduleViewportChangeEmit() {
|
|
29442
|
+
if (this.#scrollRaf !== 0) return;
|
|
29443
|
+
this.#scrollRaf = requestAnimationFrame(() => {
|
|
29444
|
+
this.#scrollRaf = 0;
|
|
29445
|
+
this.#syncVirtualWindow();
|
|
29446
|
+
this.#emitViewportChangeIfChanged();
|
|
29447
|
+
});
|
|
29448
|
+
}
|
|
29449
|
+
/**
|
|
29450
|
+
* Dispatch `vertical-list-viewport-change` with the current key sets — unless
|
|
29451
|
+
* neither set changed since the last dispatch, so coalesced frames and
|
|
29452
|
+
* no-op scrolls stay silent.
|
|
29453
|
+
*/
|
|
29454
|
+
#emitViewportChangeIfChanged() {
|
|
29455
|
+
const renderedKeys = this.renderedKeys();
|
|
29456
|
+
const visibleKeys = this.visibleKeys();
|
|
29457
|
+
if (sameKeys(this.#lastViewportRenderedKeys, renderedKeys) && sameKeys(this.#lastViewportVisibleKeys, visibleKeys)) return;
|
|
29458
|
+
this.#lastViewportRenderedKeys = renderedKeys;
|
|
29459
|
+
this.#lastViewportVisibleKeys = visibleKeys;
|
|
29460
|
+
this._dispatch(`vertical-list-viewport-change`, {
|
|
29461
|
+
renderedKeys,
|
|
29462
|
+
visibleKeys
|
|
29463
|
+
});
|
|
29249
29464
|
}
|
|
29250
29465
|
_getVisibleItems() {
|
|
29251
29466
|
return Array.from(this.querySelectorAll(ITEM_SELECTOR)).filter((el) => {
|