@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
|
@@ -9,74 +9,74 @@ import { property, state } from 'lit/decorators.js';
|
|
|
9
9
|
import { LyraElement } from '../../internal/lyra-element.js';
|
|
10
10
|
import { defineElement } from '../../internal/prefix.js';
|
|
11
11
|
import { lockScroll } from '../../internal/scroll-lock.js';
|
|
12
|
+
import { activateOverlay } from '../../internal/overlay-manager.js';
|
|
12
13
|
import { nextId, srOnly } from '../../internal/a11y.js';
|
|
14
|
+
import { closeIcon } from '../../internal/icons.js';
|
|
13
15
|
import { styles } from './dialog.styles.js';
|
|
14
|
-
const FOCUSABLE_SELECTOR = 'a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';
|
|
15
16
|
const HEADING_SELECTOR = 'h1, h2, h3, h4, h5, h6, [role="heading"]';
|
|
16
|
-
// Shadow-piercing so a slotted custom element's real focusable target (e.g.
|
|
17
|
-
// an <input> inside its own shadow root) is found even though the host tag
|
|
18
|
-
// itself doesn't match FOCUSABLE_SELECTOR. Deliberately duplicated from
|
|
19
|
-
// lyra-widget's identical helper rather than imported/shared -- widget's
|
|
20
|
-
// fullscreen mode is a separate feature and this component must not depend
|
|
21
|
-
// on it (see the module doc in dialog.ts's authoring notes).
|
|
22
|
-
function collectFocusable(el) {
|
|
23
|
-
const result = [];
|
|
24
|
-
if (el.matches(FOCUSABLE_SELECTOR)) {
|
|
25
|
-
result.push(el);
|
|
26
|
-
}
|
|
27
|
-
if (el instanceof HTMLSlotElement) {
|
|
28
|
-
for (const assigned of el.assignedElements({ flatten: true })) {
|
|
29
|
-
result.push(...collectFocusable(assigned));
|
|
30
|
-
}
|
|
31
|
-
return result;
|
|
32
|
-
}
|
|
33
|
-
const container = el.shadowRoot ?? el;
|
|
34
|
-
for (const child of Array.from(container.children)) {
|
|
35
|
-
result.push(...collectFocusable(child));
|
|
36
|
-
}
|
|
37
|
-
return result;
|
|
38
|
-
}
|
|
39
|
-
/** Whether `el` is actually laid out/paintable -- `checkVisibility()` (falling
|
|
40
|
-
* back to `getClientRects().length` where unsupported) correctly follows
|
|
41
|
-
* flattened-tree/slot assignment, unlike `offsetParent`. Mirrors
|
|
42
|
-
* lyra-widget's identical helper. */
|
|
43
|
-
function isRendered(el) {
|
|
44
|
-
return el.checkVisibility ? el.checkVisibility() : el.getClientRects().length > 0;
|
|
45
|
-
}
|
|
46
17
|
/**
|
|
47
18
|
* `<lyra-dialog>` — a general-purpose modal/overlay. `role="dialog"`,
|
|
48
19
|
* focus-trapped while open, dismissible via Escape or a backdrop click, and
|
|
49
|
-
* scroll-locks the document for as long as it's open. Chrome stays minimal
|
|
50
|
-
* no built-in title bar or close button; a consumer supplies a
|
|
51
|
-
* any close affordance itself via the default/`footer` slots.
|
|
20
|
+
* scroll-locks the document for as long as it's open. Chrome stays minimal by
|
|
21
|
+
* default — no built-in title bar or close button; a consumer supplies a
|
|
22
|
+
* heading and any close affordance itself via the default/`footer` slots.
|
|
23
|
+
* `heading`/`closable` are an opt-in convenience for the common case where
|
|
24
|
+
* hand-building that chrome isn't worth it (see below).
|
|
52
25
|
*
|
|
53
|
-
* Accessible name
|
|
54
|
-
* a
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
* is
|
|
60
|
-
*
|
|
61
|
-
*
|
|
26
|
+
* Accessible name / visible header, in priority order:
|
|
27
|
+
* 1. If a heading element (`h1`–`h6` or `[role="heading"]`) is a *direct
|
|
28
|
+
* child* (not inside `slot="footer"`), its text content becomes
|
|
29
|
+
* `aria-label` on the panel — unchanged, and takes priority over `heading`
|
|
30
|
+
* below so an existing consumer that already slots its own heading keeps
|
|
31
|
+
* rendering it exactly as before.
|
|
32
|
+
* 2. Otherwise, when `heading` is set, a visible header row (`part="header"`)
|
|
33
|
+
* renders containing that text (`part="heading"`), which becomes the
|
|
34
|
+
* `aria-labelledby` target.
|
|
35
|
+
* 3. Otherwise, when `label` is set, an invisible (`.sr-only`, exposed as the
|
|
36
|
+
* `label` part) element carrying that text is rendered inside the panel
|
|
37
|
+
* and `aria-labelledby` points at it instead.
|
|
38
|
+
* Only one of cases 2/3 ever renders at a time, so exactly one element ever
|
|
39
|
+
* claims `aria-labelledby`. `label` itself never renders visible chrome on
|
|
40
|
+
* its own — `::part(label)` can be restyled to make the sr-only text visible,
|
|
41
|
+
* or `heading` can be set instead, if a consumer wants visible chrome without
|
|
42
|
+
* slotting a real heading element.
|
|
62
43
|
*
|
|
63
|
-
* The heading case deliberately uses `aria-label` (a copied string)
|
|
64
|
-
* than `aria-labelledby` pointing at the heading's `id`: the heading is
|
|
44
|
+
* The slotted-heading case deliberately uses `aria-label` (a copied string)
|
|
45
|
+
* rather than `aria-labelledby` pointing at the heading's `id`: the heading is
|
|
65
46
|
* *light-DOM* content while `[part="panel"]` lives in this element's
|
|
66
47
|
* *shadow* tree, and an ID-reference attribute can't resolve across that
|
|
67
48
|
* boundary (verified against axe's `aria-dialog-name` rule) — unlike the
|
|
68
|
-
* `label`-prop
|
|
69
|
-
* same shadow root it labels, so `aria-labelledby` there is safe.
|
|
49
|
+
* `heading`/`label`-prop cases above, where the target element is rendered
|
|
50
|
+
* inside the same shadow root it labels, so `aria-labelledby` there is safe.
|
|
51
|
+
*
|
|
52
|
+
* `closable` renders a close (X) button in the header row (creating one, with
|
|
53
|
+
* no heading text, if `heading` is unset) that closes the dialog via the same
|
|
54
|
+
* `close()` path as Escape/backdrop-dismiss, with reason `'close-button'`.
|
|
55
|
+
*
|
|
56
|
+
* Stacking: opening one `<lyra-dialog>` while another is already open (e.g. a
|
|
57
|
+
* `confirm()` launched from within an already-open dialog) is supported --
|
|
58
|
+
* Escape and the Tab focus trap only ever act on the topmost open dialog, so
|
|
59
|
+
* dialogs beneath it stay open and untouched until the one on top closes.
|
|
70
60
|
*
|
|
71
61
|
* @customElement lyra-dialog
|
|
72
62
|
* @slot - The dialog body.
|
|
73
63
|
* @slot footer - Action buttons, rendered in a bottom row.
|
|
74
64
|
* @event lyra-dialog-close - `detail: DialogCloseReason`. Fired whenever the
|
|
75
|
-
* dialog is dismissed via Escape, a backdrop click,
|
|
65
|
+
* dialog is dismissed via Escape, a backdrop click, the built-in close
|
|
66
|
+
* button (`closable`), a `close()` call, or (with reason `'unmount'`)
|
|
67
|
+
* removal from the DOM by anything else while still open.
|
|
76
68
|
* @csspart backdrop - The full-viewport scrim behind the panel.
|
|
77
|
-
* @csspart panel - The dialog panel itself (`role="dialog"` while open).
|
|
69
|
+
* @csspart panel - The dialog panel itself (`role="dialog"` while open). Its
|
|
70
|
+
* max-inline-size is controlled by the `--lyra-dialog-max-width` custom
|
|
71
|
+
* property (default `32rem`).
|
|
72
|
+
* @csspart header - The header row, rendered when `heading` is set (and no
|
|
73
|
+
* heading is slotted) and/or `closable` is `true`.
|
|
74
|
+
* @csspart heading - The visible `heading`-text element inside `header`,
|
|
75
|
+
* rendered only when `heading` is set and no heading is slotted.
|
|
76
|
+
* @csspart close-button - The built-in close button, rendered inside `header`
|
|
77
|
+
* only when `closable` is `true`.
|
|
78
78
|
* @csspart label - The invisible `label`-text element used for
|
|
79
|
-
* `aria-labelledby` when no heading is slotted.
|
|
79
|
+
* `aria-labelledby` when no heading is slotted and `heading` is unset.
|
|
80
80
|
* @csspart body - The wrapper around the default slot.
|
|
81
81
|
* @csspart footer - The wrapper around the `footer` slot.
|
|
82
82
|
*/
|
|
@@ -87,8 +87,14 @@ export class LyraDialog extends LyraElement {
|
|
|
87
87
|
this.open = false;
|
|
88
88
|
/** Accessible name used when no heading is slotted — see the class doc for the full fallback order. */
|
|
89
89
|
this.label = '';
|
|
90
|
+
/** Renders a built-in close (X) button in the header row (creating one,
|
|
91
|
+
* with no heading text, if `heading` is unset), wired to the same
|
|
92
|
+
* `close()` path Escape/backdrop-dismiss already use, with reason
|
|
93
|
+
* `'close-button'`. */
|
|
94
|
+
this.closable = false;
|
|
90
95
|
this.hasFooterSlot = false;
|
|
91
96
|
this.srLabelId = nextId('dialog-label');
|
|
97
|
+
this.headingId = nextId('dialog-heading');
|
|
92
98
|
this.onDefaultSlotChange = () => {
|
|
93
99
|
this.detectHeading();
|
|
94
100
|
};
|
|
@@ -96,34 +102,10 @@ export class LyraDialog extends LyraElement {
|
|
|
96
102
|
this.hasFooterSlot = e.target.assignedElements({ flatten: true }).length > 0;
|
|
97
103
|
};
|
|
98
104
|
this.onBackdropClick = () => {
|
|
99
|
-
this.
|
|
105
|
+
this.overlay?.dismissBackdrop();
|
|
100
106
|
};
|
|
101
|
-
this.
|
|
102
|
-
|
|
103
|
-
return;
|
|
104
|
-
if (e.key === 'Escape') {
|
|
105
|
-
e.preventDefault();
|
|
106
|
-
this.close('escape');
|
|
107
|
-
return;
|
|
108
|
-
}
|
|
109
|
-
if (e.key !== 'Tab')
|
|
110
|
-
return;
|
|
111
|
-
const focusable = this.getFocusableElements();
|
|
112
|
-
if (focusable.length === 0) {
|
|
113
|
-
e.preventDefault();
|
|
114
|
-
return;
|
|
115
|
-
}
|
|
116
|
-
const first = focusable[0];
|
|
117
|
-
const last = focusable[focusable.length - 1];
|
|
118
|
-
const active = this.getActiveElement();
|
|
119
|
-
if (e.shiftKey && active === first) {
|
|
120
|
-
e.preventDefault();
|
|
121
|
-
last.focus();
|
|
122
|
-
}
|
|
123
|
-
else if (!e.shiftKey && active === last) {
|
|
124
|
-
e.preventDefault();
|
|
125
|
-
first.focus();
|
|
126
|
-
}
|
|
107
|
+
this.onCloseButtonClick = () => {
|
|
108
|
+
this.close('close-button');
|
|
127
109
|
};
|
|
128
110
|
}
|
|
129
111
|
static { this.styles = [LyraElement.styles, srOnly, styles]; }
|
|
@@ -134,35 +116,18 @@ export class LyraDialog extends LyraElement {
|
|
|
134
116
|
}
|
|
135
117
|
if (changed.has('open')) {
|
|
136
118
|
if (this.open) {
|
|
137
|
-
|
|
138
|
-
// some specific internal control -- unlike lyra-widget's fullscreen
|
|
139
|
-
// toggle, a dialog's trigger typically lives *outside* the
|
|
140
|
-
// component entirely, so "whatever had focus right before open"
|
|
141
|
-
// is the only generally correct definition of "the trigger".
|
|
142
|
-
const active = this.getActiveElement();
|
|
143
|
-
this.lastTrigger = active instanceof HTMLElement ? active : undefined;
|
|
144
|
-
this.releaseScrollLock = lockScroll();
|
|
145
|
-
document.addEventListener('keydown', this.onDocKeyDown);
|
|
119
|
+
this.activateOverlay();
|
|
146
120
|
}
|
|
147
121
|
else {
|
|
148
|
-
this.
|
|
149
|
-
this.releaseScrollLock = undefined;
|
|
150
|
-
document.removeEventListener('keydown', this.onDocKeyDown);
|
|
122
|
+
this.deactivateOverlay();
|
|
151
123
|
}
|
|
152
124
|
}
|
|
153
125
|
}
|
|
154
|
-
// Runs after render
|
|
155
|
-
//
|
|
156
|
-
// mirrors lyra-widget's identical ordering rationale for its fullscreen mode.
|
|
126
|
+
// Runs after render so the manager can resolve the panel and its composed
|
|
127
|
+
// focus targets, including controls projected through either slot.
|
|
157
128
|
updated(changed) {
|
|
158
129
|
if (changed.has('open') && this.open) {
|
|
159
|
-
|
|
160
|
-
if (first) {
|
|
161
|
-
first.focus();
|
|
162
|
-
}
|
|
163
|
-
else {
|
|
164
|
-
this.shadowRoot?.querySelector('[part="panel"]')?.focus();
|
|
165
|
-
}
|
|
130
|
+
this.overlay?.focusInitial();
|
|
166
131
|
}
|
|
167
132
|
}
|
|
168
133
|
connectedCallback() {
|
|
@@ -171,16 +136,40 @@ export class LyraDialog extends LyraElement {
|
|
|
171
136
|
// instance) fires disconnectedCallback then connectedCallback
|
|
172
137
|
// synchronously with no update in between, so willUpdate never reruns to
|
|
173
138
|
// notice `open` is still true -- restore the scroll lock/trap it dropped.
|
|
174
|
-
if (this.hasUpdated && this.open
|
|
175
|
-
this.
|
|
176
|
-
|
|
139
|
+
if (this.hasUpdated && this.open) {
|
|
140
|
+
if (this.overlay?.isActive()) {
|
|
141
|
+
this.overlay.resume();
|
|
142
|
+
this.releaseScrollLock ??= lockScroll(this.ownerDocument);
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
this.activateOverlay();
|
|
146
|
+
}
|
|
147
|
+
queueMicrotask(() => this.overlay?.focusInitial());
|
|
177
148
|
}
|
|
178
149
|
}
|
|
179
150
|
disconnectedCallback() {
|
|
180
151
|
super.disconnectedCallback();
|
|
181
152
|
this.releaseScrollLock?.();
|
|
182
153
|
this.releaseScrollLock = undefined;
|
|
183
|
-
|
|
154
|
+
this.overlay?.suspend();
|
|
155
|
+
if (this.open) {
|
|
156
|
+
// A reparent (drag-and-drop moving this same element instance to a new
|
|
157
|
+
// parent) fires disconnectedCallback immediately followed by a
|
|
158
|
+
// synchronous connectedCallback, with no turn of the event loop in
|
|
159
|
+
// between -- deferring this check a microtask lets that case
|
|
160
|
+
// short-circuit here once isConnected is true again, so only a genuine
|
|
161
|
+
// removal (the element still disconnected once microtasks flush) ever
|
|
162
|
+
// reaches the assignment below. Without this, removing an open dialog
|
|
163
|
+
// any way other than its own close() (a consumer's own DOM cleanup, a
|
|
164
|
+
// parent re-render that drops it, etc.) never fires
|
|
165
|
+
// `lyra-dialog-close`, so e.g. confirm()'s returned promise hangs forever.
|
|
166
|
+
queueMicrotask(() => {
|
|
167
|
+
if (!this.isConnected && this.open) {
|
|
168
|
+
this.open = false;
|
|
169
|
+
this.emit('lyra-dialog-close', 'unmount');
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
}
|
|
184
173
|
}
|
|
185
174
|
// Only direct children are scanned -- a heading nested several layers deep
|
|
186
175
|
// (or inside a slotted custom element's own shadow root) is left to the
|
|
@@ -197,43 +186,43 @@ export class LyraDialog extends LyraElement {
|
|
|
197
186
|
/**
|
|
198
187
|
* Close the dialog and return focus to whatever had it before the dialog
|
|
199
188
|
* opened. `reason` is forwarded as the `lyra-dialog-close` detail --
|
|
200
|
-
* built-in triggers pass `'escape'`/`'backdrop'`; a
|
|
201
|
-
* affordance (e.g. a footer Cancel button) should
|
|
202
|
-
* its own reason string, so every dismissal path
|
|
203
|
-
* event instead of the consumer having to also
|
|
189
|
+
* built-in triggers pass `'escape'`/`'backdrop'`/`'close-button'`; a
|
|
190
|
+
* consumer's own close affordance (e.g. a footer Cancel button) should
|
|
191
|
+
* call this directly with its own reason string, so every dismissal path
|
|
192
|
+
* funnels through the same event instead of the consumer having to also
|
|
193
|
+
* toggle `open` itself.
|
|
204
194
|
*/
|
|
205
195
|
close(reason = 'api') {
|
|
206
196
|
if (!this.open)
|
|
207
197
|
return;
|
|
208
198
|
this.open = false;
|
|
209
199
|
this.emit('lyra-dialog-close', reason);
|
|
210
|
-
this.lastTrigger?.focus();
|
|
211
200
|
}
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
};
|
|
223
|
-
return [...fromSlot('slot:not([name])'), ...fromSlot('slot[name="footer"]')].filter(isRendered);
|
|
201
|
+
activateOverlay() {
|
|
202
|
+
if (this.overlay?.isActive())
|
|
203
|
+
return;
|
|
204
|
+
this.releaseScrollLock ??= lockScroll(this.ownerDocument);
|
|
205
|
+
this.overlay = activateOverlay({
|
|
206
|
+
host: this,
|
|
207
|
+
panel: () => this.shadowRoot?.querySelector('[part="panel"]') ?? null,
|
|
208
|
+
onEscape: () => this.close('escape'),
|
|
209
|
+
onBackdrop: () => this.close('backdrop'),
|
|
210
|
+
});
|
|
224
211
|
}
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
break;
|
|
231
|
-
active = inner;
|
|
232
|
-
}
|
|
233
|
-
return active;
|
|
212
|
+
deactivateOverlay() {
|
|
213
|
+
this.releaseScrollLock?.();
|
|
214
|
+
this.releaseScrollLock = undefined;
|
|
215
|
+
this.overlay?.deactivate();
|
|
216
|
+
this.overlay = undefined;
|
|
234
217
|
}
|
|
235
218
|
render() {
|
|
236
|
-
|
|
219
|
+
// Priority order (see class doc): a slotted heading always wins; only
|
|
220
|
+
// when there isn't one does `heading` get a turn, then `label`'s
|
|
221
|
+
// sr-only fallback -- never more than one of the two below claims
|
|
222
|
+
// aria-labelledby for the same panel.
|
|
223
|
+
const useHeadingProp = !this.headingText && !!this.heading;
|
|
224
|
+
const useSrLabel = !this.headingText && !useHeadingProp && this.label.length > 0;
|
|
225
|
+
const showHeader = useHeadingProp || this.closable;
|
|
237
226
|
return html `
|
|
238
227
|
<div part="backdrop" @click=${this.onBackdropClick}></div>
|
|
239
228
|
<div
|
|
@@ -241,12 +230,33 @@ export class LyraDialog extends LyraElement {
|
|
|
241
230
|
role=${this.open ? 'dialog' : nothing}
|
|
242
231
|
aria-modal=${this.open ? 'true' : nothing}
|
|
243
232
|
aria-label=${this.headingText ?? nothing}
|
|
244
|
-
aria-labelledby=${useSrLabel ? this.srLabelId : nothing}
|
|
233
|
+
aria-labelledby=${useHeadingProp ? this.headingId : useSrLabel ? this.srLabelId : nothing}
|
|
245
234
|
tabindex="-1"
|
|
246
235
|
>
|
|
247
236
|
${useSrLabel
|
|
248
237
|
? html `<span id=${this.srLabelId} part="label" class="sr-only">${this.label}</span>`
|
|
249
238
|
: nothing}
|
|
239
|
+
${showHeader
|
|
240
|
+
? html `
|
|
241
|
+
<div part="header">
|
|
242
|
+
${useHeadingProp
|
|
243
|
+
? html `<span id=${this.headingId} part="heading">${this.heading}</span>`
|
|
244
|
+
: nothing}
|
|
245
|
+
${this.closable
|
|
246
|
+
? html `
|
|
247
|
+
<button
|
|
248
|
+
part="close-button"
|
|
249
|
+
type="button"
|
|
250
|
+
aria-label="Close"
|
|
251
|
+
@click=${this.onCloseButtonClick}
|
|
252
|
+
>
|
|
253
|
+
${closeIcon()}
|
|
254
|
+
</button>
|
|
255
|
+
`
|
|
256
|
+
: nothing}
|
|
257
|
+
</div>
|
|
258
|
+
`
|
|
259
|
+
: nothing}
|
|
250
260
|
<div part="body">
|
|
251
261
|
<slot @slotchange=${this.onDefaultSlotChange}></slot>
|
|
252
262
|
</div>
|
|
@@ -263,6 +273,12 @@ __decorate([
|
|
|
263
273
|
__decorate([
|
|
264
274
|
property()
|
|
265
275
|
], LyraDialog.prototype, "label", void 0);
|
|
276
|
+
__decorate([
|
|
277
|
+
property()
|
|
278
|
+
], LyraDialog.prototype, "heading", void 0);
|
|
279
|
+
__decorate([
|
|
280
|
+
property({ type: Boolean, attribute: 'closable' })
|
|
281
|
+
], LyraDialog.prototype, "closable", void 0);
|
|
266
282
|
__decorate([
|
|
267
283
|
state()
|
|
268
284
|
], LyraDialog.prototype, "hasFooterSlot", void 0);
|
|
@@ -9,7 +9,7 @@ export const styles = css `
|
|
|
9
9
|
display: none;
|
|
10
10
|
position: fixed;
|
|
11
11
|
inset: 0;
|
|
12
|
-
z-index: 1000;
|
|
12
|
+
z-index: var(--lyra-overlay-stack-index, 1000);
|
|
13
13
|
align-items: center;
|
|
14
14
|
justify-content: center;
|
|
15
15
|
padding: var(--lyra-space-l);
|
|
@@ -26,7 +26,10 @@ export const styles = css `
|
|
|
26
26
|
position: relative;
|
|
27
27
|
display: flex;
|
|
28
28
|
flex-direction: column;
|
|
29
|
-
max-
|
|
29
|
+
/* --lyra-dialog-max-width lets a consumer widen/narrow the panel per
|
|
30
|
+
instance (e.g. inline on the host) without overriding the whole rule --
|
|
31
|
+
same convention as lyra-media-card's --lyra-media-card-max-height. */
|
|
32
|
+
max-inline-size: min(var(--lyra-dialog-max-width, 32rem), 100%);
|
|
30
33
|
max-block-size: 100%;
|
|
31
34
|
background: var(--lyra-color-surface);
|
|
32
35
|
border: 1px solid var(--lyra-color-border);
|
|
@@ -34,6 +37,47 @@ export const styles = css `
|
|
|
34
37
|
box-shadow: var(--lyra-shadow);
|
|
35
38
|
overflow: auto;
|
|
36
39
|
}
|
|
40
|
+
[part='header'] {
|
|
41
|
+
display: flex;
|
|
42
|
+
align-items: center;
|
|
43
|
+
gap: var(--lyra-space-s);
|
|
44
|
+
padding: var(--lyra-space-m) var(--lyra-space-l);
|
|
45
|
+
border-block-end: 1px solid var(--lyra-color-border);
|
|
46
|
+
}
|
|
47
|
+
[part='heading'] {
|
|
48
|
+
flex: 1 1 auto;
|
|
49
|
+
min-inline-size: 0;
|
|
50
|
+
margin: 0;
|
|
51
|
+
font-weight: 600;
|
|
52
|
+
overflow: hidden;
|
|
53
|
+
text-overflow: ellipsis;
|
|
54
|
+
white-space: nowrap;
|
|
55
|
+
}
|
|
56
|
+
[part='close-button'] {
|
|
57
|
+
flex: 0 0 auto;
|
|
58
|
+
margin-inline-start: auto;
|
|
59
|
+
display: inline-flex;
|
|
60
|
+
align-items: center;
|
|
61
|
+
justify-content: center;
|
|
62
|
+
min-inline-size: var(--lyra-icon-button-size);
|
|
63
|
+
min-block-size: var(--lyra-icon-button-size);
|
|
64
|
+
border: none;
|
|
65
|
+
background: transparent;
|
|
66
|
+
color: var(--lyra-color-text-quiet);
|
|
67
|
+
border-radius: var(--lyra-radius);
|
|
68
|
+
cursor: pointer;
|
|
69
|
+
}
|
|
70
|
+
[part='close-button']:hover {
|
|
71
|
+
background: var(--lyra-color-brand-quiet);
|
|
72
|
+
color: var(--lyra-color-brand);
|
|
73
|
+
}
|
|
74
|
+
[part='close-button']:focus-visible {
|
|
75
|
+
outline: var(--lyra-focus-ring-width) solid var(--lyra-focus-ring-color);
|
|
76
|
+
outline-offset: var(--lyra-focus-ring-offset);
|
|
77
|
+
}
|
|
78
|
+
[part='close-button'] svg {
|
|
79
|
+
display: block;
|
|
80
|
+
}
|
|
37
81
|
[part='body'] {
|
|
38
82
|
padding: var(--lyra-space-l);
|
|
39
83
|
overflow: auto;
|
|
@@ -87,8 +87,16 @@ export declare class LyraDockPanel extends LyraElement {
|
|
|
87
87
|
resizable: boolean;
|
|
88
88
|
private drag;
|
|
89
89
|
private readonly contentId;
|
|
90
|
+
private containerResizeObserver?;
|
|
90
91
|
connectedCallback(): void;
|
|
91
92
|
disconnectedCallback(): void;
|
|
93
|
+
/** Creates (idempotently) and (re-)observes the containing element with a
|
|
94
|
+
* `ResizeObserver` that just requests a re-render on every callback --
|
|
95
|
+
* `containerPx()`/`currentSizePx()` already read the live DOM on every
|
|
96
|
+
* render, so there's no separate cached value to update here, only the
|
|
97
|
+
* render that was otherwise never being triggered. A no-op when not yet
|
|
98
|
+
* connected (no `parentElement`). */
|
|
99
|
+
private armContainerResizeObserver;
|
|
92
100
|
protected willUpdate(changed: PropertyValues): void;
|
|
93
101
|
/** `'inline'` for the `start`/`end` edges (resizing changes `inline-size`), `'block'` for
|
|
94
102
|
* `top`/`bottom` (resizing changes `block-size`). */
|
|
@@ -177,6 +177,7 @@ export class LyraDockPanel extends LyraElement {
|
|
|
177
177
|
connectedCallback() {
|
|
178
178
|
super.connectedCallback();
|
|
179
179
|
this.applyHostSize();
|
|
180
|
+
this.armContainerResizeObserver();
|
|
180
181
|
}
|
|
181
182
|
disconnectedCallback() {
|
|
182
183
|
super.disconnectedCallback();
|
|
@@ -185,6 +186,19 @@ export class LyraDockPanel extends LyraElement {
|
|
|
185
186
|
window.removeEventListener('pointerup', this.onPointerUp);
|
|
186
187
|
window.removeEventListener('pointercancel', this.onPointerUp);
|
|
187
188
|
window.removeEventListener('lostpointercapture', this.onPointerUp);
|
|
189
|
+
this.containerResizeObserver?.disconnect();
|
|
190
|
+
}
|
|
191
|
+
/** Creates (idempotently) and (re-)observes the containing element with a
|
|
192
|
+
* `ResizeObserver` that just requests a re-render on every callback --
|
|
193
|
+
* `containerPx()`/`currentSizePx()` already read the live DOM on every
|
|
194
|
+
* render, so there's no separate cached value to update here, only the
|
|
195
|
+
* render that was otherwise never being triggered. A no-op when not yet
|
|
196
|
+
* connected (no `parentElement`). */
|
|
197
|
+
armContainerResizeObserver() {
|
|
198
|
+
if (!this.parentElement)
|
|
199
|
+
return;
|
|
200
|
+
this.containerResizeObserver ??= new ResizeObserver(() => this.requestUpdate());
|
|
201
|
+
this.containerResizeObserver.observe(this.parentElement);
|
|
188
202
|
}
|
|
189
203
|
// Applied in willUpdate (before render), not updated (after render): the
|
|
190
204
|
// handle's aria-valuenow is computed during render from the host's own
|
|
@@ -275,7 +289,7 @@ export class LyraDockPanel extends LyraElement {
|
|
|
275
289
|
if (this.edge === 'bottom')
|
|
276
290
|
return this.collapsed ? -90 : 90;
|
|
277
291
|
const pinnedPhysicalEnd = this.edge === 'end' ? !isRtl(this) : isRtl(this);
|
|
278
|
-
return this.collapsed
|
|
292
|
+
return this.collapsed !== pinnedPhysicalEnd ? 0 : 180;
|
|
279
293
|
}
|
|
280
294
|
handleTemplate() {
|
|
281
295
|
if (!this.resizable || this.collapsed)
|
|
@@ -19,11 +19,25 @@ export const styles = css `
|
|
|
19
19
|
:host([edge='start']),
|
|
20
20
|
:host([edge='end']) {
|
|
21
21
|
block-size: 100%;
|
|
22
|
-
min-inline-size: var(--lyra-dock-panel-collapsed-size);
|
|
23
22
|
}
|
|
24
23
|
:host([edge='top']),
|
|
25
24
|
:host([edge='bottom']) {
|
|
26
25
|
inline-size: 100%;
|
|
26
|
+
}
|
|
27
|
+
/* The collapsed-rail floor only applies once actually collapsed -- scoped
|
|
28
|
+
here rather than to the bare [edge] selectors above, so it can never
|
|
29
|
+
override a smaller explicit min-size (resolved in JS by
|
|
30
|
+
resolveBoundsPx()) while expanded. An unconditional floor here would
|
|
31
|
+
silently win over a min-size below the rail token's width, since a CSS
|
|
32
|
+
min-inline-size/min-block-size always wins over an inline size style
|
|
33
|
+
regardless of what value applySize() computed and announced via
|
|
34
|
+
aria-valuenow. */
|
|
35
|
+
:host([edge='start'][collapsed]),
|
|
36
|
+
:host([edge='end'][collapsed]) {
|
|
37
|
+
min-inline-size: var(--lyra-dock-panel-collapsed-size);
|
|
38
|
+
}
|
|
39
|
+
:host([edge='top'][collapsed]),
|
|
40
|
+
:host([edge='bottom'][collapsed]) {
|
|
27
41
|
min-block-size: var(--lyra-dock-panel-collapsed-size);
|
|
28
42
|
}
|
|
29
43
|
|
|
@@ -40,6 +40,13 @@ export type DocumentPreviewStatus = 'idle' | 'converting' | 'ready' | 'error';
|
|
|
40
40
|
* that a *rendering* failure and a host's own state machine are different
|
|
41
41
|
* concerns.
|
|
42
42
|
*
|
|
43
|
+
* Every `src` is validated for the DOM/API sink that consumes it. Text
|
|
44
|
+
* fetches and image sources allow relative URLs plus `http:`, `https:`,
|
|
45
|
+
* `blob:`, and `data:`. Download links deliberately exclude `data:` because
|
|
46
|
+
* following a `data:text/html` URL can create an active document. Unsafe or
|
|
47
|
+
* malformed URLs never reach `fetch()`, an image `src`, or an anchor `href`;
|
|
48
|
+
* they render a non-interactive fallback/error instead.
|
|
49
|
+
*
|
|
43
50
|
* Accessibility: the `"converting"` state (no numeric `progress`) is a
|
|
44
51
|
* `role="status"` region wrapping a visually-hidden "Converting document…"
|
|
45
52
|
* string. This is a *plain* static region, not routed through
|
|
@@ -61,10 +68,10 @@ export type DocumentPreviewStatus = 'idle' | 'converting' | 'ready' | 'error';
|
|
|
61
68
|
* component doesn't natively support (i.e. whenever format dispatch would
|
|
62
69
|
* otherwise fall through to "generic"). Ignored while `mime-type` resolves
|
|
63
70
|
* to `text`/`image` dispatch, or while `status` is `"converting"`/`"error"`.
|
|
64
|
-
* @event lyra-download - `detail: { src, filename }` — fired when the
|
|
65
|
-
* generic-download fallback
|
|
66
|
-
*
|
|
67
|
-
*
|
|
71
|
+
* @event lyra-download - `detail: { src, filename }` — fired when the safe
|
|
72
|
+
* generic-download fallback link is activated. The browser download itself
|
|
73
|
+
* needs no JS (a plain `<a download>` handles it); this is purely for a host
|
|
74
|
+
* that wants to observe/log the download.
|
|
68
75
|
* @event lyra-render-error - `detail: { error }` — fired when this
|
|
69
76
|
* component's own `text/*`/`application/json` `fetch(src)` fails. Distinct
|
|
70
77
|
* from `status="error"`, which is entirely host-driven (see the class
|
|
@@ -75,13 +82,14 @@ export type DocumentPreviewStatus = 'idle' | 'converting' | 'ready' | 'error';
|
|
|
75
82
|
* @csspart body - The wrapper around whichever content is currently showing (text/image preview, the generic fallback, the spinner, or the error message).
|
|
76
83
|
* @csspart spinner - The converting/loading indicator — indeterminate (`role="status"`) or, once numeric progress is known, a determinate `role="progressbar"`. Used both for `status="converting"` and for this component's own in-flight text fetch.
|
|
77
84
|
* @csspart error - The error message region (`role="alert"`) — used both for `status="error"` and for a failed text fetch.
|
|
78
|
-
* @csspart download-link - The `<a download>` affordance in the generic fallback. Only rendered when `src` is set.
|
|
85
|
+
* @csspart download-link - The `<a download>` affordance in the generic fallback. Only rendered when `src` is set and safe for link navigation.
|
|
79
86
|
*/
|
|
80
87
|
export declare class LyraDocumentPreview extends LyraElement {
|
|
81
88
|
static styles: import("lit").CSSResultGroup[];
|
|
82
89
|
/** URL to fetch (for `text`/`application/json`) or display (`image`, or as
|
|
83
|
-
* the generic fallback's download `href`).
|
|
84
|
-
*
|
|
90
|
+
* the generic fallback's download `href`). The value is validated against
|
|
91
|
+
* a sink-specific scheme allowlist before use. Optional — gracefully
|
|
92
|
+
* absent while, e.g., a conversion is still in progress. */
|
|
85
93
|
src: string;
|
|
86
94
|
/** Drives format dispatch — see the class doc. */
|
|
87
95
|
mimeType: string;
|