@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,4 +1,4 @@
|
|
|
1
|
-
import { type TemplateResult } from 'lit';
|
|
1
|
+
import { type TemplateResult, type PropertyValues } from 'lit';
|
|
2
2
|
import { LyraElement } from '../../internal/lyra-element.js';
|
|
3
3
|
/**
|
|
4
4
|
* `<lyra-json-viewer>` — a collapsible, copyable tree view for an arbitrary
|
|
@@ -17,10 +17,10 @@ import { LyraElement } from '../../internal/lyra-element.js';
|
|
|
17
17
|
* @csspart toolbar - The wrapper around the top-level copy button (only rendered when `copyable`).
|
|
18
18
|
* @csspart tree - The wrapper around the rendered node tree.
|
|
19
19
|
* @csspart key - An object property key or array index label.
|
|
20
|
-
* @csspart value - A primitive value's text -- carries `data-type` (`string`/`number`/`boolean`/`null`/`undefined`) for per-type coloring, and `data-match` while it matches `search`.
|
|
20
|
+
* @csspart value - A primitive value's text -- carries `data-type` (`string`/`number`/`boolean`/`null`/`undefined`, or `circular` for a self-reference marker in place of a re-visited container's subtree) for per-type coloring, and `data-match` while it matches `search`.
|
|
21
21
|
* @csspart bracket - A `{`, `}`, `[`, or `]` delimiter.
|
|
22
22
|
* @csspart toggle - A container node's expand/collapse button (hidden, but present for row alignment, on leaf/empty nodes).
|
|
23
|
-
* @csspart copy-button - A copy-to-clipboard button -- the top-level one (in `toolbar
|
|
23
|
+
* @csspart copy-button - A copy-to-clipboard button -- the top-level one (in `toolbar`, labelled "Copy JSON to clipboard") or a per-node one (only rendered when `copyable`; labelled with its own key/type, e.g. "Copy age", so assistive tech can tell rows apart).
|
|
24
24
|
*/
|
|
25
25
|
export declare class LyraJsonViewer extends LyraElement {
|
|
26
26
|
static styles: import("lit").CSSResultGroup[];
|
|
@@ -34,16 +34,33 @@ export declare class LyraJsonViewer extends LyraElement {
|
|
|
34
34
|
copyable: boolean;
|
|
35
35
|
/** Case-insensitive substring match against keys/values; matches are highlighted and their ancestors auto-expanded. */
|
|
36
36
|
search: string;
|
|
37
|
-
/**
|
|
37
|
+
/**
|
|
38
|
+
* Per-path (`JSON.stringify(path)`) explicit expand/collapse, overriding
|
|
39
|
+
* the `collapsedDepth`/search defaults once a node's toggle has been used.
|
|
40
|
+
* Pruned in `willUpdate()` (to the paths still reachable in the tree)
|
|
41
|
+
* whenever `data` changes, so a long-lived instance bound to reshaping
|
|
42
|
+
* data -- this component's own stated streaming use case -- doesn't
|
|
43
|
+
* accumulate one entry per path ever toggled for the life of the instance.
|
|
44
|
+
*/
|
|
38
45
|
private expandedOverrides;
|
|
46
|
+
/** Memoized result of the last `computeSearch()` walk -- see `willUpdate()`. */
|
|
47
|
+
private searchState;
|
|
39
48
|
private isExpanded;
|
|
40
49
|
private toggleNode;
|
|
41
50
|
private writeClipboard;
|
|
42
51
|
private copy;
|
|
43
|
-
/**
|
|
52
|
+
/**
|
|
53
|
+
* Builds the key/value-match sets, the ancestor-paths-of-a-match set that
|
|
54
|
+
* `search` drives, and the full set of path keys reachable in the tree
|
|
55
|
+
* (`paths`, used to prune `expandedOverrides` -- see `willUpdate()`).
|
|
56
|
+
* Guards against a self-referencing `data` the same way `renderNode()`
|
|
57
|
+
* does: a container value already on the current recursion path is
|
|
58
|
+
* treated as a leaf instead of being walked again.
|
|
59
|
+
*/
|
|
44
60
|
private computeSearch;
|
|
45
61
|
private renderCopyButton;
|
|
46
62
|
private renderNode;
|
|
63
|
+
protected willUpdate(changed: PropertyValues): void;
|
|
47
64
|
render(): TemplateResult;
|
|
48
65
|
}
|
|
49
66
|
declare global {
|
|
@@ -15,6 +15,7 @@ const EMPTY_SEARCH = {
|
|
|
15
15
|
keyMatches: new Set(),
|
|
16
16
|
valueMatches: new Set(),
|
|
17
17
|
forceExpand: new Set(),
|
|
18
|
+
paths: new Set(),
|
|
18
19
|
};
|
|
19
20
|
function isPlainContainer(value) {
|
|
20
21
|
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
@@ -46,7 +47,12 @@ function valueType(value) {
|
|
|
46
47
|
function formatPrimitive(value, type) {
|
|
47
48
|
switch (type) {
|
|
48
49
|
case 'string':
|
|
49
|
-
|
|
50
|
+
// `type` here also covers valueType()'s function/symbol/bigint
|
|
51
|
+
// fallback (see the comment there) -- JSON.stringify() throws a
|
|
52
|
+
// TypeError for a BigInt, so only an actual string gets the
|
|
53
|
+
// quoted/escaped treatment; everything else falls back to a plain
|
|
54
|
+
// String() coercion, which renders "sensibly" without throwing.
|
|
55
|
+
return typeof value === 'string' ? JSON.stringify(value) : String(value);
|
|
50
56
|
case 'null':
|
|
51
57
|
return 'null';
|
|
52
58
|
case 'undefined':
|
|
@@ -77,10 +83,10 @@ function previewText(value, type, count) {
|
|
|
77
83
|
* @csspart toolbar - The wrapper around the top-level copy button (only rendered when `copyable`).
|
|
78
84
|
* @csspart tree - The wrapper around the rendered node tree.
|
|
79
85
|
* @csspart key - An object property key or array index label.
|
|
80
|
-
* @csspart value - A primitive value's text -- carries `data-type` (`string`/`number`/`boolean`/`null`/`undefined`) for per-type coloring, and `data-match` while it matches `search`.
|
|
86
|
+
* @csspart value - A primitive value's text -- carries `data-type` (`string`/`number`/`boolean`/`null`/`undefined`, or `circular` for a self-reference marker in place of a re-visited container's subtree) for per-type coloring, and `data-match` while it matches `search`.
|
|
81
87
|
* @csspart bracket - A `{`, `}`, `[`, or `]` delimiter.
|
|
82
88
|
* @csspart toggle - A container node's expand/collapse button (hidden, but present for row alignment, on leaf/empty nodes).
|
|
83
|
-
* @csspart copy-button - A copy-to-clipboard button -- the top-level one (in `toolbar
|
|
89
|
+
* @csspart copy-button - A copy-to-clipboard button -- the top-level one (in `toolbar`, labelled "Copy JSON to clipboard") or a per-node one (only rendered when `copyable`; labelled with its own key/type, e.g. "Copy age", so assistive tech can tell rows apart).
|
|
84
90
|
*/
|
|
85
91
|
export class LyraJsonViewer extends LyraElement {
|
|
86
92
|
constructor() {
|
|
@@ -91,8 +97,17 @@ export class LyraJsonViewer extends LyraElement {
|
|
|
91
97
|
this.copyable = false;
|
|
92
98
|
/** Case-insensitive substring match against keys/values; matches are highlighted and their ancestors auto-expanded. */
|
|
93
99
|
this.search = '';
|
|
94
|
-
/**
|
|
100
|
+
/**
|
|
101
|
+
* Per-path (`JSON.stringify(path)`) explicit expand/collapse, overriding
|
|
102
|
+
* the `collapsedDepth`/search defaults once a node's toggle has been used.
|
|
103
|
+
* Pruned in `willUpdate()` (to the paths still reachable in the tree)
|
|
104
|
+
* whenever `data` changes, so a long-lived instance bound to reshaping
|
|
105
|
+
* data -- this component's own stated streaming use case -- doesn't
|
|
106
|
+
* accumulate one entry per path ever toggled for the life of the instance.
|
|
107
|
+
*/
|
|
95
108
|
this.expandedOverrides = new Map();
|
|
109
|
+
/** Memoized result of the last `computeSearch()` walk -- see `willUpdate()`. */
|
|
110
|
+
this.searchState = EMPTY_SEARCH;
|
|
96
111
|
}
|
|
97
112
|
static { this.styles = [LyraElement.styles, styles]; }
|
|
98
113
|
isExpanded(pathKey, depth, forceExpand) {
|
|
@@ -123,50 +138,70 @@ export class LyraJsonViewer extends LyraElement {
|
|
|
123
138
|
}
|
|
124
139
|
}
|
|
125
140
|
copy(value) {
|
|
126
|
-
const text = value === undefined
|
|
141
|
+
const text = value === undefined
|
|
142
|
+
? 'undefined'
|
|
143
|
+
: // A BigInt anywhere inside `value` (not just at the root) throws a
|
|
144
|
+
// TypeError from the default JSON.stringify() serializer the same
|
|
145
|
+
// way formatPrimitive()'s unguarded call used to -- the replacer
|
|
146
|
+
// downgrades it to its decimal string form instead.
|
|
147
|
+
JSON.stringify(value, (_key, v) => (typeof v === 'bigint' ? v.toString() : v), 2);
|
|
127
148
|
this.writeClipboard(text);
|
|
128
149
|
this.emit('lyra-copy', { text });
|
|
129
150
|
}
|
|
130
|
-
/**
|
|
151
|
+
/**
|
|
152
|
+
* Builds the key/value-match sets, the ancestor-paths-of-a-match set that
|
|
153
|
+
* `search` drives, and the full set of path keys reachable in the tree
|
|
154
|
+
* (`paths`, used to prune `expandedOverrides` -- see `willUpdate()`).
|
|
155
|
+
* Guards against a self-referencing `data` the same way `renderNode()`
|
|
156
|
+
* does: a container value already on the current recursion path is
|
|
157
|
+
* treated as a leaf instead of being walked again.
|
|
158
|
+
*/
|
|
131
159
|
computeSearch() {
|
|
132
160
|
const query = this.search.trim().toLowerCase();
|
|
133
|
-
if (!query)
|
|
134
|
-
return EMPTY_SEARCH;
|
|
135
161
|
const keyMatches = new Set();
|
|
136
162
|
const valueMatches = new Set();
|
|
137
163
|
const forceExpand = new Set();
|
|
164
|
+
const paths = new Set();
|
|
165
|
+
const ancestors = new WeakSet();
|
|
138
166
|
const markAncestors = (path) => {
|
|
139
167
|
for (let i = path.length - 1; i >= 0; i--)
|
|
140
168
|
forceExpand.add(JSON.stringify(path.slice(0, i)));
|
|
141
169
|
};
|
|
142
170
|
const walk = (value, path, keyLabel) => {
|
|
143
171
|
const pathKey = JSON.stringify(path);
|
|
144
|
-
|
|
145
|
-
if (keyLabel !== undefined && keyLabel.toLowerCase().includes(query)) {
|
|
146
|
-
keyMatches.add(pathKey);
|
|
147
|
-
hit = true;
|
|
148
|
-
}
|
|
172
|
+
paths.add(pathKey);
|
|
149
173
|
const type = valueType(value);
|
|
150
|
-
if (
|
|
151
|
-
|
|
152
|
-
|
|
174
|
+
if (query) {
|
|
175
|
+
let hit = false;
|
|
176
|
+
if (keyLabel !== undefined && keyLabel.toLowerCase().includes(query)) {
|
|
177
|
+
keyMatches.add(pathKey);
|
|
178
|
+
hit = true;
|
|
179
|
+
}
|
|
180
|
+
if (type !== 'object' && type !== 'array' && formatPrimitive(value, type).toLowerCase().includes(query)) {
|
|
181
|
+
valueMatches.add(pathKey);
|
|
182
|
+
hit = true;
|
|
183
|
+
}
|
|
184
|
+
if (hit)
|
|
185
|
+
markAncestors(path);
|
|
186
|
+
}
|
|
187
|
+
if ((type === 'object' || type === 'array') && !ancestors.has(value)) {
|
|
188
|
+
ancestors.add(value);
|
|
189
|
+
for (const [k, v] of entriesOf(value))
|
|
190
|
+
walk(v, [...path, k], String(k));
|
|
191
|
+
ancestors.delete(value);
|
|
153
192
|
}
|
|
154
|
-
if (hit)
|
|
155
|
-
markAncestors(path);
|
|
156
|
-
for (const [k, v] of entriesOf(value))
|
|
157
|
-
walk(v, [...path, k], String(k));
|
|
158
193
|
};
|
|
159
194
|
walk(this.data, []);
|
|
160
|
-
return { keyMatches, valueMatches, forceExpand };
|
|
195
|
+
return { keyMatches, valueMatches, forceExpand, paths };
|
|
161
196
|
}
|
|
162
|
-
renderCopyButton(value) {
|
|
197
|
+
renderCopyButton(value, label) {
|
|
163
198
|
if (!this.copyable)
|
|
164
199
|
return nothing;
|
|
165
200
|
return html `
|
|
166
201
|
<button
|
|
167
202
|
part="copy-button"
|
|
168
203
|
type="button"
|
|
169
|
-
aria-label="Copy value"
|
|
204
|
+
aria-label="Copy ${label ?? 'value'}"
|
|
170
205
|
@click=${(e) => {
|
|
171
206
|
e.stopPropagation();
|
|
172
207
|
this.copy(value);
|
|
@@ -176,10 +211,15 @@ export class LyraJsonViewer extends LyraElement {
|
|
|
176
211
|
</button>
|
|
177
212
|
`;
|
|
178
213
|
}
|
|
179
|
-
renderNode(value, path, keyLabel, depth, search) {
|
|
214
|
+
renderNode(value, path, keyLabel, depth, search, ancestors) {
|
|
180
215
|
const pathKey = JSON.stringify(path);
|
|
181
216
|
const type = valueType(value);
|
|
182
|
-
|
|
217
|
+
// A container value already on the current recursion path (i.e. `data`
|
|
218
|
+
// self-references, directly or through a longer cycle) gets rendered as
|
|
219
|
+
// a leaf marker instead of recursing again -- recursing would blow the
|
|
220
|
+
// stack instead of degrading gracefully.
|
|
221
|
+
const isCircular = (type === 'object' || type === 'array') && ancestors.has(value);
|
|
222
|
+
const isContainer = (type === 'object' || type === 'array') && !isCircular;
|
|
183
223
|
const entries = isContainer ? entriesOf(value) : [];
|
|
184
224
|
const hasEntries = entries.length > 0;
|
|
185
225
|
const expanded = hasEntries && this.isExpanded(pathKey, depth, search.forceExpand);
|
|
@@ -187,6 +227,17 @@ export class LyraJsonViewer extends LyraElement {
|
|
|
187
227
|
const toggleLabel = keyLabel ?? (type === 'array' ? 'array' : type === 'object' ? 'object' : 'value');
|
|
188
228
|
const openBracket = type === 'array' ? '[' : '{';
|
|
189
229
|
const closeBracket = type === 'array' ? ']' : '}';
|
|
230
|
+
// Computed eagerly -- in this same synchronous call, rather than left for
|
|
231
|
+
// lit-html's `repeat` directive to invoke lazily during commit -- so the
|
|
232
|
+
// `ancestors.add()`/`.delete()` pair below brackets exactly the values on
|
|
233
|
+
// the real recursive descent through *this* subtree, regardless of
|
|
234
|
+
// whenever lit-html itself gets around to resolving the directive.
|
|
235
|
+
let childRows = [];
|
|
236
|
+
if (isContainer && expanded) {
|
|
237
|
+
ancestors.add(value);
|
|
238
|
+
childRows = entries.map(([k, v]) => this.renderNode(v, [...path, k], String(k), depth + 1, search, ancestors));
|
|
239
|
+
ancestors.delete(value);
|
|
240
|
+
}
|
|
190
241
|
const headRow = html `
|
|
191
242
|
<div class="row" style=${indentStyle}>
|
|
192
243
|
<button
|
|
@@ -205,18 +256,24 @@ export class LyraJsonViewer extends LyraElement {
|
|
|
205
256
|
? html `<span part="key" ?data-match=${search.keyMatches.has(pathKey)}>${keyLabel}</span
|
|
206
257
|
><span class="colon">:</span>`
|
|
207
258
|
: nothing}
|
|
208
|
-
${
|
|
259
|
+
${isCircular
|
|
209
260
|
? html `
|
|
210
261
|
<span part="bracket">${openBracket}</span>
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
: nothing}
|
|
214
|
-
${!expanded ? html `<span part="bracket">${closeBracket}</span>` : nothing}
|
|
262
|
+
<span part="value" data-type="circular">Circular reference</span>
|
|
263
|
+
<span part="bracket">${closeBracket}</span>
|
|
215
264
|
`
|
|
216
|
-
:
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
265
|
+
: isContainer
|
|
266
|
+
? html `
|
|
267
|
+
<span part="bracket">${openBracket}</span>
|
|
268
|
+
${hasEntries && !expanded
|
|
269
|
+
? html `<span class="preview">${previewText(value, type, entries.length)}</span>`
|
|
270
|
+
: nothing}
|
|
271
|
+
${!expanded ? html `<span part="bracket">${closeBracket}</span>` : nothing}
|
|
272
|
+
`
|
|
273
|
+
: html `<span part="value" data-type=${type} ?data-match=${search.valueMatches.has(pathKey)}
|
|
274
|
+
>${formatPrimitive(value, type)}</span
|
|
275
|
+
>`}
|
|
276
|
+
${this.renderCopyButton(value, toggleLabel)}
|
|
220
277
|
</div>
|
|
221
278
|
`;
|
|
222
279
|
// Always returned from this one call site, with a single conditional
|
|
@@ -231,7 +288,7 @@ export class LyraJsonViewer extends LyraElement {
|
|
|
231
288
|
${isContainer && expanded
|
|
232
289
|
? html `
|
|
233
290
|
<div class="children">
|
|
234
|
-
${repeat(entries, ([k]) => JSON.stringify([...path, k]), (
|
|
291
|
+
${repeat(entries, ([k]) => JSON.stringify([...path, k]), (_entry, i) => childRows[i])}
|
|
235
292
|
</div>
|
|
236
293
|
<div class="row" style=${indentStyle}>
|
|
237
294
|
<span class="toggle-space" aria-hidden="true"></span>
|
|
@@ -241,8 +298,29 @@ export class LyraJsonViewer extends LyraElement {
|
|
|
241
298
|
: nothing}
|
|
242
299
|
`;
|
|
243
300
|
}
|
|
301
|
+
willUpdate(changed) {
|
|
302
|
+
if (!this.hasUpdated || changed.has('data') || changed.has('search')) {
|
|
303
|
+
const next = this.computeSearch();
|
|
304
|
+
if (!this.hasUpdated || changed.has('data')) {
|
|
305
|
+
// A path with no entry in `next.paths` no longer exists anywhere in
|
|
306
|
+
// the new tree, so its override has nothing left to apply to --
|
|
307
|
+
// dropping it here (rather than never, as before) is what keeps a
|
|
308
|
+
// long-lived instance bound to reshaping data from accumulating one
|
|
309
|
+
// Map entry per distinct path ever toggled over its whole lifetime.
|
|
310
|
+
let pruned = null;
|
|
311
|
+
for (const key of this.expandedOverrides.keys()) {
|
|
312
|
+
if (!next.paths.has(key)) {
|
|
313
|
+
pruned ??= new Map(this.expandedOverrides);
|
|
314
|
+
pruned.delete(key);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
if (pruned)
|
|
318
|
+
this.expandedOverrides = pruned;
|
|
319
|
+
}
|
|
320
|
+
this.searchState = next;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
244
323
|
render() {
|
|
245
|
-
const search = this.computeSearch();
|
|
246
324
|
return html `
|
|
247
325
|
<div part="base" style=${this.maxHeight ? `--lyra-json-viewer-max-height:${this.maxHeight}` : nothing}>
|
|
248
326
|
${this.copyable
|
|
@@ -257,7 +335,7 @@ export class LyraJsonViewer extends LyraElement {
|
|
|
257
335
|
</button>
|
|
258
336
|
</div>`
|
|
259
337
|
: nothing}
|
|
260
|
-
<div part="tree">${this.renderNode(this.data, [], undefined, 0,
|
|
338
|
+
<div part="tree">${this.renderNode(this.data, [], undefined, 0, this.searchState, new WeakSet())}</div>
|
|
261
339
|
</div>
|
|
262
340
|
`;
|
|
263
341
|
}
|
|
@@ -132,7 +132,8 @@ export const styles = css `
|
|
|
132
132
|
color: var(--lyra-color-warning);
|
|
133
133
|
}
|
|
134
134
|
[part='value'][data-type='null'],
|
|
135
|
-
[part='value'][data-type='undefined']
|
|
135
|
+
[part='value'][data-type='undefined'],
|
|
136
|
+
[part='value'][data-type='circular'] {
|
|
136
137
|
color: var(--lyra-color-text-quiet);
|
|
137
138
|
font-style: italic;
|
|
138
139
|
}
|
|
@@ -111,6 +111,17 @@ function detectIsMac() {
|
|
|
111
111
|
// little cost, however small) from re-detecting it on every <lyra-kbd>
|
|
112
112
|
// instance or every re-render.
|
|
113
113
|
const IS_MAC = detectIsMac();
|
|
114
|
+
// The one "is there real content" predicate shared by both the initial
|
|
115
|
+
// synchronous seed (willUpdate, reading light-DOM childNodes) and the
|
|
116
|
+
// runtime slotchange handler (reading assignedNodes) — using two different
|
|
117
|
+
// predicates for the same question let them disagree: a text-only check
|
|
118
|
+
// would seed correctly for whitespace-only text but (wrongly) treat a
|
|
119
|
+
// content-less icon element as empty, and a node-count-only check would
|
|
120
|
+
// treat *any* assigned node — including a whitespace-only text node — as
|
|
121
|
+
// real content. Counting every element node as real content (regardless of
|
|
122
|
+
// its own text) while requiring non-whitespace text from text nodes gets
|
|
123
|
+
// both cases right in one place.
|
|
124
|
+
const hasRealContent = (nodes) => Array.from(nodes).some((n) => n.nodeType === Node.ELEMENT_NODE || (n.textContent ?? '').trim().length > 0);
|
|
114
125
|
/**
|
|
115
126
|
* `<lyra-kbd>` — a small chip representing a keyboard shortcut, rendering
|
|
116
127
|
* the platform-appropriate glyph for cross-platform modifier keys (⌘ on
|
|
@@ -162,13 +173,13 @@ export class LyraKbd extends LyraElement {
|
|
|
162
173
|
// keys rendering for one frame before the first slotchange event.
|
|
163
174
|
this.hasCustomContent = false;
|
|
164
175
|
this.onSlotChange = (e) => {
|
|
165
|
-
this.hasCustomContent = e.target.assignedNodes({ flatten: true })
|
|
176
|
+
this.hasCustomContent = hasRealContent(e.target.assignedNodes({ flatten: true }));
|
|
166
177
|
};
|
|
167
178
|
}
|
|
168
179
|
static { this.styles = [LyraElement.styles, styles]; }
|
|
169
180
|
willUpdate() {
|
|
170
181
|
if (!this.hasUpdated) {
|
|
171
|
-
this.hasCustomContent =
|
|
182
|
+
this.hasCustomContent = hasRealContent(this.childNodes);
|
|
172
183
|
}
|
|
173
184
|
}
|
|
174
185
|
render() {
|
|
@@ -185,15 +196,21 @@ export class LyraKbd extends LyraElement {
|
|
|
185
196
|
// lyra-context-meter's/lyra-chart's canvas usage of the same pattern):
|
|
186
197
|
// the individual glyphs and "+" separators aren't real words, so
|
|
187
198
|
// exposing them as separate accessible-tree text would read worse than
|
|
188
|
-
// the single spelled-out aria-label below. An empty `keys`
|
|
189
|
-
// nothing visible, so it's marked
|
|
190
|
-
// nameless image.
|
|
199
|
+
// the single spelled-out aria-label below. An empty `keys` (and no
|
|
200
|
+
// explicit override) renders nothing visible, so it's marked
|
|
201
|
+
// aria-hidden instead of exposed as a nameless image.
|
|
202
|
+
//
|
|
203
|
+
// role/aria-hidden are both derived from this same `ariaLabel` value
|
|
204
|
+
// (rather than each independently re-deriving "is there a label" from
|
|
205
|
+
// tokens.length/explicitLabel) so role="img" can never be absent while
|
|
206
|
+
// aria-label is present — that combination is an aria-prohibited-attr
|
|
207
|
+
// violation (a nameless-but-labeled, role-less element).
|
|
191
208
|
const ariaLabel = explicitLabel || tokens.map((t) => t.word).join('+');
|
|
192
209
|
return html `
|
|
193
210
|
<span
|
|
194
211
|
part="base"
|
|
195
|
-
role=${
|
|
196
|
-
aria-hidden=${
|
|
212
|
+
role=${ariaLabel ? 'img' : nothing}
|
|
213
|
+
aria-hidden=${ariaLabel ? nothing : 'true'}
|
|
197
214
|
aria-label=${ariaLabel || nothing}
|
|
198
215
|
>
|
|
199
216
|
${tokens.map((t, i) => html `
|
|
@@ -50,7 +50,14 @@ export type LiveRegionMode = 'polite' | 'assertive';
|
|
|
50
50
|
export declare class LyraLiveRegion extends LyraElement {
|
|
51
51
|
static styles: import("lit").CSSResultGroup[];
|
|
52
52
|
/** `polite` (role="status") waits for the user to be idle; `assertive`
|
|
53
|
-
* (role="alert") interrupts. Mirrors native `aria-live` semantics.
|
|
53
|
+
* (role="alert") interrupts. Mirrors native `aria-live` semantics.
|
|
54
|
+
*
|
|
55
|
+
* `write()` also applies `role`/`aria-live` imperatively at announce time
|
|
56
|
+
* (not only through this property's template binding) so a caller that
|
|
57
|
+
* sets `mode` and immediately force-announces in the same synchronous
|
|
58
|
+
* turn -- e.g. a stream-status transition -- gets the new urgency and the
|
|
59
|
+
* new text landing together, rather than the text beating Lit's
|
|
60
|
+
* re-render to the DOM. */
|
|
54
61
|
mode: LiveRegionMode;
|
|
55
62
|
/** Throttle window in ms — see `Announcer` in `internal/announcer.ts`. */
|
|
56
63
|
throttleMs: number;
|
|
@@ -58,6 +65,7 @@ export declare class LyraLiveRegion extends LyraElement {
|
|
|
58
65
|
private lastWritten;
|
|
59
66
|
private regionEl?;
|
|
60
67
|
private reannounceHandle?;
|
|
68
|
+
private reannounceView?;
|
|
61
69
|
private pendingWrite?;
|
|
62
70
|
constructor();
|
|
63
71
|
protected updated(changed: PropertyValues): void;
|
|
@@ -72,6 +80,7 @@ export declare class LyraLiveRegion extends LyraElement {
|
|
|
72
80
|
*/
|
|
73
81
|
announce(text: string, options?: AnnounceOptions): void;
|
|
74
82
|
private write;
|
|
83
|
+
private cancelReannounce;
|
|
75
84
|
render(): TemplateResult;
|
|
76
85
|
}
|
|
77
86
|
declare global {
|
|
@@ -61,7 +61,14 @@ export class LyraLiveRegion extends LyraElement {
|
|
|
61
61
|
constructor() {
|
|
62
62
|
super();
|
|
63
63
|
/** `polite` (role="status") waits for the user to be idle; `assertive`
|
|
64
|
-
* (role="alert") interrupts. Mirrors native `aria-live` semantics.
|
|
64
|
+
* (role="alert") interrupts. Mirrors native `aria-live` semantics.
|
|
65
|
+
*
|
|
66
|
+
* `write()` also applies `role`/`aria-live` imperatively at announce time
|
|
67
|
+
* (not only through this property's template binding) so a caller that
|
|
68
|
+
* sets `mode` and immediately force-announces in the same synchronous
|
|
69
|
+
* turn -- e.g. a stream-status transition -- gets the new urgency and the
|
|
70
|
+
* new text landing together, rather than the text beating Lit's
|
|
71
|
+
* re-render to the DOM. */
|
|
65
72
|
this.mode = 'polite';
|
|
66
73
|
/** Throttle window in ms — see `Announcer` in `internal/announcer.ts`. */
|
|
67
74
|
this.throttleMs = 500;
|
|
@@ -94,10 +101,8 @@ export class LyraLiveRegion extends LyraElement {
|
|
|
94
101
|
disconnectedCallback() {
|
|
95
102
|
super.disconnectedCallback();
|
|
96
103
|
this.announcer.cancel();
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
this.reannounceHandle = undefined;
|
|
100
|
-
}
|
|
104
|
+
this.pendingWrite = undefined;
|
|
105
|
+
this.cancelReannounce();
|
|
101
106
|
}
|
|
102
107
|
/**
|
|
103
108
|
* Queue `text` for announcement. Calls arriving within `throttle-ms` of
|
|
@@ -115,6 +120,13 @@ export class LyraLiveRegion extends LyraElement {
|
|
|
115
120
|
this.pendingWrite = text;
|
|
116
121
|
return;
|
|
117
122
|
}
|
|
123
|
+
// A same-text reannounce frame still in flight is now stale the moment
|
|
124
|
+
// any new write() call comes in -- if it fired later it would clobber
|
|
125
|
+
// whatever text this call is about to land with the older, already-
|
|
126
|
+
// superseded string. Cancel it up front so at most one reannounce is
|
|
127
|
+
// ever pending and it can never overwrite a newer announcement.
|
|
128
|
+
this.cancelReannounce();
|
|
129
|
+
const assertive = this.mode === 'assertive';
|
|
118
130
|
if (text === this.lastWritten) {
|
|
119
131
|
// Screen readers announce a live region on text-content *change* --
|
|
120
132
|
// re-writing the identical string is otherwise a silent no-op to
|
|
@@ -122,17 +134,41 @@ export class LyraLiveRegion extends LyraElement {
|
|
|
122
134
|
// (rather than in the same task) gives the DOM an actual empty ->
|
|
123
135
|
// populated transition to observe instead of a same-tick clear+set
|
|
124
136
|
// that can coalesce into nothing ever appearing to change.
|
|
137
|
+
//
|
|
138
|
+
// role/aria-live are set imperatively here (not left to Lit's
|
|
139
|
+
// template binding) so a caller that sets `mode` and immediately
|
|
140
|
+
// force-announces -- e.g. stream-status's announceTransition() --
|
|
141
|
+
// gets the new urgency in the same synchronous operation as the text,
|
|
142
|
+
// rather than racing Lit's async re-render.
|
|
143
|
+
region.setAttribute('role', assertive ? 'alert' : 'status');
|
|
144
|
+
region.setAttribute('aria-live', assertive ? 'assertive' : 'polite');
|
|
125
145
|
region.textContent = '';
|
|
126
|
-
|
|
146
|
+
const view = region.ownerDocument.defaultView;
|
|
147
|
+
if (!view) {
|
|
148
|
+
region.textContent = text;
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
this.reannounceView = view;
|
|
152
|
+
this.reannounceHandle = view.requestAnimationFrame(() => {
|
|
127
153
|
this.reannounceHandle = undefined;
|
|
154
|
+
this.reannounceView = undefined;
|
|
128
155
|
region.textContent = text;
|
|
129
156
|
});
|
|
130
157
|
}
|
|
131
158
|
else {
|
|
159
|
+
region.setAttribute('role', assertive ? 'alert' : 'status');
|
|
160
|
+
region.setAttribute('aria-live', assertive ? 'assertive' : 'polite');
|
|
132
161
|
region.textContent = text;
|
|
133
162
|
}
|
|
134
163
|
this.lastWritten = text;
|
|
135
164
|
}
|
|
165
|
+
cancelReannounce() {
|
|
166
|
+
if (this.reannounceHandle === undefined)
|
|
167
|
+
return;
|
|
168
|
+
this.reannounceView?.cancelAnimationFrame(this.reannounceHandle);
|
|
169
|
+
this.reannounceHandle = undefined;
|
|
170
|
+
this.reannounceView = undefined;
|
|
171
|
+
}
|
|
136
172
|
render() {
|
|
137
173
|
const assertive = this.mode === 'assertive';
|
|
138
174
|
return html `<div
|
|
@@ -41,10 +41,22 @@ export interface MapMarker {
|
|
|
41
41
|
* choropleth GeoJSON layer, plus a raw `map` escape hatch. Requires the
|
|
42
42
|
* optional peer dep `maplibre-gl` (consumers also import its CSS once).
|
|
43
43
|
*
|
|
44
|
+
* The underlying `maplibregl.Map` — and the WebGL context it opens — isn't
|
|
45
|
+
* constructed until this element is first visible in the viewport (tracked
|
|
46
|
+
* via `IntersectionObserver`), even once the `maplibre-gl` peer dependency
|
|
47
|
+
* has finished loading. Browsers hard-cap concurrent WebGL contexts per
|
|
48
|
+
* page, so a grid/dashboard of many `<lyra-map>` instances only constructs
|
|
49
|
+
* the ones actually on-screen instead of racing to exhaust that budget the
|
|
50
|
+
* instant each one mounts. `map` stays `undefined` (and `lyra-map-load`
|
|
51
|
+
* doesn't fire) until construction actually happens.
|
|
52
|
+
*
|
|
44
53
|
* @customElement lyra-map
|
|
45
54
|
* @event lyra-map-load - Fired once the underlying maplibregl.Map loads.
|
|
46
55
|
* @event lyra-map-click - `detail: { lngLat, feature? }`.
|
|
47
|
-
* @csspart base
|
|
56
|
+
* @csspart base - The map wrapper.
|
|
57
|
+
* @csspart container - The maplibre container.
|
|
58
|
+
* @csspart legend - The map legend.
|
|
59
|
+
* @csspart legend-swatch - A legend color swatch.
|
|
48
60
|
*
|
|
49
61
|
* ⚠️ The default `mapStyle` (when unset) uses OpenStreetMap's demo tile
|
|
50
62
|
* server, which is not suitable for production traffic — see the
|
|
@@ -61,6 +73,8 @@ export declare class LyraMap extends LyraElement {
|
|
|
61
73
|
markers: MapMarker[];
|
|
62
74
|
/** True until the lazy-loaded `maplibre-gl` peer dependency has settled (success or failure). */
|
|
63
75
|
private loading;
|
|
76
|
+
private visible;
|
|
77
|
+
private intersectionObserver?;
|
|
64
78
|
private containerEl?;
|
|
65
79
|
private _map?;
|
|
66
80
|
private _styleLoaded;
|
|
@@ -74,6 +88,15 @@ export declare class LyraMap extends LyraElement {
|
|
|
74
88
|
get map(): import('maplibre-gl').Map | undefined;
|
|
75
89
|
connectedCallback(): void;
|
|
76
90
|
disconnectedCallback(): void;
|
|
91
|
+
/**
|
|
92
|
+
* Constructs the underlying `maplibregl.Map` — called once both the
|
|
93
|
+
* lazy-loaded `maplibre-gl` module has resolved and this element has been
|
|
94
|
+
* observed intersecting the viewport, whichever settles last. Idempotent
|
|
95
|
+
* (a no-op once `_map` already exists), so it's safe to call from both the
|
|
96
|
+
* `connectedCallback()` load path and the visibility path in `updated()`
|
|
97
|
+
* below without risking a double construction.
|
|
98
|
+
*/
|
|
99
|
+
private tryConstructMap;
|
|
77
100
|
protected updated(changed: PropertyValues): void;
|
|
78
101
|
private applyChoropleth;
|
|
79
102
|
/** Removes whatever choropleth layer/source is currently applied, if any. */
|