@aceshooting/lyra-ui 17.0.0 → 18.0.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.
- package/CHANGELOG.md +254 -0
- package/README.md +2 -2
- package/custom-elements.json +1 -1
- package/dist/cli/migration-contract.json +1 -1
- package/dist/components/conversation/streaming-text/streaming-text-core.class.d.ts +22 -0
- package/dist/components/conversation/streaming-text/streaming-text-core.class.js +1 -0
- package/dist/components/conversation/streaming-text/streaming-text.class.d.ts +22 -0
- package/dist/components/conversation/streaming-text/streaming-text.class.js +1 -0
- package/dist/components/conversation/thread-list/thread-list.class.js +1 -1
- package/dist/components/data/table/table.styles.js +1 -1
- package/dist/components/forms/combobox/combobox.class.d.ts +12 -2
- package/dist/components/forms/combobox/combobox.class.js +2 -2
- package/dist/components/forms/combobox/combobox.styles.js +1 -1
- package/dist/components/forms/select/select.class.d.ts +31 -5
- package/dist/components/forms/select/select.class.js +2 -2
- package/dist/components/layout/filter-bar/filter-bar.class.d.ts +68 -6
- package/dist/components/layout/filter-bar/filter-bar.class.js +2 -2
- package/dist/components/layout/reorder-list/reorder-list.class.js +1 -1
- package/dist/components/layout/virtual-list/virtual-list.class.d.ts +107 -2
- package/dist/components/layout/virtual-list/virtual-list.class.js +12 -7
- package/dist/components/media/map/map.class.d.ts +138 -12
- package/dist/components/media/map/map.class.js +25 -20
- package/dist/components/media/map/map.styles.js +1 -1
- package/dist/custom-elements-jsx.d.ts +1 -1
- package/dist/events.d.ts +7 -1
- package/dist/internal/package-metadata.d.ts +1 -1
- package/dist/internal/package-metadata.js +1 -1
- package/dist/lyra.d.ts +1 -1
- package/dist/lyra.js +1 -1
- package/dist/svelte.d.ts +1 -1
- package/dist/testing/lyra-tag-event-map.js +1 -1
- package/dist/translations/ar/retrieval.js +1 -1
- package/dist/translations/ar/shared.js +1 -1
- package/dist/translations/de/retrieval.js +1 -1
- package/dist/translations/de/shared.js +1 -1
- package/dist/translations/es/retrieval.js +1 -1
- package/dist/translations/es/shared.js +1 -1
- package/dist/translations/fa/retrieval.js +1 -1
- package/dist/translations/fa/shared.js +1 -1
- package/dist/translations/fr/retrieval.js +1 -1
- package/dist/translations/fr/shared.js +1 -1
- package/dist/translations/he/retrieval.js +1 -1
- package/dist/translations/he/shared.js +1 -1
- package/dist/translations/it/retrieval.js +1 -1
- package/dist/translations/it/shared.js +1 -1
- package/dist/translations/ja/retrieval.js +1 -1
- package/dist/translations/ja/shared.js +1 -1
- package/dist/translations/pt-BR/retrieval.js +1 -1
- package/dist/translations/pt-BR/shared.js +1 -1
- package/dist/translations/ro/agent-tools.d.ts +1 -0
- package/dist/translations/ro/agent-tools.js +1 -0
- package/dist/translations/ro/charts.d.ts +1 -0
- package/dist/translations/ro/charts.js +1 -0
- package/dist/translations/ro/conversation.d.ts +1 -0
- package/dist/translations/ro/conversation.js +1 -0
- package/dist/translations/ro/data.d.ts +1 -0
- package/dist/translations/ro/data.js +1 -0
- package/dist/translations/ro/forms.d.ts +1 -0
- package/dist/translations/ro/forms.js +1 -0
- package/dist/translations/ro/layout.d.ts +1 -0
- package/dist/translations/ro/layout.js +1 -0
- package/dist/translations/ro/media.d.ts +1 -0
- package/dist/translations/ro/media.js +1 -0
- package/dist/translations/ro/overlays.d.ts +1 -0
- package/dist/translations/ro/overlays.js +1 -0
- package/dist/translations/ro/retrieval.d.ts +1 -0
- package/dist/translations/ro/retrieval.js +1 -0
- package/dist/translations/ro/shared.d.ts +1 -0
- package/dist/translations/ro/shared.js +1 -0
- package/dist/translations/ro/utility.d.ts +1 -0
- package/dist/translations/ro/utility.js +1 -0
- package/dist/translations/ro/viewers.d.ts +1 -0
- package/dist/translations/ro/viewers.js +5 -0
- package/dist/translations/ro.d.ts +1 -0
- package/dist/translations/ro.js +1 -0
- package/dist/translations/ru/retrieval.js +1 -1
- package/dist/translations/ru/shared.js +1 -1
- package/dist/translations/zh-CN/retrieval.js +1 -1
- package/dist/translations/zh-CN/shared.js +1 -1
- package/dist/vue.d.ts +1 -1
- package/llms/components/lr-button.md +5 -4
- package/llms/components/lr-card.md +2 -1
- package/llms/components/lr-combobox.md +7 -0
- package/llms/components/lr-filter-bar.md +86 -3
- package/llms/components/lr-icon-button.md +2 -1
- package/llms/components/lr-map.md +63 -6
- package/llms/components/lr-option.md +7 -0
- package/llms/components/lr-select.md +19 -2
- package/llms/components/lr-streaming-text-core.md +7 -3
- package/llms/components/lr-streaming-text.md +7 -2
- package/llms/components/lr-virtual-list.md +53 -0
- package/llms/shared.md +6 -3
- package/llms-full.txt +273 -22
- package/package.json +28 -2
- package/registrations.json +1 -1
- package/vscode-css-data.json +1 -1
- package/vscode-html-data.json +1 -1
- package/web-types.json +1 -1
|
@@ -9,6 +9,28 @@ export interface LyraVirtualListGroup{key:string|number;label?:string;startIndex
|
|
|
9
9
|
/** The ARIA role pairing each rendered row participates in -- see `itemRole`'s own doc for what
|
|
10
10
|
* each value maps to. */
|
|
11
11
|
export type LyraVirtualListItemRole='listitem'|'row';
|
|
12
|
+
/**
|
|
13
|
+
* Where `renderItem`'s output is instantiated.
|
|
14
|
+
*
|
|
15
|
+
* - `'shadow'` (the default) stamps it inside this component's shadow root, where only inherited
|
|
16
|
+
* custom properties and an explicitly exported part reach it.
|
|
17
|
+
* - `'light'` stamps it into the HOST'S OWN light DOM, assigned back into the windowed row wrapper
|
|
18
|
+
* through an internal named slot, so an ordinary document stylesheet styles a virtualized row.
|
|
19
|
+
* Windowing, measurement, spacer sizing, `scrollToIndex()`, the external-scroller mode and the
|
|
20
|
+
* ARIA contract all stay with this component either way.
|
|
21
|
+
*/
|
|
22
|
+
export type LyraVirtualListRowProjection='shadow'|'light';
|
|
23
|
+
/**
|
|
24
|
+
* Reserved attribute marking a light-DOM row wrapper this component created in
|
|
25
|
+
* `row-projection="light"` mode, so consumer CSS, DOM diffing and snapshot tests can recognise a
|
|
26
|
+
* library-owned light-DOM node. `::part()` cannot address one -- a projected row is in the
|
|
27
|
+
* document's tree, not a shadow tree -- so this replaces `closest('[part="row"]')` for a delegated
|
|
28
|
+
* listener in that mode. Built through `tag()`, exactly like `ANNOUNCEMENT_SINK_ATTRIBUTE`.
|
|
29
|
+
*/
|
|
30
|
+
export declare const VIRTUAL_LIST_ROW_ATTRIBUTE:string;
|
|
31
|
+
/** Reserved attribute marking the projected sticky-band wrapper. Same rationale as
|
|
32
|
+
* {@linkcode VIRTUAL_LIST_ROW_ATTRIBUTE}. */
|
|
33
|
+
export declare const VIRTUAL_LIST_STICKY_ATTRIBUTE:string;
|
|
12
34
|
/** A fixed positive pixel height, or live per-row measurement. */
|
|
13
35
|
export type LyraVirtualListRowHeight=number|'auto';type VirtualListKey=string|number;
|
|
14
36
|
/** A random-access collection that does not have to materialize one JavaScript value per row. */
|
|
@@ -280,6 +302,12 @@ rowHeight:LyraVirtualListRowHeight;
|
|
|
280
302
|
* `aria-rowindex` instead -- for a consumer composing a virtualized `role="table"` (see
|
|
281
303
|
* `<lr-dataset-viewer>`). */
|
|
282
304
|
itemRole:LyraVirtualListItemRole;
|
|
305
|
+
/** Where `renderItem`'s output is instantiated: `'shadow'` (the default) inside this component's
|
|
306
|
+
* shadow root, or `'light'` as a child of the host itself so ordinary document CSS reaches it.
|
|
307
|
+
* See the class doc's "Light-DOM row projection" section for the full contract. Unsupported
|
|
308
|
+
* attribute values and untyped property writes normalize back to `'shadow'`; the property is
|
|
309
|
+
* deliberately not reflected, matching `itemRole`. */
|
|
310
|
+
private _rowProjection;get rowProjection():LyraVirtualListRowProjection;set rowProjection(next:LyraVirtualListRowProjection);
|
|
283
311
|
/** Added to a row's 1-based index to compute `aria-rowindex` in `item-role="row"` mode (e.g. `1`
|
|
284
312
|
* when a consumer renders its own header row occupying `aria-rowindex="1"` outside this
|
|
285
313
|
* component). No effect in `'listitem'` mode. */
|
|
@@ -367,6 +395,18 @@ get scrollContainer():HTMLElement|undefined;
|
|
|
367
395
|
* update.
|
|
368
396
|
*/
|
|
369
397
|
get renderedRows():HTMLElement[];
|
|
398
|
+
/**
|
|
399
|
+
* The projected light-DOM row wrappers (`[data-lr-virtual-list-row]`) that currently exist as
|
|
400
|
+
* direct children of this host, in item order — the `row-projection="light"` counterpart of
|
|
401
|
+
* {@linkcode renderedRows}, and always empty in the default `'shadow'` mode.
|
|
402
|
+
*
|
|
403
|
+
* Each one pairs 1:1 with the `[part="row"]` wrapper it is slotted into and mirrors that
|
|
404
|
+
* wrapper's `data-row-index`/`data-row-key`. Only direct children are considered, so a nested
|
|
405
|
+
* `<lr-virtual-list>` inside a projected row never contributes its own rows here. Treat the
|
|
406
|
+
* returned elements as read-only: their lifetime belongs to the windowing math, and any of them
|
|
407
|
+
* can be recycled or removed on the next update.
|
|
408
|
+
*/
|
|
409
|
+
get projectedRows():HTMLElement[];
|
|
370
410
|
/** The configured external scroller once it is usable, or `undefined` whenever this component
|
|
371
411
|
* scrolls its own `[part="base"]` viewport. See `scrollElement` for why a non-`Element`,
|
|
372
412
|
* non-`Window` assignment resolves to "no external scroller" instead of throwing. */
|
|
@@ -433,7 +473,29 @@ private offsetsDirty;
|
|
|
433
473
|
* just `rowHeight`/`keyFunction`/a measurement) -- consumed by the next
|
|
434
474
|
* `recomputeOffsets()` call to prune `measuredHeights` entries for keys
|
|
435
475
|
* no longer present in `items`. */
|
|
436
|
-
private itemsChangedPendingPrune;private renderStart;private renderEnd;
|
|
476
|
+
private itemsChangedPendingPrune;private renderStart;private renderEnd;
|
|
477
|
+
/** The window the most recent shadow `render()` emitted, with each row's identity already
|
|
478
|
+
* resolved. `row-projection="light"` renders the SAME array, keyed by the SAME identity, so the
|
|
479
|
+
* two sides can never disagree about which rows exist or what they are called. */
|
|
480
|
+
private renderedWindow;
|
|
481
|
+
/** Trailing comment bounding the light-DOM render part; also where lit-html caches that part. */
|
|
482
|
+
private projectionAnchor?;private projectionPart?;
|
|
483
|
+
/**
|
|
484
|
+
* True until the first render is safely past. A server render can never produce projected rows --
|
|
485
|
+
* `@lit-labs/ssr` calls `connectedCallback()`, `willUpdate()` and `render()`, never
|
|
486
|
+
* `update()`/`updated()`, and there is no DOM to render into -- so activating projection
|
|
487
|
+
* unconditionally would serialize this component's bounded deterministic first window EMPTY and
|
|
488
|
+
* make the browser's first render disagree with the markup it is hydrating.
|
|
489
|
+
*
|
|
490
|
+
* Released through `seedFirstRenderState()`, the same helper `renderUnmeasuredWindow` uses: a
|
|
491
|
+
* browser-only mount clears it synchronously inside `connectedCallback()` (so the very first
|
|
492
|
+
* render is already projected, with no flash and no extra update), while a hydrating mount keeps
|
|
493
|
+
* the server's shadow-rendered window for exactly its first render and swaps into the light DOM
|
|
494
|
+
* one task later.
|
|
495
|
+
*/
|
|
496
|
+
private projectionDeferred;
|
|
497
|
+
/** Stable reference so `seedFirstRenderState()`'s pending set dedupes the re-arm below. */
|
|
498
|
+
private readonly releaseRowProjection;private visibleStart;private visibleEnd;private lastEmittedStart;private lastEmittedEnd;
|
|
437
499
|
/** Re-armed whenever the window moves away from the end of `items` -- see the `lr-load-more` event doc. */
|
|
438
500
|
private loadMoreArmed;
|
|
439
501
|
/** Identity- and source-bound correction transaction for estimate-based programmatic scrolling. */
|
|
@@ -553,7 +615,50 @@ private get stickyInset();private scrollActiveIntoView;
|
|
|
553
615
|
* and key function, and is canceled by replacement data, a new target, manual scroll intent, or
|
|
554
616
|
* disconnect, so a late observation can never drag a newer view back to a stale row.
|
|
555
617
|
*/
|
|
556
|
-
scrollToIndex(index:number,options?:{align?:'start'|'end'|'auto';behavior?:'auto'|'smooth';}):void;private hasUnmeasuredGroupThrough;private beginPendingScrollCorrection;private performScrollTo;private maybeCorrectPendingScroll;private emitRangeChangeIfNeeded;private maybeFireLoadMore;
|
|
618
|
+
scrollToIndex(index:number,options?:{align?:'start'|'end'|'auto';behavior?:'auto'|'smooth';}):void;private hasUnmeasuredGroupThrough;private beginPendingScrollCorrection;private performScrollTo;private maybeCorrectPendingScroll;private emitRangeChangeIfNeeded;private maybeFireLoadMore;
|
|
619
|
+
/** True whenever `renderItem`'s output belongs in the host's light DOM for THIS render. */
|
|
620
|
+
private get projectionActive();
|
|
621
|
+
/** The internal slot name pairing one shadow row wrapper with its projected light-DOM row.
|
|
622
|
+
* Keyed by the component's own row identity -- already the `repeat()` key on both sides -- so a
|
|
623
|
+
* scroll or a reorder moves rows without rewriting a single `slot`/`name` attribute. Slot
|
|
624
|
+
* matching is exact whole-value string comparison, so an identity containing a space or a colon
|
|
625
|
+
* still pairs correctly, and the name is never empty so it can never collide with a default
|
|
626
|
+
* slot (of which this component renders none). */
|
|
627
|
+
private rowSlotName;
|
|
628
|
+
/**
|
|
629
|
+
* Mounts, updates or tears down the light-DOM render root that holds `renderItem`'s output in
|
|
630
|
+
* `row-projection="light"` mode.
|
|
631
|
+
*
|
|
632
|
+
* The container is the HOST ITSELF — a slottable must be a direct child of the host — bounded by
|
|
633
|
+
* a trailing comment anchor, so the part only ever owns `[startMarker … anchor)`. Anything a
|
|
634
|
+
* consumer appends to this element later lands after the anchor and is never cleared by a
|
|
635
|
+
* re-render, which is also what keeps a server-rendered light child alive across hydration.
|
|
636
|
+
* `host: this` matches `ReactiveElement`'s own render options, so a `renderItem` template whose
|
|
637
|
+
* event binding is a method reference gets the same `this` it gets in shadow mode.
|
|
638
|
+
*/
|
|
639
|
+
private syncRowProjection;private ensureProjectionAnchor;
|
|
640
|
+
/**
|
|
641
|
+
* Removes the projection completely, using public API only: `render(nothing, …)` so lit-html
|
|
642
|
+
* detaches its own child parts and their directives, then the part's start marker, then the
|
|
643
|
+
* anchor. Discarding the anchor discards lit's cached root part with it (the cache lives on the
|
|
644
|
+
* `renderBefore` node), so no private-field poking is ever required and a later re-projection
|
|
645
|
+
* starts from a genuinely fresh part.
|
|
646
|
+
*
|
|
647
|
+
* After this the host's light DOM holds exactly what the consumer put there: no rows, no lit
|
|
648
|
+
* markers, no anchor. The accepted cost is that per-row DOM state inside a projected row does not
|
|
649
|
+
* survive a disconnect/reconnect; scroll position, measurements and the window are unaffected,
|
|
650
|
+
* because they live in component state rather than in the rows.
|
|
651
|
+
*/
|
|
652
|
+
private teardownRowProjection;
|
|
653
|
+
/**
|
|
654
|
+
* One light-DOM wrapper per windowed row, over the same array and keyed by the same identity the
|
|
655
|
+
* shadow window used. The wrapper carries no `part` (a `part` attribute outside a shadow tree is
|
|
656
|
+
* inert), no `role` and no inline positioning — the `[part="row"]` wrapper it is slotted into
|
|
657
|
+
* keeps sole ownership of absolute positioning, the per-frame transform and every ARIA
|
|
658
|
+
* attribute, so consumer CSS cannot break windowing. `data-row-index`/`data-row-key` are mirrored
|
|
659
|
+
* so document CSS and delegated listeners can still address a specific row.
|
|
660
|
+
*/
|
|
661
|
+
private renderProjectedRows;private renderRow;
|
|
557
662
|
/** Normalizes group definitions only when their inputs change. */
|
|
558
663
|
private recomputeGroups;private renderGroups;
|
|
559
664
|
/** The group the viewport is currently inside -- the last one whose first row's offset is at or
|
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
var __decorate=function(decorators,target,key,desc){var c=arguments.length,r=c<3?target:desc===null?desc=Object.getOwnPropertyDescriptor(target,key):desc,d;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")r=Reflect.decorate(decorators,target,key,desc);else for(var i=decorators.length-1;i>=0;i--)(d=decorators[i])&&(r=(c<3?d(r):c>3?d(target,key,r):d(target,key))||r);return c>3&&r&&Object.defineProperty(target,key,r),r};import{html,nothing}from"lit";import{property,state}from"lit/decorators.js";import{repeat}from"lit/directives/repeat.js";import{styleMap}from"lit/directives/style-map.js";import{LyraElement}from"../../../internal/lyra-element.js";import{prefersReducedMotion}from"../../../internal/motion.js";import{finiteAdd,finiteCount,finiteInteger,finiteNumber}from"../../../internal/numbers.js";import{getNumberFormat}from"../../../internal/intl-cache.js";import{getOwnDataDescriptor,MISSING_OWN_DATA_DESCRIPTOR,UNSAFE_OWN_DATA_DESCRIPTOR}from"../../../internal/data-descriptors.js";import{styles}from"./virtual-list.styles.js";const DEFAULT_ROW_ESTIMATE_PX=48,DEFAULT_GROUP_ESTIMATE_PX=32,DEFAULT_OVERSCAN_ROWS=6,MAX_OVERSCAN_ROWS=100,MAX_VIRTUAL_LIST_GROUPS=1e4,EMPTY_VIRTUAL_LIST_GROUPS=Object.freeze([]);function normalizeOverscan(value){if(value===null)return DEFAULT_OVERSCAN_ROWS;const numeric=typeof value=="number"?value:Number(value);return Number.isFinite(numeric)?Math.min(MAX_OVERSCAN_ROWS,Math.max(0,Math.floor(numeric))):DEFAULT_OVERSCAN_ROWS}const overscanConverter={fromAttribute(value){return normalizeOverscan(value)}};function virtualListGroupsChanged(value,oldValue){if(value===oldValue)return!1;const next=value,previous=oldValue;if(next==null||previous==null)return next!==previous;if(next.length!==previous.length)return!0;for(let index=0;index<next.length;index+=1){const a=next[index],b=previous[index];if(a.key!==b.key||a.label!==b.label||a.startIndex!==b.startIndex)return!0}return!1}function normalizeRowHeight(value){if(value==="auto")return"auto";const numeric=typeof value=="number"?value:Number(value);return Number.isFinite(numeric)&&numeric>0?numeric:"auto"}const rowHeightConverter={fromAttribute(value){return value===null?"auto":normalizeRowHeight(value)}};function isIndexedSource(source){return!Array.isArray(source)}const ELEMENT_NODE_TYPE=1;function isWindowScroller(target){return target.window===target}function domKeyToken(key){if(typeof key=="number"){if(Number.isNaN(key))return"number:NaN";if(Object.is(key,-0))return"number:-0"}return`${typeof key}:${String(key)}`}class LyraVirtualList extends LyraElement{constructor(){super(...arguments),this.items=[],this.renderItem=()=>nothing,this.rowHeight="auto",this.itemRole="listitem",this.rowIndexOffset=0,this.overscan=DEFAULT_OVERSCAN_ROWS,this.activeItemId="",this.loading=!1,this.hasMore=!1,this.containerScrollTop=0,this.viewportHeight=0,this.renderUnmeasuredWindow=!0,this.offsets=[0],this.rowIdentities=[],this.fixedRowHeight=null,this.measuredHeights=new Map,this.measuredIndices=new Map,this.indexedMeasurementIndices=[],this.indexedMeasurementDeltaPrefix=[0],this.indexedMeasurementIndexDirty=!0,this.offsetsDirty=!0,this.itemsChangedPendingPrune=!1,this.renderStart=0,this.renderEnd=-1,this.visibleStart=0,this.visibleEnd=-1,this.lastEmittedStart=-1,this.lastEmittedEnd=-1,this.loadMoreArmed=!0,this.measurementGeneration=0,this.isFirstUpdate=!0,this.stickyHeight=0,this.observedRows=new Map,this.observedRowKeys=new WeakMap,this.observedRowIndices=new WeakMap,this.observedGroups=new Map,this.observedGroupIndices=new WeakMap,this.externalMetricsPending=!1,this.ownerRealmGeneration=0,this.inResizeDelivery=!1,this.deferredRowObservations=new Map,this.deferredGroupObservations=new Map,this.activeIndexForLength=-1,this.activeIndexForId="",this.activeIndexCache=-1,this.pendingScrollTop=null,this.normalizedGroups=EMPTY_VIRTUAL_LIST_GROUPS,this.normalizedGroupByIndex=new Map,this.measuredGroupHeights=new Map,this.groupHeightPrefix=[0],this.onExternalViewportResize=()=>{this.syncExternalScrollMetrics()},this.onUserScrollIntent=event=>{event instanceof KeyboardEvent&&!new Set(["ArrowUp","ArrowDown","PageUp","PageDown","Home","End"," "]).has(event.key)||(this.pendingScrollCorrection=void 0)},this.onScroll=e=>{if(this.externalScroller?(this.pendingScrollTop=null,this.externalMetricsPending=!0):this.pendingScrollTop=e.currentTarget.scrollTop,this.scrollRafId!==void 0)return;const ownerDocument=this.ownerDocument,ownerWindow=ownerDocument.defaultView;if(!ownerWindow||!this.isConnected)return;const generation=this.ownerRealmGeneration,handle=ownerWindow.requestAnimationFrame(()=>{if(!(this.scrollRafId!==handle||this.scrollRafOwner!==ownerWindow||this.scrollRafDocument!==ownerDocument||!this.isCurrentOwnerWork(ownerDocument,generation))){if(this.scrollRafId=void 0,this.scrollRafOwner=void 0,this.scrollRafDocument=void 0,this.externalMetricsPending){this.externalMetricsPending=!1;const metrics=this.readScrollMetrics();metrics&&(this.pendingScrollTop=metrics.scrollTop,this.viewportHeight!==metrics.viewportHeight&&(this.viewportHeight=metrics.viewportHeight))}if(this.pendingScrollTop!==null){const scrollTop=this.pendingScrollTop;this.pendingScrollTop=null;const moved=this.containerScrollTop!==scrollTop;this.containerScrollTop=scrollTop,moved&&this.emit("lr-virtual-scroll",{scrollTop,viewportHeight:this.viewportHeight})}}});this.scrollRafId=handle,this.scrollRafOwner=ownerWindow,this.scrollRafDocument=ownerDocument},this.onRowsResized=entries=>{if(this.beginResizeDelivery(),this.fixedRowHeight!=null)return;const base=this.scrollContainer,oldScrollTop=this.readScrollMetrics()?.rawScrollTop??this.containerScrollTop;let scrollAdjustment=0,changed=!1;for(const entry of entries){const row=entry.target,key=this.observedRowKeys.get(row),index=this.observedRowIndices.get(row);if(key===void 0||index===void 0)continue;const height=entry.borderBoxSize?.[0]?.blockSize??entry.target.getBoundingClientRect().height,prev=this.measuredHeights.get(key);if(prev===void 0||Math.abs(prev-height)>.5){const oldBottom=this.rowBottomAt(index);this.measuredHeights.set(key,height),this.measuredIndices.set(key,index);const oldHeight=prev??DEFAULT_ROW_ESTIMATE_PX;oldBottom<=oldScrollTop&&(scrollAdjustment+=height-oldHeight),changed=!0}}if(changed){if(this.indexedMeasurementIndexDirty=!0,base&&scrollAdjustment!==0){const nextScrollTop=oldScrollTop+scrollAdjustment;this.applyScrollPosition(nextScrollTop),this.containerScrollTop=Math.max(0,nextScrollTop),this.pendingScrollTop=null}this.offsetsDirty=!0,this.measurementGeneration+=1,this.requestUpdate()}},this.onGroupsResized=entries=>{this.beginResizeDelivery();const base=this.scrollContainer,oldScrollTop=this.readScrollMetrics()?.rawScrollTop??this.containerScrollTop;let scrollAdjustment=0,changed=!1;for(const entry of entries){const marker=entry.target,index=this.observedGroupIndices.get(marker);if(index===void 0||!this.normalizedGroupByIndex.has(index))continue;const height=entry.borderBoxSize?.[0]?.blockSize??entry.target.getBoundingClientRect().height;if(!Number.isFinite(height)||height<0)continue;const previous=this.measuredGroupHeights.get(index)??DEFAULT_GROUP_ESTIMATE_PX;if(Math.abs(previous-height)<=.5)continue;const oldRowTop=this.offsetAt(index);this.measuredGroupHeights.set(index,height),oldRowTop<=oldScrollTop&&(scrollAdjustment+=height-previous),changed=!0}if(changed){if(base&&scrollAdjustment!==0){const nextScrollTop=oldScrollTop+scrollAdjustment;this.applyScrollPosition(nextScrollTop),this.containerScrollTop=Math.max(0,nextScrollTop),this.pendingScrollTop=null}this.offsetsDirty=!0,this.measurementGeneration+=1,this.requestUpdate()}},this.onStickyResized=entries=>{this.beginResizeDelivery();const entry=entries[0];if(!entry)return;const height=entry.borderBoxSize?.[0]?.blockSize??entry.contentRect.height;Math.abs(this.stickyHeight-height)>.5&&(this.stickyHeight=height)}}static{this.ownedCollectionProperties=Object.freeze(["items","source","groups"])}static{this.identityCollectionProperties=Object.freeze(["items","source"])}static{this.identityCollectionObjectProperties=Object.freeze(["source"])}static{this.styles=[LyraElement.styles,styles]}get scrollContainer(){return this.renderRoot?.querySelector('[part="base"]')??void 0}get renderedRows(){const root=this.renderRoot;return root?[...root.querySelectorAll('[part="row"]')]:[]}get externalScroller(){const target=this.scrollElement;if(target!=null)return isWindowScroller(target)||target.nodeType===ELEMENT_NODE_TYPE?target:void 0}get spacerElement(){return this.renderRoot?.querySelector('[part="spacer"]')??void 0}readScrollMetrics(){const base=this.scrollContainer;if(!base)return null;const external=this.externalScroller;if(!external)return{scrollTop:base.scrollTop,rawScrollTop:base.scrollTop,viewportHeight:base.clientHeight};const spacerTop=(this.spacerElement??base).getBoundingClientRect().top;if(isWindowScroller(external)){const documentHeight=finiteNumber(external.document?.documentElement?.clientHeight??0,0),rawScrollTop2=finiteNumber(-spacerTop,0);return{scrollTop:Math.max(0,rawScrollTop2),rawScrollTop:rawScrollTop2,viewportHeight:documentHeight>0?documentHeight:finiteNumber(external.innerHeight,0)}}const scrollerTop=external.getBoundingClientRect().top,rawScrollTop=finiteNumber(scrollerTop-spacerTop,0);return{scrollTop:Math.max(0,rawScrollTop),rawScrollTop,viewportHeight:finiteNumber(external.clientHeight,0)}}applyScrollPosition(top,behavior){const external=this.externalScroller;if(!external){const base=this.scrollContainer;if(!base)return;const next2=Math.max(0,finiteNumber(top,0));behavior===void 0?base.scrollTop=next2:base.scrollTo({top:next2,behavior});return}const metrics=this.readScrollMetrics();if(!metrics)return;const delta=finiteNumber(top,metrics.rawScrollTop)-metrics.rawScrollTop;if(isWindowScroller(external)){const options={top:Math.max(0,finiteNumber(external.scrollY+delta,0))};behavior!==void 0&&(options.behavior=behavior),external.scrollTo(options);return}const next=Math.max(0,finiteNumber(external.scrollTop+delta,0));behavior===void 0?external.scrollTop=next:external.scrollTo({top:next,behavior})}syncExternalScrollMetrics(){const metrics=this.readScrollMetrics();metrics&&(this.viewportHeight!==metrics.viewportHeight&&(this.viewportHeight=metrics.viewportHeight),this.containerScrollTop!==metrics.scrollTop&&(this.containerScrollTop=metrics.scrollTop))}get safeRowIndexOffset(){return finiteCount(this.rowIndexOffset)}computedAriaRowIndex(index){return finiteInteger(finiteAdd(index+1,this.safeRowIndexOffset),1,1,Number.MAX_SAFE_INTEGER)}get activeIndex(){if(this.activeItemId==="")return-1;const source=this.effectiveSource,count=this.itemCount;if(this.activeIndexFor===source&&this.activeIndexForLength===count&&Object.is(this.activeIndexForId,this.activeItemId)&&this.activeIndexForKeyFn===this.keyFunction)return this.activeIndexCache;if(this.activeIndexFor=source,this.activeIndexForLength=count,this.activeIndexForId=this.activeItemId,this.activeIndexForKeyFn=this.keyFunction,this.activeIndexCache=-1,isIndexedSource(source)){if(!this.keyFunction&&source.indexOfKey){const candidate=source.indexOfKey(this.activeItemId);Number.isInteger(candidate)&&candidate>=0&&candidate<count&&(this.activeIndexCache=candidate)}return this.activeIndexCache}for(let index=0;index<count;index++){const item=this.itemAt(index);if(Object.is(this.keyOf(item,index),this.activeItemId)){this.activeIndexCache=index;break}}return this.activeIndexCache}connectedCallback(){super.connectedCallback(),this.ownerDocument.defaultView&&this.seedFirstRenderState(()=>{this.renderUnmeasuredWindow=!1,this.requestUpdate()}),this.resetOwnerRealmWork();const ownerDocument=this.ownerDocument,ownerWindow=ownerDocument.defaultView,generation=this.ownerRealmGeneration,ResizeObserverCtor=ownerWindow?.ResizeObserver;if(ResizeObserverCtor){const rowObserver=new ResizeObserverCtor(entries=>{this.rowResizeObserver!==rowObserver||!this.isCurrentOwnerWork(ownerDocument,generation)||this.onRowsResized(entries)}),groupObserver=new ResizeObserverCtor(entries=>{this.groupResizeObserver!==groupObserver||!this.isCurrentOwnerWork(ownerDocument,generation)||this.onGroupsResized(entries)}),stickyObserver=new ResizeObserverCtor(entries=>{this.stickyResizeObserver!==stickyObserver||!this.isCurrentOwnerWork(ownerDocument,generation)||this.onStickyResized(entries)});this.rowResizeObserver=rowObserver,this.groupResizeObserver=groupObserver,this.stickyResizeObserver=stickyObserver}this.hasUpdated&&(this.attachContainerListeners(),this.syncRowObservers(),this.syncGroupObservers(),this.syncStickyOverlay())}disconnectedCallback(){this.resetOwnerRealmWork(),super.disconnectedCallback()}adoptedCallback(){super.adoptedCallback(),this.resetOwnerRealmWork()}isCurrentOwnerWork(ownerDocument,generation){return this.ownerRealmGeneration===generation&&this.isConnected&&this.ownerDocument===ownerDocument}resetOwnerRealmWork(){this.ownerRealmGeneration+=1,this.rowResizeObserver?.disconnect(),this.rowResizeObserver=void 0,this.groupResizeObserver?.disconnect(),this.groupResizeObserver=void 0,this.observedRows.clear(),this.observedGroups.clear(),this.deferredRowObservations.clear(),this.deferredGroupObservations.clear(),this.inResizeDelivery=!1,this.rowObserveRafId!==void 0&&this.rowObserveRafOwner?.cancelAnimationFrame(this.rowObserveRafId),this.rowObserveRafId=void 0,this.rowObserveRafOwner=void 0,this.rowObserveRafDocument=void 0,this.containerResizeObserver?.disconnect(),this.containerResizeObserver=void 0,this.stickyResizeObserver?.disconnect(),this.stickyResizeObserver=void 0,this.observedSticky=void 0,this.scrollRafId!==void 0&&this.scrollRafOwner?.cancelAnimationFrame(this.scrollRafId),this.scrollRafId=void 0,this.scrollRafOwner=void 0,this.scrollRafDocument=void 0,this.pendingScrollTop=null,this.externalMetricsPending=!1,this.pendingScrollCorrection=void 0,this.detachContainerListeners(),this.scrollListenerTarget=void 0}firstUpdated(changed){super.firstUpdated(changed),this.attachContainerListeners()}willUpdate(changed){super.willUpdate(changed),this.isFirstUpdate=!this.hasUpdated,(changed.has("items")||changed.has("source")||changed.has("keyFunction")||changed.has("rowHeight")||changed.has("groups")||changed.has("activeItemId")||changed.has("scrollElement"))&&(this.pendingScrollCorrection=void 0),(changed.has("items")||changed.has("source")||changed.has("rowHeight")||changed.has("keyFunction")||changed.has("groups"))&&(this.offsetsDirty=!0),(changed.has("items")||changed.has("source"))&&(this.itemsChangedPendingPrune=!0),(changed.has("keyFunction")||isIndexedSource(this.effectiveSource)&&(changed.has("items")||changed.has("source")))&&(this.measuredHeights.clear(),this.measuredIndices.clear(),this.indexedMeasurementIndexDirty=!0),changed.has("groups")&&this.measuredGroupHeights.clear(),(changed.has("items")||changed.has("source")||changed.has("groups"))&&this.recomputeGroups(),changed.has("rowHeight")&&(this.fixedRowHeight=this.parseRowHeight(this.rowHeight),this.fixedRowHeight!=null&&(this.measuredHeights.clear(),this.measuredIndices.clear(),this.indexedMeasurementIndexDirty=!0)),this.offsetsDirty&&(this.recomputeOffsets(),this.offsetsDirty=!1),this.computeRange()}updated(changed){super.updated(changed),this.syncRowObservers(),this.syncGroupObservers(),this.syncStickyOverlay(),changed.has("scrollElement")&&!this.isFirstUpdate&&this.attachContainerListeners(),changed.has("activeItemId")&&!this.isFirstUpdate&&this.scrollActiveIntoView(),this.emitRangeChangeIfNeeded(),this.maybeFireLoadMore(),this.maybeCorrectPendingScroll()}parseRowHeight(value){const normalized=normalizeRowHeight(value);return normalized==="auto"?null:normalized}get effectiveSource(){return this.source??this.items}get itemCount(){const source=this.effectiveSource;return isIndexedSource(source)?finiteCount(source.count):source.length}itemAt(index){const source=this.effectiveSource;return isIndexedSource(source)?source.itemAt(index):source[index]}keyOf(item,index){const source=this.effectiveSource,key=this.keyFunction?this.keyFunction(item,index):isIndexedSource(source)?source.keyAt?.(index)??index:index;return typeof key=="string"||typeof key=="number"?key:index}rowIdentity(key,occurrence){const token=domKeyToken(key);return`${token.length}:${token}:${occurrence}`}identityAt(index,item=this.itemAt(index)){return isIndexedSource(this.effectiveSource)?this.rowIdentity(this.keyOf(item,index),index):this.rowIdentities[index]??this.rowIdentity(this.keyOf(item,index),index)}groupHeightAt(index){const group=this.normalizedGroupByIndex.get(index);return!group||group.label===""?0:this.measuredGroupHeights.get(index)??DEFAULT_GROUP_ESTIMATE_PX}rowHeightAt(index){return this.fixedRowHeight!=null?this.fixedRowHeight:this.measuredHeights.get(this.identityAt(index))??DEFAULT_ROW_ESTIMATE_PX}groupContributionThrough(index){let low=0,high=this.normalizedGroups.length;for(;low<high;){const middle=low+high>>1;this.normalizedGroups[middle].startIndex<=index?low=middle+1:high=middle}return this.groupHeightPrefix[low]??0}recomputeGroupHeightPrefix(){const prefix=new Array(this.normalizedGroups.length+1);prefix[0]=0;for(let index=0;index<this.normalizedGroups.length;index++){const group=this.normalizedGroups[index],height=group.label===""?0:this.measuredGroupHeights.get(group.startIndex)??DEFAULT_GROUP_ESTIMATE_PX;prefix[index+1]=finiteAdd(prefix[index],height)}this.groupHeightPrefix=prefix}indexedOffsetForIndex(index){const baseHeight=this.fixedRowHeight??DEFAULT_ROW_ESTIMATE_PX;let offset=index>Number.MAX_VALUE/baseHeight?Number.MAX_VALUE:index*baseHeight;if(this.fixedRowHeight==null){this.rebuildIndexedMeasurementIndex();let low=0,high=this.indexedMeasurementIndices.length;for(;low<high;){const middle=low+high>>1;this.indexedMeasurementIndices[middle]<index?low=middle+1:high=middle}offset=finiteAdd(offset,this.indexedMeasurementDeltaPrefix[low]??0)}return Math.max(0,finiteAdd(offset,this.groupContributionThrough(index)))}rebuildIndexedMeasurementIndex(){if(!this.indexedMeasurementIndexDirty)return;const retained=[];for(const[identity,index]of this.measuredIndices){const height=this.measuredHeights.get(identity);height!==void 0&&retained.push({index,delta:height-DEFAULT_ROW_ESTIMATE_PX})}retained.sort((a,b)=>a.index-b.index);const indices=new Array(retained.length),prefix=new Array(retained.length+1);prefix[0]=0;for(let position=0;position<retained.length;position++){const measurement=retained[position];indices[position]=measurement.index,prefix[position+1]=finiteAdd(prefix[position],measurement.delta)}this.indexedMeasurementIndices=indices,this.indexedMeasurementDeltaPrefix=prefix,this.indexedMeasurementIndexDirty=!1}pruneIndexedMeasurements(){if(!isIndexedSource(this.effectiveSource)||this.fixedRowHeight!=null||this.renderEnd<this.renderStart)return!1;const renderedCount=this.renderEnd-this.renderStart+1,retentionRows=Math.max(renderedCount,normalizeOverscan(this.overscan)*4),firstRetained=Math.max(0,this.renderStart-retentionRows),lastRetained=Math.min(this.itemCount-1,this.renderEnd+retentionRows);let removedDeltaBeforeWindow=0,pruned=!1;for(const[identity,measuredIndex]of this.measuredIndices)if(measuredIndex<firstRetained||measuredIndex>lastRetained){const height=this.measuredHeights.get(identity);height!==void 0&&measuredIndex<firstRetained&&(removedDeltaBeforeWindow=finiteAdd(removedDeltaBeforeWindow,height-DEFAULT_ROW_ESTIMATE_PX)),this.measuredIndices.delete(identity),this.measuredHeights.delete(identity),pruned=!0}if(pruned&&(this.indexedMeasurementIndexDirty=!0,removedDeltaBeforeWindow!==0)){const nextScrollTop=(this.readScrollMetrics()?.rawScrollTop??this.containerScrollTop)-removedDeltaBeforeWindow;this.applyScrollPosition(nextScrollTop),this.containerScrollTop=Math.max(0,nextScrollTop),this.pendingScrollTop=null}return pruned}offsetAt(index){return isIndexedSource(this.effectiveSource)?this.indexedOffsetForIndex(index):this.offsets[index]??0}recomputeOffsets(){const n=this.itemCount;if(this.recomputeGroupHeightPrefix(),isIndexedSource(this.effectiveSource)){this.offsets=[0],this.rowIdentities=[],this.itemsChangedPendingPrune=!1;return}const offsets=new Array(n+1);let cursor=0;const liveKeys=this.itemsChangedPendingPrune&&this.fixedRowHeight==null?new Set:null,occurrences=new Map,identities=new Array(n);for(let i=0;i<n;i++){cursor=finiteAdd(cursor,this.groupHeightAt(i)),offsets[i]=cursor;const key=this.keyOf(this.itemAt(i),i),token=domKeyToken(key),occurrence=occurrences.get(token)??0;occurrences.set(token,occurrence+1);const identity=this.rowIdentity(key,occurrence);identities[i]=identity;let h;this.fixedRowHeight!=null?h=this.fixedRowHeight:(liveKeys?.add(identity),h=this.measuredHeights.get(identity)??DEFAULT_ROW_ESTIMATE_PX),cursor=finiteAdd(cursor,h)}if(offsets[n]=cursor,this.offsets=offsets,this.rowIdentities=identities,this.itemsChangedPendingPrune=!1,liveKeys){for(const key of this.measuredHeights.keys())liveKeys.has(key)||(this.measuredHeights.delete(key),this.measuredIndices.delete(key),this.indexedMeasurementIndexDirty=!0);for(const key of this.measuredIndices.keys())liveKeys.has(key)||(this.measuredIndices.delete(key),this.indexedMeasurementIndexDirty=!0)}}groupTopAt(index){return Math.max(0,this.offsetAt(index)-this.groupHeightAt(index))}rowBottomAt(index){return finiteAdd(this.offsetAt(index),this.rowHeightAt(index))}entryTopAt(index){return this.groupTopAt(index)}findIndexAtOrAfter(offset){let lo=0,hi=this.itemCount-1;for(;lo<hi;){const mid=lo+Math.floor((hi-lo)/2);this.rowBottomAt(mid)<=offset?lo=mid+1:hi=mid}return lo}findIndexAtOrBefore(offset){let lo=0,hi=this.itemCount-1;for(;lo<hi;){const mid=lo+Math.ceil((hi-lo)/2);this.entryTopAt(mid)<offset?lo=mid:hi=mid-1}return lo}offsetForIndex(index){const clamped=Math.min(this.itemCount,Math.max(0,Math.trunc(index)||0));return this.offsetAt(clamped)}indexAtOffset(px){const n=this.itemCount;return n===0?-1:Number.isFinite(px)?Math.min(n-1,Math.max(0,this.findIndexAtOrAfter(px))):px>0?n-1:0}computeRange(){const n=this.itemCount;if(n===0){this.visibleStart=0,this.visibleEnd=-1,this.renderStart=0,this.renderEnd=-1;return}if(this.viewportHeight<=0){if(!this.renderUnmeasuredWindow){this.visibleStart=0,this.visibleEnd=-1,this.renderStart=0,this.renderEnd=-1;return}this.visibleStart=0,this.visibleEnd=0,this.renderStart=0,this.renderEnd=Math.min(n-1,normalizeOverscan(this.overscan));return}const viewTop=this.containerScrollTop,viewBottom=viewTop+this.viewportHeight;this.visibleStart=this.findIndexAtOrAfter(viewTop),this.visibleEnd=this.findIndexAtOrBefore(viewBottom);const overscan=normalizeOverscan(this.overscan);this.renderStart=Math.max(0,this.visibleStart-overscan),this.renderEnd=Math.min(n-1,this.visibleEnd+overscan),this.pruneIndexedMeasurements()&&this.computeRange()}attachContainerListeners(){const base=this.scrollContainer,ownerDocument=this.ownerDocument,ownerWindow=ownerDocument.defaultView;if(!base||!this.isConnected||!ownerWindow)return;this.containerResizeObserver?.disconnect(),this.containerResizeObserver=void 0,this.detachContainerListeners();const external=this.externalScroller,scrollTarget=external??base,generation=this.ownerRealmGeneration,ResizeObserverCtor=ownerWindow.ResizeObserver;if(ResizeObserverCtor){const observer=new ResizeObserverCtor(entries=>{if(this.containerResizeObserver!==observer||this.scrollListenerTarget!==scrollTarget||!this.isCurrentOwnerWork(ownerDocument,generation))return;if(this.beginResizeDelivery(),external){this.syncExternalScrollMetrics();return}const entry=entries[0];entry&&(this.viewportHeight=entry.borderBoxSize?.[0]?.blockSize??entry.contentRect.height)});this.containerResizeObserver=observer,observer.observe(base),external&&!isWindowScroller(external)&&observer.observe(external)}scrollTarget.addEventListener("scroll",this.onScroll,{passive:!0}),scrollTarget.addEventListener("wheel",this.onUserScrollIntent,{passive:!0}),scrollTarget.addEventListener("pointerdown",this.onUserScrollIntent,{passive:!0}),scrollTarget.addEventListener("touchstart",this.onUserScrollIntent,{passive:!0}),scrollTarget.addEventListener("keydown",this.onUserScrollIntent),this.scrollListenerTarget=scrollTarget,external&&isWindowScroller(external)&&(external.addEventListener("resize",this.onExternalViewportResize,{passive:!0}),this.viewportResizeTarget=external),ownerWindow.queueMicrotask(()=>{if(this.scrollListenerTarget!==scrollTarget||this.scrollContainer!==base||!this.isCurrentOwnerWork(ownerDocument,generation))return;const metrics=this.readScrollMetrics();metrics&&(this.viewportHeight!==metrics.viewportHeight&&(this.viewportHeight=metrics.viewportHeight),this.containerScrollTop!==metrics.scrollTop&&(this.containerScrollTop=metrics.scrollTop))})}detachContainerListeners(){const viewportTarget=this.viewportResizeTarget;viewportTarget&&(viewportTarget.removeEventListener("resize",this.onExternalViewportResize),this.viewportResizeTarget=void 0);const target=this.scrollListenerTarget;target&&(target.removeEventListener("scroll",this.onScroll),target.removeEventListener("wheel",this.onUserScrollIntent),target.removeEventListener("pointerdown",this.onUserScrollIntent),target.removeEventListener("touchstart",this.onUserScrollIntent),target.removeEventListener("keydown",this.onUserScrollIntent))}beginResizeDelivery(){if(this.inResizeDelivery=!0,this.rowObserveRafId!==void 0)return;const ownerDocument=this.ownerDocument,ownerWindow=ownerDocument.defaultView;if(!ownerWindow||!this.isConnected){this.inResizeDelivery=!1;return}const generation=this.ownerRealmGeneration,handle=ownerWindow.requestAnimationFrame(()=>{if(this.rowObserveRafId!==handle||this.rowObserveRafOwner!==ownerWindow||this.rowObserveRafDocument!==ownerDocument||!this.isCurrentOwnerWork(ownerDocument,generation))return;this.rowObserveRafId=void 0,this.rowObserveRafOwner=void 0,this.rowObserveRafDocument=void 0,this.inResizeDelivery=!1;const ro=this.rowResizeObserver;for(const[identity,el]of this.deferredRowObservations)ro&&this.observedRows.get(identity)===el&&ro.observe(el);this.deferredRowObservations.clear();const groupObserver=this.groupResizeObserver;for(const[index,el]of this.deferredGroupObservations)groupObserver&&this.observedGroups.get(index)===el&&groupObserver.observe(el);this.deferredGroupObservations.clear()});this.rowObserveRafId=handle,this.rowObserveRafOwner=ownerWindow,this.rowObserveRafDocument=ownerDocument}syncRowObservers(){const ro=this.rowResizeObserver;if(!ro)return;if(this.fixedRowHeight!=null){for(const el of this.observedRows.values())ro.unobserve(el);this.observedRows.clear(),this.deferredRowObservations.clear();return}const current=new Map;this.renderRoot.querySelectorAll('[part="row"]').forEach(el=>{const index=Number(el.getAttribute("data-row-index"));if(!Number.isInteger(index)||index<0||index>=this.itemCount)return;const identity=this.identityAt(index);current.set(identity,el),this.observedRowKeys.set(el,identity),this.observedRowIndices.set(el,index)});for(const[identity,el]of this.observedRows)current.get(identity)!==el&&(ro.unobserve(el),this.observedRows.delete(identity),this.deferredRowObservations.delete(identity));for(const[identity,el]of current)this.observedRows.has(identity)||(this.observedRows.set(identity,el),this.inResizeDelivery?this.deferredRowObservations.set(identity,el):ro.observe(el))}syncGroupObservers(){const observer=this.groupResizeObserver;if(!observer)return;const current=new Map;this.renderRoot.querySelectorAll('[part="group"][data-group-index]').forEach(marker=>{const index=Number(marker.dataset.groupIndex);!Number.isInteger(index)||!this.normalizedGroupByIndex.has(index)||(current.set(index,marker),this.observedGroupIndices.set(marker,index))});for(const[index,marker]of this.observedGroups)current.get(index)!==marker&&(observer.unobserve(marker),this.observedGroups.delete(index),this.deferredGroupObservations.delete(index));for(const[index,marker]of current)this.observedGroups.has(index)||(this.observedGroups.set(index,marker),this.inResizeDelivery?this.deferredGroupObservations.set(index,marker):observer.observe(marker))}get stickyInset(){return this.renderStickyGroup?this.stickyHeight:0}scrollActiveIntoView(){const index=this.activeIndex;if(index<0)return;const behavior=prefersReducedMotion(this.ownerDocument.defaultView)?"auto":"smooth";this.performScrollTo(index,"auto",behavior)&&this.beginPendingScrollCorrection(index,"auto",behavior,this.activeItemId)}scrollToIndex(index,options){const n=this.itemCount;if(n===0)return;const clamped=finiteInteger(index,0,0,n-1),align=options?.align??"auto",behavior=prefersReducedMotion(this.ownerDocument.defaultView)?"auto":options?.behavior??"smooth";this.performScrollTo(clamped,align,behavior)?this.beginPendingScrollCorrection(clamped,align,behavior):this.pendingScrollCorrection=void 0}hasUnmeasuredGroupThrough(index){return this.normalizedGroups.some(group=>group.startIndex<=index&&group.label!==""&&!this.measuredGroupHeights.has(group.startIndex))}beginPendingScrollCorrection(index,align,behavior,activeItemId){if(this.fixedRowHeight!=null&&!this.hasUnmeasuredGroupThrough(index)){this.pendingScrollCorrection=void 0;return}this.pendingScrollCorrection={identity:this.identityAt(index),index,align,behavior,source:this.effectiveSource,keyFunction:this.keyFunction,activeItemId:activeItemId===""?void 0:activeItemId,lastMeasurementGeneration:this.measurementGeneration}}performScrollTo(index,align,behavior){const metrics=this.readScrollMetrics();if(!metrics)return!1;const inset=this.stickyInset,top=this.offsetAt(index),bottom=this.rowBottomAt(index),viewTop=metrics.rawScrollTop,viewBottom=viewTop+metrics.viewportHeight;let target=null;return align==="start"?target=top-inset:align==="end"?target=bottom-metrics.viewportHeight:top-inset<viewTop?target=top-inset:bottom>viewBottom&&(target=bottom-metrics.viewportHeight),target===null?!1:(this.applyScrollPosition(target,behavior),!0)}maybeCorrectPendingScroll(){const pending=this.pendingScrollCorrection;if(!pending||pending.lastMeasurementGeneration>=this.measurementGeneration)return;if(pending.source!==this.effectiveSource||pending.keyFunction!==this.keyFunction||pending.activeItemId!==void 0&&!Object.is(pending.activeItemId,this.activeItemId)){this.pendingScrollCorrection=void 0;return}const index=pending.activeItemId!==void 0?this.activeIndex:isIndexedSource(this.effectiveSource)?pending.index:this.rowIdentities.indexOf(pending.identity);if(index<0||index>=this.itemCount||this.identityAt(index)!==pending.identity){this.pendingScrollCorrection=void 0;return}this.performScrollTo(index,pending.align,pending.behavior),pending.index=index,pending.lastMeasurementGeneration=this.measurementGeneration,(this.fixedRowHeight!=null||this.measuredHeights.has(pending.identity))&&!this.hasUnmeasuredGroupThrough(index)&&(this.pendingScrollCorrection=void 0)}emitRangeChangeIfNeeded(){if(this.visibleEnd<this.visibleStart){this.lastEmittedStart=-1,this.lastEmittedEnd=-1;return}this.visibleStart===this.lastEmittedStart&&this.visibleEnd===this.lastEmittedEnd||(this.lastEmittedStart=this.visibleStart,this.lastEmittedEnd=this.visibleEnd,this.emit("lr-visible-range-change",{start:this.visibleStart,end:this.visibleEnd}))}maybeFireLoadMore(){const n=this.itemCount;if(!(n>0&&this.visibleEnd>=n-1)){this.loadMoreArmed=!0;return}!this.hasMore||this.loading||!this.loadMoreArmed||(this.loadMoreArmed=!1,this.emit("lr-load-more"))}renderRow(item,index,total,activeIndex){const key=this.keyOf(item,index),top=this.offsetAt(index),isActive=index===activeIndex,isRowMode=this.itemRole==="row";return html`
|
|
1
|
+
var __decorate=function(decorators,target,key,desc){var c=arguments.length,r=c<3?target:desc===null?desc=Object.getOwnPropertyDescriptor(target,key):desc,d;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")r=Reflect.decorate(decorators,target,key,desc);else for(var i=decorators.length-1;i>=0;i--)(d=decorators[i])&&(r=(c<3?d(r):c>3?d(target,key,r):d(target,key))||r);return c>3&&r&&Object.defineProperty(target,key,r),r};import{html,nothing,render}from"lit";import{html as staticHtml,unsafeStatic}from"lit/static-html.js";import{property,state}from"lit/decorators.js";import{repeat}from"lit/directives/repeat.js";import{styleMap}from"lit/directives/style-map.js";import{LyraElement}from"../../../internal/lyra-element.js";import{literalSetConverter}from"../../../internal/converters.js";import{tag}from"../../../internal/prefix.js";import{prefersReducedMotion}from"../../../internal/motion.js";import{finiteAdd,finiteCount,finiteInteger,finiteNumber}from"../../../internal/numbers.js";import{getNumberFormat}from"../../../internal/intl-cache.js";import{getOwnDataDescriptor,MISSING_OWN_DATA_DESCRIPTOR,UNSAFE_OWN_DATA_DESCRIPTOR}from"../../../internal/data-descriptors.js";import{styles}from"./virtual-list.styles.js";const DEFAULT_ROW_ESTIMATE_PX=48,DEFAULT_GROUP_ESTIMATE_PX=32,DEFAULT_OVERSCAN_ROWS=6,MAX_OVERSCAN_ROWS=100,MAX_VIRTUAL_LIST_GROUPS=1e4,EMPTY_VIRTUAL_LIST_GROUPS=Object.freeze([]);function normalizeOverscan(value){if(value===null)return DEFAULT_OVERSCAN_ROWS;const numeric=typeof value=="number"?value:Number(value);return Number.isFinite(numeric)?Math.min(MAX_OVERSCAN_ROWS,Math.max(0,Math.floor(numeric))):DEFAULT_OVERSCAN_ROWS}const overscanConverter={fromAttribute(value){return normalizeOverscan(value)}};function virtualListGroupsChanged(value,oldValue){if(value===oldValue)return!1;const next=value,previous=oldValue;if(next==null||previous==null)return next!==previous;if(next.length!==previous.length)return!0;for(let index=0;index<next.length;index+=1){const a=next[index],b=previous[index];if(a.key!==b.key||a.label!==b.label||a.startIndex!==b.startIndex)return!0}return!1}const ROW_PROJECTION=literalSetConverter(["shadow","light"],"shadow"),VIRTUAL_LIST_ROW_ATTRIBUTE=`data-${tag("virtual-list-row")}`,VIRTUAL_LIST_STICKY_ATTRIBUTE=`data-${tag("virtual-list-sticky")}`,ROW_ATTRIBUTE_STATIC=unsafeStatic(VIRTUAL_LIST_ROW_ATTRIBUTE),PROJECTION_ANCHOR_MARKER=`${tag("virtual-list")}-projection`;function normalizeRowHeight(value){if(value==="auto")return"auto";const numeric=typeof value=="number"?value:Number(value);return Number.isFinite(numeric)&&numeric>0?numeric:"auto"}const rowHeightConverter={fromAttribute(value){return value===null?"auto":normalizeRowHeight(value)}};function isIndexedSource(source){return!Array.isArray(source)}const ELEMENT_NODE_TYPE=1;function isWindowScroller(target){return target.window===target}function domKeyToken(key){if(typeof key=="number"){if(Number.isNaN(key))return"number:NaN";if(Object.is(key,-0))return"number:-0"}return`${typeof key}:${String(key)}`}class LyraVirtualList extends LyraElement{constructor(){super(...arguments),this.items=[],this.renderItem=()=>nothing,this.rowHeight="auto",this.itemRole="listitem",this._rowProjection="shadow",this.rowIndexOffset=0,this.overscan=DEFAULT_OVERSCAN_ROWS,this.activeItemId="",this.loading=!1,this.hasMore=!1,this.containerScrollTop=0,this.viewportHeight=0,this.renderUnmeasuredWindow=!0,this.offsets=[0],this.rowIdentities=[],this.fixedRowHeight=null,this.measuredHeights=new Map,this.measuredIndices=new Map,this.indexedMeasurementIndices=[],this.indexedMeasurementDeltaPrefix=[0],this.indexedMeasurementIndexDirty=!0,this.offsetsDirty=!0,this.itemsChangedPendingPrune=!1,this.renderStart=0,this.renderEnd=-1,this.renderedWindow=[],this.projectionDeferred=!0,this.releaseRowProjection=()=>{this.projectionDeferred=!1,this.requestUpdate()},this.visibleStart=0,this.visibleEnd=-1,this.lastEmittedStart=-1,this.lastEmittedEnd=-1,this.loadMoreArmed=!0,this.measurementGeneration=0,this.isFirstUpdate=!0,this.stickyHeight=0,this.observedRows=new Map,this.observedRowKeys=new WeakMap,this.observedRowIndices=new WeakMap,this.observedGroups=new Map,this.observedGroupIndices=new WeakMap,this.externalMetricsPending=!1,this.ownerRealmGeneration=0,this.inResizeDelivery=!1,this.deferredRowObservations=new Map,this.deferredGroupObservations=new Map,this.activeIndexForLength=-1,this.activeIndexForId="",this.activeIndexCache=-1,this.pendingScrollTop=null,this.normalizedGroups=EMPTY_VIRTUAL_LIST_GROUPS,this.normalizedGroupByIndex=new Map,this.measuredGroupHeights=new Map,this.groupHeightPrefix=[0],this.onExternalViewportResize=()=>{this.syncExternalScrollMetrics()},this.onUserScrollIntent=event=>{event instanceof KeyboardEvent&&!new Set(["ArrowUp","ArrowDown","PageUp","PageDown","Home","End"," "]).has(event.key)||(this.pendingScrollCorrection=void 0)},this.onScroll=e=>{if(this.externalScroller?(this.pendingScrollTop=null,this.externalMetricsPending=!0):this.pendingScrollTop=e.currentTarget.scrollTop,this.scrollRafId!==void 0)return;const ownerDocument=this.ownerDocument,ownerWindow=ownerDocument.defaultView;if(!ownerWindow||!this.isConnected)return;const generation=this.ownerRealmGeneration,handle=ownerWindow.requestAnimationFrame(()=>{if(!(this.scrollRafId!==handle||this.scrollRafOwner!==ownerWindow||this.scrollRafDocument!==ownerDocument||!this.isCurrentOwnerWork(ownerDocument,generation))){if(this.scrollRafId=void 0,this.scrollRafOwner=void 0,this.scrollRafDocument=void 0,this.externalMetricsPending){this.externalMetricsPending=!1;const metrics=this.readScrollMetrics();metrics&&(this.pendingScrollTop=metrics.scrollTop,this.viewportHeight!==metrics.viewportHeight&&(this.viewportHeight=metrics.viewportHeight))}if(this.pendingScrollTop!==null){const scrollTop=this.pendingScrollTop;this.pendingScrollTop=null;const moved=this.containerScrollTop!==scrollTop;this.containerScrollTop=scrollTop,moved&&this.emit("lr-virtual-scroll",{scrollTop,viewportHeight:this.viewportHeight})}}});this.scrollRafId=handle,this.scrollRafOwner=ownerWindow,this.scrollRafDocument=ownerDocument},this.onRowsResized=entries=>{if(this.beginResizeDelivery(),this.fixedRowHeight!=null)return;const base=this.scrollContainer,oldScrollTop=this.readScrollMetrics()?.rawScrollTop??this.containerScrollTop;let scrollAdjustment=0,changed=!1;for(const entry of entries){const row=entry.target,key=this.observedRowKeys.get(row),index=this.observedRowIndices.get(row);if(key===void 0||index===void 0)continue;const height=entry.borderBoxSize?.[0]?.blockSize??entry.target.getBoundingClientRect().height,prev=this.measuredHeights.get(key);if(prev===void 0||Math.abs(prev-height)>.5){const oldBottom=this.rowBottomAt(index);this.measuredHeights.set(key,height),this.measuredIndices.set(key,index);const oldHeight=prev??DEFAULT_ROW_ESTIMATE_PX;oldBottom<=oldScrollTop&&(scrollAdjustment+=height-oldHeight),changed=!0}}if(changed){if(this.indexedMeasurementIndexDirty=!0,base&&scrollAdjustment!==0){const nextScrollTop=oldScrollTop+scrollAdjustment;this.applyScrollPosition(nextScrollTop),this.containerScrollTop=Math.max(0,nextScrollTop),this.pendingScrollTop=null}this.offsetsDirty=!0,this.measurementGeneration+=1,this.requestUpdate()}},this.onGroupsResized=entries=>{this.beginResizeDelivery();const base=this.scrollContainer,oldScrollTop=this.readScrollMetrics()?.rawScrollTop??this.containerScrollTop;let scrollAdjustment=0,changed=!1;for(const entry of entries){const marker=entry.target,index=this.observedGroupIndices.get(marker);if(index===void 0||!this.normalizedGroupByIndex.has(index))continue;const height=entry.borderBoxSize?.[0]?.blockSize??entry.target.getBoundingClientRect().height;if(!Number.isFinite(height)||height<0)continue;const previous=this.measuredGroupHeights.get(index)??DEFAULT_GROUP_ESTIMATE_PX;if(Math.abs(previous-height)<=.5)continue;const oldRowTop=this.offsetAt(index);this.measuredGroupHeights.set(index,height),oldRowTop<=oldScrollTop&&(scrollAdjustment+=height-previous),changed=!0}if(changed){if(base&&scrollAdjustment!==0){const nextScrollTop=oldScrollTop+scrollAdjustment;this.applyScrollPosition(nextScrollTop),this.containerScrollTop=Math.max(0,nextScrollTop),this.pendingScrollTop=null}this.offsetsDirty=!0,this.measurementGeneration+=1,this.requestUpdate()}},this.onStickyResized=entries=>{this.beginResizeDelivery();const entry=entries[0];if(!entry)return;const height=entry.borderBoxSize?.[0]?.blockSize??entry.contentRect.height;Math.abs(this.stickyHeight-height)>.5&&(this.stickyHeight=height)}}static{this.ownedCollectionProperties=Object.freeze(["items","source","groups"])}static{this.identityCollectionProperties=Object.freeze(["items","source"])}static{this.identityCollectionObjectProperties=Object.freeze(["source"])}static{this.styles=[LyraElement.styles,styles]}get rowProjection(){return this._rowProjection}set rowProjection(next){const normalized=ROW_PROJECTION.normalize(next),previous=this._rowProjection;previous!==normalized&&(this._rowProjection=normalized,this.requestUpdate("rowProjection",previous))}get scrollContainer(){return this.renderRoot?.querySelector('[part="base"]')??void 0}get renderedRows(){const root=this.renderRoot;return root?[...root.querySelectorAll('[part="row"]')]:[]}get projectedRows(){const rows=[];for(const child of this.children)child.hasAttribute(VIRTUAL_LIST_ROW_ATTRIBUTE)&&rows.push(child);return rows}get externalScroller(){const target=this.scrollElement;if(target!=null)return isWindowScroller(target)||target.nodeType===ELEMENT_NODE_TYPE?target:void 0}get spacerElement(){return this.renderRoot?.querySelector('[part="spacer"]')??void 0}readScrollMetrics(){const base=this.scrollContainer;if(!base)return null;const external=this.externalScroller;if(!external)return{scrollTop:base.scrollTop,rawScrollTop:base.scrollTop,viewportHeight:base.clientHeight};const spacerTop=(this.spacerElement??base).getBoundingClientRect().top;if(isWindowScroller(external)){const documentHeight=finiteNumber(external.document?.documentElement?.clientHeight??0,0),rawScrollTop2=finiteNumber(-spacerTop,0);return{scrollTop:Math.max(0,rawScrollTop2),rawScrollTop:rawScrollTop2,viewportHeight:documentHeight>0?documentHeight:finiteNumber(external.innerHeight,0)}}const scrollerTop=external.getBoundingClientRect().top,rawScrollTop=finiteNumber(scrollerTop-spacerTop,0);return{scrollTop:Math.max(0,rawScrollTop),rawScrollTop,viewportHeight:finiteNumber(external.clientHeight,0)}}applyScrollPosition(top,behavior){const external=this.externalScroller;if(!external){const base=this.scrollContainer;if(!base)return;const next2=Math.max(0,finiteNumber(top,0));behavior===void 0?base.scrollTop=next2:base.scrollTo({top:next2,behavior});return}const metrics=this.readScrollMetrics();if(!metrics)return;const delta=finiteNumber(top,metrics.rawScrollTop)-metrics.rawScrollTop;if(isWindowScroller(external)){const options={top:Math.max(0,finiteNumber(external.scrollY+delta,0))};behavior!==void 0&&(options.behavior=behavior),external.scrollTo(options);return}const next=Math.max(0,finiteNumber(external.scrollTop+delta,0));behavior===void 0?external.scrollTop=next:external.scrollTo({top:next,behavior})}syncExternalScrollMetrics(){const metrics=this.readScrollMetrics();metrics&&(this.viewportHeight!==metrics.viewportHeight&&(this.viewportHeight=metrics.viewportHeight),this.containerScrollTop!==metrics.scrollTop&&(this.containerScrollTop=metrics.scrollTop))}get safeRowIndexOffset(){return finiteCount(this.rowIndexOffset)}computedAriaRowIndex(index){return finiteInteger(finiteAdd(index+1,this.safeRowIndexOffset),1,1,Number.MAX_SAFE_INTEGER)}get activeIndex(){if(this.activeItemId==="")return-1;const source=this.effectiveSource,count=this.itemCount;if(this.activeIndexFor===source&&this.activeIndexForLength===count&&Object.is(this.activeIndexForId,this.activeItemId)&&this.activeIndexForKeyFn===this.keyFunction)return this.activeIndexCache;if(this.activeIndexFor=source,this.activeIndexForLength=count,this.activeIndexForId=this.activeItemId,this.activeIndexForKeyFn=this.keyFunction,this.activeIndexCache=-1,isIndexedSource(source)){if(!this.keyFunction&&source.indexOfKey){const candidate=source.indexOfKey(this.activeItemId);Number.isInteger(candidate)&&candidate>=0&&candidate<count&&(this.activeIndexCache=candidate)}return this.activeIndexCache}for(let index=0;index<count;index++){const item=this.itemAt(index);if(Object.is(this.keyOf(item,index),this.activeItemId)){this.activeIndexCache=index;break}}return this.activeIndexCache}connectedCallback(){super.connectedCallback(),this.ownerDocument.defaultView&&(this.seedFirstRenderState(()=>{this.renderUnmeasuredWindow=!1,this.requestUpdate()}),this.seedFirstRenderState(this.releaseRowProjection),this.hasUpdated&&(this.projectionDeferred=!1)),this.resetOwnerRealmWork();const ownerDocument=this.ownerDocument,ownerWindow=ownerDocument.defaultView,generation=this.ownerRealmGeneration,ResizeObserverCtor=ownerWindow?.ResizeObserver;if(ResizeObserverCtor){const rowObserver=new ResizeObserverCtor(entries=>{this.rowResizeObserver!==rowObserver||!this.isCurrentOwnerWork(ownerDocument,generation)||this.onRowsResized(entries)}),groupObserver=new ResizeObserverCtor(entries=>{this.groupResizeObserver!==groupObserver||!this.isCurrentOwnerWork(ownerDocument,generation)||this.onGroupsResized(entries)}),stickyObserver=new ResizeObserverCtor(entries=>{this.stickyResizeObserver!==stickyObserver||!this.isCurrentOwnerWork(ownerDocument,generation)||this.onStickyResized(entries)});this.rowResizeObserver=rowObserver,this.groupResizeObserver=groupObserver,this.stickyResizeObserver=stickyObserver}this.hasUpdated&&(this.syncRowProjection(),this.attachContainerListeners(),this.syncRowObservers(),this.syncGroupObservers(),this.syncStickyOverlay())}disconnectedCallback(){this.teardownRowProjection(),this.resetOwnerRealmWork(),super.disconnectedCallback()}adoptedCallback(){super.adoptedCallback(),this.teardownRowProjection(),this.resetOwnerRealmWork()}isCurrentOwnerWork(ownerDocument,generation){return this.ownerRealmGeneration===generation&&this.isConnected&&this.ownerDocument===ownerDocument}resetOwnerRealmWork(){this.ownerRealmGeneration+=1,this.rowResizeObserver?.disconnect(),this.rowResizeObserver=void 0,this.groupResizeObserver?.disconnect(),this.groupResizeObserver=void 0,this.observedRows.clear(),this.observedGroups.clear(),this.deferredRowObservations.clear(),this.deferredGroupObservations.clear(),this.inResizeDelivery=!1,this.rowObserveRafId!==void 0&&this.rowObserveRafOwner?.cancelAnimationFrame(this.rowObserveRafId),this.rowObserveRafId=void 0,this.rowObserveRafOwner=void 0,this.rowObserveRafDocument=void 0,this.containerResizeObserver?.disconnect(),this.containerResizeObserver=void 0,this.stickyResizeObserver?.disconnect(),this.stickyResizeObserver=void 0,this.observedSticky=void 0,this.scrollRafId!==void 0&&this.scrollRafOwner?.cancelAnimationFrame(this.scrollRafId),this.scrollRafId=void 0,this.scrollRafOwner=void 0,this.scrollRafDocument=void 0,this.pendingScrollTop=null,this.externalMetricsPending=!1,this.pendingScrollCorrection=void 0,this.detachContainerListeners(),this.scrollListenerTarget=void 0}firstUpdated(changed){super.firstUpdated(changed),this.attachContainerListeners()}willUpdate(changed){super.willUpdate(changed),this.projectionDeferred&&!this.hasUpdated&&this.ownerDocument?.defaultView&&this.seedFirstRenderState(this.releaseRowProjection),this.isFirstUpdate=!this.hasUpdated,(changed.has("items")||changed.has("source")||changed.has("keyFunction")||changed.has("rowHeight")||changed.has("groups")||changed.has("activeItemId")||changed.has("scrollElement"))&&(this.pendingScrollCorrection=void 0),(changed.has("items")||changed.has("source")||changed.has("rowHeight")||changed.has("keyFunction")||changed.has("groups"))&&(this.offsetsDirty=!0),(changed.has("items")||changed.has("source"))&&(this.itemsChangedPendingPrune=!0),(changed.has("keyFunction")||isIndexedSource(this.effectiveSource)&&(changed.has("items")||changed.has("source")))&&(this.measuredHeights.clear(),this.measuredIndices.clear(),this.indexedMeasurementIndexDirty=!0),changed.has("groups")&&this.measuredGroupHeights.clear(),(changed.has("items")||changed.has("source")||changed.has("groups"))&&this.recomputeGroups(),changed.has("rowHeight")&&(this.fixedRowHeight=this.parseRowHeight(this.rowHeight),this.fixedRowHeight!=null&&(this.measuredHeights.clear(),this.measuredIndices.clear(),this.indexedMeasurementIndexDirty=!0)),this.offsetsDirty&&(this.recomputeOffsets(),this.offsetsDirty=!1),this.computeRange()}updated(changed){super.updated(changed),this.syncRowProjection(),this.syncRowObservers(),this.syncGroupObservers(),this.syncStickyOverlay(),changed.has("scrollElement")&&!this.isFirstUpdate&&this.attachContainerListeners(),changed.has("activeItemId")&&!this.isFirstUpdate&&this.scrollActiveIntoView(),this.emitRangeChangeIfNeeded(),this.maybeFireLoadMore(),this.maybeCorrectPendingScroll()}parseRowHeight(value){const normalized=normalizeRowHeight(value);return normalized==="auto"?null:normalized}get effectiveSource(){return this.source??this.items}get itemCount(){const source=this.effectiveSource;return isIndexedSource(source)?finiteCount(source.count):source.length}itemAt(index){const source=this.effectiveSource;return isIndexedSource(source)?source.itemAt(index):source[index]}keyOf(item,index){const source=this.effectiveSource,key=this.keyFunction?this.keyFunction(item,index):isIndexedSource(source)?source.keyAt?.(index)??index:index;return typeof key=="string"||typeof key=="number"?key:index}rowIdentity(key,occurrence){const token=domKeyToken(key);return`${token.length}:${token}:${occurrence}`}identityAt(index,item=this.itemAt(index)){return isIndexedSource(this.effectiveSource)?this.rowIdentity(this.keyOf(item,index),index):this.rowIdentities[index]??this.rowIdentity(this.keyOf(item,index),index)}groupHeightAt(index){const group=this.normalizedGroupByIndex.get(index);return!group||group.label===""?0:this.measuredGroupHeights.get(index)??DEFAULT_GROUP_ESTIMATE_PX}rowHeightAt(index){return this.fixedRowHeight!=null?this.fixedRowHeight:this.measuredHeights.get(this.identityAt(index))??DEFAULT_ROW_ESTIMATE_PX}groupContributionThrough(index){let low=0,high=this.normalizedGroups.length;for(;low<high;){const middle=low+high>>1;this.normalizedGroups[middle].startIndex<=index?low=middle+1:high=middle}return this.groupHeightPrefix[low]??0}recomputeGroupHeightPrefix(){const prefix=new Array(this.normalizedGroups.length+1);prefix[0]=0;for(let index=0;index<this.normalizedGroups.length;index++){const group=this.normalizedGroups[index],height=group.label===""?0:this.measuredGroupHeights.get(group.startIndex)??DEFAULT_GROUP_ESTIMATE_PX;prefix[index+1]=finiteAdd(prefix[index],height)}this.groupHeightPrefix=prefix}indexedOffsetForIndex(index){const baseHeight=this.fixedRowHeight??DEFAULT_ROW_ESTIMATE_PX;let offset=index>Number.MAX_VALUE/baseHeight?Number.MAX_VALUE:index*baseHeight;if(this.fixedRowHeight==null){this.rebuildIndexedMeasurementIndex();let low=0,high=this.indexedMeasurementIndices.length;for(;low<high;){const middle=low+high>>1;this.indexedMeasurementIndices[middle]<index?low=middle+1:high=middle}offset=finiteAdd(offset,this.indexedMeasurementDeltaPrefix[low]??0)}return Math.max(0,finiteAdd(offset,this.groupContributionThrough(index)))}rebuildIndexedMeasurementIndex(){if(!this.indexedMeasurementIndexDirty)return;const retained=[];for(const[identity,index]of this.measuredIndices){const height=this.measuredHeights.get(identity);height!==void 0&&retained.push({index,delta:height-DEFAULT_ROW_ESTIMATE_PX})}retained.sort((a,b)=>a.index-b.index);const indices=new Array(retained.length),prefix=new Array(retained.length+1);prefix[0]=0;for(let position=0;position<retained.length;position++){const measurement=retained[position];indices[position]=measurement.index,prefix[position+1]=finiteAdd(prefix[position],measurement.delta)}this.indexedMeasurementIndices=indices,this.indexedMeasurementDeltaPrefix=prefix,this.indexedMeasurementIndexDirty=!1}pruneIndexedMeasurements(){if(!isIndexedSource(this.effectiveSource)||this.fixedRowHeight!=null||this.renderEnd<this.renderStart)return!1;const renderedCount=this.renderEnd-this.renderStart+1,retentionRows=Math.max(renderedCount,normalizeOverscan(this.overscan)*4),firstRetained=Math.max(0,this.renderStart-retentionRows),lastRetained=Math.min(this.itemCount-1,this.renderEnd+retentionRows);let removedDeltaBeforeWindow=0,pruned=!1;for(const[identity,measuredIndex]of this.measuredIndices)if(measuredIndex<firstRetained||measuredIndex>lastRetained){const height=this.measuredHeights.get(identity);height!==void 0&&measuredIndex<firstRetained&&(removedDeltaBeforeWindow=finiteAdd(removedDeltaBeforeWindow,height-DEFAULT_ROW_ESTIMATE_PX)),this.measuredIndices.delete(identity),this.measuredHeights.delete(identity),pruned=!0}if(pruned&&(this.indexedMeasurementIndexDirty=!0,removedDeltaBeforeWindow!==0)){const nextScrollTop=(this.readScrollMetrics()?.rawScrollTop??this.containerScrollTop)-removedDeltaBeforeWindow;this.applyScrollPosition(nextScrollTop),this.containerScrollTop=Math.max(0,nextScrollTop),this.pendingScrollTop=null}return pruned}offsetAt(index){return isIndexedSource(this.effectiveSource)?this.indexedOffsetForIndex(index):this.offsets[index]??0}recomputeOffsets(){const n=this.itemCount;if(this.recomputeGroupHeightPrefix(),isIndexedSource(this.effectiveSource)){this.offsets=[0],this.rowIdentities=[],this.itemsChangedPendingPrune=!1;return}const offsets=new Array(n+1);let cursor=0;const liveKeys=this.itemsChangedPendingPrune&&this.fixedRowHeight==null?new Set:null,occurrences=new Map,identities=new Array(n);for(let i=0;i<n;i++){cursor=finiteAdd(cursor,this.groupHeightAt(i)),offsets[i]=cursor;const key=this.keyOf(this.itemAt(i),i),token=domKeyToken(key),occurrence=occurrences.get(token)??0;occurrences.set(token,occurrence+1);const identity=this.rowIdentity(key,occurrence);identities[i]=identity;let h;this.fixedRowHeight!=null?h=this.fixedRowHeight:(liveKeys?.add(identity),h=this.measuredHeights.get(identity)??DEFAULT_ROW_ESTIMATE_PX),cursor=finiteAdd(cursor,h)}if(offsets[n]=cursor,this.offsets=offsets,this.rowIdentities=identities,this.itemsChangedPendingPrune=!1,liveKeys){for(const key of this.measuredHeights.keys())liveKeys.has(key)||(this.measuredHeights.delete(key),this.measuredIndices.delete(key),this.indexedMeasurementIndexDirty=!0);for(const key of this.measuredIndices.keys())liveKeys.has(key)||(this.measuredIndices.delete(key),this.indexedMeasurementIndexDirty=!0)}}groupTopAt(index){return Math.max(0,this.offsetAt(index)-this.groupHeightAt(index))}rowBottomAt(index){return finiteAdd(this.offsetAt(index),this.rowHeightAt(index))}entryTopAt(index){return this.groupTopAt(index)}findIndexAtOrAfter(offset){let lo=0,hi=this.itemCount-1;for(;lo<hi;){const mid=lo+Math.floor((hi-lo)/2);this.rowBottomAt(mid)<=offset?lo=mid+1:hi=mid}return lo}findIndexAtOrBefore(offset){let lo=0,hi=this.itemCount-1;for(;lo<hi;){const mid=lo+Math.ceil((hi-lo)/2);this.entryTopAt(mid)<offset?lo=mid:hi=mid-1}return lo}offsetForIndex(index){const clamped=Math.min(this.itemCount,Math.max(0,Math.trunc(index)||0));return this.offsetAt(clamped)}indexAtOffset(px){const n=this.itemCount;return n===0?-1:Number.isFinite(px)?Math.min(n-1,Math.max(0,this.findIndexAtOrAfter(px))):px>0?n-1:0}computeRange(){const n=this.itemCount;if(n===0){this.visibleStart=0,this.visibleEnd=-1,this.renderStart=0,this.renderEnd=-1;return}if(this.viewportHeight<=0){if(!this.renderUnmeasuredWindow){this.visibleStart=0,this.visibleEnd=-1,this.renderStart=0,this.renderEnd=-1;return}this.visibleStart=0,this.visibleEnd=0,this.renderStart=0,this.renderEnd=Math.min(n-1,normalizeOverscan(this.overscan));return}const viewTop=this.containerScrollTop,viewBottom=viewTop+this.viewportHeight;this.visibleStart=this.findIndexAtOrAfter(viewTop),this.visibleEnd=this.findIndexAtOrBefore(viewBottom);const overscan=normalizeOverscan(this.overscan);this.renderStart=Math.max(0,this.visibleStart-overscan),this.renderEnd=Math.min(n-1,this.visibleEnd+overscan),this.pruneIndexedMeasurements()&&this.computeRange()}attachContainerListeners(){const base=this.scrollContainer,ownerDocument=this.ownerDocument,ownerWindow=ownerDocument.defaultView;if(!base||!this.isConnected||!ownerWindow)return;this.containerResizeObserver?.disconnect(),this.containerResizeObserver=void 0,this.detachContainerListeners();const external=this.externalScroller,scrollTarget=external??base,generation=this.ownerRealmGeneration,ResizeObserverCtor=ownerWindow.ResizeObserver;if(ResizeObserverCtor){const observer=new ResizeObserverCtor(entries=>{if(this.containerResizeObserver!==observer||this.scrollListenerTarget!==scrollTarget||!this.isCurrentOwnerWork(ownerDocument,generation))return;if(this.beginResizeDelivery(),external){this.syncExternalScrollMetrics();return}const entry=entries[0];entry&&(this.viewportHeight=entry.borderBoxSize?.[0]?.blockSize??entry.contentRect.height)});this.containerResizeObserver=observer,observer.observe(base),external&&!isWindowScroller(external)&&observer.observe(external)}scrollTarget.addEventListener("scroll",this.onScroll,{passive:!0}),scrollTarget.addEventListener("wheel",this.onUserScrollIntent,{passive:!0}),scrollTarget.addEventListener("pointerdown",this.onUserScrollIntent,{passive:!0}),scrollTarget.addEventListener("touchstart",this.onUserScrollIntent,{passive:!0}),scrollTarget.addEventListener("keydown",this.onUserScrollIntent),this.scrollListenerTarget=scrollTarget,external&&isWindowScroller(external)&&(external.addEventListener("resize",this.onExternalViewportResize,{passive:!0}),this.viewportResizeTarget=external),ownerWindow.queueMicrotask(()=>{if(this.scrollListenerTarget!==scrollTarget||this.scrollContainer!==base||!this.isCurrentOwnerWork(ownerDocument,generation))return;const metrics=this.readScrollMetrics();metrics&&(this.viewportHeight!==metrics.viewportHeight&&(this.viewportHeight=metrics.viewportHeight),this.containerScrollTop!==metrics.scrollTop&&(this.containerScrollTop=metrics.scrollTop))})}detachContainerListeners(){const viewportTarget=this.viewportResizeTarget;viewportTarget&&(viewportTarget.removeEventListener("resize",this.onExternalViewportResize),this.viewportResizeTarget=void 0);const target=this.scrollListenerTarget;target&&(target.removeEventListener("scroll",this.onScroll),target.removeEventListener("wheel",this.onUserScrollIntent),target.removeEventListener("pointerdown",this.onUserScrollIntent),target.removeEventListener("touchstart",this.onUserScrollIntent),target.removeEventListener("keydown",this.onUserScrollIntent))}beginResizeDelivery(){if(this.inResizeDelivery=!0,this.rowObserveRafId!==void 0)return;const ownerDocument=this.ownerDocument,ownerWindow=ownerDocument.defaultView;if(!ownerWindow||!this.isConnected){this.inResizeDelivery=!1;return}const generation=this.ownerRealmGeneration,handle=ownerWindow.requestAnimationFrame(()=>{if(this.rowObserveRafId!==handle||this.rowObserveRafOwner!==ownerWindow||this.rowObserveRafDocument!==ownerDocument||!this.isCurrentOwnerWork(ownerDocument,generation))return;this.rowObserveRafId=void 0,this.rowObserveRafOwner=void 0,this.rowObserveRafDocument=void 0,this.inResizeDelivery=!1;const ro=this.rowResizeObserver;for(const[identity,el]of this.deferredRowObservations)ro&&this.observedRows.get(identity)===el&&ro.observe(el);this.deferredRowObservations.clear();const groupObserver=this.groupResizeObserver;for(const[index,el]of this.deferredGroupObservations)groupObserver&&this.observedGroups.get(index)===el&&groupObserver.observe(el);this.deferredGroupObservations.clear()});this.rowObserveRafId=handle,this.rowObserveRafOwner=ownerWindow,this.rowObserveRafDocument=ownerDocument}syncRowObservers(){const ro=this.rowResizeObserver;if(!ro)return;if(this.fixedRowHeight!=null){for(const el of this.observedRows.values())ro.unobserve(el);this.observedRows.clear(),this.deferredRowObservations.clear();return}const current=new Map;this.renderRoot.querySelectorAll('[part="row"]').forEach(el=>{const index=Number(el.getAttribute("data-row-index"));if(!Number.isInteger(index)||index<0||index>=this.itemCount)return;const identity=this.identityAt(index);current.set(identity,el),this.observedRowKeys.set(el,identity),this.observedRowIndices.set(el,index)});for(const[identity,el]of this.observedRows)current.get(identity)!==el&&(ro.unobserve(el),this.observedRows.delete(identity),this.deferredRowObservations.delete(identity));for(const[identity,el]of current)this.observedRows.has(identity)||(this.observedRows.set(identity,el),this.inResizeDelivery?this.deferredRowObservations.set(identity,el):ro.observe(el))}syncGroupObservers(){const observer=this.groupResizeObserver;if(!observer)return;const current=new Map;this.renderRoot.querySelectorAll('[part="group"][data-group-index]').forEach(marker=>{const index=Number(marker.dataset.groupIndex);!Number.isInteger(index)||!this.normalizedGroupByIndex.has(index)||(current.set(index,marker),this.observedGroupIndices.set(marker,index))});for(const[index,marker]of this.observedGroups)current.get(index)!==marker&&(observer.unobserve(marker),this.observedGroups.delete(index),this.deferredGroupObservations.delete(index));for(const[index,marker]of current)this.observedGroups.has(index)||(this.observedGroups.set(index,marker),this.inResizeDelivery?this.deferredGroupObservations.set(index,marker):observer.observe(marker))}get stickyInset(){return this.renderStickyGroup?this.stickyHeight:0}scrollActiveIntoView(){const index=this.activeIndex;if(index<0)return;const behavior=prefersReducedMotion(this.ownerDocument.defaultView)?"auto":"smooth";this.performScrollTo(index,"auto",behavior)&&this.beginPendingScrollCorrection(index,"auto",behavior,this.activeItemId)}scrollToIndex(index,options){const n=this.itemCount;if(n===0)return;const clamped=finiteInteger(index,0,0,n-1),align=options?.align??"auto",behavior=prefersReducedMotion(this.ownerDocument.defaultView)?"auto":options?.behavior??"smooth";this.performScrollTo(clamped,align,behavior)?this.beginPendingScrollCorrection(clamped,align,behavior):this.pendingScrollCorrection=void 0}hasUnmeasuredGroupThrough(index){return this.normalizedGroups.some(group=>group.startIndex<=index&&group.label!==""&&!this.measuredGroupHeights.has(group.startIndex))}beginPendingScrollCorrection(index,align,behavior,activeItemId){if(this.fixedRowHeight!=null&&!this.hasUnmeasuredGroupThrough(index)){this.pendingScrollCorrection=void 0;return}this.pendingScrollCorrection={identity:this.identityAt(index),index,align,behavior,source:this.effectiveSource,keyFunction:this.keyFunction,activeItemId:activeItemId===""?void 0:activeItemId,lastMeasurementGeneration:this.measurementGeneration}}performScrollTo(index,align,behavior){const metrics=this.readScrollMetrics();if(!metrics)return!1;const inset=this.stickyInset,top=this.offsetAt(index),bottom=this.rowBottomAt(index),viewTop=metrics.rawScrollTop,viewBottom=viewTop+metrics.viewportHeight;let target=null;return align==="start"?target=top-inset:align==="end"?target=bottom-metrics.viewportHeight:top-inset<viewTop?target=top-inset:bottom>viewBottom&&(target=bottom-metrics.viewportHeight),target===null?!1:(this.applyScrollPosition(target,behavior),!0)}maybeCorrectPendingScroll(){const pending=this.pendingScrollCorrection;if(!pending||pending.lastMeasurementGeneration>=this.measurementGeneration)return;if(pending.source!==this.effectiveSource||pending.keyFunction!==this.keyFunction||pending.activeItemId!==void 0&&!Object.is(pending.activeItemId,this.activeItemId)){this.pendingScrollCorrection=void 0;return}const index=pending.activeItemId!==void 0?this.activeIndex:isIndexedSource(this.effectiveSource)?pending.index:this.rowIdentities.indexOf(pending.identity);if(index<0||index>=this.itemCount||this.identityAt(index)!==pending.identity){this.pendingScrollCorrection=void 0;return}this.performScrollTo(index,pending.align,pending.behavior),pending.index=index,pending.lastMeasurementGeneration=this.measurementGeneration,(this.fixedRowHeight!=null||this.measuredHeights.has(pending.identity))&&!this.hasUnmeasuredGroupThrough(index)&&(this.pendingScrollCorrection=void 0)}emitRangeChangeIfNeeded(){if(this.visibleEnd<this.visibleStart){this.lastEmittedStart=-1,this.lastEmittedEnd=-1;return}this.visibleStart===this.lastEmittedStart&&this.visibleEnd===this.lastEmittedEnd||(this.lastEmittedStart=this.visibleStart,this.lastEmittedEnd=this.visibleEnd,this.emit("lr-visible-range-change",{start:this.visibleStart,end:this.visibleEnd}))}maybeFireLoadMore(){const n=this.itemCount;if(!(n>0&&this.visibleEnd>=n-1)){this.loadMoreArmed=!0;return}!this.hasMore||this.loading||!this.loadMoreArmed||(this.loadMoreArmed=!1,this.emit("lr-load-more"))}get projectionActive(){return!this.projectionDeferred&&this.rowProjection==="light"}rowSlotName(identity){return`${tag("virtual-list")}-row-${identity}`}syncRowProjection(){if(!this.projectionActive||!this.isConnected){this.projectionAnchor!==void 0&&this.teardownRowProjection();return}const anchor=this.ensureProjectionAnchor();this.projectionPart=render(this.renderProjectedRows(),this,{renderBefore:anchor,host:this})}ensureProjectionAnchor(){const existing=this.projectionAnchor;if(existing!==void 0&&existing.parentNode===this&&existing.ownerDocument===this.ownerDocument)return existing;existing!==void 0&&this.teardownRowProjection();const anchor=this.ownerDocument.createComment(PROJECTION_ANCHOR_MARKER);return this.append(anchor),this.projectionAnchor=anchor,this.projectionPart=void 0,anchor}teardownRowProjection(){const anchor=this.projectionAnchor,part=this.projectionPart;if(this.projectionAnchor=void 0,this.projectionPart=void 0,anchor!==void 0){if(part!==void 0){const container=anchor.parentNode;container!==null&&render(nothing,container,{renderBefore:anchor,host:this});const start=part.startNode;start?.parentNode?.removeChild(start)}anchor.parentNode?.removeChild(anchor)}}renderProjectedRows(){return repeat(this.renderedWindow,w=>w.identity,w=>staticHtml`<div
|
|
2
|
+
${ROW_ATTRIBUTE_STATIC}
|
|
3
|
+
slot=${this.rowSlotName(w.identity)}
|
|
4
|
+
data-row-index=${w.index}
|
|
5
|
+
data-row-key=${domKeyToken(this.keyOf(w.item,w.index))}
|
|
6
|
+
>${this.renderItem(w.item,w.index)}</div>`)}renderRow(item,index,total,activeIndex,identity){const key=this.keyOf(item,index),top=this.offsetAt(index),isActive=index===activeIndex,isRowMode=this.itemRole==="row";return html`
|
|
2
7
|
<div
|
|
3
8
|
part="row"
|
|
4
9
|
role=${isRowMode?"row":"listitem"}
|
|
@@ -10,7 +15,7 @@ var __decorate=function(decorators,target,key,desc){var c=arguments.length,r=c<3
|
|
|
10
15
|
aria-current=${isActive?"true":"false"}
|
|
11
16
|
style=${styleMap({transform:`translateY(${top}px)`})}
|
|
12
17
|
>
|
|
13
|
-
${this.renderItem(item,index)}
|
|
18
|
+
${this.projectionActive?html`<slot name=${this.rowSlotName(identity)}></slot>`:this.renderItem(item,index)}
|
|
14
19
|
</div>
|
|
15
20
|
`}recomputeGroups(){const normalized=[],seen=new Set;try{const groups=this.groups;if(!Array.isArray(groups))throw new TypeError("groups must be an array");const length=getOwnDataDescriptor(groups,"length");if(length===MISSING_OWN_DATA_DESCRIPTOR||length===UNSAFE_OWN_DATA_DESCRIPTOR||typeof length.value!="number"||!Number.isSafeInteger(length.value)||length.value<0)throw new TypeError("groups must have a bounded length");for(let position=0;position<Math.min(length.value,MAX_VIRTUAL_LIST_GROUPS);position+=1){const entry=getOwnDataDescriptor(groups,String(position));if(entry===MISSING_OWN_DATA_DESCRIPTOR||entry===UNSAFE_OWN_DATA_DESCRIPTOR||entry.value===null||typeof entry.value!="object"||Array.isArray(entry.value))continue;const key=getOwnDataDescriptor(entry.value,"key"),label=getOwnDataDescriptor(entry.value,"label"),startIndex=getOwnDataDescriptor(entry.value,"startIndex");if(key===MISSING_OWN_DATA_DESCRIPTOR||key===UNSAFE_OWN_DATA_DESCRIPTOR||startIndex===MISSING_OWN_DATA_DESCRIPTOR||startIndex===UNSAFE_OWN_DATA_DESCRIPTOR||label===UNSAFE_OWN_DATA_DESCRIPTOR||typeof key.value!="string"&&typeof key.value!="number"||typeof startIndex.value!="number"||!Number.isInteger(startIndex.value)||startIndex.value<0||startIndex.value>=this.itemCount||seen.has(startIndex.value))continue;const labelValue=label===MISSING_OWN_DATA_DESCRIPTOR||typeof label.value!="string"?void 0:label.value;seen.add(startIndex.value),normalized.push(Object.freeze({key:key.value,startIndex:startIndex.value,...labelValue===void 0?{}:{label:labelValue}}))}}catch{}this.normalizedGroups=Object.freeze(normalized.sort((a,b)=>a.startIndex-b.startIndex)),this.normalizedGroupByIndex.clear();for(const group of this.normalizedGroups)this.normalizedGroupByIndex.set(group.startIndex,group)}renderGroups(){return this.normalizedGroups.filter(group=>group.startIndex>=this.renderStart&&group.startIndex<=this.renderEnd).filter(group=>group.label!=="").map(group=>html`
|
|
16
21
|
<div
|
|
@@ -20,7 +25,7 @@ var __decorate=function(decorators,target,key,desc){var c=arguments.length,r=c<3
|
|
|
20
25
|
>
|
|
21
26
|
${group.label??(typeof group.key=="number"?getNumberFormat(this.effectiveLocale).format(group.key):group.key)}
|
|
22
27
|
</div>
|
|
23
|
-
`)}currentStickyGroup(){const groups=this.normalizedGroups;if(groups.length===0)return null;const scrollTop=this.containerScrollTop;let low=0,high=groups.length-1,current=-1;for(;low<=high;){const middle=low+high>>1;this.groupTopAt(groups[middle].startIndex)<=scrollTop?(current=middle,low=middle+1):high=middle-1}if(current<0)return{group:groups[0],shift:0,active:!1};const next=groups[current+1];let shift=0;if(next&&this.stickyHeight>0){const distance=this.groupTopAt(next.startIndex)-scrollTop;distance<this.stickyHeight&&(shift=Math.min(0,distance-this.stickyHeight))}return{group:groups[current],shift,active:!0}}renderStickyLayer(){const
|
|
28
|
+
`)}currentStickyGroup(){const groups=this.normalizedGroups;if(groups.length===0)return null;const scrollTop=this.containerScrollTop;let low=0,high=groups.length-1,current=-1;for(;low<=high;){const middle=low+high>>1;this.groupTopAt(groups[middle].startIndex)<=scrollTop?(current=middle,low=middle+1):high=middle-1}if(current<0)return{group:groups[0],shift:0,active:!1};const next=groups[current+1];let shift=0;if(next&&this.stickyHeight>0){const distance=this.groupTopAt(next.startIndex)-scrollTop;distance<this.stickyHeight&&(shift=Math.min(0,distance-this.stickyHeight))}return{group:groups[current],shift,active:!0}}renderStickyLayer(){const render2=this.renderStickyGroup;if(!render2)return nothing;const state2=this.currentStickyGroup();return state2?html`
|
|
24
29
|
<div
|
|
25
30
|
part="sticky-group"
|
|
26
31
|
aria-hidden="true"
|
|
@@ -28,9 +33,9 @@ var __decorate=function(decorators,target,key,desc){var c=arguments.length,r=c<3
|
|
|
28
33
|
?data-inactive=${!state2.active}
|
|
29
34
|
style=${state2.shift!==0?`transform:translateY(${state2.shift}px)`:nothing}
|
|
30
35
|
>
|
|
31
|
-
${
|
|
36
|
+
${render2(state2.group)}
|
|
32
37
|
</div>
|
|
33
|
-
`:nothing}syncStickyOverlay(){const overlay=this.renderRoot.querySelector('[part="sticky-group"]');overlay!==this.observedSticky&&(this.observedSticky&&this.stickyResizeObserver?.unobserve(this.observedSticky),this.observedSticky=overlay??void 0,overlay&&this.stickyResizeObserver?.observe(overlay))}render(){const n=this.itemCount,totalHeight=this.offsetAt(n),windowed=[];for(let i=this.renderStart;i<=this.renderEnd;i++)windowed.push({item:this.
|
|
38
|
+
`:nothing}syncStickyOverlay(){const overlay=this.renderRoot.querySelector('[part="sticky-group"]');overlay!==this.observedSticky&&(this.observedSticky&&this.stickyResizeObserver?.unobserve(this.observedSticky),this.observedSticky=overlay??void 0,overlay&&this.stickyResizeObserver?.observe(overlay))}render(){const n=this.itemCount,totalHeight=this.offsetAt(n),windowed=[];for(let i=this.renderStart;i<=this.renderEnd;i++){const item=this.itemAt(i);windowed.push({item,index:i,identity:this.identityAt(i,item)})}this.renderedWindow=windowed;const isRowMode=this.itemRole==="row",stickyInset=this.stickyInset,activeIndex=this.activeIndex,isExternallyScrolled=this.externalScroller!==void 0;return html`
|
|
34
39
|
<div
|
|
35
40
|
part="base"
|
|
36
41
|
role=${isRowMode?"rowgroup":"list"}
|
|
@@ -46,8 +51,8 @@ var __decorate=function(decorators,target,key,desc){var c=arguments.length,r=c<3
|
|
|
46
51
|
style=${styleMap({height:`${totalHeight}px`})}
|
|
47
52
|
>
|
|
48
53
|
${this.renderGroups()}
|
|
49
|
-
${repeat(windowed,w=>
|
|
54
|
+
${repeat(windowed,w=>w.identity,w=>this.renderRow(w.item,w.index,n,activeIndex,w.identity))}
|
|
50
55
|
${this.renderStickyLayer()}
|
|
51
56
|
</div>
|
|
52
57
|
</div>
|
|
53
|
-
`}}__decorate([property({attribute:!1})],LyraVirtualList.prototype,"items",void 0),__decorate([property({attribute:!1})],LyraVirtualList.prototype,"source",void 0),__decorate([property({attribute:!1})],LyraVirtualList.prototype,"renderItem",void 0),__decorate([property({attribute:!1})],LyraVirtualList.prototype,"keyFunction",void 0),__decorate([property({attribute:!1,hasChanged:virtualListGroupsChanged})],LyraVirtualList.prototype,"groups",void 0),__decorate([property({attribute:!1})],LyraVirtualList.prototype,"renderStickyGroup",void 0),__decorate([property({attribute:"row-height",converter:rowHeightConverter})],LyraVirtualList.prototype,"rowHeight",void 0),__decorate([property({attribute:"item-role"})],LyraVirtualList.prototype,"itemRole",void 0),__decorate([property({type:Number,attribute:"row-index-offset"})],LyraVirtualList.prototype,"rowIndexOffset",void 0),__decorate([property({converter:overscanConverter})],LyraVirtualList.prototype,"overscan",void 0),__decorate([property({attribute:"active-item-id"})],LyraVirtualList.prototype,"activeItemId",void 0),__decorate([property({type:Boolean,reflect:!0})],LyraVirtualList.prototype,"loading",void 0),__decorate([property({type:Boolean,attribute:"has-more",reflect:!0})],LyraVirtualList.prototype,"hasMore",void 0),__decorate([property({attribute:!1})],LyraVirtualList.prototype,"scrollElement",void 0),__decorate([state()],LyraVirtualList.prototype,"containerScrollTop",void 0),__decorate([state()],LyraVirtualList.prototype,"viewportHeight",void 0),__decorate([state()],LyraVirtualList.prototype,"stickyHeight",void 0);export{LyraVirtualList,MAX_OVERSCAN_ROWS};
|
|
58
|
+
`}}__decorate([property({attribute:!1})],LyraVirtualList.prototype,"items",void 0),__decorate([property({attribute:!1})],LyraVirtualList.prototype,"source",void 0),__decorate([property({attribute:!1})],LyraVirtualList.prototype,"renderItem",void 0),__decorate([property({attribute:!1})],LyraVirtualList.prototype,"keyFunction",void 0),__decorate([property({attribute:!1,hasChanged:virtualListGroupsChanged})],LyraVirtualList.prototype,"groups",void 0),__decorate([property({attribute:!1})],LyraVirtualList.prototype,"renderStickyGroup",void 0),__decorate([property({attribute:"row-height",converter:rowHeightConverter})],LyraVirtualList.prototype,"rowHeight",void 0),__decorate([property({attribute:"item-role"})],LyraVirtualList.prototype,"itemRole",void 0),__decorate([property({attribute:"row-projection",converter:ROW_PROJECTION})],LyraVirtualList.prototype,"rowProjection",null),__decorate([property({type:Number,attribute:"row-index-offset"})],LyraVirtualList.prototype,"rowIndexOffset",void 0),__decorate([property({converter:overscanConverter})],LyraVirtualList.prototype,"overscan",void 0),__decorate([property({attribute:"active-item-id"})],LyraVirtualList.prototype,"activeItemId",void 0),__decorate([property({type:Boolean,reflect:!0})],LyraVirtualList.prototype,"loading",void 0),__decorate([property({type:Boolean,attribute:"has-more",reflect:!0})],LyraVirtualList.prototype,"hasMore",void 0),__decorate([property({attribute:!1})],LyraVirtualList.prototype,"scrollElement",void 0),__decorate([state()],LyraVirtualList.prototype,"containerScrollTop",void 0),__decorate([state()],LyraVirtualList.prototype,"viewportHeight",void 0),__decorate([state()],LyraVirtualList.prototype,"stickyHeight",void 0);export{LyraVirtualList,MAX_OVERSCAN_ROWS,VIRTUAL_LIST_ROW_ATTRIBUTE,VIRTUAL_LIST_STICKY_ATTRIBUTE};
|
|
@@ -4,15 +4,27 @@ export type LyraMapLegendPattern='solid'|'diagonal'|'dots'|'crosshatch';
|
|
|
4
4
|
/** One immutable, bounded map-legend row. Pattern is required so color is never the sole cue. */
|
|
5
5
|
export interface LyraMapLegendEntry{readonly color:string;readonly label:string;readonly pattern:LyraMapLegendPattern;
|
|
6
6
|
/**
|
|
7
|
+
* Category key this row stands for -- the same string a `point.colors` / `point.icons` entry
|
|
8
|
+
* matches against `point.field` / `point.iconField`. Trimmed, bounded to 256 characters and
|
|
9
|
+
* retained in the canonical readback, unlike the `value` on the `icon` record below, which is
|
|
10
|
+
* still dropped. A row that carries one becomes a keyboard-operable visibility toggle under
|
|
11
|
+
* `legendInteractive`; a row without one stays inert. An absent, non-string, empty or
|
|
12
|
+
* whitespace-only key leaves no `value` key at all, so a legend that never used categories
|
|
13
|
+
* reads back exactly as it did before this field existed.
|
|
14
|
+
*/
|
|
15
|
+
readonly value?:string;
|
|
16
|
+
/**
|
|
7
17
|
* Optional glyph painted inside `[part="legend-swatch"]`, in the entry's own color, instead of
|
|
8
18
|
* the solid color block that would otherwise cover it. Deliberately the record `point.icons`
|
|
9
19
|
* already carries, so a key can reproduce the symbol its point layer draws rather than
|
|
10
20
|
* describing it in color alone — hand the legend the very icon object the layer renders.
|
|
11
21
|
*
|
|
12
|
-
* The
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
22
|
+
* The **icon record's own** `value` is accepted so a pass-through needs no reshaping, and is
|
|
23
|
+
* left out of the canonical readback: a row's category key is the row-level `value` above, and
|
|
24
|
+
* is never derived from the glyph's. Deriving it would silently make a row interactive that the
|
|
25
|
+
* author never marked. Validation is the point icon's own (path data only, at most 8192
|
|
26
|
+
* characters, positive `viewBox` dimensions); an unusable record is dropped and the row keeps
|
|
27
|
+
* rendering its color swatch.
|
|
16
28
|
*
|
|
17
29
|
* That per-record 8192-character cap is deliberately the whole bound on path data, with no
|
|
18
30
|
* aggregate budget of the kind `label` carries across the legend. Two reasons. The admission
|
|
@@ -325,7 +337,19 @@ export interface LyraMapInstance{getCanvas():HTMLCanvasElement;getCenter():{lng:
|
|
|
325
337
|
*/
|
|
326
338
|
setMaxBounds?(bounds?:unknown):unknown;}
|
|
327
339
|
/** A pan-constraining box, `[[west, south], [east, north]]`, in the order maplibre-gl takes. */
|
|
328
|
-
export type LyraMapBounds=readonly[readonly[number,number],readonly[number,number]];export declare function buildGeoJsonPropertyDiff(previous:unknown,next:unknown):MapLibreGeoJsonDiff|null;
|
|
340
|
+
export type LyraMapBounds=readonly[readonly[number,number],readonly[number,number]];export declare function buildGeoJsonPropertyDiff(previous:unknown,next:unknown):MapLibreGeoJsonDiff|null;
|
|
341
|
+
/**
|
|
342
|
+
* Complete proposed visibility snapshot for one map legend category, mirroring
|
|
343
|
+
* `LyraChartLegendVisibilityChangeDetail`'s shape so a host that already reconciles a chart legend
|
|
344
|
+
* reconciles this one the same way. Frozen, and detached from the component's own state.
|
|
345
|
+
*/
|
|
346
|
+
export interface LyraMapLegendToggleDetail{
|
|
347
|
+
/** The activated row's `value` category key, exactly as it was admitted. */
|
|
348
|
+
readonly value:string;
|
|
349
|
+
/** Proposed visibility of `value` after this toggle. */
|
|
350
|
+
readonly visible:boolean;
|
|
351
|
+
/** Complete canonical proposed hidden-category set, in the order it would be committed. */
|
|
352
|
+
readonly hiddenCategories:readonly string[];}export interface LyraMapEventMap{'lr-map-load':CustomEvent<null>;'lr-map-marker-activate':CustomEvent<LyraMapMarkerActivationDetail>;'lr-map-legend-toggle':CustomEvent<LyraMapLegendToggleDetail>;'lr-map-click':CustomEvent<{readonly lngLat:readonly[number,number];readonly feature:Feature|undefined;
|
|
329
353
|
/** Which layer `feature` was hit on, so a click is attributable when both a choropleth and
|
|
330
354
|
* `dataLayers` are painted. `'cluster'` marks a hit on a clustered entry's aggregate circle,
|
|
331
355
|
* whose `point_count`/`cluster_id` properties describe the group rather than one feature.
|
|
@@ -370,6 +394,17 @@ readonly sourceId:string|undefined;}>;}
|
|
|
370
394
|
*
|
|
371
395
|
* @customElement lr-map
|
|
372
396
|
* @event lr-map-load - Fired once the underlying maplibregl.Map loads.
|
|
397
|
+
* @event lr-map-legend-toggle - **Cancelable.** Fired once when an interactive legend row is
|
|
398
|
+
* activated by pointer or by Enter/Space, carrying the immutable
|
|
399
|
+
* `detail: { value, visible, hiddenCategories }` -- the activated category key, its proposed
|
|
400
|
+
* visibility, and the complete proposed hidden set in the order it would be committed.
|
|
401
|
+
* `preventDefault()` is a real veto: `hiddenCategories` is not written, the row's `aria-pressed`
|
|
402
|
+
* does not change, the MapLibre paint is untouched, and nothing is announced, which is what lets
|
|
403
|
+
* a host own the set and write it itself. There is deliberately no second confirmation event:
|
|
404
|
+
* the committed state is `hiddenCategories`, which the host already observes, so a paired
|
|
405
|
+
* before/after vocabulary would be permanent public surface nobody asked for. A programmatic
|
|
406
|
+
* `hiddenCategories` assignment reconciles without emitting anything -- this event is a
|
|
407
|
+
* DOM-interaction proposal only.
|
|
373
408
|
* @event lr-map-marker-activate - Fired once when an accepted declarative marker is activated by
|
|
374
409
|
* pointer/click or by Enter/Space. The immutable detail carries its normalized `id`, validated
|
|
375
410
|
* `lngLat`, accepted marker snapshot, and activation `source`.
|
|
@@ -384,12 +419,20 @@ readonly sourceId:string|undefined;}>;}
|
|
|
384
419
|
* @csspart container - The MapLibre container. Its generated canvas is the actual focusable map
|
|
385
420
|
* region and receives the host-first accessible name and effective locale.
|
|
386
421
|
* @slot legend - Custom legend content, rendered inside the legend panel's own layout so it stays
|
|
387
|
-
* positioned with the map instead of floating beside it.
|
|
422
|
+
* positioned with the map instead of floating beside it. Slotted content is never made
|
|
423
|
+
* interactive by `legendInteractive`, which only reaches rows projected from `legend`.
|
|
388
424
|
* @csspart legend - The map legend.
|
|
389
425
|
* @csspart legend-swatch - A legend color swatch, or the entry's glyph when it carries an `icon`
|
|
390
426
|
* — in which case the swatch drops its color block and pattern overlay, keeps the `pattern`
|
|
391
427
|
* border framing the glyph as its non-color cue, carries `data-icon="true"`, and paints the
|
|
392
|
-
* glyph itself in the entry color.
|
|
428
|
+
* glyph itself in the entry color. It nests inside `legend-toggle` on an interactive row and
|
|
429
|
+
* stays `aria-hidden`/`inert` there, so it never contributes to the button's accessible name.
|
|
430
|
+
* @csspart legend-toggle - The `button` an interactive legend row renders around its swatch and
|
|
431
|
+
* label when `legendInteractive` is set and the row carries a `value`. Absent entirely when
|
|
432
|
+
* either is missing, so an unset map's legend markup is unchanged.
|
|
433
|
+
* @csspart legend-toggle-hidden - Second token carried alongside `legend-toggle` while that row's
|
|
434
|
+
* category is in `hiddenCategories`. State lives in the part name rather than a separate
|
|
435
|
+
* attribute, so `::part(legend-toggle-hidden)` is a reachable styling hook.
|
|
393
436
|
* @csspart legend-gradient - The continuous ramp bar rendered from `legendGradient`.
|
|
394
437
|
* @csspart legend-lo - The low endpoint caption of the `legendGradient` bar (mirrors `lr-heatmap`).
|
|
395
438
|
* @csspart legend-hi - The high endpoint caption of the `legendGradient` bar (mirrors `lr-heatmap`).
|
|
@@ -414,6 +457,12 @@ readonly sourceId:string|undefined;}>;}
|
|
|
414
457
|
* @cssprop [--lr-map-choropleth-fill-opacity=0.75] - Fill opacity for choropleth and polygon
|
|
415
458
|
* `dataLayers` fills. Read from the resolved cascade whenever those layers are applied or painted
|
|
416
459
|
* after a theme change.
|
|
460
|
+
* @cssprop [--lr-map-hidden-category-opacity=0.15] - Opacity a hidden category's points, point
|
|
461
|
+
* strokes and point icons are muted to in the rendered MapLibre paint. Read from the resolved
|
|
462
|
+
* cascade on every paint, because MapLibre draws to a WebGL canvas the CSS cascade never reaches.
|
|
463
|
+
* @cssprop [--lr-map-legend-hidden-swatch-opacity=0.5] - Opacity of a hidden interactive legend
|
|
464
|
+
* row's decorative swatch. Only the `aria-hidden` swatch dims; the label re-colors through the
|
|
465
|
+
* quiet text token instead, so it keeps AA contrast.
|
|
417
466
|
* @cssprop [--lr-map-popup-close-button-hover-bg=var(--lr-color-brand-quiet)] - Hover background
|
|
418
467
|
* of `popup-close-button`.
|
|
419
468
|
* @cssprop [--lr-map-popup-close-button-hover-color=var(--lr-color-brand)] - Hover foreground of
|
|
@@ -422,6 +471,18 @@ readonly sourceId:string|undefined;}>;}
|
|
|
422
471
|
* @cssprop [--lr-map-popup-close-button-active-color=var(--lr-color-brand)] - Pressed foreground
|
|
423
472
|
* of `popup-close-button`.
|
|
424
473
|
*
|
|
474
|
+
* The legend is read-only unless `legendInteractive` is set, which is opt-in for a reason: an
|
|
475
|
+
* unset map renders exactly the key it rendered before, with no button, no extra attribute and no
|
|
476
|
+
* extra MapLibre paint key. Only a row that carries its own `value` becomes a toggle -- the key is
|
|
477
|
+
* never derived from an `icon` record's `value`, which would silently make a row operable the
|
|
478
|
+
* author never marked. Each toggle is a native `button`, so it is one independent tab stop per row
|
|
479
|
+
* (a 100-row legend contributes 100, exactly as a 100-series `lr-chart` legend does) and it grows
|
|
480
|
+
* to the shared `--lr-icon-button-size` hit-area floor. Activation emits the cancelable
|
|
481
|
+
* `lr-map-legend-toggle`; there is deliberately no confirmation event, because the committed state
|
|
482
|
+
* is `hiddenCategories` and the host already observes it. A hidden category mutes its points,
|
|
483
|
+
* point strokes and point icons through `--lr-map-hidden-category-opacity`; a `kind: 'heatmap'`
|
|
484
|
+
* entry is deliberately out of scope, having no per-category field to mute.
|
|
485
|
+
*
|
|
425
486
|
* No style or tile provider is selected implicitly. Set `mapStyle` explicitly before connection;
|
|
426
487
|
* this prevents a bare component from making an undeclared third-party request.
|
|
427
488
|
* @status stable
|
|
@@ -500,6 +561,30 @@ legendGradientHiLabel:string|null;
|
|
|
500
561
|
/** Counts from the latest bounded legend normalization. `truncated` covers omitted rows or
|
|
501
562
|
* shortened labels; the returned record is frozen and never aliases caller input. */
|
|
502
563
|
get legendProjection():LyraMapLegendProjection;
|
|
564
|
+
/**
|
|
565
|
+
* Turns every legend row that carries a `value` into a keyboard-operable visibility toggle;
|
|
566
|
+
* rows without one stay inert. Default `false`, and an unset map renders exactly the read-only
|
|
567
|
+
* key it rendered before this property existed -- no button, no extra attribute, and no extra
|
|
568
|
+
* MapLibre paint key.
|
|
569
|
+
*
|
|
570
|
+
* Each toggle is an independently tabbable native `button`, so Enter and Space are the
|
|
571
|
+
* platform's own activation and no roving tabindex is involved. The consequence is stated
|
|
572
|
+
* rather than hidden: a 100-row interactive legend contributes 100 tab stops, exactly as a
|
|
573
|
+
* 100-series `lr-chart` legend does. Each row also grows to the `--lr-icon-button-size` hit-area
|
|
574
|
+
* floor; the legend panel's own `max-block-size`/`overflow: auto` contains the taller list.
|
|
575
|
+
*/
|
|
576
|
+
legendInteractive:boolean;private _hiddenCategories;
|
|
577
|
+
/**
|
|
578
|
+
* Complete controlled set of muted category keys, mirroring `lr-chart`'s `hiddenDatasets`.
|
|
579
|
+
* Clone-owned and frozen; non-string, empty, whitespace-only and duplicate entries are dropped,
|
|
580
|
+
* and at most 100 keys are retained. Honoured on the first render and the first MapLibre paint,
|
|
581
|
+
* not only after a user toggle. An empty array deliberately means every category is visible.
|
|
582
|
+
*
|
|
583
|
+
* Controlled public state, so it deliberately survives a disconnect and reconnect: the
|
|
584
|
+
* "reset transient open-state in `disconnectedCallback()`" rule covers dropdown/preview/tooltip
|
|
585
|
+
* `@state`, not a documented property a host owns and re-reads.
|
|
586
|
+
*/
|
|
587
|
+
get hiddenCategories():readonly string[];set hiddenCategories(value:readonly string[]);
|
|
503
588
|
/** Optional GeoJSON choropleth layer and value-to-color configuration. */
|
|
504
589
|
choropleth?:Readonly<LyraMapChoroplethLayer>;
|
|
505
590
|
/** Point markers rendered over the map. Explicit IDs are unique-nonempty first-wins. An idless
|
|
@@ -530,7 +615,7 @@ label:string;
|
|
|
530
615
|
private loading;
|
|
531
616
|
/** Classified failure rendered as localized ordinary text and announced through the owner
|
|
532
617
|
* document's assertive sink. */
|
|
533
|
-
private failure?;private errorAnnouncementSink?;private loadLibrary;private visible;private intersectionObserver?;private containerEl?;private _map?;private _styleLoaded;private _appliedChoroplethSourceId?;private _appliedFillLayerId?;private _appliedDataLayerIds;
|
|
618
|
+
private failure?;private errorAnnouncementSink?;private legendAnnouncementSink?;private loadLibrary;private visible;private intersectionObserver?;private containerEl?;private _map?;private _styleLoaded;private _appliedChoroplethSourceId?;private _appliedFillLayerId?;private _appliedDataLayerIds;
|
|
534
619
|
/**
|
|
535
620
|
* The rendering shape (`'auto'`, a cluster signature, `'heatmap'`) each applied data layer was
|
|
536
621
|
* built with, keyed identically to `_appliedDataLayerIds`.
|
|
@@ -543,7 +628,12 @@ private failure?;private errorAnnouncementSink?;private loadLibrary;private visi
|
|
|
543
628
|
private _appliedDataLayerShapes;
|
|
544
629
|
/** Last GeoJSON applied per resolved source id, so an update can be diffed against it rather
|
|
545
630
|
* than replacing the whole source. Holds a reference, not a copy -- it is only ever compared. */
|
|
546
|
-
private _appliedGeoJson;private _nextDataLayerId;private nextPointIconId;private appliedPointPaint;
|
|
631
|
+
private _appliedGeoJson;private _nextDataLayerId;private nextPointIconId;private appliedPointPaint;
|
|
632
|
+
/** Layer ids whose paint currently carries a muting opacity, so the first paint after the last
|
|
633
|
+
* category is un-hidden can restore it -- and a layer that was never muted keeps its paint
|
|
634
|
+
* object free of the key entirely. Keyed by layer id, not source id, because one source's
|
|
635
|
+
* circle and point-icon layers mute independently on different fields. */
|
|
636
|
+
private appliedPointMuting;private appliedPointIcons;private _maplibreModule?;
|
|
547
637
|
/** True only after WebGL2 has been proved in the current owner-document realm. */
|
|
548
638
|
private _webglReady;private _markerInstances;private _markerLabels;private _markerPopupIds;private readonly markerActivationDetails;private _configuredPopups;private _nextPopupId;private peerChromeObserver?;private observedPeerContainer?;private mapResizeObserver?;private observedMapContainer?;private _markerColors;private _connectGeneration;
|
|
549
639
|
/** The underlying runtime `maplibregl.Map`, declared through Lyra's peer-neutral common-method
|
|
@@ -596,7 +686,9 @@ private get safeCenter();connectedCallback():void;disconnectedCallback():void;pr
|
|
|
596
686
|
* below without risking a double construction.
|
|
597
687
|
*/
|
|
598
688
|
private tryConstructMap;protected updated(changed:PropertyValues):void;protected willUpdate(changed:PropertyValues):void;
|
|
599
|
-
/** Repaints token-derived MapLibre values without touching sources,
|
|
689
|
+
/** Repaints token-derived and visibility-derived MapLibre values without touching sources,
|
|
690
|
+
* layers, or map geometry -- which is exactly what a theme change and a `hiddenCategories`
|
|
691
|
+
* change each need. */
|
|
600
692
|
private refreshThemePaint;private applyChoropleth;private choroplethColorExpression;
|
|
601
693
|
/**
|
|
602
694
|
* Keeps the choropleth out of every caller-controlled data-layer namespace. Repeatedly prefixing
|
|
@@ -630,7 +722,18 @@ private paintDataLayer;
|
|
|
630
722
|
/** The pre-existing geometry split: polygons filled, lines/outlines stroked, points circled. */
|
|
631
723
|
private applyGeometryLayers;
|
|
632
724
|
/** Paint-only half of `applyGeometryLayers`. See `paintDataLayer` for why the halves are split. */
|
|
633
|
-
private paintGeometryLayers;private lineColor;
|
|
725
|
+
private paintGeometryLayers;private lineColor;
|
|
726
|
+
/**
|
|
727
|
+
* A `match` expression over `['get', field]` while any admitted category is hidden; a literal
|
|
728
|
+
* `1` on the first paint after the last category is un-hidden; and `undefined` whenever nothing
|
|
729
|
+
* is or was muted on `layerId` -- which is what leaves a `legendInteractive`-unset map
|
|
730
|
+
* byte-identical: the paint key is never written, so MapLibre keeps its own default and the
|
|
731
|
+
* layer's paint object gains no extra property.
|
|
732
|
+
*
|
|
733
|
+
* The flat `label, output` pair form is deliberately the shape `point.colors` already emits two
|
|
734
|
+
* lines above its own `match`, so this file speaks one expression idiom rather than two.
|
|
735
|
+
*/
|
|
736
|
+
private mutedPointOpacity;private paintPoints;private pointIconColor;private removePointIcons;private applyPointIcons;private paintPointIcons;
|
|
634
737
|
/**
|
|
635
738
|
* `['step', ['get', 'point_count'], …]` over the authored cluster color breaks, or the layer's
|
|
636
739
|
* own flat color when none were supplied.
|
|
@@ -686,4 +789,27 @@ private syncPeerChromeParts;private observePeerChrome;private syncPopupSemantics
|
|
|
686
789
|
* holds fewer than two usable stops. Part names mirror `lr-heatmap`'s
|
|
687
790
|
* `legend-lo`/`legend-hi` so a consumer styling both components learns one vocabulary.
|
|
688
791
|
*/
|
|
689
|
-
|
|
792
|
+
/**
|
|
793
|
+
* The swatch-plus-label pair every legend row renders: directly inside the row when the row is
|
|
794
|
+
* inert, and inside the row's toggle button when `legendInteractive` has made it operable. One
|
|
795
|
+
* source of truth, so the two branches can never drift, and an unset map keeps rendering exactly
|
|
796
|
+
* the markup it rendered before the toggle existed.
|
|
797
|
+
*/
|
|
798
|
+
private renderLegendRowContent;
|
|
799
|
+
/**
|
|
800
|
+
* Flips one category's visibility from a legend toggle activation.
|
|
801
|
+
*
|
|
802
|
+
* `hiddenCategories` is a key set, so every row carrying the activated key flips together --
|
|
803
|
+
* self-consistent by construction rather than by a per-row visibility flag that two rows
|
|
804
|
+
* describing one category could disagree about.
|
|
805
|
+
*/
|
|
806
|
+
private toggleLegendCategory;
|
|
807
|
+
/**
|
|
808
|
+
* The state change belongs in a live region because the thing that changed -- the map, and the
|
|
809
|
+
* legend row's own styling -- is not the focused element, and `aria-pressed` alone only reports
|
|
810
|
+
* the button's new state once focus is already on it.
|
|
811
|
+
*/
|
|
812
|
+
private announceLegendVisibility;
|
|
813
|
+
/** Acquired lazily on the first toggle, and re-acquired against a new owner document, so a map
|
|
814
|
+
* that never renders an interactive legend never mounts a live region at all. */
|
|
815
|
+
private syncLegendAnnouncementSink;private releaseLegendAnnouncementSink;private renderLegendGradient;render():TemplateResult;}declare global{interface HTMLElementTagNameMap{'lr-map':LyraMap;}}
|