@aceshooting/lyra-ui 2.0.0 → 2.1.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/README.md +87 -14
- package/custom-elements.json +11555 -5539
- package/dist/components/app-rail/app-rail-item.d.ts +30 -0
- package/dist/components/app-rail/app-rail-item.js +68 -0
- package/dist/components/app-rail/app-rail-item.styles.d.ts +1 -0
- package/dist/components/app-rail/app-rail-item.styles.js +65 -0
- package/dist/components/app-rail/app-rail.d.ts +21 -24
- package/dist/components/app-rail/app-rail.js +68 -132
- package/dist/components/app-rail/app-rail.styles.js +5 -2
- package/dist/components/attachment-chip/attachment-chip.d.ts +38 -11
- package/dist/components/attachment-chip/attachment-chip.js +73 -29
- package/dist/components/attachment-trigger/attachment-trigger.d.ts +13 -0
- package/dist/components/attachment-trigger/attachment-trigger.js +13 -1
- package/dist/components/attachment-trigger/attachment-trigger.styles.js +28 -6
- package/dist/components/chart/bar-chart.js +2 -18
- package/dist/components/chart/box-plot.d.ts +25 -1
- package/dist/components/chart/box-plot.js +136 -6
- package/dist/components/chart/box-plot.styles.js +13 -0
- package/dist/components/chart/bubble-chart.js +2 -18
- package/dist/components/chart/chart.d.ts +54 -10
- package/dist/components/chart/chart.js +182 -39
- package/dist/components/chart/doughnut-chart.js +2 -18
- package/dist/components/chart/histogram-bin.d.ts +5 -2
- package/dist/components/chart/histogram-bin.js +12 -4
- package/dist/components/chart/histogram.js +8 -16
- package/dist/components/chart/line-chart.js +2 -18
- package/dist/components/chart/lite-chart.d.ts +80 -3
- package/dist/components/chart/lite-chart.js +250 -53
- package/dist/components/chart/pie-chart.js +2 -18
- package/dist/components/chart/polar-area-chart.js +2 -18
- package/dist/components/chart/radar-chart.js +2 -18
- package/dist/components/chart/scatter-chart.js +2 -18
- package/dist/components/chat-composer/chat-composer.d.ts +42 -1
- package/dist/components/chat-composer/chat-composer.js +84 -3
- package/dist/components/chat-composer/chat-composer.styles.js +11 -1
- package/dist/components/chat-message/chat-message.d.ts +32 -4
- package/dist/components/chat-message/chat-message.js +57 -17
- package/dist/components/checkbox/checkbox.d.ts +66 -8
- package/dist/components/checkbox/checkbox.js +173 -50
- package/dist/components/checkbox/checkbox.styles.js +9 -2
- package/dist/components/chip/chip-group.js +8 -2
- package/dist/components/chip/chip.js +9 -2
- package/dist/components/citation-badge/citation-badge.js +21 -3
- package/dist/components/code-block/code-block.d.ts +38 -0
- package/dist/components/code-block/code-block.js +72 -7
- package/dist/components/code-block/code-loader.d.ts +44 -1
- package/dist/components/code-block/code-loader.js +63 -0
- package/dist/components/combobox/combobox.d.ts +46 -5
- package/dist/components/combobox/combobox.js +175 -35
- package/dist/components/combobox/combobox.styles.js +3 -3
- package/dist/components/context-meter/context-meter.js +17 -8
- package/dist/components/context-meter/context-meter.styles.js +0 -6
- package/dist/components/conversation-item/conversation-item.d.ts +13 -16
- package/dist/components/conversation-item/conversation-item.js +29 -20
- package/dist/components/date-picker/calendar-core.d.ts +24 -0
- package/dist/components/date-picker/calendar-core.js +51 -4
- package/dist/components/date-picker/date-input.d.ts +77 -10
- package/dist/components/date-picker/date-input.js +278 -73
- package/dist/components/date-picker/date-picker.d.ts +28 -4
- package/dist/components/date-picker/date-picker.js +95 -37
- package/dist/components/dialog/confirm.js +3 -6
- package/dist/components/dialog/dialog.d.ts +75 -31
- package/dist/components/dialog/dialog.js +147 -131
- package/dist/components/dialog/dialog.styles.js +46 -2
- package/dist/components/dock-panel/dock-panel.d.ts +8 -0
- package/dist/components/dock-panel/dock-panel.js +15 -1
- package/dist/components/dock-panel/dock-panel.styles.js +15 -1
- package/dist/components/document-preview/document-preview.d.ts +15 -7
- package/dist/components/document-preview/document-preview.js +29 -13
- package/dist/components/empty/empty.d.ts +1 -2
- package/dist/components/empty/empty.js +18 -12
- package/dist/components/empty/empty.styles.js +0 -3
- package/dist/components/export-button/export-button.d.ts +12 -0
- package/dist/components/export-button/export-button.js +33 -5
- package/dist/components/export-button/export-button.styles.js +5 -1
- package/dist/components/file-input/accept.js +2 -0
- package/dist/components/file-input/file-input.d.ts +10 -1
- package/dist/components/file-input/file-input.js +36 -5
- package/dist/components/flag/flag.d.ts +1 -1
- package/dist/components/flag/flag.js +15 -1
- package/dist/components/flag/flag.styles.js +1 -1
- package/dist/components/flag/language-map.d.ts +4 -1
- package/dist/components/flag/language-map.js +6 -3
- package/dist/components/gauge/gauge.d.ts +10 -1
- package/dist/components/gauge/gauge.js +28 -9
- package/dist/components/generation-status/generation-status.d.ts +13 -5
- package/dist/components/generation-status/generation-status.js +59 -5
- package/dist/components/graph/graph.d.ts +37 -3
- package/dist/components/graph/graph.js +132 -20
- package/dist/components/heatmap/calendar-grid.d.ts +15 -6
- package/dist/components/heatmap/calendar-grid.js +17 -6
- package/dist/components/heatmap/heatmap-scale.d.ts +5 -1
- package/dist/components/heatmap/heatmap-scale.js +8 -2
- package/dist/components/heatmap/heatmap.d.ts +166 -25
- package/dist/components/heatmap/heatmap.js +372 -89
- package/dist/components/json-viewer/json-viewer.d.ts +22 -5
- package/dist/components/json-viewer/json-viewer.js +115 -37
- package/dist/components/json-viewer/json-viewer.styles.js +2 -1
- package/dist/components/kbd/kbd.js +24 -7
- package/dist/components/live-region/live-region.d.ts +10 -1
- package/dist/components/live-region/live-region.js +42 -6
- package/dist/components/map/map.d.ts +24 -1
- package/dist/components/map/map.js +89 -24
- package/dist/components/markdown/markdown-loader.d.ts +24 -0
- package/dist/components/markdown/markdown-loader.js +35 -1
- package/dist/components/markdown/markdown.d.ts +46 -8
- package/dist/components/markdown/markdown.js +136 -31
- package/dist/components/markdown/markdown.styles.js +7 -1
- package/dist/components/media-card/media-card.d.ts +25 -17
- package/dist/components/media-card/media-card.js +43 -65
- package/dist/components/mention-popover/mention-popover.d.ts +4 -1
- package/dist/components/mention-popover/mention-popover.js +23 -5
- package/dist/components/menu/menu-item.d.ts +32 -3
- package/dist/components/menu/menu-item.js +94 -7
- package/dist/components/menu/menu-item.styles.js +8 -0
- package/dist/components/menu/menu.d.ts +25 -1
- package/dist/components/menu/menu.js +99 -3
- package/dist/components/menu/menu.styles.js +3 -2
- package/dist/components/model-select/model-select.d.ts +48 -3
- package/dist/components/model-select/model-select.js +120 -22
- package/dist/components/model-select/model-select.styles.js +17 -3
- package/dist/components/model-settings-panel/model-settings-panel.d.ts +25 -1
- package/dist/components/model-settings-panel/model-settings-panel.js +65 -1
- package/dist/components/playback/playback.d.ts +6 -2
- package/dist/components/playback/playback.js +72 -29
- package/dist/components/playback/playback.styles.js +6 -1
- package/dist/components/responsive-panel/responsive-panel.d.ts +29 -16
- package/dist/components/responsive-panel/responsive-panel.js +130 -132
- package/dist/components/responsive-panel/responsive-panel.styles.js +1 -1
- package/dist/components/result-card/result-card.d.ts +8 -2
- package/dist/components/result-card/result-card.js +9 -3
- package/dist/components/result-card/result-card.styles.js +0 -1
- package/dist/components/select/select.d.ts +59 -20
- package/dist/components/select/select.js +125 -43
- package/dist/components/skeleton/skeleton.d.ts +3 -0
- package/dist/components/skeleton/skeleton.js +7 -1
- package/dist/components/skeleton/skeleton.styles.js +5 -4
- package/dist/components/slider/slider.d.ts +57 -5
- package/dist/components/slider/slider.js +195 -80
- package/dist/components/source-card/source-card.d.ts +17 -5
- package/dist/components/source-card/source-card.js +55 -8
- package/dist/components/source-card/source-card.styles.js +1 -1
- package/dist/components/source-list/source-list.js +9 -1
- package/dist/components/sparkline/sparkline.js +34 -10
- package/dist/components/split/split.d.ts +141 -14
- package/dist/components/split/split.js +357 -52
- package/dist/components/split/split.styles.js +18 -1
- package/dist/components/stat/stat.d.ts +10 -4
- package/dist/components/stat/stat.js +46 -11
- package/dist/components/stream-status/stream-status.d.ts +27 -11
- package/dist/components/stream-status/stream-status.js +95 -13
- package/dist/components/streaming-text/streaming-text.d.ts +9 -3
- package/dist/components/streaming-text/streaming-text.js +25 -10
- package/dist/components/streaming-text/streaming-text.styles.js +3 -2
- package/dist/components/switch/switch.d.ts +52 -7
- package/dist/components/switch/switch.js +111 -40
- package/dist/components/switch/switch.styles.js +1 -1
- package/dist/components/table/table.d.ts +18 -3
- package/dist/components/table/table.js +88 -20
- package/dist/components/tabs/tabs.d.ts +23 -0
- package/dist/components/tabs/tabs.js +76 -12
- package/dist/components/tabs/tabs.styles.js +11 -0
- package/dist/components/thinking-panel/thinking-panel.d.ts +3 -1
- package/dist/components/thinking-panel/thinking-panel.js +34 -9
- package/dist/components/thinking-panel/thinking-panel.styles.js +6 -0
- package/dist/components/time-range/time-range.d.ts +59 -2
- package/dist/components/time-range/time-range.js +163 -67
- package/dist/components/toast/toast-item.d.ts +12 -3
- package/dist/components/toast/toast-item.js +90 -53
- package/dist/components/toast/toast-item.styles.js +59 -28
- package/dist/components/toast/toast.js +17 -5
- package/dist/components/toast/toaster.js +10 -1
- package/dist/components/tool-approval-dialog/tool-approval-dialog.d.ts +11 -10
- package/dist/components/tool-approval-dialog/tool-approval-dialog.js +50 -124
- package/dist/components/tool-approval-dialog/tool-approval-dialog.styles.js +1 -1
- package/dist/components/tool-call-chip/tool-call-chip.d.ts +18 -2
- package/dist/components/tool-call-chip/tool-call-chip.js +86 -25
- package/dist/components/tool-param-form/tool-param-form.d.ts +89 -28
- package/dist/components/tool-param-form/tool-param-form.js +350 -106
- package/dist/components/tool-result-dialog/tool-result-dialog.d.ts +27 -7
- package/dist/components/tool-result-dialog/tool-result-dialog.js +80 -115
- package/dist/components/tool-result-dialog/tool-result-dialog.styles.js +1 -1
- package/dist/components/tool-result-view/registry.d.ts +0 -8
- package/dist/components/tool-result-view/registry.js +7 -2
- package/dist/components/tool-result-view/tool-result-view.d.ts +6 -3
- package/dist/components/tool-result-view/tool-result-view.js +18 -4
- package/dist/components/tool-select-dialog/tool-select-dialog.d.ts +11 -11
- package/dist/components/tool-select-dialog/tool-select-dialog.js +44 -133
- package/dist/components/tool-select-dialog/tool-select-dialog.styles.js +13 -4
- package/dist/components/tree/tree-node.d.ts +4 -1
- package/dist/components/tree/tree-node.js +4 -1
- package/dist/components/tree/tree.d.ts +17 -8
- package/dist/components/tree/tree.js +21 -20
- package/dist/components/typing-indicator/typing-indicator.d.ts +12 -2
- package/dist/components/typing-indicator/typing-indicator.js +16 -4
- package/dist/components/typing-indicator/typing-indicator.styles.js +2 -2
- package/dist/components/virtual-list/virtual-list.d.ts +56 -19
- package/dist/components/virtual-list/virtual-list.js +184 -38
- package/dist/components/virtual-list/virtual-list.styles.js +12 -0
- package/dist/components/widget/widget.d.ts +5 -4
- package/dist/components/widget/widget.js +54 -120
- package/dist/components/widget/widget.styles.js +8 -2
- package/dist/components/word-cloud/word-cloud-layout.d.ts +7 -0
- package/dist/components/word-cloud/word-cloud-layout.js +20 -6
- package/dist/components/word-cloud/word-cloud.d.ts +22 -2
- package/dist/components/word-cloud/word-cloud.js +45 -6
- package/dist/components/word-cloud/word-cloud.styles.js +13 -1
- package/dist/internal/anchored-validity.d.ts +1 -0
- package/dist/internal/anchored-validity.js +86 -0
- package/dist/internal/form-associated.d.ts +7 -0
- package/dist/internal/form-associated.js +43 -4
- package/dist/internal/numbers.d.ts +12 -0
- package/dist/internal/numbers.js +26 -0
- package/dist/internal/overlay-manager.d.ts +51 -0
- package/dist/internal/overlay-manager.js +523 -0
- package/dist/internal/positioner.js +27 -3
- package/dist/internal/safe-url.d.ts +12 -0
- package/dist/internal/safe-url.js +41 -0
- package/dist/internal/tokens.styles.js +17 -11
- package/dist/lyra.d.ts +5 -2
- package/dist/lyra.js +3 -1
- package/llms-full.txt +970 -426
- package/llms.txt +5 -4
- package/package.json +19 -2
|
@@ -1,22 +1,26 @@
|
|
|
1
1
|
import { type TemplateResult, type PropertyValues } from 'lit';
|
|
2
2
|
import { LyraElement } from '../../internal/lyra-element.js';
|
|
3
|
+
/** Largest accepted overscan on either side of the visible range. This keeps
|
|
4
|
+
* an accidental huge value from defeating virtualization. */
|
|
5
|
+
export declare const MAX_OVERSCAN_ROWS = 100;
|
|
3
6
|
/** `lyra-visible-range-changed` detail -- the current visible (non-overscanned) item index range. */
|
|
4
7
|
export interface VirtualListRange {
|
|
5
8
|
start: number;
|
|
6
9
|
end: number;
|
|
7
10
|
}
|
|
8
|
-
/**
|
|
11
|
+
/** A visible group label anchored to the first row in its group. */
|
|
9
12
|
export interface VirtualListGroup {
|
|
10
13
|
key: string | number;
|
|
11
14
|
label?: string;
|
|
12
15
|
startIndex: number;
|
|
13
16
|
}
|
|
17
|
+
type VirtualListKey = string | number;
|
|
14
18
|
/**
|
|
15
19
|
* `<lyra-virtual-list>` — a generic windowed/virtualized list host. Renders
|
|
16
20
|
* only the items within the current viewport (plus `overscan` padding rows
|
|
17
21
|
* on each side) as real DOM, regardless of how large `items` is, so a
|
|
18
|
-
* multi-thousand-row chat history sidebar
|
|
19
|
-
*
|
|
22
|
+
* multi-thousand-row chat history sidebar or long message thread stays cheap
|
|
23
|
+
* to scroll.
|
|
20
24
|
*
|
|
21
25
|
* Content is entirely caller-supplied: `renderItem(item, index)` returns
|
|
22
26
|
* whatever `lit-html` value should represent that row (typically a
|
|
@@ -46,12 +50,18 @@ export interface VirtualListGroup {
|
|
|
46
50
|
* avoids maintaining two parallel rendering strategies for a difference
|
|
47
51
|
* that's otherwise just "how is row *i*'s height looked up").
|
|
48
52
|
*
|
|
49
|
-
* The `offsets` array is rebuilt
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
53
|
+
* The `offsets` array is rebuilt only when `items`, `row-height`, or
|
|
54
|
+
* `keyFunction` change, or a row's measured height changes -- not on every
|
|
55
|
+
* update, so a pure scroll-position tick (potentially every rAF while
|
|
56
|
+
* scrolling) only re-runs the cheap range/visibility math in
|
|
57
|
+
* `computeRange()`, never the `O(n)` offsets rebuild (which, in
|
|
58
|
+
* `row-height="auto"` mode, also means a `keyFunction` call per item). For
|
|
59
|
+
* the list sizes this component is meant for (a scrollable history sidebar,
|
|
60
|
+
* realistically hundreds to a few thousand rows) that rebuild is a trivial
|
|
61
|
+
* `O(n)` arithmetic loop even when it does run; it is *not* the right
|
|
62
|
+
* approach for a hundred-thousand-row list without further work (e.g. a
|
|
63
|
+
* Fenwick/segment tree for `O(log n)` offset queries+updates), which is out
|
|
64
|
+
* of scope here.
|
|
55
65
|
*
|
|
56
66
|
* **Accessibility.** The scroll container is `role="list"` and each rendered
|
|
57
67
|
* row is `role="listitem"`, deliberately *not* `listbox`/`option` — this
|
|
@@ -70,10 +80,10 @@ export interface VirtualListGroup {
|
|
|
70
80
|
* focusable content of its own is otherwise unreachable by keyboard (native
|
|
71
81
|
* arrow/Page Up/Page Down scrolling included).
|
|
72
82
|
*
|
|
73
|
-
* **Grouping.** `groups`
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
83
|
+
* **Grouping.** When supplied, `groups` renders a labeled group marker at the
|
|
84
|
+
* corresponding `startIndex`. Group markers are positioned independently of
|
|
85
|
+
* the row window, so they remain available when the first row in a group is
|
|
86
|
+
* outside the current overscanned range.
|
|
77
87
|
*
|
|
78
88
|
* @customElement lyra-virtual-list
|
|
79
89
|
* @event lyra-load-more - Fired once per approach to the bottom of the list
|
|
@@ -90,6 +100,7 @@ export interface VirtualListGroup {
|
|
|
90
100
|
* @csspart base - The scrollable container (`role="list"`).
|
|
91
101
|
* @csspart spacer - The full-content-height inner element that gives the
|
|
92
102
|
* container its true scrollable extent.
|
|
103
|
+
* @csspart group - A positioned group label.
|
|
93
104
|
* @csspart row - One rendered row's absolutely-positioned wrapper
|
|
94
105
|
* (`role="listitem"`); `renderItem`'s return value renders inside it.
|
|
95
106
|
*/
|
|
@@ -105,26 +116,48 @@ export declare class LyraVirtualList extends LyraElement {
|
|
|
105
116
|
* scroll position and any per-row DOM state can attach to the wrong row
|
|
106
117
|
* across a mutation (same caveat as `<lyra-table>`'s `rowKey`). */
|
|
107
118
|
keyFunction?: (item: unknown, index: number) => string | number;
|
|
108
|
-
/**
|
|
119
|
+
/** Group labels positioned at their first row's `startIndex`. Invalid or
|
|
120
|
+
* duplicate indexes are ignored during rendering. */
|
|
109
121
|
groups?: VirtualListGroup[];
|
|
110
122
|
/** `'auto'` (default) measures each row's real height via `ResizeObserver`;
|
|
111
123
|
* a numeric string fixes every row to that many pixels. */
|
|
112
124
|
rowHeight: string;
|
|
113
|
-
/** Extra rows rendered beyond the visible viewport on each side, to reduce
|
|
125
|
+
/** Extra rows rendered beyond the visible viewport on each side, to reduce
|
|
126
|
+
* blank-frame risk during fast scrolling. Normalized to a whole number in
|
|
127
|
+
* the inclusive range 0–`MAX_OVERSCAN_ROWS`; non-finite values use the
|
|
128
|
+
* default. */
|
|
114
129
|
overscan: number;
|
|
115
|
-
/** When set and it matches a row's `keyFunction` result, that row is
|
|
116
|
-
|
|
130
|
+
/** When set and it matches a row's typed `keyFunction` result, that row is
|
|
131
|
+
* smoothly scrolled into view whenever this changes. Attribute values are
|
|
132
|
+
* strings; assign the property for a numeric key. */
|
|
133
|
+
activeId: VirtualListKey | '';
|
|
117
134
|
loading: boolean;
|
|
118
135
|
/** When true, scrolling near the bottom fires `lyra-load-more`. */
|
|
119
136
|
hasMore: boolean;
|
|
120
137
|
private containerScrollTop;
|
|
121
138
|
private viewportHeight;
|
|
122
|
-
/** `offsets[i]` = row `i`'s pixel top; `offsets[items.length]` = total content height. Rebuilt
|
|
139
|
+
/** `offsets[i]` = row `i`'s pixel top; `offsets[items.length]` = total content height. Rebuilt only when `offsetsDirty` is set -- see `willUpdate()`. */
|
|
123
140
|
private offsets;
|
|
124
141
|
/** Parsed `rowHeight`: a positive pixel number, or `null` for `'auto'` (measured) mode. */
|
|
125
142
|
private fixedRowHeight;
|
|
126
|
-
/** `row-height="auto"` per-row measured heights, keyed by
|
|
143
|
+
/** `row-height="auto"` per-row measured heights, keyed by
|
|
144
|
+
* keyFunction result. Pruned to the current `items`'
|
|
145
|
+
* live keys whenever `items` changes (see `recomputeOffsets()`), so a
|
|
146
|
+
* long-lived instance handed many wholly different `items` arrays over
|
|
147
|
+
* its life doesn't grow this map without bound. */
|
|
127
148
|
private readonly measuredHeights;
|
|
149
|
+
/** True whenever `offsets` needs rebuilding before the next render --
|
|
150
|
+
* set initially and whenever `items`/`rowHeight`/`keyFunction` change or
|
|
151
|
+
* a row's measured height changes, but *not* on a pure scroll-position
|
|
152
|
+
* update, so the `O(n)` rebuild (including a `keyFunction` call per item
|
|
153
|
+
* in `row-height="auto"` mode) only runs when something that actually
|
|
154
|
+
* affects row heights or ordering changed. */
|
|
155
|
+
private offsetsDirty;
|
|
156
|
+
/** Set alongside `offsetsDirty` specifically when `items` changed (not
|
|
157
|
+
* just `rowHeight`/`keyFunction`/a measurement) -- consumed by the next
|
|
158
|
+
* `recomputeOffsets()` call to prune `measuredHeights` entries for keys
|
|
159
|
+
* no longer present in `items`. */
|
|
160
|
+
private itemsChangedPendingPrune;
|
|
128
161
|
private renderStart;
|
|
129
162
|
private renderEnd;
|
|
130
163
|
private visibleStart;
|
|
@@ -137,6 +170,8 @@ export declare class LyraVirtualList extends LyraElement {
|
|
|
137
170
|
private rowResizeObserver?;
|
|
138
171
|
private containerResizeObserver?;
|
|
139
172
|
private readonly observedRows;
|
|
173
|
+
private readonly observedRowKeys;
|
|
174
|
+
private readonly observedRowIndices;
|
|
140
175
|
private scrollRafId?;
|
|
141
176
|
private pendingScrollTop;
|
|
142
177
|
connectedCallback(): void;
|
|
@@ -164,6 +199,7 @@ export declare class LyraVirtualList extends LyraElement {
|
|
|
164
199
|
private emitRangeChangeIfNeeded;
|
|
165
200
|
private maybeFireLoadMore;
|
|
166
201
|
private renderRow;
|
|
202
|
+
private renderGroups;
|
|
167
203
|
render(): TemplateResult;
|
|
168
204
|
}
|
|
169
205
|
declare global {
|
|
@@ -171,3 +207,4 @@ declare global {
|
|
|
171
207
|
'lyra-virtual-list': LyraVirtualList;
|
|
172
208
|
}
|
|
173
209
|
}
|
|
210
|
+
export {};
|
|
@@ -16,15 +16,43 @@ import { styles } from './virtual-list.styles.js';
|
|
|
16
16
|
* chat-list row that the initial scrollbar/spacer size doesn't jump wildly
|
|
17
17
|
* once real measurements arrive. Irrelevant in fixed-`row-height` mode. */
|
|
18
18
|
const DEFAULT_ROW_ESTIMATE_PX = 48;
|
|
19
|
+
const DEFAULT_OVERSCAN_ROWS = 6;
|
|
20
|
+
/** Largest accepted overscan on either side of the visible range. This keeps
|
|
21
|
+
* an accidental huge value from defeating virtualization. */
|
|
22
|
+
export const MAX_OVERSCAN_ROWS = 100;
|
|
23
|
+
function normalizeOverscan(value) {
|
|
24
|
+
if (value === null)
|
|
25
|
+
return DEFAULT_OVERSCAN_ROWS;
|
|
26
|
+
const numeric = typeof value === 'number' ? value : Number(value);
|
|
27
|
+
if (!Number.isFinite(numeric))
|
|
28
|
+
return DEFAULT_OVERSCAN_ROWS;
|
|
29
|
+
return Math.min(MAX_OVERSCAN_ROWS, Math.max(0, Math.floor(numeric)));
|
|
30
|
+
}
|
|
31
|
+
const overscanConverter = {
|
|
32
|
+
fromAttribute(value) {
|
|
33
|
+
return normalizeOverscan(value);
|
|
34
|
+
},
|
|
35
|
+
};
|
|
19
36
|
function prefersReducedMotion() {
|
|
20
37
|
return typeof window !== 'undefined' && !!window.matchMedia?.('(prefers-reduced-motion: reduce)').matches;
|
|
21
38
|
}
|
|
39
|
+
/** A typed key is used in maps and active-row matching; this token is only for
|
|
40
|
+
* DOM attributes, where every value is necessarily a string. */
|
|
41
|
+
function domKeyToken(key) {
|
|
42
|
+
if (typeof key === 'number') {
|
|
43
|
+
if (Number.isNaN(key))
|
|
44
|
+
return 'number:NaN';
|
|
45
|
+
if (Object.is(key, -0))
|
|
46
|
+
return 'number:-0';
|
|
47
|
+
}
|
|
48
|
+
return `${typeof key}:${String(key)}`;
|
|
49
|
+
}
|
|
22
50
|
/**
|
|
23
51
|
* `<lyra-virtual-list>` — a generic windowed/virtualized list host. Renders
|
|
24
52
|
* only the items within the current viewport (plus `overscan` padding rows
|
|
25
53
|
* on each side) as real DOM, regardless of how large `items` is, so a
|
|
26
|
-
* multi-thousand-row chat history sidebar
|
|
27
|
-
*
|
|
54
|
+
* multi-thousand-row chat history sidebar or long message thread stays cheap
|
|
55
|
+
* to scroll.
|
|
28
56
|
*
|
|
29
57
|
* Content is entirely caller-supplied: `renderItem(item, index)` returns
|
|
30
58
|
* whatever `lit-html` value should represent that row (typically a
|
|
@@ -54,12 +82,18 @@ function prefersReducedMotion() {
|
|
|
54
82
|
* avoids maintaining two parallel rendering strategies for a difference
|
|
55
83
|
* that's otherwise just "how is row *i*'s height looked up").
|
|
56
84
|
*
|
|
57
|
-
* The `offsets` array is rebuilt
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
85
|
+
* The `offsets` array is rebuilt only when `items`, `row-height`, or
|
|
86
|
+
* `keyFunction` change, or a row's measured height changes -- not on every
|
|
87
|
+
* update, so a pure scroll-position tick (potentially every rAF while
|
|
88
|
+
* scrolling) only re-runs the cheap range/visibility math in
|
|
89
|
+
* `computeRange()`, never the `O(n)` offsets rebuild (which, in
|
|
90
|
+
* `row-height="auto"` mode, also means a `keyFunction` call per item). For
|
|
91
|
+
* the list sizes this component is meant for (a scrollable history sidebar,
|
|
92
|
+
* realistically hundreds to a few thousand rows) that rebuild is a trivial
|
|
93
|
+
* `O(n)` arithmetic loop even when it does run; it is *not* the right
|
|
94
|
+
* approach for a hundred-thousand-row list without further work (e.g. a
|
|
95
|
+
* Fenwick/segment tree for `O(log n)` offset queries+updates), which is out
|
|
96
|
+
* of scope here.
|
|
63
97
|
*
|
|
64
98
|
* **Accessibility.** The scroll container is `role="list"` and each rendered
|
|
65
99
|
* row is `role="listitem"`, deliberately *not* `listbox`/`option` — this
|
|
@@ -78,10 +112,10 @@ function prefersReducedMotion() {
|
|
|
78
112
|
* focusable content of its own is otherwise unreachable by keyboard (native
|
|
79
113
|
* arrow/Page Up/Page Down scrolling included).
|
|
80
114
|
*
|
|
81
|
-
* **Grouping.** `groups`
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
*
|
|
115
|
+
* **Grouping.** When supplied, `groups` renders a labeled group marker at the
|
|
116
|
+
* corresponding `startIndex`. Group markers are positioned independently of
|
|
117
|
+
* the row window, so they remain available when the first row in a group is
|
|
118
|
+
* outside the current overscanned range.
|
|
85
119
|
*
|
|
86
120
|
* @customElement lyra-virtual-list
|
|
87
121
|
* @event lyra-load-more - Fired once per approach to the bottom of the list
|
|
@@ -98,6 +132,7 @@ function prefersReducedMotion() {
|
|
|
98
132
|
* @csspart base - The scrollable container (`role="list"`).
|
|
99
133
|
* @csspart spacer - The full-content-height inner element that gives the
|
|
100
134
|
* container its true scrollable extent.
|
|
135
|
+
* @csspart group - A positioned group label.
|
|
101
136
|
* @csspart row - One rendered row's absolutely-positioned wrapper
|
|
102
137
|
* (`role="listitem"`); `renderItem`'s return value renders inside it.
|
|
103
138
|
*/
|
|
@@ -111,9 +146,14 @@ export class LyraVirtualList extends LyraElement {
|
|
|
111
146
|
/** `'auto'` (default) measures each row's real height via `ResizeObserver`;
|
|
112
147
|
* a numeric string fixes every row to that many pixels. */
|
|
113
148
|
this.rowHeight = 'auto';
|
|
114
|
-
/** Extra rows rendered beyond the visible viewport on each side, to reduce
|
|
115
|
-
|
|
116
|
-
|
|
149
|
+
/** Extra rows rendered beyond the visible viewport on each side, to reduce
|
|
150
|
+
* blank-frame risk during fast scrolling. Normalized to a whole number in
|
|
151
|
+
* the inclusive range 0–`MAX_OVERSCAN_ROWS`; non-finite values use the
|
|
152
|
+
* default. */
|
|
153
|
+
this.overscan = DEFAULT_OVERSCAN_ROWS;
|
|
154
|
+
/** When set and it matches a row's typed `keyFunction` result, that row is
|
|
155
|
+
* smoothly scrolled into view whenever this changes. Attribute values are
|
|
156
|
+
* strings; assign the property for a numeric key. */
|
|
117
157
|
this.activeId = '';
|
|
118
158
|
this.loading = false;
|
|
119
159
|
/** When true, scrolling near the bottom fires `lyra-load-more`. */
|
|
@@ -124,12 +164,28 @@ export class LyraVirtualList extends LyraElement {
|
|
|
124
164
|
// scrolls itself; [part="base"] does).
|
|
125
165
|
this.containerScrollTop = 0;
|
|
126
166
|
this.viewportHeight = 0;
|
|
127
|
-
/** `offsets[i]` = row `i`'s pixel top; `offsets[items.length]` = total content height. Rebuilt
|
|
167
|
+
/** `offsets[i]` = row `i`'s pixel top; `offsets[items.length]` = total content height. Rebuilt only when `offsetsDirty` is set -- see `willUpdate()`. */
|
|
128
168
|
this.offsets = [0];
|
|
129
169
|
/** Parsed `rowHeight`: a positive pixel number, or `null` for `'auto'` (measured) mode. */
|
|
130
170
|
this.fixedRowHeight = null;
|
|
131
|
-
/** `row-height="auto"` per-row measured heights, keyed by
|
|
171
|
+
/** `row-height="auto"` per-row measured heights, keyed by
|
|
172
|
+
* keyFunction result. Pruned to the current `items`'
|
|
173
|
+
* live keys whenever `items` changes (see `recomputeOffsets()`), so a
|
|
174
|
+
* long-lived instance handed many wholly different `items` arrays over
|
|
175
|
+
* its life doesn't grow this map without bound. */
|
|
132
176
|
this.measuredHeights = new Map();
|
|
177
|
+
/** True whenever `offsets` needs rebuilding before the next render --
|
|
178
|
+
* set initially and whenever `items`/`rowHeight`/`keyFunction` change or
|
|
179
|
+
* a row's measured height changes, but *not* on a pure scroll-position
|
|
180
|
+
* update, so the `O(n)` rebuild (including a `keyFunction` call per item
|
|
181
|
+
* in `row-height="auto"` mode) only runs when something that actually
|
|
182
|
+
* affects row heights or ordering changed. */
|
|
183
|
+
this.offsetsDirty = true;
|
|
184
|
+
/** Set alongside `offsetsDirty` specifically when `items` changed (not
|
|
185
|
+
* just `rowHeight`/`keyFunction`/a measurement) -- consumed by the next
|
|
186
|
+
* `recomputeOffsets()` call to prune `measuredHeights` entries for keys
|
|
187
|
+
* no longer present in `items`. */
|
|
188
|
+
this.itemsChangedPendingPrune = false;
|
|
133
189
|
this.renderStart = 0;
|
|
134
190
|
this.renderEnd = -1;
|
|
135
191
|
this.visibleStart = 0;
|
|
@@ -140,6 +196,8 @@ export class LyraVirtualList extends LyraElement {
|
|
|
140
196
|
this.loadMoreArmed = true;
|
|
141
197
|
this.isFirstUpdate = true;
|
|
142
198
|
this.observedRows = new Map();
|
|
199
|
+
this.observedRowKeys = new WeakMap();
|
|
200
|
+
this.observedRowIndices = new WeakMap();
|
|
143
201
|
this.pendingScrollTop = null;
|
|
144
202
|
this.onScroll = (e) => {
|
|
145
203
|
this.pendingScrollTop = e.currentTarget.scrollTop;
|
|
@@ -159,10 +217,15 @@ export class LyraVirtualList extends LyraElement {
|
|
|
159
217
|
this.onRowsResized = (entries) => {
|
|
160
218
|
if (this.fixedRowHeight != null)
|
|
161
219
|
return;
|
|
220
|
+
const base = this.renderRoot.querySelector('[part="base"]');
|
|
221
|
+
const oldScrollTop = base?.scrollTop ?? this.containerScrollTop;
|
|
222
|
+
let scrollAdjustment = 0;
|
|
162
223
|
let changed = false;
|
|
163
224
|
for (const entry of entries) {
|
|
164
|
-
const
|
|
165
|
-
|
|
225
|
+
const row = entry.target;
|
|
226
|
+
const key = this.observedRowKeys.get(row);
|
|
227
|
+
const index = this.observedRowIndices.get(row);
|
|
228
|
+
if (key === undefined || index === undefined)
|
|
166
229
|
continue;
|
|
167
230
|
const height = entry.borderBoxSize?.[0]?.blockSize ?? entry.target.getBoundingClientRect().height;
|
|
168
231
|
const prev = this.measuredHeights.get(key);
|
|
@@ -170,11 +233,25 @@ export class LyraVirtualList extends LyraElement {
|
|
|
170
233
|
// isn't worth a full offsets rebuild + re-render.
|
|
171
234
|
if (prev === undefined || Math.abs(prev - height) > 0.5) {
|
|
172
235
|
this.measuredHeights.set(key, height);
|
|
236
|
+
// Keep the first visible row anchored while a row fully above it
|
|
237
|
+
// changes size. Otherwise auto-height measurement makes the viewport
|
|
238
|
+
// jump as soon as an earlier row is laid out.
|
|
239
|
+
const oldHeight = prev ?? DEFAULT_ROW_ESTIMATE_PX;
|
|
240
|
+
if (this.offsets[index + 1] <= oldScrollTop)
|
|
241
|
+
scrollAdjustment += height - oldHeight;
|
|
173
242
|
changed = true;
|
|
174
243
|
}
|
|
175
244
|
}
|
|
176
|
-
if (changed)
|
|
245
|
+
if (changed) {
|
|
246
|
+
if (base && scrollAdjustment !== 0) {
|
|
247
|
+
const nextScrollTop = Math.max(0, oldScrollTop + scrollAdjustment);
|
|
248
|
+
base.scrollTop = nextScrollTop;
|
|
249
|
+
this.containerScrollTop = nextScrollTop;
|
|
250
|
+
this.pendingScrollTop = null;
|
|
251
|
+
}
|
|
252
|
+
this.offsetsDirty = true;
|
|
177
253
|
this.requestUpdate();
|
|
254
|
+
}
|
|
178
255
|
};
|
|
179
256
|
}
|
|
180
257
|
static { this.styles = [LyraElement.styles, styles]; }
|
|
@@ -184,9 +261,15 @@ export class LyraVirtualList extends LyraElement {
|
|
|
184
261
|
// firstUpdated() only ever fires once per element instance -- a
|
|
185
262
|
// disconnect/reconnect (e.g. a reparenting drag) needs its own
|
|
186
263
|
// re-attach here, since the container observer/scroll listener were
|
|
187
|
-
// torn down in disconnectedCallback below.
|
|
188
|
-
|
|
264
|
+
// torn down in disconnectedCallback below. syncRowObservers() is called
|
|
265
|
+
// directly here (rather than left for the next Lit render) because a
|
|
266
|
+
// reconnect that doesn't also change some other reactive property never
|
|
267
|
+
// triggers one, which would otherwise leave every already-rendered row
|
|
268
|
+
// permanently unwatched by the freshly created ResizeObserver above.
|
|
269
|
+
if (this.hasUpdated) {
|
|
189
270
|
this.attachContainerListeners();
|
|
271
|
+
this.syncRowObservers();
|
|
272
|
+
}
|
|
190
273
|
}
|
|
191
274
|
disconnectedCallback() {
|
|
192
275
|
super.disconnectedCallback();
|
|
@@ -206,10 +289,21 @@ export class LyraVirtualList extends LyraElement {
|
|
|
206
289
|
}
|
|
207
290
|
willUpdate(changed) {
|
|
208
291
|
this.isFirstUpdate = !this.hasUpdated;
|
|
292
|
+
if (changed.has('items') || changed.has('rowHeight') || changed.has('keyFunction')) {
|
|
293
|
+
this.offsetsDirty = true;
|
|
294
|
+
}
|
|
295
|
+
if (changed.has('items')) {
|
|
296
|
+
this.itemsChangedPendingPrune = true;
|
|
297
|
+
}
|
|
209
298
|
if (changed.has('rowHeight')) {
|
|
210
299
|
this.fixedRowHeight = this.parseRowHeight(this.rowHeight);
|
|
211
300
|
}
|
|
212
|
-
this.
|
|
301
|
+
if (this.offsetsDirty) {
|
|
302
|
+
this.recomputeOffsets();
|
|
303
|
+
this.offsetsDirty = false;
|
|
304
|
+
}
|
|
305
|
+
// Always cheap: just arithmetic over the already-current offsets +
|
|
306
|
+
// scroll/viewport state, so this runs on a pure scroll-driven update too.
|
|
213
307
|
this.computeRange();
|
|
214
308
|
}
|
|
215
309
|
updated(changed) {
|
|
@@ -230,19 +324,40 @@ export class LyraVirtualList extends LyraElement {
|
|
|
230
324
|
return Number.isFinite(n) && n > 0 ? n : null;
|
|
231
325
|
}
|
|
232
326
|
keyOf(item, index) {
|
|
233
|
-
|
|
327
|
+
const key = this.keyFunction ? this.keyFunction(item, index) : index;
|
|
328
|
+
return typeof key === 'string' || typeof key === 'number' ? key : index;
|
|
234
329
|
}
|
|
235
330
|
recomputeOffsets() {
|
|
236
331
|
const n = this.items.length;
|
|
237
332
|
const offsets = new Array(n + 1);
|
|
238
333
|
offsets[0] = 0;
|
|
334
|
+
// Only build the live-keys set (and only when in row-height="auto" mode,
|
|
335
|
+
// where measuredHeights is actually populated) when items itself changed
|
|
336
|
+
// -- a measurement-only or rowHeight/keyFunction-only recompute has no
|
|
337
|
+
// stale entries to prune, so skipping this keeps those cases as cheap as
|
|
338
|
+
// before.
|
|
339
|
+
const pruneStale = this.itemsChangedPendingPrune && this.fixedRowHeight == null;
|
|
340
|
+
const liveKeys = pruneStale ? new Set() : null;
|
|
239
341
|
for (let i = 0; i < n; i++) {
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
342
|
+
let h;
|
|
343
|
+
if (this.fixedRowHeight != null) {
|
|
344
|
+
h = this.fixedRowHeight;
|
|
345
|
+
}
|
|
346
|
+
else {
|
|
347
|
+
const key = this.keyOf(this.items[i], i);
|
|
348
|
+
liveKeys?.add(key);
|
|
349
|
+
h = this.measuredHeights.get(key) ?? DEFAULT_ROW_ESTIMATE_PX;
|
|
350
|
+
}
|
|
243
351
|
offsets[i + 1] = offsets[i] + h;
|
|
244
352
|
}
|
|
245
353
|
this.offsets = offsets;
|
|
354
|
+
this.itemsChangedPendingPrune = false;
|
|
355
|
+
if (liveKeys) {
|
|
356
|
+
for (const key of this.measuredHeights.keys()) {
|
|
357
|
+
if (!liveKeys.has(key))
|
|
358
|
+
this.measuredHeights.delete(key);
|
|
359
|
+
}
|
|
360
|
+
}
|
|
246
361
|
}
|
|
247
362
|
/** First item index whose bottom edge is at/after `offset`. */
|
|
248
363
|
findIndexAtOrAfter(offset) {
|
|
@@ -285,8 +400,12 @@ export class LyraVirtualList extends LyraElement {
|
|
|
285
400
|
const viewBottom = viewTop + this.viewportHeight;
|
|
286
401
|
this.visibleStart = this.findIndexAtOrAfter(viewTop);
|
|
287
402
|
this.visibleEnd = this.findIndexAtOrBefore(viewBottom);
|
|
288
|
-
|
|
289
|
-
|
|
403
|
+
// Property assignments bypass Lit's attribute converter, so normalize at
|
|
404
|
+
// the arithmetic boundary too. This preserves virtualization even when
|
|
405
|
+
// JavaScript writes Infinity, NaN, a negative, or an excessive number.
|
|
406
|
+
const overscan = normalizeOverscan(this.overscan);
|
|
407
|
+
this.renderStart = Math.max(0, this.visibleStart - overscan);
|
|
408
|
+
this.renderEnd = Math.min(n - 1, this.visibleEnd + overscan);
|
|
290
409
|
}
|
|
291
410
|
attachContainerListeners() {
|
|
292
411
|
const base = this.renderRoot.querySelector('[part="base"]');
|
|
@@ -328,9 +447,13 @@ export class LyraVirtualList extends LyraElement {
|
|
|
328
447
|
}
|
|
329
448
|
const current = new Map();
|
|
330
449
|
this.renderRoot.querySelectorAll('[part="row"]').forEach((el) => {
|
|
331
|
-
const
|
|
332
|
-
if (
|
|
333
|
-
|
|
450
|
+
const index = Number(el.getAttribute('aria-posinset')) - 1;
|
|
451
|
+
if (!Number.isInteger(index) || index < 0 || index >= this.items.length)
|
|
452
|
+
return;
|
|
453
|
+
const key = this.keyOf(this.items[index], index);
|
|
454
|
+
current.set(key, el);
|
|
455
|
+
this.observedRowKeys.set(el, key);
|
|
456
|
+
this.observedRowIndices.set(el, index);
|
|
334
457
|
});
|
|
335
458
|
for (const [key, el] of this.observedRows) {
|
|
336
459
|
if (current.get(key) !== el) {
|
|
@@ -346,9 +469,9 @@ export class LyraVirtualList extends LyraElement {
|
|
|
346
469
|
}
|
|
347
470
|
}
|
|
348
471
|
scrollActiveIntoView() {
|
|
349
|
-
if (
|
|
472
|
+
if (this.activeId === '')
|
|
350
473
|
return;
|
|
351
|
-
const index = this.items.findIndex((item, i) =>
|
|
474
|
+
const index = this.items.findIndex((item, i) => Object.is(this.keyOf(item, i), this.activeId));
|
|
352
475
|
if (index < 0)
|
|
353
476
|
return;
|
|
354
477
|
const base = this.renderRoot.querySelector('[part="base"]');
|
|
@@ -392,14 +515,14 @@ export class LyraVirtualList extends LyraElement {
|
|
|
392
515
|
this.emit('lyra-load-more');
|
|
393
516
|
}
|
|
394
517
|
renderRow(item, index, total) {
|
|
395
|
-
const key =
|
|
518
|
+
const key = this.keyOf(item, index);
|
|
396
519
|
const top = this.offsets[index] ?? 0;
|
|
397
|
-
const isActive = this.activeId !== '' && key
|
|
520
|
+
const isActive = this.activeId !== '' && Object.is(key, this.activeId);
|
|
398
521
|
return html `
|
|
399
522
|
<div
|
|
400
523
|
part="row"
|
|
401
524
|
role="listitem"
|
|
402
|
-
data-row-key=${key}
|
|
525
|
+
data-row-key=${domKeyToken(key)}
|
|
403
526
|
aria-setsize=${total}
|
|
404
527
|
aria-posinset=${index + 1}
|
|
405
528
|
aria-current=${isActive ? 'true' : nothing}
|
|
@@ -409,6 +532,28 @@ export class LyraVirtualList extends LyraElement {
|
|
|
409
532
|
</div>
|
|
410
533
|
`;
|
|
411
534
|
}
|
|
535
|
+
renderGroups() {
|
|
536
|
+
const seen = new Set();
|
|
537
|
+
return (this.groups ?? [])
|
|
538
|
+
.filter((group) => {
|
|
539
|
+
const index = group.startIndex;
|
|
540
|
+
if (!Number.isInteger(index) || index < 0 || index >= this.items.length || seen.has(index))
|
|
541
|
+
return false;
|
|
542
|
+
seen.add(index);
|
|
543
|
+
return true;
|
|
544
|
+
})
|
|
545
|
+
.sort((a, b) => a.startIndex - b.startIndex)
|
|
546
|
+
.map((group) => html `
|
|
547
|
+
<div
|
|
548
|
+
part="group"
|
|
549
|
+
role="heading"
|
|
550
|
+
aria-level="2"
|
|
551
|
+
style=${styleMap({ transform: `translateY(${this.offsets[group.startIndex] ?? 0}px)` })}
|
|
552
|
+
>
|
|
553
|
+
${group.label ?? String(group.key)}
|
|
554
|
+
</div>
|
|
555
|
+
`);
|
|
556
|
+
}
|
|
412
557
|
render() {
|
|
413
558
|
const n = this.items.length;
|
|
414
559
|
const totalHeight = this.offsets[n] ?? 0;
|
|
@@ -419,6 +564,7 @@ export class LyraVirtualList extends LyraElement {
|
|
|
419
564
|
return html `
|
|
420
565
|
<div part="base" role="list" tabindex="0" aria-busy=${this.loading ? 'true' : nothing}>
|
|
421
566
|
<div part="spacer" style=${styleMap({ height: `${totalHeight}px` })}>
|
|
567
|
+
${this.renderGroups()}
|
|
422
568
|
${repeat(windowed, (w) => this.keyOf(w.item, w.index), (w) => this.renderRow(w.item, w.index, n))}
|
|
423
569
|
</div>
|
|
424
570
|
</div>
|
|
@@ -441,7 +587,7 @@ __decorate([
|
|
|
441
587
|
property({ attribute: 'row-height' })
|
|
442
588
|
], LyraVirtualList.prototype, "rowHeight", void 0);
|
|
443
589
|
__decorate([
|
|
444
|
-
property({
|
|
590
|
+
property({ converter: overscanConverter })
|
|
445
591
|
], LyraVirtualList.prototype, "overscan", void 0);
|
|
446
592
|
__decorate([
|
|
447
593
|
property({ attribute: 'active-id' })
|
|
@@ -38,6 +38,18 @@ export const styles = css `
|
|
|
38
38
|
re-render -- hinting the compositor avoids a full repaint per frame. */
|
|
39
39
|
will-change: transform;
|
|
40
40
|
}
|
|
41
|
+
[part='group'] {
|
|
42
|
+
position: absolute;
|
|
43
|
+
inset-inline: 0;
|
|
44
|
+
inset-block-start: 0;
|
|
45
|
+
z-index: 1;
|
|
46
|
+
padding: var(--lyra-space-xs) var(--lyra-space-s);
|
|
47
|
+
background: var(--lyra-color-surface);
|
|
48
|
+
color: var(--lyra-color-text-quiet);
|
|
49
|
+
font-size: 0.875em;
|
|
50
|
+
font-weight: 600;
|
|
51
|
+
pointer-events: none;
|
|
52
|
+
}
|
|
41
53
|
:host([loading]) [part='base'] {
|
|
42
54
|
cursor: progress;
|
|
43
55
|
}
|
|
@@ -42,18 +42,19 @@ export declare class LyraWidget extends LyraElement {
|
|
|
42
42
|
compact: boolean;
|
|
43
43
|
private hasActionsSlot;
|
|
44
44
|
private releaseScrollLock?;
|
|
45
|
-
private
|
|
45
|
+
private overlayHandle?;
|
|
46
|
+
private explicitTrigger?;
|
|
46
47
|
private readonly bodyId;
|
|
47
48
|
protected willUpdate(changed: PropertyValues): void;
|
|
48
49
|
protected updated(changed: PropertyValues): void;
|
|
49
50
|
connectedCallback(): void;
|
|
50
51
|
disconnectedCallback(): void;
|
|
52
|
+
private activateFullscreenOverlay;
|
|
53
|
+
private deactivateFullscreenOverlay;
|
|
51
54
|
private onActionsSlotChange;
|
|
52
55
|
private toggleCollapsed;
|
|
53
56
|
private toggleFullscreen;
|
|
54
|
-
private
|
|
55
|
-
private getFocusableElements;
|
|
56
|
-
private getActiveElement;
|
|
57
|
+
private dismissFullscreen;
|
|
57
58
|
private onBackdropClick;
|
|
58
59
|
render(): TemplateResult;
|
|
59
60
|
}
|