@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 @@
|
|
|
1
|
+
export declare const styles: import("lit").CSSResult;
|
|
@@ -0,0 +1,135 @@
|
|
|
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-xs);
|
|
10
|
+
box-sizing: border-box;
|
|
11
|
+
border: 1px solid var(--lyra-color-border);
|
|
12
|
+
border-radius: var(--lyra-radius);
|
|
13
|
+
background: var(--lyra-color-surface);
|
|
14
|
+
padding: var(--lyra-space-s);
|
|
15
|
+
transition: border-color var(--lyra-transition-fast);
|
|
16
|
+
}
|
|
17
|
+
[part='base']:focus-within {
|
|
18
|
+
border-color: var(--lyra-color-brand);
|
|
19
|
+
}
|
|
20
|
+
:host([disabled]) [part='base'] {
|
|
21
|
+
opacity: var(--lyra-opacity-disabled);
|
|
22
|
+
cursor: not-allowed;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/* :empty never matches [part='chips'] -- it always contains a literal
|
|
26
|
+
<slot> child regardless of assigned content -- so real emptiness is
|
|
27
|
+
tracked in JS (hasChipsSlot) and reflected via [hidden] instead (same
|
|
28
|
+
fix as lyra-date-input's hint/error parts). Author-level display rules
|
|
29
|
+
always beat the UA stylesheet's [hidden] rule regardless of source
|
|
30
|
+
order/specificity (different cascade origins), so the override below is
|
|
31
|
+
required, not redundant. */
|
|
32
|
+
[part='chips'] {
|
|
33
|
+
display: flex;
|
|
34
|
+
flex-wrap: wrap;
|
|
35
|
+
gap: var(--lyra-space-xs);
|
|
36
|
+
}
|
|
37
|
+
[part='chips'][hidden] {
|
|
38
|
+
display: none;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
[part='row'] {
|
|
42
|
+
display: flex;
|
|
43
|
+
align-items: flex-end;
|
|
44
|
+
gap: var(--lyra-space-s);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
[part='leading'] {
|
|
48
|
+
display: flex;
|
|
49
|
+
flex: 0 0 auto;
|
|
50
|
+
align-items: center;
|
|
51
|
+
/* Matches the textarea's own first-line box so a leading icon button
|
|
52
|
+
sits level with placeholder/typed text at min-rows, not glued to the
|
|
53
|
+
row's cross-axis edge. */
|
|
54
|
+
padding-block-end: var(--lyra-space-xs);
|
|
55
|
+
}
|
|
56
|
+
[part='leading'][hidden] {
|
|
57
|
+
display: none;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
[part='textarea'] {
|
|
61
|
+
flex: 1 1 auto;
|
|
62
|
+
min-inline-size: 0;
|
|
63
|
+
box-sizing: border-box;
|
|
64
|
+
resize: none;
|
|
65
|
+
border: none;
|
|
66
|
+
outline: none;
|
|
67
|
+
background: transparent;
|
|
68
|
+
color: inherit;
|
|
69
|
+
font: inherit;
|
|
70
|
+
/* A concrete, unitless line-height so the runtime auto-resize logic
|
|
71
|
+
(chat-composer.ts's resizeTextarea()) can read a real pixel value
|
|
72
|
+
back out of getComputedStyle() -- the UA default of "normal" has no
|
|
73
|
+
single resolved px figure to measure rows against. */
|
|
74
|
+
line-height: 1.5;
|
|
75
|
+
padding-block: var(--lyra-space-xs);
|
|
76
|
+
overflow-y: hidden;
|
|
77
|
+
}
|
|
78
|
+
[part='textarea']::placeholder {
|
|
79
|
+
color: var(--lyra-color-text-quiet);
|
|
80
|
+
}
|
|
81
|
+
[part='textarea']:disabled {
|
|
82
|
+
cursor: not-allowed;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
[part='trailing'] {
|
|
86
|
+
display: flex;
|
|
87
|
+
flex: 0 0 auto;
|
|
88
|
+
align-items: center;
|
|
89
|
+
gap: var(--lyra-space-xs);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
[part='action-button'] {
|
|
93
|
+
display: inline-flex;
|
|
94
|
+
align-items: center;
|
|
95
|
+
justify-content: center;
|
|
96
|
+
flex: 0 0 auto;
|
|
97
|
+
box-sizing: border-box;
|
|
98
|
+
min-inline-size: var(--lyra-icon-button-size);
|
|
99
|
+
min-block-size: var(--lyra-icon-button-size);
|
|
100
|
+
border: none;
|
|
101
|
+
border-radius: var(--lyra-radius);
|
|
102
|
+
background: var(--lyra-color-brand);
|
|
103
|
+
color: var(--lyra-color-on-brand);
|
|
104
|
+
font-size: 1.125rem;
|
|
105
|
+
line-height: 1;
|
|
106
|
+
cursor: pointer;
|
|
107
|
+
transition: background-color var(--lyra-transition-fast);
|
|
108
|
+
}
|
|
109
|
+
[part='action-button']:hover {
|
|
110
|
+
background: var(--lyra-color-brand);
|
|
111
|
+
filter: brightness(1.1);
|
|
112
|
+
}
|
|
113
|
+
[part='action-button']:focus-visible {
|
|
114
|
+
outline: var(--lyra-focus-ring-width) solid var(--lyra-focus-ring-color);
|
|
115
|
+
outline-offset: var(--lyra-focus-ring-offset);
|
|
116
|
+
}
|
|
117
|
+
[part='action-button']:disabled {
|
|
118
|
+
cursor: not-allowed;
|
|
119
|
+
opacity: var(--lyra-opacity-disabled);
|
|
120
|
+
}
|
|
121
|
+
/* Stop affordance while generating -- a neutral/quiet treatment rather
|
|
122
|
+
than the resting brand fill, so it doesn't read as "send is still
|
|
123
|
+
available" while a response is in flight. */
|
|
124
|
+
:host([status='sending']) [part='action-button'],
|
|
125
|
+
:host([status='streaming']) [part='action-button'] {
|
|
126
|
+
background: var(--lyra-color-text-quiet);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
@media (prefers-reduced-motion: reduce) {
|
|
130
|
+
[part='base'],
|
|
131
|
+
[part='action-button'] {
|
|
132
|
+
transition: none !important;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
`;
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { type TemplateResult, type PropertyValues } from 'lit';
|
|
2
|
+
import { LyraElement } from '../../internal/lyra-element.js';
|
|
3
|
+
import '../live-region/live-region.js';
|
|
4
|
+
export type ChatMessageRole = 'user' | 'assistant' | 'system';
|
|
5
|
+
export type ChatMessageStatus = 'sending' | 'sent' | 'failed' | 'streaming';
|
|
6
|
+
/**
|
|
7
|
+
* `<lyra-chat-message>` — a role-based message bubble *shell* for a chat/
|
|
8
|
+
* agent conversation surface. It renders none of the message content itself:
|
|
9
|
+
* the default slot carries whatever a consumer wants to display (plain
|
|
10
|
+
* text, a `<lyra-markdown>`, a custom template, anything at all) and this
|
|
11
|
+
* component only supplies the surrounding chrome — alignment/coloring by
|
|
12
|
+
* `role`, an avatar/badges header row, an optional collapse toggle, an
|
|
13
|
+
* attachments strip, and a status-aware footer (a live-updating status dot +
|
|
14
|
+
* text, the formatted `timestamp`, a built-in retry affordance for
|
|
15
|
+
* `status="failed"`, and an `actions` slot for everything else).
|
|
16
|
+
*
|
|
17
|
+
* No built-in copy button is rendered. Deciding what "the copyable text" of
|
|
18
|
+
* an arbitrary slotted message even means (plain text? the rendered
|
|
19
|
+
* markdown source? something else?) is exactly the kind of content
|
|
20
|
+
* interpretation this shell deliberately stays out of — slot a copy control
|
|
21
|
+
* into `actions` instead. Firing `lyra-copy` (`detail: { text }`) from that
|
|
22
|
+
* control keeps the event name consistent with `<lyra-json-viewer>`'s own
|
|
23
|
+
* copy affordance, for anything listening at the conversation-surface level.
|
|
24
|
+
*
|
|
25
|
+
* Accessibility of `status`: the current status is always available as
|
|
26
|
+
* plain visible text (`[part="status-text"]`), never color alone. A
|
|
27
|
+
* transition *to* `"failed"`, or *from* `"streaming"` to `"sent"` (a stream
|
|
28
|
+
* finishing), is additionally announced through an internal
|
|
29
|
+
* `<lyra-live-region>` (see that component's header for the throttled-
|
|
30
|
+
* announcement wiring this composes) so a screen-reader user who isn't
|
|
31
|
+
* currently focused on this message still learns about it. This differs
|
|
32
|
+
* from `<lyra-typing-indicator>`'s deliberately simpler `role="status"`
|
|
33
|
+
* approach — that component only ever has one thing to announce (its own
|
|
34
|
+
* mount); this one has a `status` that can flip between several values
|
|
35
|
+
* across a single element's lifetime, which is exactly the coalescing job
|
|
36
|
+
* `<lyra-live-region>` exists for.
|
|
37
|
+
*
|
|
38
|
+
* `role` is a message-author role (`user`/`assistant`/`system`, matching
|
|
39
|
+
* the vocabulary of every chat/completion API), *not* a WAI-ARIA role, so
|
|
40
|
+
* it reflects to a `data-role` attribute rather than the bare `role`
|
|
41
|
+
* attribute — `role="user"` would collide with `Element`'s own ARIA `role`
|
|
42
|
+
* accessor and is not a valid ARIA role token to begin with.
|
|
43
|
+
*
|
|
44
|
+
* @customElement lyra-chat-message
|
|
45
|
+
* @slot - The message body.
|
|
46
|
+
* @slot avatar - An avatar/icon for the message author.
|
|
47
|
+
* @slot badges - Small status/metric chips (e.g. token count, latency, model name) — entirely app-supplied; this component computes none of that itself.
|
|
48
|
+
* @slot actions - Action controls (e.g. copy, retry), rendered at the end of the footer.
|
|
49
|
+
* @slot attachments - File/image attachment chips, rendered below the message body.
|
|
50
|
+
* @event lyra-retry - Fired by the built-in retry button, only rendered when `status="failed"`.
|
|
51
|
+
* @event lyra-collapse-toggle - `detail: boolean` (the new `collapsed` state) — fired when the user activates the built-in collapse button.
|
|
52
|
+
* @csspart bubble - The message bubble root.
|
|
53
|
+
* @csspart header - The row above the message body — avatar, badges, and the collapse toggle. Hidden entirely when none of those have anything to show.
|
|
54
|
+
* @csspart avatar - The wrapper around the `avatar` slot.
|
|
55
|
+
* @csspart badges - The wrapper around the `badges` slot.
|
|
56
|
+
* @csspart collapse-button - The built-in collapse/expand toggle (only rendered when `collapsible`).
|
|
57
|
+
* @csspart body - The wrapper around the default slot (the message content). Hidden while `collapsed`.
|
|
58
|
+
* @csspart attachments - The wrapper around the `attachments` slot.
|
|
59
|
+
* @csspart footer - The row below the message body — status, timestamp, retry, and actions. Hidden entirely when none of those have anything to show.
|
|
60
|
+
* @csspart status-indicator - A small decorative (`aria-hidden`) dot reflecting `status`; absent while `status="sent"`.
|
|
61
|
+
* @csspart status-text - The visible text twin of `status-indicator` — carries the state in text, not just color.
|
|
62
|
+
* @csspart timestamp - The formatted `timestamp`, rendered in a `<time>` element.
|
|
63
|
+
* @csspart retry-button - The built-in retry button (only rendered when `status="failed"`).
|
|
64
|
+
* @csspart actions - The wrapper around the `actions` slot.
|
|
65
|
+
*/
|
|
66
|
+
export declare class LyraChatMessage extends LyraElement {
|
|
67
|
+
static styles: import("lit").CSSResultGroup[];
|
|
68
|
+
/** Who authored the message. Reflects to `data-role` — see the class doc. */
|
|
69
|
+
role: ChatMessageRole;
|
|
70
|
+
/** Delivery/generation state. Drives the footer's status dot/text and, for
|
|
71
|
+
* `"failed"`, the bubble's danger treatment and the built-in retry button. */
|
|
72
|
+
status: ChatMessageStatus;
|
|
73
|
+
/** When the message was sent/received. Accepts a `Date` or anything
|
|
74
|
+
* `new Date()` can parse (e.g. an ISO 8601 string); invalid input is
|
|
75
|
+
* treated the same as unset (no timestamp rendered). */
|
|
76
|
+
timestamp?: Date | string;
|
|
77
|
+
/** Overrides the default `hour:minute` rendering of `timestamp` — this
|
|
78
|
+
* library has no i18n system of its own, so an overridable formatter is
|
|
79
|
+
* the established way to hand locale-sensitive display back to the
|
|
80
|
+
* consumer (mirrors `lyra-heatmap`'s `cellText`). */
|
|
81
|
+
formatTimestamp?: (date: Date) => string;
|
|
82
|
+
/** Shows the built-in collapse/expand toggle in the header. */
|
|
83
|
+
collapsible: boolean;
|
|
84
|
+
/** Whether the message body is currently hidden. Effective whenever set,
|
|
85
|
+
* independent of `collapsible` — `collapsible` only controls whether the
|
|
86
|
+
* built-in toggle button is rendered, mirroring `lyra-widget`'s identical
|
|
87
|
+
* `collapsible`/`collapsed` pair. */
|
|
88
|
+
collapsed: boolean;
|
|
89
|
+
private hasAvatarSlot;
|
|
90
|
+
private hasBadgesSlot;
|
|
91
|
+
private hasAttachmentsSlot;
|
|
92
|
+
private hasActionsSlot;
|
|
93
|
+
private liveRegion?;
|
|
94
|
+
private readonly bodyId;
|
|
95
|
+
protected willUpdate(): void;
|
|
96
|
+
protected updated(changed: PropertyValues): void;
|
|
97
|
+
private hasSlotted;
|
|
98
|
+
private get normalizedTimestamp();
|
|
99
|
+
private get statusText();
|
|
100
|
+
private announceStatusChange;
|
|
101
|
+
private onAvatarSlotChange;
|
|
102
|
+
private onBadgesSlotChange;
|
|
103
|
+
private onAttachmentsSlotChange;
|
|
104
|
+
private onActionsSlotChange;
|
|
105
|
+
private toggleCollapsed;
|
|
106
|
+
private onRetryClick;
|
|
107
|
+
render(): TemplateResult;
|
|
108
|
+
}
|
|
109
|
+
declare global {
|
|
110
|
+
interface HTMLElementTagNameMap {
|
|
111
|
+
'lyra-chat-message': LyraChatMessage;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
@@ -0,0 +1,291 @@
|
|
|
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, svg } from 'lit';
|
|
8
|
+
import { property, state, query } 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 { chevronIcon } from '../../internal/icons.js';
|
|
13
|
+
import '../live-region/live-region.js';
|
|
14
|
+
import { styles } from './chat-message.styles.js';
|
|
15
|
+
// Mirrors the shared icon set's viewBox/stroke conventions
|
|
16
|
+
// (internal/icons.ts's chevronIcon()/closeIcon()/etc.) without adding a
|
|
17
|
+
// retry glyph to that module -- it's off limits here -- so this one-off icon
|
|
18
|
+
// still reads as part of the same visual language as the rest of the
|
|
19
|
+
// library's inline icons. Same approach lyra-checkbox's own local
|
|
20
|
+
// checkmark/indeterminate glyphs take for the identical reason.
|
|
21
|
+
const ICON_VIEW_BOX = '0 0 24 24';
|
|
22
|
+
const ICON_STROKE_WIDTH = '1.75';
|
|
23
|
+
function retryIcon() {
|
|
24
|
+
return svg `
|
|
25
|
+
<svg
|
|
26
|
+
width="1em"
|
|
27
|
+
height="1em"
|
|
28
|
+
viewBox=${ICON_VIEW_BOX}
|
|
29
|
+
fill="none"
|
|
30
|
+
stroke="currentColor"
|
|
31
|
+
stroke-width=${ICON_STROKE_WIDTH}
|
|
32
|
+
stroke-linecap="round"
|
|
33
|
+
stroke-linejoin="round"
|
|
34
|
+
aria-hidden="true"
|
|
35
|
+
focusable="false"
|
|
36
|
+
><polyline points="1 4 1 10 7 10"></polyline><path d="M3.51 15a9 9 0 1 0 2.13-9.36L1 10"></path></svg>
|
|
37
|
+
`;
|
|
38
|
+
}
|
|
39
|
+
/** `hour:minute` in the runtime's default locale -- the sensible baseline
|
|
40
|
+
* this library (with no i18n system of its own) can offer without
|
|
41
|
+
* hardcoding English strings; `formatTimestamp` overrides it. */
|
|
42
|
+
function defaultFormatTimestamp(date) {
|
|
43
|
+
return new Intl.DateTimeFormat(undefined, { hour: 'numeric', minute: '2-digit' }).format(date);
|
|
44
|
+
}
|
|
45
|
+
/** Visible (not just color-coded) text for every non-resting status --
|
|
46
|
+
* `'sent'` renders nothing here, it's the resting state. */
|
|
47
|
+
const STATUS_TEXT = {
|
|
48
|
+
sending: 'Sending…',
|
|
49
|
+
streaming: 'Responding…',
|
|
50
|
+
failed: 'Failed to send',
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* `<lyra-chat-message>` — a role-based message bubble *shell* for a chat/
|
|
54
|
+
* agent conversation surface. It renders none of the message content itself:
|
|
55
|
+
* the default slot carries whatever a consumer wants to display (plain
|
|
56
|
+
* text, a `<lyra-markdown>`, a custom template, anything at all) and this
|
|
57
|
+
* component only supplies the surrounding chrome — alignment/coloring by
|
|
58
|
+
* `role`, an avatar/badges header row, an optional collapse toggle, an
|
|
59
|
+
* attachments strip, and a status-aware footer (a live-updating status dot +
|
|
60
|
+
* text, the formatted `timestamp`, a built-in retry affordance for
|
|
61
|
+
* `status="failed"`, and an `actions` slot for everything else).
|
|
62
|
+
*
|
|
63
|
+
* No built-in copy button is rendered. Deciding what "the copyable text" of
|
|
64
|
+
* an arbitrary slotted message even means (plain text? the rendered
|
|
65
|
+
* markdown source? something else?) is exactly the kind of content
|
|
66
|
+
* interpretation this shell deliberately stays out of — slot a copy control
|
|
67
|
+
* into `actions` instead. Firing `lyra-copy` (`detail: { text }`) from that
|
|
68
|
+
* control keeps the event name consistent with `<lyra-json-viewer>`'s own
|
|
69
|
+
* copy affordance, for anything listening at the conversation-surface level.
|
|
70
|
+
*
|
|
71
|
+
* Accessibility of `status`: the current status is always available as
|
|
72
|
+
* plain visible text (`[part="status-text"]`), never color alone. A
|
|
73
|
+
* transition *to* `"failed"`, or *from* `"streaming"` to `"sent"` (a stream
|
|
74
|
+
* finishing), is additionally announced through an internal
|
|
75
|
+
* `<lyra-live-region>` (see that component's header for the throttled-
|
|
76
|
+
* announcement wiring this composes) so a screen-reader user who isn't
|
|
77
|
+
* currently focused on this message still learns about it. This differs
|
|
78
|
+
* from `<lyra-typing-indicator>`'s deliberately simpler `role="status"`
|
|
79
|
+
* approach — that component only ever has one thing to announce (its own
|
|
80
|
+
* mount); this one has a `status` that can flip between several values
|
|
81
|
+
* across a single element's lifetime, which is exactly the coalescing job
|
|
82
|
+
* `<lyra-live-region>` exists for.
|
|
83
|
+
*
|
|
84
|
+
* `role` is a message-author role (`user`/`assistant`/`system`, matching
|
|
85
|
+
* the vocabulary of every chat/completion API), *not* a WAI-ARIA role, so
|
|
86
|
+
* it reflects to a `data-role` attribute rather than the bare `role`
|
|
87
|
+
* attribute — `role="user"` would collide with `Element`'s own ARIA `role`
|
|
88
|
+
* accessor and is not a valid ARIA role token to begin with.
|
|
89
|
+
*
|
|
90
|
+
* @customElement lyra-chat-message
|
|
91
|
+
* @slot - The message body.
|
|
92
|
+
* @slot avatar - An avatar/icon for the message author.
|
|
93
|
+
* @slot badges - Small status/metric chips (e.g. token count, latency, model name) — entirely app-supplied; this component computes none of that itself.
|
|
94
|
+
* @slot actions - Action controls (e.g. copy, retry), rendered at the end of the footer.
|
|
95
|
+
* @slot attachments - File/image attachment chips, rendered below the message body.
|
|
96
|
+
* @event lyra-retry - Fired by the built-in retry button, only rendered when `status="failed"`.
|
|
97
|
+
* @event lyra-collapse-toggle - `detail: boolean` (the new `collapsed` state) — fired when the user activates the built-in collapse button.
|
|
98
|
+
* @csspart bubble - The message bubble root.
|
|
99
|
+
* @csspart header - The row above the message body — avatar, badges, and the collapse toggle. Hidden entirely when none of those have anything to show.
|
|
100
|
+
* @csspart avatar - The wrapper around the `avatar` slot.
|
|
101
|
+
* @csspart badges - The wrapper around the `badges` slot.
|
|
102
|
+
* @csspart collapse-button - The built-in collapse/expand toggle (only rendered when `collapsible`).
|
|
103
|
+
* @csspart body - The wrapper around the default slot (the message content). Hidden while `collapsed`.
|
|
104
|
+
* @csspart attachments - The wrapper around the `attachments` slot.
|
|
105
|
+
* @csspart footer - The row below the message body — status, timestamp, retry, and actions. Hidden entirely when none of those have anything to show.
|
|
106
|
+
* @csspart status-indicator - A small decorative (`aria-hidden`) dot reflecting `status`; absent while `status="sent"`.
|
|
107
|
+
* @csspart status-text - The visible text twin of `status-indicator` — carries the state in text, not just color.
|
|
108
|
+
* @csspart timestamp - The formatted `timestamp`, rendered in a `<time>` element.
|
|
109
|
+
* @csspart retry-button - The built-in retry button (only rendered when `status="failed"`).
|
|
110
|
+
* @csspart actions - The wrapper around the `actions` slot.
|
|
111
|
+
*/
|
|
112
|
+
export class LyraChatMessage extends LyraElement {
|
|
113
|
+
constructor() {
|
|
114
|
+
super(...arguments);
|
|
115
|
+
/** Who authored the message. Reflects to `data-role` — see the class doc. */
|
|
116
|
+
this.role = 'assistant';
|
|
117
|
+
/** Delivery/generation state. Drives the footer's status dot/text and, for
|
|
118
|
+
* `"failed"`, the bubble's danger treatment and the built-in retry button. */
|
|
119
|
+
this.status = 'sent';
|
|
120
|
+
/** Shows the built-in collapse/expand toggle in the header. */
|
|
121
|
+
this.collapsible = false;
|
|
122
|
+
/** Whether the message body is currently hidden. Effective whenever set,
|
|
123
|
+
* independent of `collapsible` — `collapsible` only controls whether the
|
|
124
|
+
* built-in toggle button is rendered, mirroring `lyra-widget`'s identical
|
|
125
|
+
* `collapsible`/`collapsed` pair. */
|
|
126
|
+
this.collapsed = false;
|
|
127
|
+
this.hasAvatarSlot = false;
|
|
128
|
+
this.hasBadgesSlot = false;
|
|
129
|
+
this.hasAttachmentsSlot = false;
|
|
130
|
+
this.hasActionsSlot = false;
|
|
131
|
+
this.bodyId = nextId('chat-message-body');
|
|
132
|
+
this.onAvatarSlotChange = (e) => {
|
|
133
|
+
this.hasAvatarSlot = e.target.assignedElements({ flatten: true }).length > 0;
|
|
134
|
+
};
|
|
135
|
+
this.onBadgesSlotChange = (e) => {
|
|
136
|
+
this.hasBadgesSlot = e.target.assignedElements({ flatten: true }).length > 0;
|
|
137
|
+
};
|
|
138
|
+
this.onAttachmentsSlotChange = (e) => {
|
|
139
|
+
this.hasAttachmentsSlot = e.target.assignedElements({ flatten: true }).length > 0;
|
|
140
|
+
};
|
|
141
|
+
this.onActionsSlotChange = (e) => {
|
|
142
|
+
this.hasActionsSlot = e.target.assignedElements({ flatten: true }).length > 0;
|
|
143
|
+
};
|
|
144
|
+
this.toggleCollapsed = () => {
|
|
145
|
+
this.collapsed = !this.collapsed;
|
|
146
|
+
this.emit('lyra-collapse-toggle', this.collapsed);
|
|
147
|
+
};
|
|
148
|
+
this.onRetryClick = () => {
|
|
149
|
+
this.emit('lyra-retry');
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
static { this.styles = [LyraElement.styles, styles]; }
|
|
153
|
+
willUpdate() {
|
|
154
|
+
if (!this.hasUpdated) {
|
|
155
|
+
this.hasAvatarSlot = this.hasSlotted('avatar');
|
|
156
|
+
this.hasBadgesSlot = this.hasSlotted('badges');
|
|
157
|
+
this.hasAttachmentsSlot = this.hasSlotted('attachments');
|
|
158
|
+
this.hasActionsSlot = this.hasSlotted('actions');
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
// `changed.get('status')` is `undefined` on the very first update (Lit
|
|
162
|
+
// only records the *first* old value seen since the last completed
|
|
163
|
+
// update, and the constructor's own field-initializer assignment is that
|
|
164
|
+
// first change, from the truly-unset internal slot) -- so this naturally
|
|
165
|
+
// skips announcing whatever status a message happens to mount with, and
|
|
166
|
+
// only ever fires for a real, later transition.
|
|
167
|
+
updated(changed) {
|
|
168
|
+
if (changed.has('status')) {
|
|
169
|
+
this.announceStatusChange(changed.get('status'));
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
hasSlotted(name) {
|
|
173
|
+
return Array.from(this.children).some((el) => el.getAttribute('slot') === name);
|
|
174
|
+
}
|
|
175
|
+
get normalizedTimestamp() {
|
|
176
|
+
if (this.timestamp === undefined)
|
|
177
|
+
return undefined;
|
|
178
|
+
const date = this.timestamp instanceof Date ? this.timestamp : new Date(this.timestamp);
|
|
179
|
+
return Number.isNaN(date.getTime()) ? undefined : date;
|
|
180
|
+
}
|
|
181
|
+
get statusText() {
|
|
182
|
+
return this.status === 'sent' ? undefined : STATUS_TEXT[this.status];
|
|
183
|
+
}
|
|
184
|
+
announceStatusChange(previous) {
|
|
185
|
+
if (previous === undefined || previous === this.status)
|
|
186
|
+
return;
|
|
187
|
+
const region = this.liveRegion;
|
|
188
|
+
if (!region)
|
|
189
|
+
return;
|
|
190
|
+
if (this.status === 'failed') {
|
|
191
|
+
region.mode = 'assertive';
|
|
192
|
+
region.announce('Message failed to send.', { force: true });
|
|
193
|
+
}
|
|
194
|
+
else if (previous === 'streaming' && this.status === 'sent') {
|
|
195
|
+
region.mode = 'polite';
|
|
196
|
+
region.announce('Message complete.', { force: true });
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
render() {
|
|
200
|
+
const ts = this.normalizedTimestamp;
|
|
201
|
+
const formatter = this.formatTimestamp ?? defaultFormatTimestamp;
|
|
202
|
+
const statusText = this.statusText;
|
|
203
|
+
const showHeader = this.hasAvatarSlot || this.hasBadgesSlot || this.collapsible;
|
|
204
|
+
// `statusText` is already truthy whenever `status === 'failed'`, so it
|
|
205
|
+
// alone covers that case here too.
|
|
206
|
+
const showFooter = Boolean(statusText) || Boolean(ts) || this.hasActionsSlot;
|
|
207
|
+
return html `
|
|
208
|
+
<div part="bubble">
|
|
209
|
+
<div part="header" ?hidden=${!showHeader}>
|
|
210
|
+
<span part="avatar" ?hidden=${!this.hasAvatarSlot}
|
|
211
|
+
><slot name="avatar" @slotchange=${this.onAvatarSlotChange}></slot
|
|
212
|
+
></span>
|
|
213
|
+
<span part="badges" ?hidden=${!this.hasBadgesSlot}
|
|
214
|
+
><slot name="badges" @slotchange=${this.onBadgesSlotChange}></slot
|
|
215
|
+
></span>
|
|
216
|
+
${this.collapsible
|
|
217
|
+
? html `<button
|
|
218
|
+
part="collapse-button"
|
|
219
|
+
type="button"
|
|
220
|
+
aria-expanded=${this.collapsed ? 'false' : 'true'}
|
|
221
|
+
aria-controls=${this.bodyId}
|
|
222
|
+
aria-label=${this.collapsed ? 'Expand message' : 'Collapse message'}
|
|
223
|
+
@click=${this.toggleCollapsed}
|
|
224
|
+
>
|
|
225
|
+
<span class="chevron" style=${`transform:rotate(${this.collapsed ? '0deg' : '90deg'})`}
|
|
226
|
+
>${chevronIcon()}</span
|
|
227
|
+
>
|
|
228
|
+
</button>`
|
|
229
|
+
: nothing}
|
|
230
|
+
</div>
|
|
231
|
+
<div part="body" id=${this.bodyId} ?hidden=${this.collapsed}>
|
|
232
|
+
<slot></slot>
|
|
233
|
+
</div>
|
|
234
|
+
<div part="attachments" ?hidden=${!this.hasAttachmentsSlot}>
|
|
235
|
+
<slot name="attachments" @slotchange=${this.onAttachmentsSlotChange}></slot>
|
|
236
|
+
</div>
|
|
237
|
+
<div part="footer" ?hidden=${!showFooter}>
|
|
238
|
+
${statusText
|
|
239
|
+
? html `<span part="status-indicator" aria-hidden="true"></span><span part="status-text"
|
|
240
|
+
>${statusText}</span
|
|
241
|
+
>`
|
|
242
|
+
: nothing}
|
|
243
|
+
${ts ? html `<time part="timestamp" datetime=${ts.toISOString()}>${formatter(ts)}</time>` : nothing}
|
|
244
|
+
${this.status === 'failed'
|
|
245
|
+
? html `<button part="retry-button" type="button" @click=${this.onRetryClick}>
|
|
246
|
+
${retryIcon()}<span>Retry</span>
|
|
247
|
+
</button>`
|
|
248
|
+
: nothing}
|
|
249
|
+
<span part="actions" ?hidden=${!this.hasActionsSlot}
|
|
250
|
+
><slot name="actions" @slotchange=${this.onActionsSlotChange}></slot
|
|
251
|
+
></span>
|
|
252
|
+
</div>
|
|
253
|
+
<lyra-live-region></lyra-live-region>
|
|
254
|
+
</div>
|
|
255
|
+
`;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
__decorate([
|
|
259
|
+
property({ reflect: true, attribute: 'data-role' })
|
|
260
|
+
], LyraChatMessage.prototype, "role", void 0);
|
|
261
|
+
__decorate([
|
|
262
|
+
property({ reflect: true })
|
|
263
|
+
], LyraChatMessage.prototype, "status", void 0);
|
|
264
|
+
__decorate([
|
|
265
|
+
property({ attribute: false })
|
|
266
|
+
], LyraChatMessage.prototype, "timestamp", void 0);
|
|
267
|
+
__decorate([
|
|
268
|
+
property({ attribute: false })
|
|
269
|
+
], LyraChatMessage.prototype, "formatTimestamp", void 0);
|
|
270
|
+
__decorate([
|
|
271
|
+
property({ type: Boolean, reflect: true })
|
|
272
|
+
], LyraChatMessage.prototype, "collapsible", void 0);
|
|
273
|
+
__decorate([
|
|
274
|
+
property({ type: Boolean, reflect: true })
|
|
275
|
+
], LyraChatMessage.prototype, "collapsed", void 0);
|
|
276
|
+
__decorate([
|
|
277
|
+
state()
|
|
278
|
+
], LyraChatMessage.prototype, "hasAvatarSlot", void 0);
|
|
279
|
+
__decorate([
|
|
280
|
+
state()
|
|
281
|
+
], LyraChatMessage.prototype, "hasBadgesSlot", void 0);
|
|
282
|
+
__decorate([
|
|
283
|
+
state()
|
|
284
|
+
], LyraChatMessage.prototype, "hasAttachmentsSlot", void 0);
|
|
285
|
+
__decorate([
|
|
286
|
+
state()
|
|
287
|
+
], LyraChatMessage.prototype, "hasActionsSlot", void 0);
|
|
288
|
+
__decorate([
|
|
289
|
+
query('lyra-live-region')
|
|
290
|
+
], LyraChatMessage.prototype, "liveRegion", void 0);
|
|
291
|
+
defineElement('chat-message', LyraChatMessage);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const styles: import("lit").CSSResult;
|