@aceshooting/lyra-ui 1.2.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -0
- package/custom-elements.json +23341 -11202
- package/dist/components/app-rail/app-rail.d.ts +171 -0
- package/dist/components/app-rail/app-rail.js +483 -0
- package/dist/components/app-rail/app-rail.styles.d.ts +1 -0
- package/dist/components/app-rail/app-rail.styles.js +125 -0
- package/dist/components/attachment-chip/attachment-chip.d.ts +114 -0
- package/dist/components/attachment-chip/attachment-chip.js +312 -0
- package/dist/components/attachment-chip/attachment-chip.styles.d.ts +1 -0
- package/dist/components/attachment-chip/attachment-chip.styles.js +184 -0
- package/dist/components/attachment-trigger/attachment-trigger.d.ts +83 -0
- package/dist/components/attachment-trigger/attachment-trigger.js +258 -0
- package/dist/components/attachment-trigger/attachment-trigger.styles.d.ts +1 -0
- package/dist/components/attachment-trigger/attachment-trigger.styles.js +68 -0
- package/dist/components/chart/box-plot.js +11 -1
- package/dist/components/chart/chart-loader.d.ts +44 -13
- package/dist/components/chart/chart-loader.js +65 -18
- package/dist/components/chart/chart.d.ts +1 -2
- package/dist/components/chart/chart.js +67 -12
- package/dist/components/chart/histogram-bin.d.ts +4 -1
- package/dist/components/chart/histogram-bin.js +24 -14
- package/dist/components/chart/lite-chart.d.ts +54 -0
- package/dist/components/chart/lite-chart.js +140 -22
- package/dist/components/chart/lite-chart.styles.js +9 -0
- package/dist/components/chat-composer/chat-composer.d.ts +92 -0
- package/dist/components/chat-composer/chat-composer.js +285 -0
- package/dist/components/chat-composer/chat-composer.styles.d.ts +1 -0
- package/dist/components/chat-composer/chat-composer.styles.js +135 -0
- package/dist/components/chat-message/chat-message.d.ts +113 -0
- package/dist/components/chat-message/chat-message.js +291 -0
- package/dist/components/chat-message/chat-message.styles.d.ts +1 -0
- package/dist/components/chat-message/chat-message.styles.js +203 -0
- package/dist/components/checkbox/checkbox.d.ts +59 -0
- package/dist/components/checkbox/checkbox.js +230 -0
- package/dist/components/checkbox/checkbox.styles.d.ts +1 -0
- package/dist/components/checkbox/checkbox.styles.js +70 -0
- package/dist/components/chip/chip-group.d.ts +56 -0
- package/dist/components/chip/chip-group.js +124 -0
- package/dist/components/chip/chip-group.styles.d.ts +1 -0
- package/dist/components/chip/chip-group.styles.js +57 -0
- package/dist/components/chip/chip.d.ts +64 -0
- package/dist/components/chip/chip.js +115 -0
- package/dist/components/chip/chip.styles.d.ts +1 -0
- package/dist/components/chip/chip.styles.js +115 -0
- package/dist/components/citation-badge/citation-badge.d.ts +113 -0
- package/dist/components/citation-badge/citation-badge.js +300 -0
- package/dist/components/citation-badge/citation-badge.styles.d.ts +1 -0
- package/dist/components/citation-badge/citation-badge.styles.js +96 -0
- package/dist/components/code-block/code-block.d.ts +89 -0
- package/dist/components/code-block/code-block.js +317 -0
- package/dist/components/code-block/code-block.styles.d.ts +1 -0
- package/dist/components/code-block/code-block.styles.js +187 -0
- package/dist/components/code-block/code-loader.d.ts +44 -0
- package/dist/components/code-block/code-loader.js +79 -0
- package/dist/components/combobox/combobox.d.ts +19 -1
- package/dist/components/combobox/combobox.js +84 -14
- package/dist/components/combobox/option.d.ts +5 -1
- package/dist/components/combobox/option.js +35 -0
- package/dist/components/context-meter/context-meter.d.ts +53 -0
- package/dist/components/context-meter/context-meter.js +150 -0
- package/dist/components/context-meter/context-meter.styles.d.ts +1 -0
- package/dist/components/context-meter/context-meter.styles.js +120 -0
- package/dist/components/conversation-item/conversation-item.d.ts +128 -0
- package/dist/components/conversation-item/conversation-item.js +322 -0
- package/dist/components/conversation-item/conversation-item.styles.d.ts +1 -0
- package/dist/components/conversation-item/conversation-item.styles.js +155 -0
- package/dist/components/date-picker/date-input.d.ts +24 -0
- package/dist/components/date-picker/date-input.js +134 -22
- package/dist/components/date-picker/date-picker.d.ts +7 -0
- package/dist/components/date-picker/date-picker.js +85 -16
- package/dist/components/dialog/confirm.d.ts +40 -0
- package/dist/components/dialog/confirm.js +79 -0
- package/dist/components/dialog/dialog.d.ts +85 -0
- package/dist/components/dialog/dialog.js +272 -0
- package/dist/components/dialog/dialog.styles.d.ts +1 -0
- package/dist/components/dialog/dialog.styles.js +52 -0
- package/dist/components/dock-panel/dock-panel.d.ts +134 -0
- package/dist/components/dock-panel/dock-panel.js +345 -0
- package/dist/components/dock-panel/dock-panel.styles.d.ts +1 -0
- package/dist/components/dock-panel/dock-panel.styles.js +145 -0
- package/dist/components/document-preview/document-preview.d.ts +135 -0
- package/dist/components/document-preview/document-preview.js +372 -0
- package/dist/components/document-preview/document-preview.styles.d.ts +1 -0
- package/dist/components/document-preview/document-preview.styles.js +191 -0
- package/dist/components/export-button/csv.js +1 -1
- package/dist/components/export-button/export-button.js +2 -0
- package/dist/components/flag/flag.d.ts +29 -13
- package/dist/components/flag/flag.js +39 -13
- package/dist/components/gauge/gauge.js +19 -10
- package/dist/components/generation-status/generation-status.d.ts +109 -0
- package/dist/components/generation-status/generation-status.js +273 -0
- package/dist/components/generation-status/generation-status.styles.d.ts +1 -0
- package/dist/components/generation-status/generation-status.styles.js +84 -0
- package/dist/components/heatmap/calendar-grid.d.ts +4 -1
- package/dist/components/heatmap/calendar-grid.js +25 -12
- package/dist/components/heatmap/heatmap-scale.d.ts +6 -0
- package/dist/components/heatmap/heatmap-scale.js +7 -1
- package/dist/components/heatmap/heatmap.d.ts +74 -0
- package/dist/components/heatmap/heatmap.js +135 -23
- package/dist/components/json-viewer/json-viewer.d.ts +53 -0
- package/dist/components/json-viewer/json-viewer.js +283 -0
- package/dist/components/json-viewer/json-viewer.styles.d.ts +1 -0
- package/dist/components/json-viewer/json-viewer.styles.js +176 -0
- package/dist/components/kbd/kbd.d.ts +77 -0
- package/dist/components/kbd/kbd.js +214 -0
- package/dist/components/kbd/kbd.styles.d.ts +1 -0
- package/dist/components/kbd/kbd.styles.js +52 -0
- package/dist/components/live-region/live-region.d.ts +81 -0
- package/dist/components/live-region/live-region.js +153 -0
- package/dist/components/live-region/live-region.styles.d.ts +1 -0
- package/dist/components/live-region/live-region.styles.js +10 -0
- package/dist/components/map/map.d.ts +8 -6
- package/dist/components/map/map.js +44 -8
- package/dist/components/markdown/markdown-loader.d.ts +34 -0
- package/dist/components/markdown/markdown-loader.js +43 -0
- package/dist/components/markdown/markdown.d.ts +81 -0
- package/dist/components/markdown/markdown.js +284 -0
- package/dist/components/markdown/markdown.styles.d.ts +1 -0
- package/dist/components/markdown/markdown.styles.js +82 -0
- package/dist/components/media-card/media-card.d.ts +122 -0
- package/dist/components/media-card/media-card.js +295 -0
- package/dist/components/media-card/media-card.styles.d.ts +1 -0
- package/dist/components/media-card/media-card.styles.js +132 -0
- package/dist/components/mention-popover/mention-popover.d.ts +200 -0
- package/dist/components/mention-popover/mention-popover.js +475 -0
- package/dist/components/mention-popover/mention-popover.styles.d.ts +1 -0
- package/dist/components/mention-popover/mention-popover.styles.js +101 -0
- package/dist/components/menu/menu-item.d.ts +62 -0
- package/dist/components/menu/menu-item.js +119 -0
- package/dist/components/menu/menu-item.styles.d.ts +1 -0
- package/dist/components/menu/menu-item.styles.js +67 -0
- package/dist/components/menu/menu.d.ts +143 -0
- package/dist/components/menu/menu.js +365 -0
- package/dist/components/menu/menu.styles.d.ts +1 -0
- package/dist/components/menu/menu.styles.js +66 -0
- package/dist/components/model-select/model-select.d.ts +125 -0
- package/dist/components/model-select/model-select.js +490 -0
- package/dist/components/model-select/model-select.styles.d.ts +1 -0
- package/dist/components/model-select/model-select.styles.js +189 -0
- package/dist/components/model-settings-panel/model-settings-panel.d.ts +69 -0
- package/dist/components/model-settings-panel/model-settings-panel.js +145 -0
- package/dist/components/model-settings-panel/model-settings-panel.styles.d.ts +1 -0
- package/dist/components/model-settings-panel/model-settings-panel.styles.js +82 -0
- package/dist/components/playback/playback.d.ts +13 -1
- package/dist/components/playback/playback.js +47 -14
- package/dist/components/responsive-panel/responsive-panel.d.ts +150 -0
- package/dist/components/responsive-panel/responsive-panel.js +365 -0
- package/dist/components/responsive-panel/responsive-panel.styles.d.ts +1 -0
- package/dist/components/responsive-panel/responsive-panel.styles.js +103 -0
- package/dist/components/result-card/result-card.d.ts +44 -0
- package/dist/components/result-card/result-card.js +83 -0
- package/dist/components/result-card/result-card.styles.d.ts +1 -0
- package/dist/components/result-card/result-card.styles.js +50 -0
- package/dist/components/result-card/result-field.d.ts +36 -0
- package/dist/components/result-card/result-field.js +87 -0
- package/dist/components/result-card/result-field.styles.d.ts +1 -0
- package/dist/components/result-card/result-field.styles.js +32 -0
- package/dist/components/select/select.d.ts +43 -2
- package/dist/components/select/select.js +150 -17
- package/dist/components/slider/slider.d.ts +89 -0
- package/dist/components/slider/slider.js +352 -0
- package/dist/components/slider/slider.styles.d.ts +1 -0
- package/dist/components/slider/slider.styles.js +87 -0
- package/dist/components/source-card/source-card.d.ts +92 -0
- package/dist/components/source-card/source-card.js +148 -0
- package/dist/components/source-card/source-card.styles.d.ts +1 -0
- package/dist/components/source-card/source-card.styles.js +69 -0
- package/dist/components/source-list/source-list.d.ts +63 -0
- package/dist/components/source-list/source-list.js +122 -0
- package/dist/components/source-list/source-list.styles.d.ts +1 -0
- package/dist/components/source-list/source-list.styles.js +59 -0
- package/dist/components/sparkline/sparkline.js +27 -13
- package/dist/components/split/split.d.ts +93 -1
- package/dist/components/split/split.js +284 -15
- package/dist/components/split/split.styles.js +30 -0
- package/dist/components/stat/stat.d.ts +6 -1
- package/dist/components/stat/stat.js +8 -2
- package/dist/components/stream-status/stream-status.d.ts +110 -0
- package/dist/components/stream-status/stream-status.js +210 -0
- package/dist/components/stream-status/stream-status.styles.d.ts +1 -0
- package/dist/components/stream-status/stream-status.styles.js +103 -0
- package/dist/components/streaming-text/streaming-text.d.ts +98 -0
- package/dist/components/streaming-text/streaming-text.js +209 -0
- package/dist/components/streaming-text/streaming-text.styles.d.ts +1 -0
- package/dist/components/streaming-text/streaming-text.styles.js +62 -0
- package/dist/components/switch/switch.d.ts +58 -0
- package/dist/components/switch/switch.js +179 -0
- package/dist/components/switch/switch.styles.d.ts +1 -0
- package/dist/components/switch/switch.styles.js +75 -0
- package/dist/components/table/table.d.ts +73 -4
- package/dist/components/table/table.js +169 -20
- package/dist/components/table/table.styles.js +6 -1
- package/dist/components/tabs/tabs.d.ts +51 -0
- package/dist/components/tabs/tabs.js +190 -0
- package/dist/components/tabs/tabs.styles.d.ts +1 -0
- package/dist/components/tabs/tabs.styles.js +63 -0
- package/dist/components/thinking-panel/thinking-panel.d.ts +121 -0
- package/dist/components/thinking-panel/thinking-panel.js +235 -0
- package/dist/components/thinking-panel/thinking-panel.styles.d.ts +1 -0
- package/dist/components/thinking-panel/thinking-panel.styles.js +117 -0
- package/dist/components/toast/toast-item.d.ts +1 -0
- package/dist/components/toast/toast-item.js +31 -6
- package/dist/components/tool-approval-dialog/tool-approval-dialog.d.ts +130 -0
- package/dist/components/tool-approval-dialog/tool-approval-dialog.js +403 -0
- package/dist/components/tool-approval-dialog/tool-approval-dialog.styles.d.ts +1 -0
- package/dist/components/tool-approval-dialog/tool-approval-dialog.styles.js +160 -0
- package/dist/components/tool-call-chip/tool-call-chip.d.ts +89 -0
- package/dist/components/tool-call-chip/tool-call-chip.js +288 -0
- package/dist/components/tool-call-chip/tool-call-chip.styles.d.ts +1 -0
- package/dist/components/tool-call-chip/tool-call-chip.styles.js +203 -0
- package/dist/components/tool-param-form/tool-param-form.d.ts +145 -0
- package/dist/components/tool-param-form/tool-param-form.js +366 -0
- package/dist/components/tool-param-form/tool-param-form.styles.d.ts +1 -0
- package/dist/components/tool-param-form/tool-param-form.styles.js +75 -0
- package/dist/components/tool-result-dialog/tool-result-dialog.d.ts +102 -0
- package/dist/components/tool-result-dialog/tool-result-dialog.js +393 -0
- package/dist/components/tool-result-dialog/tool-result-dialog.styles.d.ts +1 -0
- package/dist/components/tool-result-dialog/tool-result-dialog.styles.js +176 -0
- package/dist/components/tool-result-view/registry.d.ts +81 -0
- package/dist/components/tool-result-view/registry.js +84 -0
- package/dist/components/tool-result-view/tool-result-view.d.ts +55 -0
- package/dist/components/tool-result-view/tool-result-view.js +138 -0
- package/dist/components/tool-result-view/tool-result-view.styles.d.ts +1 -0
- package/dist/components/tool-result-view/tool-result-view.styles.js +13 -0
- package/dist/components/tool-select-dialog/tool-select-dialog.d.ts +151 -0
- package/dist/components/tool-select-dialog/tool-select-dialog.js +439 -0
- package/dist/components/tool-select-dialog/tool-select-dialog.styles.d.ts +1 -0
- package/dist/components/tool-select-dialog/tool-select-dialog.styles.js +182 -0
- package/dist/components/tree/tree-node.d.ts +11 -2
- package/dist/components/tree/tree-node.js +16 -6
- package/dist/components/tree/tree.d.ts +8 -2
- package/dist/components/tree/tree.js +18 -11
- package/dist/components/typing-indicator/typing-indicator.d.ts +60 -0
- package/dist/components/typing-indicator/typing-indicator.js +96 -0
- package/dist/components/typing-indicator/typing-indicator.styles.d.ts +1 -0
- package/dist/components/typing-indicator/typing-indicator.styles.js +132 -0
- package/dist/components/virtual-list/virtual-list.d.ts +173 -0
- package/dist/components/virtual-list/virtual-list.js +461 -0
- package/dist/components/virtual-list/virtual-list.styles.d.ts +1 -0
- package/dist/components/virtual-list/virtual-list.styles.js +44 -0
- package/dist/components/word-cloud/word-cloud-layout.js +14 -1
- package/dist/components/word-cloud/word-cloud.d.ts +6 -0
- package/dist/components/word-cloud/word-cloud.js +25 -14
- package/dist/components/word-cloud/word-cloud.styles.js +3 -2
- package/dist/internal/announcer.d.ts +57 -0
- package/dist/internal/announcer.js +71 -0
- package/dist/internal/form-associated.d.ts +1 -0
- package/dist/internal/form-associated.js +55 -11
- package/dist/internal/group-by-recency.d.ts +50 -0
- package/dist/internal/group-by-recency.js +80 -0
- package/dist/internal/rtl.d.ts +23 -0
- package/dist/internal/rtl.js +28 -0
- package/dist/internal/scroll-lock.d.ts +10 -5
- package/dist/internal/scroll-lock.js +30 -14
- package/dist/internal/tokens.styles.js +6 -0
- package/dist/lyra.d.ts +130 -31
- package/dist/lyra.js +94 -26
- package/llms-full.txt +3836 -17
- package/llms.txt +16 -1
- package/package.json +23 -5
- package/dist/components/chart/bar-chart.stories.d.ts +0 -5
- package/dist/components/chart/bar-chart.stories.js +0 -20
- package/dist/components/chart/box-plot.stories.d.ts +0 -5
- package/dist/components/chart/box-plot.stories.js +0 -29
- package/dist/components/chart/bubble-chart.stories.d.ts +0 -5
- package/dist/components/chart/bubble-chart.stories.js +0 -26
- package/dist/components/chart/chart.stories.d.ts +0 -32
- package/dist/components/chart/chart.stories.js +0 -141
- package/dist/components/chart/doughnut-chart.stories.d.ts +0 -5
- package/dist/components/chart/doughnut-chart.stories.js +0 -26
- package/dist/components/chart/histogram.stories.d.ts +0 -5
- package/dist/components/chart/histogram.stories.js +0 -17
- package/dist/components/chart/line-chart.stories.d.ts +0 -22
- package/dist/components/chart/line-chart.stories.js +0 -99
- package/dist/components/chart/lite-chart.stories.d.ts +0 -14
- package/dist/components/chart/lite-chart.stories.js +0 -114
- package/dist/components/chart/pie-chart.stories.d.ts +0 -5
- package/dist/components/chart/pie-chart.stories.js +0 -26
- package/dist/components/chart/polar-area-chart.stories.d.ts +0 -5
- package/dist/components/chart/polar-area-chart.stories.js +0 -20
- package/dist/components/chart/radar-chart.stories.d.ts +0 -5
- package/dist/components/chart/radar-chart.stories.js +0 -20
- package/dist/components/chart/scatter-chart.stories.d.ts +0 -5
- package/dist/components/chart/scatter-chart.stories.js +0 -31
- package/dist/components/combobox/combobox.stories.d.ts +0 -24
- package/dist/components/combobox/combobox.stories.js +0 -102
- package/dist/components/date-picker/date-input.stories.d.ts +0 -10
- package/dist/components/date-picker/date-input.stories.js +0 -48
- package/dist/components/date-picker/date-picker.stories.d.ts +0 -10
- package/dist/components/date-picker/date-picker.stories.js +0 -25
- package/dist/components/empty/empty.stories.d.ts +0 -7
- package/dist/components/empty/empty.stories.js +0 -34
- package/dist/components/export-button/export-button.stories.d.ts +0 -7
- package/dist/components/export-button/export-button.stories.js +0 -37
- package/dist/components/file-input/file-input.stories.d.ts +0 -7
- package/dist/components/file-input/file-input.stories.js +0 -19
- package/dist/components/flag/flag.stories.d.ts +0 -6
- package/dist/components/flag/flag.stories.js +0 -31
- package/dist/components/gauge/gauge.stories.d.ts +0 -8
- package/dist/components/gauge/gauge.stories.js +0 -19
- package/dist/components/graph/graph.stories.d.ts +0 -8
- package/dist/components/graph/graph.stories.js +0 -68
- package/dist/components/heatmap/heatmap.stories.d.ts +0 -27
- package/dist/components/heatmap/heatmap.stories.js +0 -179
- package/dist/components/map/map.stories.d.ts +0 -15
- package/dist/components/map/map.stories.js +0 -135
- package/dist/components/playback/playback.stories.d.ts +0 -7
- package/dist/components/playback/playback.stories.js +0 -16
- package/dist/components/select/select.stories.d.ts +0 -21
- package/dist/components/select/select.stories.js +0 -91
- package/dist/components/skeleton/skeleton.stories.d.ts +0 -5
- package/dist/components/skeleton/skeleton.stories.js +0 -16
- package/dist/components/sparkline/sparkline.stories.d.ts +0 -11
- package/dist/components/sparkline/sparkline.stories.js +0 -39
- package/dist/components/split/split.stories.d.ts +0 -7
- package/dist/components/split/split.stories.js +0 -36
- package/dist/components/stat/stat.stories.d.ts +0 -9
- package/dist/components/stat/stat.stories.js +0 -81
- package/dist/components/table/table.stories.d.ts +0 -12
- package/dist/components/table/table.stories.js +0 -67
- package/dist/components/time-range/time-range.stories.d.ts +0 -8
- package/dist/components/time-range/time-range.stories.js +0 -26
- package/dist/components/toast/toast.stories.d.ts +0 -8
- package/dist/components/toast/toast.stories.js +0 -72
- package/dist/components/tree/tree.stories.d.ts +0 -9
- package/dist/components/tree/tree.stories.js +0 -52
- package/dist/components/widget/widget.stories.d.ts +0 -9
- package/dist/components/widget/widget.stories.js +0 -74
- package/dist/components/word-cloud/word-cloud.stories.d.ts +0 -10
- package/dist/components/word-cloud/word-cloud.stories.js +0 -55
|
@@ -0,0 +1,366 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { html, nothing } from 'lit';
|
|
8
|
+
import { property, state } from 'lit/decorators.js';
|
|
9
|
+
import { LyraElement } from '../../internal/lyra-element.js';
|
|
10
|
+
import { defineElement } from '../../internal/prefix.js';
|
|
11
|
+
import { nextId } from '../../internal/a11y.js';
|
|
12
|
+
import { styles } from './tool-param-form.styles.js';
|
|
13
|
+
import '../select/select.js';
|
|
14
|
+
import '../combobox/option.js';
|
|
15
|
+
import '../checkbox/checkbox.js';
|
|
16
|
+
const EMPTY_SCHEMA = { type: 'object', properties: {} };
|
|
17
|
+
/** `true` when `v` counts as "empty" for `prop`'s type, for the one validation rule this phase implements. */
|
|
18
|
+
function isFieldEmpty(prop, v) {
|
|
19
|
+
if (prop.type === 'boolean') {
|
|
20
|
+
// A checkbox always holds a concrete true/false once rendered — there's
|
|
21
|
+
// no third "unset" visual state to represent JSON Schema's "key absent"
|
|
22
|
+
// meaning. Reusing <lyra-checkbox>'s own required semantics (must be
|
|
23
|
+
// checked) gives `required` on a boolean field an actually useful
|
|
24
|
+
// meaning here — e.g. a `confirmDestroy: boolean, required` param — and
|
|
25
|
+
// matches the control it's composed from instead of inventing a second,
|
|
26
|
+
// inconsistent definition of "required checkbox".
|
|
27
|
+
return v !== true;
|
|
28
|
+
}
|
|
29
|
+
if (v === undefined || v === null)
|
|
30
|
+
return true;
|
|
31
|
+
if (prop.type === 'string')
|
|
32
|
+
return typeof v !== 'string' || v.trim() === '';
|
|
33
|
+
// number / integer
|
|
34
|
+
return typeof v !== 'number' || Number.isNaN(v);
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* `<lyra-tool-param-form>` — renders one form control per top-level property
|
|
38
|
+
* of a JSON Schema object, for ad hoc tool invocation or approval-editing UIs
|
|
39
|
+
* (e.g. "the agent wants to call `create_event(title, attendees, allDay)` —
|
|
40
|
+
* let the user tweak the arguments before running it").
|
|
41
|
+
*
|
|
42
|
+
* **Scope limitation (intentional, not accidental):** this phase only
|
|
43
|
+
* understands a *flat* object schema — every `properties` entry must be
|
|
44
|
+
* `'string'`, `'number'`, `'integer'`, `'boolean'`, or a string `enum`.
|
|
45
|
+
* Nested objects, arrays, `oneOf`/`anyOf`/`allOf`, `$ref`, and any other
|
|
46
|
+
* JSON Schema keyword are not read. A full JSON-Schema-to-form renderer is
|
|
47
|
+
* out of scope for this component; a property whose `type` isn't one of the
|
|
48
|
+
* four above renders a visible "Unsupported field type" note instead of
|
|
49
|
+
* silently dropping it or throwing.
|
|
50
|
+
*
|
|
51
|
+
* Fields render in `Object.keys(schema.properties)` order (insertion order,
|
|
52
|
+
* which is reliable for a plain object's string keys). A field's label is
|
|
53
|
+
* `title ?? ` the property key; `description` renders as helper text below
|
|
54
|
+
* the control; a key listed in `required` gets a visible `*` and the
|
|
55
|
+
* underlying control's own `required` wiring.
|
|
56
|
+
*
|
|
57
|
+
* This component owns no Submit/Cancel/Approve chrome — a consumer composes
|
|
58
|
+
* it inside their own dialog (e.g. a tool-approval dialog) and reads
|
|
59
|
+
* `.value`/`.errors`/`checkValidity()` (or calls `reportValidity()` right
|
|
60
|
+
* before acting, which also reveals any inline errors that user interaction
|
|
61
|
+
* hasn't surfaced yet).
|
|
62
|
+
*
|
|
63
|
+
* `value` is exactly what the consumer last set it to — a field with no
|
|
64
|
+
* entry in `value` but a schema `default` displays (and is *emitted*, via
|
|
65
|
+
* `lyra-input`) as that default, but the `value` *property* itself is left
|
|
66
|
+
* alone until the user actually edits that field. This mirrors an
|
|
67
|
+
* uncontrolled `<input placeholder>` not writing to `.value`, and means the
|
|
68
|
+
* very first `lyra-input` a consumer receives already carries every default
|
|
69
|
+
* resolved, so round-tripping `e.detail.value` back into `.value` converges
|
|
70
|
+
* after one edit.
|
|
71
|
+
*
|
|
72
|
+
* Optional native `<form>` participation is implemented via `ElementInternals`
|
|
73
|
+
* attached directly (this component's value is a whole object, not a plain
|
|
74
|
+
* string, so the `FormAssociated` string-value mixin doesn't fit — same
|
|
75
|
+
* shape as `<lyra-combobox>`'s array-valued case). This is a nice-to-have
|
|
76
|
+
* layered on top of the primary integration contract (`value` +
|
|
77
|
+
* `lyra-input`/`lyra-validity-change`), not a requirement: a consumer that
|
|
78
|
+
* never puts this inside a `<form>` loses nothing.
|
|
79
|
+
*
|
|
80
|
+
* @customElement lyra-tool-param-form
|
|
81
|
+
* @event lyra-input - A field's value changed. `detail: { value }` — the
|
|
82
|
+
* full current value object (every property, defaults resolved), not just
|
|
83
|
+
* the field that changed.
|
|
84
|
+
* @event lyra-validity-change - Overall validity changed (a required field
|
|
85
|
+
* became empty/non-empty). `detail: { valid: boolean; errors: Record<string, string> }`.
|
|
86
|
+
* @csspart base - The outer wrapper around all fields.
|
|
87
|
+
* @csspart field - One property's wrapper (label + control + description + error).
|
|
88
|
+
* @csspart label - A field's label.
|
|
89
|
+
* @csspart description - A field's helper text, from `schema.description`.
|
|
90
|
+
* @csspart error - A field's inline validation message (only rendered once the field has been visited).
|
|
91
|
+
*/
|
|
92
|
+
export class LyraToolParamForm extends LyraElement {
|
|
93
|
+
static { this.formAssociated = true; }
|
|
94
|
+
static { this.styles = [LyraElement.styles, styles]; }
|
|
95
|
+
constructor() {
|
|
96
|
+
super();
|
|
97
|
+
this.schema = EMPTY_SCHEMA;
|
|
98
|
+
this.value = {};
|
|
99
|
+
/** Submission key for the optional native `<form>` participation — see the class doc. */
|
|
100
|
+
this.name = '';
|
|
101
|
+
this.disabled = false;
|
|
102
|
+
// The true (touched-independent) per-field error set, recomputed in
|
|
103
|
+
// willUpdate() so it's available to the very same render() pass rather
|
|
104
|
+
// than lagging a frame behind in updated(). Exposed publicly (read-only)
|
|
105
|
+
// via the `errors` getter below, under a leading underscore here so the
|
|
106
|
+
// getter itself can be named plain `errors` without a collision.
|
|
107
|
+
this._errors = {};
|
|
108
|
+
// Which fields have been visited (focusout'd) at least once — gates only
|
|
109
|
+
// the *visual* error/aria-invalid presentation, matching every other
|
|
110
|
+
// form control in this library (lyra-select/lyra-combobox/lyra-model-select
|
|
111
|
+
// all avoid flashing red before the user has touched anything).
|
|
112
|
+
this.touchedFields = new Set();
|
|
113
|
+
this.baseId = nextId('tool-param-form');
|
|
114
|
+
this.internals = this.attachInternals();
|
|
115
|
+
}
|
|
116
|
+
connectedCallback() {
|
|
117
|
+
super.connectedCallback();
|
|
118
|
+
// Seed `errors`/`internals` validity synchronously at connect time —
|
|
119
|
+
// `checkValidity()`/a wrapping `<form>`'s own `reportValidity()` must
|
|
120
|
+
// see the correct answer even if called before Lit's first (async)
|
|
121
|
+
// update has run, mirroring lyra-select's/lyra-checkbox's identical
|
|
122
|
+
// connectedCallback -> updateValidity() call.
|
|
123
|
+
this._errors = this.computeErrors();
|
|
124
|
+
this.syncInternals();
|
|
125
|
+
}
|
|
126
|
+
/** `value`, with any property missing from it filled in from `schema`'s own `default` — see the class doc. */
|
|
127
|
+
get effectiveValue() {
|
|
128
|
+
const props = this.schema?.properties ?? {};
|
|
129
|
+
const out = { ...this.value };
|
|
130
|
+
for (const key of Object.keys(props)) {
|
|
131
|
+
// `hasOwnProperty`, not `out[key] === undefined` — a number field the
|
|
132
|
+
// user has explicitly cleared is `{ days: undefined }` (a real own
|
|
133
|
+
// property, via the `{...this.value, [key]: val}` spread in
|
|
134
|
+
// setFieldValue()), and must stay cleared rather than silently
|
|
135
|
+
// snapping back to its default just because its current value also
|
|
136
|
+
// happens to be `undefined`. Only a key genuinely absent from `value`
|
|
137
|
+
// (never touched, or reset back to `{}`) falls back to the default.
|
|
138
|
+
if (!Object.prototype.hasOwnProperty.call(this.value, key) && props[key].default !== undefined) {
|
|
139
|
+
out[key] = props[key].default;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return out;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* The current per-field validation errors (`{ [propertyKey]: message }`),
|
|
146
|
+
* required-and-empty only — mirrors the last `lyra-validity-change`
|
|
147
|
+
* event's `errors`. Independent of which fields have been visited; a
|
|
148
|
+
* consumer wanting the visited-only, screen-reader-announced subset
|
|
149
|
+
* should read the rendered `[part="error"]` elements instead.
|
|
150
|
+
*/
|
|
151
|
+
get errors() {
|
|
152
|
+
return { ...this._errors };
|
|
153
|
+
}
|
|
154
|
+
/** The current per-field validation errors (required-and-empty only), independent of `touchedFields`. */
|
|
155
|
+
computeErrors() {
|
|
156
|
+
const props = this.schema?.properties ?? {};
|
|
157
|
+
const required = new Set(this.schema?.required ?? []);
|
|
158
|
+
const effective = this.effectiveValue;
|
|
159
|
+
const out = {};
|
|
160
|
+
for (const key of Object.keys(props)) {
|
|
161
|
+
if (!required.has(key))
|
|
162
|
+
continue;
|
|
163
|
+
if (isFieldEmpty(props[key], effective[key])) {
|
|
164
|
+
out[key] = 'This field is required.';
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
return out;
|
|
168
|
+
}
|
|
169
|
+
/** Non-mutating validity check — unlike `reportValidity()`, never reveals inline errors. */
|
|
170
|
+
checkValidity() {
|
|
171
|
+
return this.internals.checkValidity();
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Reveals inline errors for every currently-invalid required field (as if
|
|
175
|
+
* each had been visited) and returns overall validity — the hook a
|
|
176
|
+
* consumer's own Submit/Approve button should call right before acting,
|
|
177
|
+
* mirroring a native `<form>`'s `reportValidity()`.
|
|
178
|
+
*/
|
|
179
|
+
reportValidity() {
|
|
180
|
+
const errors = this.computeErrors();
|
|
181
|
+
if (Object.keys(errors).length > 0) {
|
|
182
|
+
this.touchedFields = new Set([...this.touchedFields, ...Object.keys(errors)]);
|
|
183
|
+
}
|
|
184
|
+
return this.internals.checkValidity();
|
|
185
|
+
}
|
|
186
|
+
formResetCallback() {
|
|
187
|
+
this.value = {};
|
|
188
|
+
this.touchedFields = new Set();
|
|
189
|
+
}
|
|
190
|
+
formDisabledCallback(disabled) {
|
|
191
|
+
this.disabled = disabled;
|
|
192
|
+
}
|
|
193
|
+
willUpdate(changed) {
|
|
194
|
+
if (changed.has('value') || changed.has('schema') || !this.hasUpdated) {
|
|
195
|
+
this._errors = this.computeErrors();
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
/** Pushes `effectiveValue`/`errors` into `ElementInternals` — see the class doc's form-participation note. */
|
|
199
|
+
syncInternals() {
|
|
200
|
+
this.internals.setFormValue(JSON.stringify(this.effectiveValue));
|
|
201
|
+
if (Object.keys(this._errors).length === 0) {
|
|
202
|
+
this.internals.setValidity({});
|
|
203
|
+
}
|
|
204
|
+
else {
|
|
205
|
+
const firstMessage = Object.values(this._errors)[0] ?? 'Some required fields are empty.';
|
|
206
|
+
this.internals.setValidity({ valueMissing: true }, firstMessage);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
updated(changed) {
|
|
210
|
+
if (changed.has('value') || changed.has('schema')) {
|
|
211
|
+
this.syncInternals();
|
|
212
|
+
const valid = Object.keys(this._errors).length === 0;
|
|
213
|
+
const key = JSON.stringify({ valid, errors: this._errors });
|
|
214
|
+
if (key !== this.lastValidityKey) {
|
|
215
|
+
this.lastValidityKey = key;
|
|
216
|
+
this.emit('lyra-validity-change', { valid, errors: { ...this._errors } });
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
setFieldValue(key, val) {
|
|
221
|
+
this.value = { ...this.value, [key]: val };
|
|
222
|
+
this.emit('lyra-input', { value: this.effectiveValue });
|
|
223
|
+
}
|
|
224
|
+
markTouched(key) {
|
|
225
|
+
if (this.touchedFields.has(key))
|
|
226
|
+
return;
|
|
227
|
+
this.touchedFields = new Set(this.touchedFields).add(key);
|
|
228
|
+
}
|
|
229
|
+
onTextInput(key, e) {
|
|
230
|
+
this.setFieldValue(key, e.target.value);
|
|
231
|
+
}
|
|
232
|
+
onNumberInput(key, e) {
|
|
233
|
+
const raw = e.target;
|
|
234
|
+
const n = raw.valueAsNumber;
|
|
235
|
+
this.setFieldValue(key, Number.isNaN(n) ? undefined : n);
|
|
236
|
+
}
|
|
237
|
+
onSelectChange(key, e) {
|
|
238
|
+
this.setFieldValue(key, e.target.value);
|
|
239
|
+
}
|
|
240
|
+
onCheckboxChange(key, e) {
|
|
241
|
+
this.setFieldValue(key, e.detail.checked);
|
|
242
|
+
}
|
|
243
|
+
renderControl(key, prop, fieldId, label, required, describedBy, errorMessage, effective) {
|
|
244
|
+
if (prop.type === 'string' && prop.enum && prop.enum.length > 0) {
|
|
245
|
+
// <lyra-select>/<lyra-checkbox> don't forward a host-level
|
|
246
|
+
// aria-describedby to their internal focusable element (neither
|
|
247
|
+
// reads it — and this component doesn't own either file to add that),
|
|
248
|
+
// so a plain aria-describedby here would silently do nothing for
|
|
249
|
+
// assistive tech. Fold the error into aria-label instead, which both
|
|
250
|
+
// select.ts and checkbox.ts *do* read from the host and thread
|
|
251
|
+
// through -- the description text still reads fine from its adjacent,
|
|
252
|
+
// DOM-order-following <p part="description"> even without a formal
|
|
253
|
+
// aria-describedby association.
|
|
254
|
+
return html `<lyra-select
|
|
255
|
+
id=${fieldId}
|
|
256
|
+
aria-label=${errorMessage ? `${label}. ${errorMessage}` : label}
|
|
257
|
+
.value=${typeof effective === 'string' ? effective : ''}
|
|
258
|
+
?required=${required}
|
|
259
|
+
?disabled=${this.disabled}
|
|
260
|
+
@change=${(e) => this.onSelectChange(key, e)}
|
|
261
|
+
>
|
|
262
|
+
${prop.enum.map((v) => html `<lyra-option value=${v}>${v}</lyra-option>`)}
|
|
263
|
+
</lyra-select>`;
|
|
264
|
+
}
|
|
265
|
+
if (prop.type === 'string') {
|
|
266
|
+
return html `<input
|
|
267
|
+
class="control"
|
|
268
|
+
type="text"
|
|
269
|
+
id=${fieldId}
|
|
270
|
+
aria-describedby=${describedBy || nothing}
|
|
271
|
+
aria-invalid=${errorMessage ? 'true' : nothing}
|
|
272
|
+
.value=${typeof effective === 'string' ? effective : ''}
|
|
273
|
+
?required=${required}
|
|
274
|
+
?disabled=${this.disabled}
|
|
275
|
+
@input=${(e) => this.onTextInput(key, e)}
|
|
276
|
+
/>`;
|
|
277
|
+
}
|
|
278
|
+
if (prop.type === 'number' || prop.type === 'integer') {
|
|
279
|
+
const numValue = typeof effective === 'number' && !Number.isNaN(effective) ? String(effective) : '';
|
|
280
|
+
return html `<input
|
|
281
|
+
class="control"
|
|
282
|
+
type="number"
|
|
283
|
+
id=${fieldId}
|
|
284
|
+
step=${prop.type === 'integer' ? '1' : 'any'}
|
|
285
|
+
aria-describedby=${describedBy || nothing}
|
|
286
|
+
aria-invalid=${errorMessage ? 'true' : nothing}
|
|
287
|
+
.value=${numValue}
|
|
288
|
+
?required=${required}
|
|
289
|
+
?disabled=${this.disabled}
|
|
290
|
+
@input=${(e) => this.onNumberInput(key, e)}
|
|
291
|
+
/>`;
|
|
292
|
+
}
|
|
293
|
+
if (prop.type === 'boolean') {
|
|
294
|
+
// The label lives inside the slot rather than as a sibling <label> --
|
|
295
|
+
// that slot *is* lyra-checkbox's documented way to give it an
|
|
296
|
+
// accessible name (see checkbox.ts's own @slot doc), and unlike
|
|
297
|
+
// aria-describedby, this genuinely works since it's real slotted
|
|
298
|
+
// content, not an inert host attribute.
|
|
299
|
+
return html `<lyra-checkbox
|
|
300
|
+
id=${fieldId}
|
|
301
|
+
?checked=${effective === true}
|
|
302
|
+
?required=${required}
|
|
303
|
+
?disabled=${this.disabled}
|
|
304
|
+
@lyra-change=${(e) => this.onCheckboxChange(key, e)}
|
|
305
|
+
>
|
|
306
|
+
<span part="label">${label}</span>
|
|
307
|
+
</lyra-checkbox>`;
|
|
308
|
+
}
|
|
309
|
+
// Defensive fallback for a schema property outside this phase's scope
|
|
310
|
+
// (see the class doc) — render a visible note instead of silently
|
|
311
|
+
// dropping the field or throwing.
|
|
312
|
+
return html `<p class="unsupported">Unsupported field type "${prop.type}".</p>`;
|
|
313
|
+
}
|
|
314
|
+
renderField(key, prop, index) {
|
|
315
|
+
const required = (this.schema.required ?? []).includes(key);
|
|
316
|
+
const label = prop.title ?? key;
|
|
317
|
+
const fieldId = `${this.baseId}-f${index}`;
|
|
318
|
+
const descId = prop.description ? `${fieldId}-desc` : '';
|
|
319
|
+
const errId = this._errors[key] ? `${fieldId}-err` : '';
|
|
320
|
+
const describedBy = [descId, this.touchedFields.has(key) ? errId : ''].filter(Boolean).join(' ');
|
|
321
|
+
const hasError = this.touchedFields.has(key) && Boolean(this._errors[key]);
|
|
322
|
+
const errorMessage = hasError ? this._errors[key] : '';
|
|
323
|
+
const effective = this.effectiveValue[key];
|
|
324
|
+
const isBoolean = prop.type === 'boolean';
|
|
325
|
+
return html `
|
|
326
|
+
<div part="field" class="field" data-key=${key} data-type=${prop.type} ?data-required=${required}
|
|
327
|
+
@focusout=${() => this.markTouched(key)}
|
|
328
|
+
>
|
|
329
|
+
${isBoolean
|
|
330
|
+
? nothing
|
|
331
|
+
: html `<label part="label" for=${fieldId}>${label}</label>`}
|
|
332
|
+
${this.renderControl(key, prop, fieldId, label, required, describedBy, errorMessage, effective)}
|
|
333
|
+
${prop.description
|
|
334
|
+
? html `<p part="description" id=${descId}>${prop.description}</p>`
|
|
335
|
+
: nothing}
|
|
336
|
+
${hasError ? html `<p part="error" id=${errId} role="alert">${this._errors[key]}</p>` : nothing}
|
|
337
|
+
</div>
|
|
338
|
+
`;
|
|
339
|
+
}
|
|
340
|
+
render() {
|
|
341
|
+
const props = this.schema?.properties ?? {};
|
|
342
|
+
const keys = Object.keys(props);
|
|
343
|
+
return html `<div part="base">
|
|
344
|
+
${keys.map((key, i) => this.renderField(key, props[key], i))}
|
|
345
|
+
</div>`;
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
__decorate([
|
|
349
|
+
property({ attribute: false })
|
|
350
|
+
], LyraToolParamForm.prototype, "schema", void 0);
|
|
351
|
+
__decorate([
|
|
352
|
+
property({ attribute: false })
|
|
353
|
+
], LyraToolParamForm.prototype, "value", void 0);
|
|
354
|
+
__decorate([
|
|
355
|
+
property()
|
|
356
|
+
], LyraToolParamForm.prototype, "name", void 0);
|
|
357
|
+
__decorate([
|
|
358
|
+
property({ type: Boolean, reflect: true })
|
|
359
|
+
], LyraToolParamForm.prototype, "disabled", void 0);
|
|
360
|
+
__decorate([
|
|
361
|
+
state()
|
|
362
|
+
], LyraToolParamForm.prototype, "_errors", void 0);
|
|
363
|
+
__decorate([
|
|
364
|
+
state()
|
|
365
|
+
], LyraToolParamForm.prototype, "touchedFields", void 0);
|
|
366
|
+
defineElement('tool-param-form', LyraToolParamForm);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const styles: import("lit").CSSResult;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { css } from 'lit';
|
|
2
|
+
export const styles = css `
|
|
3
|
+
:host {
|
|
4
|
+
display: block;
|
|
5
|
+
}
|
|
6
|
+
[part='base'] {
|
|
7
|
+
display: flex;
|
|
8
|
+
flex-direction: column;
|
|
9
|
+
gap: var(--lyra-space-l);
|
|
10
|
+
}
|
|
11
|
+
[part='field'] {
|
|
12
|
+
display: flex;
|
|
13
|
+
flex-direction: column;
|
|
14
|
+
align-items: flex-start;
|
|
15
|
+
gap: var(--lyra-space-xs);
|
|
16
|
+
}
|
|
17
|
+
[part='label'] {
|
|
18
|
+
display: block;
|
|
19
|
+
font-size: 0.875rem;
|
|
20
|
+
font-weight: 600;
|
|
21
|
+
}
|
|
22
|
+
/* Applies to a boolean field's slotted <span part="label"> (inside
|
|
23
|
+
<lyra-checkbox>) too -- see tool-param-form.ts's class doc for why that
|
|
24
|
+
span still belongs to *this* component's shadow tree for CSS purposes
|
|
25
|
+
even though it's visually projected into a child element's template. */
|
|
26
|
+
[part='field'][data-required] [part='label']::after {
|
|
27
|
+
content: ' *';
|
|
28
|
+
color: var(--lyra-color-danger);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
[part='field'] > lyra-select,
|
|
32
|
+
[part='field'] > input.control {
|
|
33
|
+
inline-size: 100%;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
input.control {
|
|
37
|
+
box-sizing: border-box;
|
|
38
|
+
min-block-size: 2.5rem;
|
|
39
|
+
padding: var(--lyra-space-xs) var(--lyra-space-s);
|
|
40
|
+
border: 1px solid var(--lyra-color-border);
|
|
41
|
+
border-radius: var(--lyra-radius);
|
|
42
|
+
background: var(--lyra-color-surface);
|
|
43
|
+
color: inherit;
|
|
44
|
+
font: inherit;
|
|
45
|
+
font-size: 1rem;
|
|
46
|
+
}
|
|
47
|
+
input.control:focus-visible {
|
|
48
|
+
outline: var(--lyra-focus-ring-width) solid var(--lyra-focus-ring-color);
|
|
49
|
+
outline-offset: var(--lyra-focus-ring-offset);
|
|
50
|
+
}
|
|
51
|
+
input.control[aria-invalid='true'] {
|
|
52
|
+
border-color: var(--lyra-color-danger);
|
|
53
|
+
}
|
|
54
|
+
input.control:disabled {
|
|
55
|
+
opacity: var(--lyra-opacity-disabled);
|
|
56
|
+
cursor: not-allowed;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
[part='description'] {
|
|
60
|
+
margin: 0;
|
|
61
|
+
font-size: 0.8125rem;
|
|
62
|
+
color: var(--lyra-color-text-quiet);
|
|
63
|
+
}
|
|
64
|
+
[part='error'] {
|
|
65
|
+
margin: 0;
|
|
66
|
+
font-size: 0.8125rem;
|
|
67
|
+
color: var(--lyra-color-danger);
|
|
68
|
+
}
|
|
69
|
+
.unsupported {
|
|
70
|
+
margin: 0;
|
|
71
|
+
font-size: 0.8125rem;
|
|
72
|
+
font-style: italic;
|
|
73
|
+
color: var(--lyra-color-text-quiet);
|
|
74
|
+
}
|
|
75
|
+
`;
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { type TemplateResult, type PropertyValues } from 'lit';
|
|
2
|
+
import { LyraElement } from '../../internal/lyra-element.js';
|
|
3
|
+
/** Same status vocabulary as `<lyra-tool-call-chip>`. */
|
|
4
|
+
export type ToolResultStatus = 'pending' | 'running' | 'success' | 'error' | 'denied';
|
|
5
|
+
/**
|
|
6
|
+
* Reason the dialog was dismissed, forwarded as the `lyra-dialog-close` event
|
|
7
|
+
* detail -- mirrors `<lyra-dialog>`'s own `DialogCloseReason` shape.
|
|
8
|
+
* `'escape'`/`'backdrop'` come from the dialog's own built-in dismiss
|
|
9
|
+
* triggers, `'close-button'` from the built-in header close button, and any
|
|
10
|
+
* other string is whatever a caller passes to `close()` directly (e.g. a
|
|
11
|
+
* consumer's own footer action).
|
|
12
|
+
*/
|
|
13
|
+
export type ToolResultDialogCloseReason = 'escape' | 'backdrop' | 'close-button' | 'api' | string;
|
|
14
|
+
/**
|
|
15
|
+
* `<lyra-tool-result-dialog>` — a full tool-call detail overlay: a status/
|
|
16
|
+
* duration header plus a `body` slot where a consumer typically places a
|
|
17
|
+
* `<lyra-tabs>` with Input/Preview/JSON/Raw panels. This component knows
|
|
18
|
+
* nothing about what's inside that slot — it only supplies the modal chrome
|
|
19
|
+
* around it.
|
|
20
|
+
*
|
|
21
|
+
* This is its own standalone overlay implementation (`role="dialog"`,
|
|
22
|
+
* focus-trapped, Escape/backdrop-dismissible, scroll-locking) rather than
|
|
23
|
+
* nesting a `<lyra-dialog>` in its shadow template — see `<lyra-dialog>`'s
|
|
24
|
+
* own header comment for why a new overlay component in this library
|
|
25
|
+
* duplicates that pattern locally instead of composing the previous one:
|
|
26
|
+
* slot-forwarding into a nested `<lyra-dialog>` would put a forwarding
|
|
27
|
+
* `<slot>` where a light-DOM-scanning descendant (e.g. a slotted
|
|
28
|
+
* `<lyra-tabs>`'s own `Array.from(this.children)` scan) expects real
|
|
29
|
+
* projected content.
|
|
30
|
+
*
|
|
31
|
+
* `maximized` toggles between a constrained modal size and a near-fullscreen
|
|
32
|
+
* size within the same open dialog and open/close lifecycle — unlike
|
|
33
|
+
* `<lyra-widget>`'s fullscreen mode, there's no non-modal resting state to
|
|
34
|
+
* return to, so no separate scroll-lock/focus-trap bookkeeping is needed for
|
|
35
|
+
* the transition itself.
|
|
36
|
+
*
|
|
37
|
+
* @customElement lyra-tool-result-dialog
|
|
38
|
+
* @slot body - The dialog's main content — typically a `<lyra-tabs>` with
|
|
39
|
+
* Input/Preview/JSON/Raw panels, entirely consumer-assembled.
|
|
40
|
+
* @slot footer - Optional action buttons, rendered in a bottom row.
|
|
41
|
+
* @event lyra-dialog-close - `detail: ToolResultDialogCloseReason`. Fired
|
|
42
|
+
* exactly once per dismissal, via Escape, a backdrop click, the built-in
|
|
43
|
+
* close button, or a `close()` call.
|
|
44
|
+
* @event lyra-maximize-change - `detail: boolean` (the new `maximized`
|
|
45
|
+
* state), fired when the header's maximize/restore toggle is clicked.
|
|
46
|
+
* @csspart backdrop - The full-viewport scrim behind the panel.
|
|
47
|
+
* @csspart panel - The dialog panel itself (`role="dialog"` while open).
|
|
48
|
+
* @csspart header - The row containing the tool name, status, duration, and toggle/close buttons.
|
|
49
|
+
* @csspart title - The wrapper around the tool name, status, and duration.
|
|
50
|
+
* @csspart tool-name - The `tool-name` text.
|
|
51
|
+
* @csspart status - The status badge (icon + text).
|
|
52
|
+
* @csspart duration - The formatted `duration-ms` text.
|
|
53
|
+
* @csspart header-actions - The wrapper around the maximize and close buttons.
|
|
54
|
+
* @csspart maximize-button - The built-in maximize/restore toggle button.
|
|
55
|
+
* @csspart close-button - The built-in close button.
|
|
56
|
+
* @csspart body - The wrapper around the `body` slot.
|
|
57
|
+
* @csspart footer - The wrapper around the `footer` slot.
|
|
58
|
+
*/
|
|
59
|
+
export declare class LyraToolResultDialog extends LyraElement {
|
|
60
|
+
static styles: import("lit").CSSResultGroup[];
|
|
61
|
+
/** Whether the dialog is open. Set this (or call `close()`) — there is no separate `show()`/`hide()` pair. */
|
|
62
|
+
open: boolean;
|
|
63
|
+
/** The tool's name, rendered prominently in the header. */
|
|
64
|
+
toolName: string;
|
|
65
|
+
/** The tool call's current lifecycle state — drives the header's status badge. */
|
|
66
|
+
status: ToolResultStatus;
|
|
67
|
+
/** How long the call took, in milliseconds. Omitted from the header entirely when unset. */
|
|
68
|
+
durationMs?: number;
|
|
69
|
+
/** Near-fullscreen presentation of the same open dialog. */
|
|
70
|
+
maximized: boolean;
|
|
71
|
+
private hasFooterSlot;
|
|
72
|
+
private releaseScrollLock?;
|
|
73
|
+
private lastTrigger?;
|
|
74
|
+
private readonly titleId;
|
|
75
|
+
protected willUpdate(changed: PropertyValues): void;
|
|
76
|
+
protected updated(changed: PropertyValues): void;
|
|
77
|
+
connectedCallback(): void;
|
|
78
|
+
disconnectedCallback(): void;
|
|
79
|
+
private onFooterSlotChange;
|
|
80
|
+
/**
|
|
81
|
+
* Close the dialog and return focus to whatever had it before the dialog
|
|
82
|
+
* opened. `reason` is forwarded as the `lyra-dialog-close` detail --
|
|
83
|
+
* built-in triggers pass `'escape'`/`'backdrop'`/`'close-button'`; a
|
|
84
|
+
* consumer's own close affordance (e.g. a footer action button) should
|
|
85
|
+
* call this directly with its own reason string, so every dismissal path
|
|
86
|
+
* funnels through the same event instead of the consumer having to also
|
|
87
|
+
* toggle `open` itself.
|
|
88
|
+
*/
|
|
89
|
+
close(reason?: ToolResultDialogCloseReason): void;
|
|
90
|
+
private onBackdropClick;
|
|
91
|
+
private onCloseButtonClick;
|
|
92
|
+
private toggleMaximized;
|
|
93
|
+
private onDocKeyDown;
|
|
94
|
+
private getFocusableElements;
|
|
95
|
+
private getActiveElement;
|
|
96
|
+
render(): TemplateResult;
|
|
97
|
+
}
|
|
98
|
+
declare global {
|
|
99
|
+
interface HTMLElementTagNameMap {
|
|
100
|
+
'lyra-tool-result-dialog': LyraToolResultDialog;
|
|
101
|
+
}
|
|
102
|
+
}
|