@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 PropertyValues, type TemplateResult } from 'lit';
|
|
2
2
|
import { LyraElement } from '../../internal/lyra-element.js';
|
|
3
3
|
import type { LyraModelCatalog } from '../model-select/model-select.js';
|
|
4
4
|
import '../model-select/model-select.js';
|
|
@@ -24,6 +24,12 @@ export interface ModelSettingsChangeDetail {
|
|
|
24
24
|
* components themselves for the exact semantics of `catalog`/`allowCustom`
|
|
25
25
|
* and `temperatureMin`/`temperatureMax`/`temperatureStep`.
|
|
26
26
|
*
|
|
27
|
+
* The panel's own `temperature` readout mirrors the slider's *live* value —
|
|
28
|
+
* updated on every `lyra-input` (drag/key-repeat), not just the committed
|
|
29
|
+
* `lyra-change` — and is re-clamped into `[temperatureMin, temperatureMax]`
|
|
30
|
+
* (snapped to `temperatureStep`) whenever those three properties change, so
|
|
31
|
+
* it can never drift from what the nested `lyra-slider` itself shows.
|
|
32
|
+
*
|
|
27
33
|
* @customElement lyra-model-settings-panel
|
|
28
34
|
* @event lyra-change - Either child control changed. `detail: { modelValue: string; inCatalog: boolean; temperature: number }` — always the full current settings, not just whatever changed.
|
|
29
35
|
* @csspart base - The outermost wrapping container.
|
|
@@ -51,15 +57,33 @@ export declare class LyraModelSettingsPanel extends LyraElement {
|
|
|
51
57
|
* the same two rows side by side with a smaller temperature caption, for
|
|
52
58
|
* toolbars/sidebars where the vertical layout's height doesn't fit. */
|
|
53
59
|
layout: ModelSettingsPanelLayout;
|
|
60
|
+
/** Disables the panel as a unit by forwarding to both the internal
|
|
61
|
+
* `lyra-model-select` and `lyra-slider` — a wrapping `<fieldset disabled>`
|
|
62
|
+
* alone would not reach either, since a form-associated control's own
|
|
63
|
+
* `disabled` IDL property/attribute is never mutated by fieldset cascading. */
|
|
64
|
+
disabled: boolean;
|
|
54
65
|
/** Whether `modelValue` is present in `catalog` — recomputed fresh from
|
|
55
66
|
* scratch (like `lyra-model-select`'s own `effectiveEntries`) rather than
|
|
56
67
|
* cached from the last child event, so it's still correct when
|
|
57
68
|
* `modelValue` was assigned directly instead of via the child's own
|
|
58
69
|
* `lyra-change`. */
|
|
59
70
|
private get inCatalog();
|
|
71
|
+
/** Clamps `raw` into `[temperatureMin, temperatureMax]`, snapped to
|
|
72
|
+
* `temperatureStep`'s grid anchored at the low end -- exactly mirroring
|
|
73
|
+
* `lyra-slider`'s own private `clampValue`/`domain` math -- so the
|
|
74
|
+
* mirrored `temperature` readout can never disagree with what the nested
|
|
75
|
+
* slider itself would clamp the same raw number to. */
|
|
76
|
+
private clampTemperature;
|
|
60
77
|
private emitChange;
|
|
61
78
|
private onModelChange;
|
|
62
79
|
private onTemperatureChange;
|
|
80
|
+
/** Mirrors the slider's *live* (uncommitted) value into the panel's own
|
|
81
|
+
* `temperature` readout -- display only, no `emitChange()` -- mirroring
|
|
82
|
+
* native `input` (continuous) vs. `change` (committed) semantics so the
|
|
83
|
+
* readout tracks an in-progress drag/key-repeat instead of only updating
|
|
84
|
+
* once the interaction commits. */
|
|
85
|
+
private onTemperatureInput;
|
|
86
|
+
protected willUpdate(changed: PropertyValues<this>): void;
|
|
63
87
|
render(): TemplateResult;
|
|
64
88
|
}
|
|
65
89
|
declare global {
|
|
@@ -8,6 +8,7 @@ import { html } from 'lit';
|
|
|
8
8
|
import { property } from 'lit/decorators.js';
|
|
9
9
|
import { LyraElement } from '../../internal/lyra-element.js';
|
|
10
10
|
import { defineElement } from '../../internal/prefix.js';
|
|
11
|
+
import { finiteNumber, finiteRange } from '../../internal/numbers.js';
|
|
11
12
|
import { styles } from './model-settings-panel.styles.js';
|
|
12
13
|
import '../model-select/model-select.js';
|
|
13
14
|
import '../slider/slider.js';
|
|
@@ -18,6 +19,15 @@ const DEFAULT_TEMPERATURE_STEP = 0.1;
|
|
|
18
19
|
// starting point. Reassign `temperature` yourself if your provider's own
|
|
19
20
|
// default differs (OpenAI and Anthropic both default to 1, which this matches).
|
|
20
21
|
const DEFAULT_TEMPERATURE = 1;
|
|
22
|
+
/** Number of decimal digits in `n`'s shortest string representation, e.g.
|
|
23
|
+
* `0.1` -> 1, `5` -> 0. Mirrors lyra-slider's identical helper so the
|
|
24
|
+
* panel's own re-clamping of `temperature` lands on the exact same
|
|
25
|
+
* step-grid values the nested slider itself would compute. */
|
|
26
|
+
function decimalPlaces(n) {
|
|
27
|
+
const str = n.toString();
|
|
28
|
+
const dot = str.indexOf('.');
|
|
29
|
+
return dot === -1 ? 0 : str.length - dot - 1;
|
|
30
|
+
}
|
|
21
31
|
/**
|
|
22
32
|
* `<lyra-model-settings-panel>` — a fixed composition of `<lyra-model-select>`
|
|
23
33
|
* and `<lyra-slider>` into one agent-configuration card: pick a provider's
|
|
@@ -31,6 +41,12 @@ const DEFAULT_TEMPERATURE = 1;
|
|
|
31
41
|
* components themselves for the exact semantics of `catalog`/`allowCustom`
|
|
32
42
|
* and `temperatureMin`/`temperatureMax`/`temperatureStep`.
|
|
33
43
|
*
|
|
44
|
+
* The panel's own `temperature` readout mirrors the slider's *live* value —
|
|
45
|
+
* updated on every `lyra-input` (drag/key-repeat), not just the committed
|
|
46
|
+
* `lyra-change` — and is re-clamped into `[temperatureMin, temperatureMax]`
|
|
47
|
+
* (snapped to `temperatureStep`) whenever those three properties change, so
|
|
48
|
+
* it can never drift from what the nested `lyra-slider` itself shows.
|
|
49
|
+
*
|
|
34
50
|
* @customElement lyra-model-settings-panel
|
|
35
51
|
* @event lyra-change - Either child control changed. `detail: { modelValue: string; inCatalog: boolean; temperature: number }` — always the full current settings, not just whatever changed.
|
|
36
52
|
* @csspart base - The outermost wrapping container.
|
|
@@ -57,6 +73,11 @@ export class LyraModelSettingsPanel extends LyraElement {
|
|
|
57
73
|
* the same two rows side by side with a smaller temperature caption, for
|
|
58
74
|
* toolbars/sidebars where the vertical layout's height doesn't fit. */
|
|
59
75
|
this.layout = 'vertical';
|
|
76
|
+
/** Disables the panel as a unit by forwarding to both the internal
|
|
77
|
+
* `lyra-model-select` and `lyra-slider` — a wrapping `<fieldset disabled>`
|
|
78
|
+
* alone would not reach either, since a form-associated control's own
|
|
79
|
+
* `disabled` IDL property/attribute is never mutated by fieldset cascading. */
|
|
80
|
+
this.disabled = false;
|
|
60
81
|
this.onModelChange = (e) => {
|
|
61
82
|
this.modelValue = e.detail.value;
|
|
62
83
|
this.emitChange();
|
|
@@ -65,6 +86,14 @@ export class LyraModelSettingsPanel extends LyraElement {
|
|
|
65
86
|
this.temperature = e.detail.value;
|
|
66
87
|
this.emitChange();
|
|
67
88
|
};
|
|
89
|
+
/** Mirrors the slider's *live* (uncommitted) value into the panel's own
|
|
90
|
+
* `temperature` readout -- display only, no `emitChange()` -- mirroring
|
|
91
|
+
* native `input` (continuous) vs. `change` (committed) semantics so the
|
|
92
|
+
* readout tracks an in-progress drag/key-repeat instead of only updating
|
|
93
|
+
* once the interaction commits. */
|
|
94
|
+
this.onTemperatureInput = (e) => {
|
|
95
|
+
this.temperature = e.detail.value;
|
|
96
|
+
};
|
|
68
97
|
}
|
|
69
98
|
static { this.styles = [LyraElement.styles, styles]; }
|
|
70
99
|
/** Whether `modelValue` is present in `catalog` — recomputed fresh from
|
|
@@ -78,6 +107,28 @@ export class LyraModelSettingsPanel extends LyraElement {
|
|
|
78
107
|
return false;
|
|
79
108
|
return catalog.some((entry) => (typeof entry === 'string' ? entry === this.modelValue : entry.id === this.modelValue));
|
|
80
109
|
}
|
|
110
|
+
/** Clamps `raw` into `[temperatureMin, temperatureMax]`, snapped to
|
|
111
|
+
* `temperatureStep`'s grid anchored at the low end -- exactly mirroring
|
|
112
|
+
* `lyra-slider`'s own private `clampValue`/`domain` math -- so the
|
|
113
|
+
* mirrored `temperature` readout can never disagree with what the nested
|
|
114
|
+
* slider itself would clamp the same raw number to. */
|
|
115
|
+
clampTemperature(raw) {
|
|
116
|
+
const rawMin = this.temperatureMin;
|
|
117
|
+
const rawMax = this.temperatureMax;
|
|
118
|
+
const min = finiteNumber(rawMin, DEFAULT_TEMPERATURE_MIN);
|
|
119
|
+
const max = finiteNumber(rawMax, DEFAULT_TEMPERATURE_MAX);
|
|
120
|
+
const lo = Math.min(min, max);
|
|
121
|
+
const hi = Math.max(min, max);
|
|
122
|
+
const step = finiteRange(this.temperatureStep, 0, 0);
|
|
123
|
+
const hasStep = step > 0;
|
|
124
|
+
let stepped = finiteNumber(raw, lo);
|
|
125
|
+
if (hasStep) {
|
|
126
|
+
const stepsFromLo = Math.round((raw - lo) / step);
|
|
127
|
+
const factor = 10 ** decimalPlaces(step);
|
|
128
|
+
stepped = Math.round((lo + stepsFromLo * step) * factor) / factor;
|
|
129
|
+
}
|
|
130
|
+
return Math.min(hi, Math.max(lo, stepped));
|
|
131
|
+
}
|
|
81
132
|
emitChange() {
|
|
82
133
|
this.emit('lyra-change', {
|
|
83
134
|
modelValue: this.modelValue,
|
|
@@ -85,6 +136,13 @@ export class LyraModelSettingsPanel extends LyraElement {
|
|
|
85
136
|
temperature: this.temperature,
|
|
86
137
|
});
|
|
87
138
|
}
|
|
139
|
+
willUpdate(changed) {
|
|
140
|
+
if (changed.has('temperatureMin') || changed.has('temperatureMax') || changed.has('temperatureStep')) {
|
|
141
|
+
const clamped = this.clampTemperature(this.temperature);
|
|
142
|
+
if (clamped !== this.temperature)
|
|
143
|
+
this.temperature = clamped;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
88
146
|
render() {
|
|
89
147
|
return html `
|
|
90
148
|
<div part="base">
|
|
@@ -94,6 +152,7 @@ export class LyraModelSettingsPanel extends LyraElement {
|
|
|
94
152
|
.catalog=${this.catalog}
|
|
95
153
|
.value=${this.modelValue}
|
|
96
154
|
.allowCustom=${this.allowCustom}
|
|
155
|
+
.disabled=${this.disabled}
|
|
97
156
|
placeholder="Select a model…"
|
|
98
157
|
@lyra-change=${this.onModelChange}
|
|
99
158
|
></lyra-model-select>
|
|
@@ -107,9 +166,11 @@ export class LyraModelSettingsPanel extends LyraElement {
|
|
|
107
166
|
.step=${this.temperatureStep}
|
|
108
167
|
.valueAsNumber=${this.temperature}
|
|
109
168
|
.showValue=${false}
|
|
169
|
+
.disabled=${this.disabled}
|
|
170
|
+
@lyra-input=${this.onTemperatureInput}
|
|
110
171
|
@lyra-change=${this.onTemperatureChange}
|
|
111
172
|
></lyra-slider>
|
|
112
|
-
<span part="temperature-value">${this.temperature}</span>
|
|
173
|
+
<span part="temperature-value" aria-hidden="true">${this.temperature}</span>
|
|
113
174
|
</div>
|
|
114
175
|
</div>
|
|
115
176
|
`;
|
|
@@ -142,4 +203,7 @@ __decorate([
|
|
|
142
203
|
__decorate([
|
|
143
204
|
property({ reflect: true })
|
|
144
205
|
], LyraModelSettingsPanel.prototype, "layout", void 0);
|
|
206
|
+
__decorate([
|
|
207
|
+
property({ type: Boolean, reflect: true })
|
|
208
|
+
], LyraModelSettingsPanel.prototype, "disabled", void 0);
|
|
145
209
|
defineElement('model-settings-panel', LyraModelSettingsPanel);
|
|
@@ -9,7 +9,9 @@ import { LyraElement } from '../../internal/lyra-element.js';
|
|
|
9
9
|
* @event lyra-play - Fired when playback starts.
|
|
10
10
|
* @event lyra-pause - Fired when playback stops (including auto-pause).
|
|
11
11
|
* @event lyra-step - `detail: { index }`, fired on every tick and manual step.
|
|
12
|
-
* @csspart base
|
|
12
|
+
* @csspart base - The playback controls wrapper.
|
|
13
|
+
* @csspart play-button - The play/pause button.
|
|
14
|
+
* @csspart slider - The playback position slider.
|
|
13
15
|
*/
|
|
14
16
|
export declare class LyraPlayback extends LyraElement {
|
|
15
17
|
static styles: import("lit").CSSResultGroup[];
|
|
@@ -39,7 +41,9 @@ export declare class LyraPlayback extends LyraElement {
|
|
|
39
41
|
private _playing;
|
|
40
42
|
get playing(): boolean;
|
|
41
43
|
set playing(next: boolean);
|
|
42
|
-
/** Largest index reachable at the current `length` (never negative
|
|
44
|
+
/** Largest index reachable at the current `length` (never negative, and
|
|
45
|
+
* never NaN — a non-finite `length` falls back to 0 rather than leaking a
|
|
46
|
+
* literal "NaN" into the rendered slider's `max` attribute). */
|
|
43
47
|
private get maxIndex();
|
|
44
48
|
disconnectedCallback(): void;
|
|
45
49
|
protected willUpdate(changed: PropertyValues): void;
|
|
@@ -9,14 +9,27 @@ import { property } from 'lit/decorators.js';
|
|
|
9
9
|
import { LyraElement } from '../../internal/lyra-element.js';
|
|
10
10
|
import { defineElement } from '../../internal/prefix.js';
|
|
11
11
|
import { playIcon, pauseIcon } from '../../internal/icons.js';
|
|
12
|
+
import { finiteCount, finiteDuration, MAX_TIMEOUT_MS } from '../../internal/numbers.js';
|
|
12
13
|
import { styles } from './playback.styles.js';
|
|
13
14
|
const MIN_INTERVAL_MS = 16; // ~one animation frame; prevents a near-zero-delay tick loop
|
|
14
|
-
|
|
15
|
+
// Deduplicated per distinct bad value (like the analogous one-time warnings
|
|
16
|
+
// in lyra-heatmap/lyra-word-cloud) rather than a single once-ever flag, so a
|
|
17
|
+
// later, genuinely different bad value is never silently swallowed by an
|
|
18
|
+
// earlier, unrelated one.
|
|
19
|
+
const warnedInvalidIntervals = new Set();
|
|
15
20
|
function warnInvalidInterval(value) {
|
|
16
|
-
if (
|
|
21
|
+
if (warnedInvalidIntervals.has(value))
|
|
17
22
|
return;
|
|
18
|
-
|
|
19
|
-
|
|
23
|
+
warnedInvalidIntervals.add(value);
|
|
24
|
+
// The clamp fires for any value outside the timer-safe range, so report the
|
|
25
|
+
// reason that actually applies instead of collapsing every bad value into
|
|
26
|
+
// one misleading "non-finite or non-positive" message.
|
|
27
|
+
const reason = !Number.isFinite(value)
|
|
28
|
+
? 'non-finite'
|
|
29
|
+
: value < MIN_INTERVAL_MS
|
|
30
|
+
? `below the ${MIN_INTERVAL_MS}ms floor`
|
|
31
|
+
: `above the ${MAX_TIMEOUT_MS}ms ceiling`;
|
|
32
|
+
console.warn(`<lyra-playback> interval-ms (${value}) is ${reason}; clamping to ${MIN_INTERVAL_MS}ms.`);
|
|
20
33
|
}
|
|
21
34
|
/**
|
|
22
35
|
* `<lyra-playback>` — steps an index through `[0, length)` on a fixed
|
|
@@ -27,7 +40,9 @@ function warnInvalidInterval(value) {
|
|
|
27
40
|
* @event lyra-play - Fired when playback starts.
|
|
28
41
|
* @event lyra-pause - Fired when playback stops (including auto-pause).
|
|
29
42
|
* @event lyra-step - `detail: { index }`, fired on every tick and manual step.
|
|
30
|
-
* @csspart base
|
|
43
|
+
* @csspart base - The playback controls wrapper.
|
|
44
|
+
* @csspart play-button - The play/pause button.
|
|
45
|
+
* @csspart slider - The playback position slider.
|
|
31
46
|
*/
|
|
32
47
|
export class LyraPlayback extends LyraElement {
|
|
33
48
|
constructor() {
|
|
@@ -64,7 +79,7 @@ export class LyraPlayback extends LyraElement {
|
|
|
64
79
|
return;
|
|
65
80
|
this._playing = next;
|
|
66
81
|
if (next) {
|
|
67
|
-
if (this.length <= 1) {
|
|
82
|
+
if (finiteCount(this.length) <= 1) {
|
|
68
83
|
this._playing = false;
|
|
69
84
|
return;
|
|
70
85
|
}
|
|
@@ -78,9 +93,11 @@ export class LyraPlayback extends LyraElement {
|
|
|
78
93
|
}
|
|
79
94
|
this.requestUpdate('playing', old);
|
|
80
95
|
}
|
|
81
|
-
/** Largest index reachable at the current `length` (never negative
|
|
96
|
+
/** Largest index reachable at the current `length` (never negative, and
|
|
97
|
+
* never NaN — a non-finite `length` falls back to 0 rather than leaking a
|
|
98
|
+
* literal "NaN" into the rendered slider's `max` attribute). */
|
|
82
99
|
get maxIndex() {
|
|
83
|
-
return Math.max(0, this.length - 1);
|
|
100
|
+
return Math.max(0, finiteCount(this.length) - 1);
|
|
84
101
|
}
|
|
85
102
|
disconnectedCallback() {
|
|
86
103
|
super.disconnectedCallback();
|
|
@@ -89,6 +106,19 @@ export class LyraPlayback extends LyraElement {
|
|
|
89
106
|
willUpdate(changed) {
|
|
90
107
|
if (changed.has('hidden') && this.hidden)
|
|
91
108
|
this.pause();
|
|
109
|
+
// A non-finite `length`/`index` (e.g. externally assigned NaN) must not
|
|
110
|
+
// linger: `maxIndex` already falls back to a safe value for rendering,
|
|
111
|
+
// but `next()`/`previous()` compare `index`/`length` directly and would
|
|
112
|
+
// otherwise stay permanently bricked (NaN comparisons are always
|
|
113
|
+
// false). Checked unconditionally — not just under the `length` branch
|
|
114
|
+
// below — so a corrupted `index` alone still self-heals on the very next
|
|
115
|
+
// update, without requiring `length` to also change.
|
|
116
|
+
const length = finiteCount(this.length);
|
|
117
|
+
const index = finiteCount(this.index);
|
|
118
|
+
if (length !== this.length)
|
|
119
|
+
this.length = length;
|
|
120
|
+
if (index !== this.index)
|
|
121
|
+
this.index = index;
|
|
92
122
|
if (changed.has('length')) {
|
|
93
123
|
// If length is externally reduced to <= 1 while playing, the timer
|
|
94
124
|
// would otherwise keep firing forever — and the play button (the only
|
|
@@ -104,7 +134,7 @@ export class LyraPlayback extends LyraElement {
|
|
|
104
134
|
}
|
|
105
135
|
/** Start playback; no-op if there's nothing to advance through. */
|
|
106
136
|
play() {
|
|
107
|
-
if (this.playing || this.length <= 1)
|
|
137
|
+
if (this.playing || finiteCount(this.length) <= 1)
|
|
108
138
|
return;
|
|
109
139
|
this.playing = true;
|
|
110
140
|
}
|
|
@@ -124,24 +154,32 @@ export class LyraPlayback extends LyraElement {
|
|
|
124
154
|
// `interval-ms` live takes effect on the very next step instead of only
|
|
125
155
|
// after a pause/play cycle.
|
|
126
156
|
scheduleTick() {
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
157
|
+
const rawDelay = this.intervalMs;
|
|
158
|
+
const delay = finiteDuration(rawDelay, MIN_INTERVAL_MS, MIN_INTERVAL_MS);
|
|
159
|
+
if (delay !== rawDelay)
|
|
160
|
+
warnInvalidInterval(rawDelay);
|
|
161
|
+
// Self-identifying: a synchronous pause()+play() (or a synchronous
|
|
162
|
+
// play() from a 'lyra-pause'/'lyra-step' listener) invoked while this
|
|
163
|
+
// callback is running schedules its own new timer and overwrites
|
|
164
|
+
// `this.timer` before this callback resumes. Only the timer that is
|
|
165
|
+
// still the current one is allowed to reschedule itself — every other,
|
|
166
|
+
// now-superseded chain quietly stops instead of spawning a second,
|
|
167
|
+
// untracked chain that pause()/disconnectedCallback() can never reach.
|
|
168
|
+
const id = window.setTimeout(() => {
|
|
133
169
|
this.tick();
|
|
134
|
-
if (this.playing)
|
|
170
|
+
if (this.playing && this.timer === id)
|
|
135
171
|
this.scheduleTick();
|
|
136
172
|
}, delay);
|
|
173
|
+
this.timer = id;
|
|
137
174
|
}
|
|
138
175
|
tick() {
|
|
139
|
-
const
|
|
140
|
-
|
|
176
|
+
const length = finiteCount(this.length);
|
|
177
|
+
const next = finiteCount(this.index) + 1;
|
|
178
|
+
if (next >= length) {
|
|
141
179
|
if (this.loop)
|
|
142
180
|
this.setIndex(0);
|
|
143
181
|
else {
|
|
144
|
-
this.setIndex(
|
|
182
|
+
this.setIndex(length - 1);
|
|
145
183
|
this.pause();
|
|
146
184
|
}
|
|
147
185
|
}
|
|
@@ -150,32 +188,37 @@ export class LyraPlayback extends LyraElement {
|
|
|
150
188
|
}
|
|
151
189
|
}
|
|
152
190
|
setIndex(i) {
|
|
153
|
-
this.index = i;
|
|
191
|
+
this.index = finiteCount(i, 0, this.maxIndex);
|
|
154
192
|
this.emit('lyra-step', { index: this.index });
|
|
155
193
|
}
|
|
156
194
|
/** Advance one step without starting playback. */
|
|
157
195
|
next() {
|
|
158
|
-
|
|
159
|
-
|
|
196
|
+
const index = finiteCount(this.index);
|
|
197
|
+
if (index + 1 < finiteCount(this.length))
|
|
198
|
+
this.setIndex(index + 1);
|
|
160
199
|
}
|
|
161
200
|
/** Go back one step without starting playback. */
|
|
162
201
|
previous() {
|
|
163
|
-
|
|
164
|
-
|
|
202
|
+
const index = finiteCount(this.index);
|
|
203
|
+
if (index > 0)
|
|
204
|
+
this.setIndex(index - 1);
|
|
165
205
|
}
|
|
166
206
|
/** Jump to an explicit index, pausing playback. */
|
|
167
207
|
goTo(index) {
|
|
168
208
|
this.pause();
|
|
169
|
-
this.setIndex(
|
|
209
|
+
this.setIndex(finiteCount(index, 0, this.maxIndex));
|
|
170
210
|
}
|
|
171
211
|
render() {
|
|
212
|
+
const maxIndex = this.maxIndex;
|
|
213
|
+
const index = finiteCount(this.index, 0, maxIndex);
|
|
214
|
+
const disabled = finiteCount(this.length) <= 1;
|
|
172
215
|
return html `
|
|
173
216
|
<div part="base">
|
|
174
217
|
<button
|
|
175
218
|
part="play-button"
|
|
176
219
|
type="button"
|
|
177
220
|
aria-label=${this.playing ? 'Pause' : 'Play'}
|
|
178
|
-
?disabled=${
|
|
221
|
+
?disabled=${disabled}
|
|
179
222
|
@click=${() => this.toggle()}
|
|
180
223
|
>
|
|
181
224
|
${this.playing ? pauseIcon() : playIcon()}
|
|
@@ -184,10 +227,10 @@ export class LyraPlayback extends LyraElement {
|
|
|
184
227
|
part="slider"
|
|
185
228
|
type="range"
|
|
186
229
|
min="0"
|
|
187
|
-
max=${
|
|
188
|
-
.value=${String(
|
|
230
|
+
max=${maxIndex}
|
|
231
|
+
.value=${String(index)}
|
|
189
232
|
aria-label="Playback position"
|
|
190
|
-
?disabled=${
|
|
233
|
+
?disabled=${disabled}
|
|
191
234
|
@input=${(e) => this.goTo(Number(e.target.value))}
|
|
192
235
|
/>
|
|
193
236
|
</div>
|
|
@@ -4,6 +4,11 @@ export const styles = css `
|
|
|
4
4
|
display: inline-flex;
|
|
5
5
|
align-items: center;
|
|
6
6
|
gap: var(--lyra-space-s);
|
|
7
|
+
/* Derived from --lyra-icon-button-size (0.35 * 2.5rem = 0.875rem, the
|
|
8
|
+
prior bare literal) so the rendered play/pause SVG icon (icons render
|
|
9
|
+
at width/height: 1em, so this font-size directly controls its pixel
|
|
10
|
+
size) tracks the button's own token instead of drifting from it. */
|
|
11
|
+
--lyra-playback-icon-size: calc(var(--lyra-icon-button-size) * 0.35);
|
|
7
12
|
}
|
|
8
13
|
[part='base'] {
|
|
9
14
|
display: flex;
|
|
@@ -21,7 +26,7 @@ export const styles = css `
|
|
|
21
26
|
display: inline-flex;
|
|
22
27
|
align-items: center;
|
|
23
28
|
justify-content: center;
|
|
24
|
-
font-size:
|
|
29
|
+
font-size: var(--lyra-playback-icon-size);
|
|
25
30
|
}
|
|
26
31
|
[part='play-button']:hover {
|
|
27
32
|
border-color: var(--lyra-color-brand);
|
|
@@ -43,18 +43,26 @@ export declare function resolveEffectiveMode(mode: ResponsivePanelMode, belowBre
|
|
|
43
43
|
* attributes and backdrop element, differ), so lit-html's diffing keeps
|
|
44
44
|
* `[part="body"]` and its `<slot>` as the same DOM node across the
|
|
45
45
|
* transition -- scroll position and focus inside the slotted content survive
|
|
46
|
-
* it for free
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
* doing so on a resize could yank focus away from an input the user is
|
|
50
|
-
* actively typing into inside the now-newly-modal panel, which is worse UX
|
|
51
|
-
* than a modal that's very briefly missing its initial focus placement.
|
|
46
|
+
* it for free. When an open inline panel becomes modal, focus already inside
|
|
47
|
+
* is preserved and outside focus moves to the first available target. Closing
|
|
48
|
+
* still returns to the opener captured by the original inline open.
|
|
52
49
|
*
|
|
53
|
-
* The overlay presentation
|
|
54
|
-
* focus
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
50
|
+
* The overlay presentation uses the library's shared overlay coordinator for
|
|
51
|
+
* focus trapping, Escape/backdrop dismissal, inerting, and stack ordering,
|
|
52
|
+
* while retaining this component's own responsive rendering and close event.
|
|
53
|
+
*
|
|
54
|
+
* Accessible name (overlay presentation only -- the inline presentation has
|
|
55
|
+
* no dialog semantics to name): `label`, when set, is used verbatim. When
|
|
56
|
+
* `label` is empty, this falls back to the `header` slot's content -- a
|
|
57
|
+
* heading element (`h1`–`h6` or `[role="heading"]`) among the slotted header
|
|
58
|
+
* content wins if present, otherwise the header slot's full text content is
|
|
59
|
+
* used, mirroring lyra-dialog's `detectHeading()`/`headingText` fallback (see
|
|
60
|
+
* dialog.ts's module doc for why this uses `aria-label`, a copied string,
|
|
61
|
+
* rather than `aria-labelledby`: the header content is light DOM while
|
|
62
|
+
* `[part="panel"]` lives in this element's shadow tree, and an ID-reference
|
|
63
|
+
* attribute can't resolve across that boundary). A panel opened without
|
|
64
|
+
* either `label` or header content still renders `role="dialog"` with no
|
|
65
|
+
* accessible name -- set one of the two to avoid that.
|
|
58
66
|
*
|
|
59
67
|
* @customElement lyra-responsive-panel
|
|
60
68
|
* @slot - The panel body.
|
|
@@ -95,7 +103,8 @@ export declare class LyraResponsivePanel extends LyraElement {
|
|
|
95
103
|
* height. */
|
|
96
104
|
variant: ResponsivePanelVariant;
|
|
97
105
|
/** Accessible name for the overlay presentation's `role="dialog"`. Unused in the inline
|
|
98
|
-
* presentation, which has no dialog semantics to name.
|
|
106
|
+
* presentation, which has no dialog semantics to name. When empty, falls back to the `header`
|
|
107
|
+
* slot's content -- see the class doc for the full fallback order. */
|
|
99
108
|
label: string;
|
|
100
109
|
/** CSS length passed to `matchMedia` as `(max-width: <this>)` to decide, in `mode="auto"`,
|
|
101
110
|
* whether the effective presentation is `'overlay'` (below/at this width) or `'inline'`
|
|
@@ -105,19 +114,25 @@ export declare class LyraResponsivePanel extends LyraElement {
|
|
|
105
114
|
private effectiveMode;
|
|
106
115
|
private hasHeaderSlot;
|
|
107
116
|
private hasFooterSlot;
|
|
117
|
+
/** Fallback accessible name sourced from the `header` slot's content -- see `detectHeadingText()`. */
|
|
118
|
+
private headingText?;
|
|
108
119
|
private mediaQuery?;
|
|
109
120
|
private releaseScrollLock?;
|
|
110
121
|
private lastTrigger?;
|
|
111
|
-
|
|
122
|
+
private overlayHandle?;
|
|
123
|
+
/** Whether the overlay-only mechanics (scroll-lock and shared overlay registration) are currently
|
|
112
124
|
* engaged -- derived from `effectiveMode === 'overlay' && open`, tracked separately from those
|
|
113
125
|
* two properties so willUpdate can diff "was engaged" vs "should be engaged now" regardless of
|
|
114
126
|
* which of the two changed. */
|
|
115
127
|
private overlayChromeActive;
|
|
128
|
+
private focusOverlayAfterUpdate;
|
|
116
129
|
private isFirstUpdate;
|
|
117
130
|
protected willUpdate(changed: PropertyValues): void;
|
|
118
131
|
protected updated(changed: PropertyValues): void;
|
|
119
132
|
connectedCallback(): void;
|
|
120
133
|
disconnectedCallback(): void;
|
|
134
|
+
private activateOverlayChrome;
|
|
135
|
+
private deactivateOverlayChrome;
|
|
121
136
|
private setupMediaQuery;
|
|
122
137
|
private onMediaChange;
|
|
123
138
|
/** The breakpoint-response logic itself, kept callable independently of the
|
|
@@ -126,6 +141,7 @@ export declare class LyraResponsivePanel extends LyraElement {
|
|
|
126
141
|
private handleBreakpointChange;
|
|
127
142
|
private onHeaderSlotChange;
|
|
128
143
|
private onFooterSlotChange;
|
|
144
|
+
private detectHeadingText;
|
|
129
145
|
/**
|
|
130
146
|
* Close the panel. `reason` is forwarded as the `lyra-close` detail --
|
|
131
147
|
* built-in overlay triggers pass `'escape'`/`'backdrop'`; a consumer's own
|
|
@@ -138,9 +154,6 @@ export declare class LyraResponsivePanel extends LyraElement {
|
|
|
138
154
|
*/
|
|
139
155
|
close(reason?: ResponsivePanelCloseReason): void;
|
|
140
156
|
private onBackdropClick;
|
|
141
|
-
private onDocKeyDown;
|
|
142
|
-
private getFocusableElements;
|
|
143
|
-
private getActiveElement;
|
|
144
157
|
render(): TemplateResult;
|
|
145
158
|
}
|
|
146
159
|
declare global {
|