@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,125 @@
|
|
|
1
|
+
import { css } from 'lit';
|
|
2
|
+
export const styles = css `
|
|
3
|
+
:host {
|
|
4
|
+
display: block;
|
|
5
|
+
/* Component-specific sizing -- not shared design tokens, so a consumer
|
|
6
|
+
can retheme any of them without a raw literal leaking into the public
|
|
7
|
+
API (same rationale as lyra-dialog's --lyra-dialog-overlay-color and
|
|
8
|
+
lyra-widget's --lyra-widget-overlay-color). */
|
|
9
|
+
--lyra-app-rail-width: 15rem;
|
|
10
|
+
--lyra-app-rail-icon-width: 4rem;
|
|
11
|
+
--lyra-app-rail-mobile-width: 18rem;
|
|
12
|
+
--lyra-app-rail-overlay-color: rgb(0 0 0 / 0.5);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
[part='toggle'] {
|
|
16
|
+
display: none;
|
|
17
|
+
align-items: center;
|
|
18
|
+
justify-content: center;
|
|
19
|
+
min-inline-size: var(--lyra-icon-button-size);
|
|
20
|
+
min-block-size: var(--lyra-icon-button-size);
|
|
21
|
+
border: 1px solid var(--lyra-color-border);
|
|
22
|
+
border-radius: var(--lyra-radius);
|
|
23
|
+
background: var(--lyra-color-surface);
|
|
24
|
+
color: var(--lyra-color-text);
|
|
25
|
+
cursor: pointer;
|
|
26
|
+
}
|
|
27
|
+
:host([mode='mobile']) [part='toggle'] {
|
|
28
|
+
display: inline-flex;
|
|
29
|
+
}
|
|
30
|
+
[part='toggle']:hover {
|
|
31
|
+
background: var(--lyra-color-brand-quiet);
|
|
32
|
+
color: var(--lyra-color-brand);
|
|
33
|
+
}
|
|
34
|
+
[part='toggle']:focus-visible {
|
|
35
|
+
outline: var(--lyra-focus-ring-width) solid var(--lyra-focus-ring-color);
|
|
36
|
+
outline-offset: var(--lyra-focus-ring-offset);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
[part='backdrop'] {
|
|
40
|
+
position: fixed;
|
|
41
|
+
inset: 0;
|
|
42
|
+
z-index: 999;
|
|
43
|
+
background: var(--lyra-app-rail-overlay-color);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/* [part="base"]/[part="panel"] are the SAME element -- this
|
|
47
|
+
component promotes it in place for the mobile overlay (mirrors
|
|
48
|
+
lyra-widget's fullscreen mode) rather than duplicating the slotted nav
|
|
49
|
+
content into a second element, which slot projection can't do anyway
|
|
50
|
+
(a light-DOM node can only be assigned to one <slot> at a time). Its
|
|
51
|
+
part attribute switches between the two names per render, so the two
|
|
52
|
+
rulesets below are always mutually exclusive on it. */
|
|
53
|
+
[part='base'] {
|
|
54
|
+
display: flex;
|
|
55
|
+
flex-direction: column;
|
|
56
|
+
inline-size: var(--lyra-app-rail-width);
|
|
57
|
+
block-size: 100%;
|
|
58
|
+
border-inline-end: 1px solid var(--lyra-color-border);
|
|
59
|
+
background: var(--lyra-color-surface);
|
|
60
|
+
overflow-y: auto;
|
|
61
|
+
transition: inline-size var(--lyra-transition-base);
|
|
62
|
+
}
|
|
63
|
+
:host([mode='icon-only']) [part='base'] {
|
|
64
|
+
inline-size: var(--lyra-app-rail-icon-width);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
[part='panel'] {
|
|
68
|
+
position: fixed;
|
|
69
|
+
inset-block: 0;
|
|
70
|
+
inset-inline-start: 0;
|
|
71
|
+
z-index: 1000;
|
|
72
|
+
display: flex;
|
|
73
|
+
flex-direction: column;
|
|
74
|
+
inline-size: min(var(--lyra-app-rail-mobile-width), 85vw);
|
|
75
|
+
background: var(--lyra-color-surface);
|
|
76
|
+
box-shadow: var(--lyra-shadow);
|
|
77
|
+
overflow-y: auto;
|
|
78
|
+
transform: translateX(-100%);
|
|
79
|
+
transition: transform var(--lyra-transition-base);
|
|
80
|
+
}
|
|
81
|
+
/* translateX is a physical transform -- CSS logical properties don't cover
|
|
82
|
+
it -- so the offscreen direction is flipped explicitly for RTL via
|
|
83
|
+
:dir() rather than needing internal/rtl.ts's JS helper (that helper is
|
|
84
|
+
for pointer/keyboard math that can't be expressed in CSS at all; this
|
|
85
|
+
can). */
|
|
86
|
+
:host(:dir(rtl)) [part='panel'] {
|
|
87
|
+
transform: translateX(100%);
|
|
88
|
+
}
|
|
89
|
+
:host([mode='mobile'][open]) [part='panel'] {
|
|
90
|
+
transform: translateX(0);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
[part='header'] {
|
|
94
|
+
padding: var(--lyra-space-m);
|
|
95
|
+
border-block-end: 1px solid var(--lyra-color-border);
|
|
96
|
+
}
|
|
97
|
+
[part='header'][hidden] {
|
|
98
|
+
display: none;
|
|
99
|
+
}
|
|
100
|
+
[part='footer'] {
|
|
101
|
+
padding: var(--lyra-space-m);
|
|
102
|
+
border-block-start: 1px solid var(--lyra-color-border);
|
|
103
|
+
}
|
|
104
|
+
[part='footer'][hidden] {
|
|
105
|
+
display: none;
|
|
106
|
+
}
|
|
107
|
+
[part='nav'] {
|
|
108
|
+
flex: 1 1 auto;
|
|
109
|
+
overflow-y: auto;
|
|
110
|
+
padding: var(--lyra-space-s);
|
|
111
|
+
display: flex;
|
|
112
|
+
flex-direction: column;
|
|
113
|
+
gap: var(--lyra-space-xs);
|
|
114
|
+
}
|
|
115
|
+
:host([mode='icon-only']) [part='nav'] {
|
|
116
|
+
align-items: center;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
@media (prefers-reduced-motion: reduce) {
|
|
120
|
+
[part='base'],
|
|
121
|
+
[part='panel'] {
|
|
122
|
+
transition: none !important;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
`;
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { type TemplateResult, type PropertyValues } from 'lit';
|
|
2
|
+
import { LyraElement } from '../../internal/lyra-element.js';
|
|
3
|
+
export type AttachmentChipStatus = 'pending' | 'uploading' | 'error' | 'done';
|
|
4
|
+
export interface AttachmentChipIdDetail {
|
|
5
|
+
id: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* `512` -> `"512 B"`; `2415919` -> `"2.3 MB"`. Whole bytes never get a
|
|
9
|
+
* decimal (there's no meaningful fraction of a byte); every unit past that
|
|
10
|
+
* gets exactly one decimal place. Returns `""` for a negative/non-finite
|
|
11
|
+
* input so a missing/unknown size renders nothing instead of `"NaN B"`.
|
|
12
|
+
*/
|
|
13
|
+
export declare function formatFileSize(bytes: number): string;
|
|
14
|
+
/**
|
|
15
|
+
* `<lyra-attachment-chip>` — a compact chip representing one file queued for
|
|
16
|
+
* (or already part of) a chat message: a composer's pre-send attachment
|
|
17
|
+
* tray, or a sent message's `attachments` slot (see `<lyra-chat-message>`).
|
|
18
|
+
*
|
|
19
|
+
* Two independent ways to populate it, matching the two points in a message's
|
|
20
|
+
* lifecycle this is used at:
|
|
21
|
+
* - Set `file` to a real `File` (fresh from a picker/drop) — `name`, `size`,
|
|
22
|
+
* `mime-type` and the image thumbnail are all auto-derived from it.
|
|
23
|
+
* - Set the plain `name`/`size`/`mime-type`/`thumbnail-src` props instead,
|
|
24
|
+
* for reconstructing a chip from server-persisted attachment metadata
|
|
25
|
+
* (e.g. after a page reload, when no real `File` object exists any more).
|
|
26
|
+
*
|
|
27
|
+
* `file` always wins when both are present — see each accessor's own doc.
|
|
28
|
+
* The image thumbnail for a real `File` is a lazily-created (only once the
|
|
29
|
+
* thumbnail is actually about to render, not eagerly on assignment)
|
|
30
|
+
* `URL.createObjectURL()` blob URL, revoked automatically once `file`
|
|
31
|
+
* changes away from the object it was created for, and on disconnect — this
|
|
32
|
+
* component never leaks a blob URL.
|
|
33
|
+
*
|
|
34
|
+
* Identifying *which* attachment a `lyra-remove`/`lyra-retry` event is about:
|
|
35
|
+
* this deliberately reuses the platform's own `id`/`id` attribute (every
|
|
36
|
+
* element already has one; there's no need to shadow it with a second,
|
|
37
|
+
* differently-named Lit property, unlike e.g. `<lyra-tool-call-chip>`'s
|
|
38
|
+
* `call-id` which identifies a *call*, a concept distinct from the chip
|
|
39
|
+
* element itself). Set `id="..."` when you have a stable server-side
|
|
40
|
+
* attachment id. When `id` is left unset and `file` is set, a stable id is
|
|
41
|
+
* derived from `` `${file.name}:${file.size}:${file.lastModified}` `` — stable
|
|
42
|
+
* across re-renders of the *same* `File` object without requiring the
|
|
43
|
+
* consumer to invent one. When neither is available, a generated internal id
|
|
44
|
+
* is used as a last resort so the event always has *some* id.
|
|
45
|
+
*
|
|
46
|
+
* @customElement lyra-attachment-chip
|
|
47
|
+
* @event lyra-remove - The user activated the remove (×) button. `detail: { id }`. Only rendered while `removable`.
|
|
48
|
+
* @event lyra-retry - The user activated the retry button. `detail: { id }`. Only rendered while `status="error"`.
|
|
49
|
+
* @csspart base - The chip's root container.
|
|
50
|
+
* @csspart thumbnail - The leading image thumbnail / generic file glyph.
|
|
51
|
+
* @csspart meta - Wrapper around `name` and `size`.
|
|
52
|
+
* @csspart name - The filename (ellipsis-truncated via CSS; the untruncated name is always available via the native `title` tooltip).
|
|
53
|
+
* @csspart size - The human-readable formatted file size. Hidden when no size is known.
|
|
54
|
+
* @csspart status-text - The visible text twin of the status accent color — carries the state in text, not just color. Empty/hidden for `pending`/`done`.
|
|
55
|
+
* @csspart progress - The numeric upload progress bar (`role="progressbar"`), shown only while `status="uploading"` and `progress` is a meaningful (>0) number.
|
|
56
|
+
* @csspart progress-fill - The filled portion of `progress`.
|
|
57
|
+
* @csspart spinner - The indeterminate upload spinner, shown instead of `progress` while `status="uploading"` and `progress` is unset/0.
|
|
58
|
+
* @csspart retry-button - The retry affordance, only rendered while `status="error"`.
|
|
59
|
+
* @csspart remove-button - The remove (×) affordance, only rendered while `removable`.
|
|
60
|
+
*/
|
|
61
|
+
export declare class LyraAttachmentChip extends LyraElement {
|
|
62
|
+
static styles: import("lit").CSSResultGroup[];
|
|
63
|
+
/** A real `File`, e.g. fresh from `<lyra-file-input>`'s `lyra-files` event.
|
|
64
|
+
* When set, `name`/`size`/`mime-type`/the image thumbnail are all derived
|
|
65
|
+
* from it, taking precedence over the independent props below. */
|
|
66
|
+
file?: File;
|
|
67
|
+
/** Filename, used only while `file` is unset. */
|
|
68
|
+
name: string;
|
|
69
|
+
/** File size in bytes, used only while `file` is unset. */
|
|
70
|
+
size: number;
|
|
71
|
+
/** MIME type, used only while `file` is unset. */
|
|
72
|
+
mimeType: string;
|
|
73
|
+
/** Thumbnail image URL, used only while `file` is unset (a real `File`'s
|
|
74
|
+
* thumbnail always comes from a generated object URL instead — see the
|
|
75
|
+
* class doc). Unlike the other independent props this one has no
|
|
76
|
+
* `file`-derived equivalent to defer to for a non-image file; it's simply
|
|
77
|
+
* rendered whenever present. */
|
|
78
|
+
thumbnailSrc: string;
|
|
79
|
+
/** Lifecycle state — drives the accent tint and which of `progress`/`spinner`/`retry-button` renders. */
|
|
80
|
+
status: AttachmentChipStatus;
|
|
81
|
+
/** Upload completion, 0-100. Only meaningful while `status="uploading"`;
|
|
82
|
+
* a value of 0 (the default) or `NaN` falls back to the indeterminate spinner. */
|
|
83
|
+
progress: number;
|
|
84
|
+
/** Shows the remove (×) button. */
|
|
85
|
+
removable: boolean;
|
|
86
|
+
private objectUrl?;
|
|
87
|
+
private objectUrlFile?;
|
|
88
|
+
private readonly fallbackId;
|
|
89
|
+
private get effectiveName();
|
|
90
|
+
private get effectiveSize();
|
|
91
|
+
private get effectiveMimeType();
|
|
92
|
+
private get resolvedId();
|
|
93
|
+
private get hasNumericProgress();
|
|
94
|
+
private get clampedProgress();
|
|
95
|
+
/** Returns (creating or reusing as needed) the object URL for `file`'s
|
|
96
|
+
* image thumbnail. Only ever called from `render()`, i.e. only once a
|
|
97
|
+
* thumbnail is actually about to be painted -- never eagerly from a
|
|
98
|
+
* `file`/`willUpdate`/`updated` property-change hook -- so a `file` that's
|
|
99
|
+
* reassigned several times before the next paint never creates URLs that
|
|
100
|
+
* are immediately thrown away unused. */
|
|
101
|
+
private ensureObjectUrl;
|
|
102
|
+
private revokeObjectUrl;
|
|
103
|
+
protected updated(changed: PropertyValues): void;
|
|
104
|
+
disconnectedCallback(): void;
|
|
105
|
+
private onRemoveClick;
|
|
106
|
+
private onRetryClick;
|
|
107
|
+
private renderThumbnail;
|
|
108
|
+
render(): TemplateResult;
|
|
109
|
+
}
|
|
110
|
+
declare global {
|
|
111
|
+
interface HTMLElementTagNameMap {
|
|
112
|
+
'lyra-attachment-chip': LyraAttachmentChip;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
@@ -0,0 +1,312 @@
|
|
|
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 } 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 { closeIcon } from '../../internal/icons.js';
|
|
13
|
+
import { styles } from './attachment-chip.styles.js';
|
|
14
|
+
// Mirrors the shared icon set's viewBox/stroke conventions
|
|
15
|
+
// (internal/icons.ts's chevronIcon()/closeIcon()/etc.) without adding a
|
|
16
|
+
// generic-file glyph to that module -- it's off limits here -- so this one-off
|
|
17
|
+
// icon still reads as part of the same visual language as the rest of the
|
|
18
|
+
// library's inline icons. `closeIcon()` itself already exists there and is
|
|
19
|
+
// imported directly rather than duplicated (see `<lyra-toast-item>`'s /
|
|
20
|
+
// `<lyra-widget>`'s identical import for the same remove/dismiss glyph).
|
|
21
|
+
const ICON_VIEW_BOX = '0 0 24 24';
|
|
22
|
+
const ICON_STROKE_WIDTH = '1.75';
|
|
23
|
+
/** A generic "document" glyph, used as the thumbnail for any non-image file. */
|
|
24
|
+
function fileGlyph() {
|
|
25
|
+
return svg `
|
|
26
|
+
<svg
|
|
27
|
+
width="1em"
|
|
28
|
+
height="1em"
|
|
29
|
+
viewBox=${ICON_VIEW_BOX}
|
|
30
|
+
fill="none"
|
|
31
|
+
stroke="currentColor"
|
|
32
|
+
stroke-width=${ICON_STROKE_WIDTH}
|
|
33
|
+
stroke-linecap="round"
|
|
34
|
+
stroke-linejoin="round"
|
|
35
|
+
aria-hidden="true"
|
|
36
|
+
focusable="false"
|
|
37
|
+
><path d="M6 2h8l6 6v12a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2Z"></path><polyline points="14 2 14 8 20 8"></polyline></svg>
|
|
38
|
+
`;
|
|
39
|
+
}
|
|
40
|
+
// Same shape as `<lyra-chat-message>`'s local `retryIcon()` -- duplicated
|
|
41
|
+
// rather than imported (these are two independent, separately-consumable
|
|
42
|
+
// components) but kept visually identical so a retry affordance reads the
|
|
43
|
+
// same wherever it shows up in the library.
|
|
44
|
+
function retryIcon() {
|
|
45
|
+
return svg `
|
|
46
|
+
<svg
|
|
47
|
+
width="1em"
|
|
48
|
+
height="1em"
|
|
49
|
+
viewBox=${ICON_VIEW_BOX}
|
|
50
|
+
fill="none"
|
|
51
|
+
stroke="currentColor"
|
|
52
|
+
stroke-width=${ICON_STROKE_WIDTH}
|
|
53
|
+
stroke-linecap="round"
|
|
54
|
+
stroke-linejoin="round"
|
|
55
|
+
aria-hidden="true"
|
|
56
|
+
focusable="false"
|
|
57
|
+
><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>
|
|
58
|
+
`;
|
|
59
|
+
}
|
|
60
|
+
const BYTE_UNITS = ['B', 'KB', 'MB', 'GB', 'TB'];
|
|
61
|
+
/**
|
|
62
|
+
* `512` -> `"512 B"`; `2415919` -> `"2.3 MB"`. Whole bytes never get a
|
|
63
|
+
* decimal (there's no meaningful fraction of a byte); every unit past that
|
|
64
|
+
* gets exactly one decimal place. Returns `""` for a negative/non-finite
|
|
65
|
+
* input so a missing/unknown size renders nothing instead of `"NaN B"`.
|
|
66
|
+
*/
|
|
67
|
+
export function formatFileSize(bytes) {
|
|
68
|
+
if (!Number.isFinite(bytes) || bytes < 0)
|
|
69
|
+
return '';
|
|
70
|
+
if (bytes < 1024)
|
|
71
|
+
return `${Math.round(bytes)} B`;
|
|
72
|
+
let value = bytes;
|
|
73
|
+
let unitIndex = 0;
|
|
74
|
+
while (value >= 1024 && unitIndex < BYTE_UNITS.length - 1) {
|
|
75
|
+
value /= 1024;
|
|
76
|
+
unitIndex++;
|
|
77
|
+
}
|
|
78
|
+
return `${value.toFixed(1)} ${BYTE_UNITS[unitIndex]}`;
|
|
79
|
+
}
|
|
80
|
+
/** Visible (not just color-coded) text for every non-resting status --
|
|
81
|
+
* `'pending'`/`'done'` render nothing here, they're resting states. */
|
|
82
|
+
function statusText(status, progress) {
|
|
83
|
+
if (status === 'error')
|
|
84
|
+
return 'Upload failed';
|
|
85
|
+
if (status === 'uploading') {
|
|
86
|
+
return Number.isFinite(progress) && progress > 0 ? `Uploading ${Math.round(Math.min(100, progress))}%` : 'Uploading…';
|
|
87
|
+
}
|
|
88
|
+
return '';
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* `<lyra-attachment-chip>` — a compact chip representing one file queued for
|
|
92
|
+
* (or already part of) a chat message: a composer's pre-send attachment
|
|
93
|
+
* tray, or a sent message's `attachments` slot (see `<lyra-chat-message>`).
|
|
94
|
+
*
|
|
95
|
+
* Two independent ways to populate it, matching the two points in a message's
|
|
96
|
+
* lifecycle this is used at:
|
|
97
|
+
* - Set `file` to a real `File` (fresh from a picker/drop) — `name`, `size`,
|
|
98
|
+
* `mime-type` and the image thumbnail are all auto-derived from it.
|
|
99
|
+
* - Set the plain `name`/`size`/`mime-type`/`thumbnail-src` props instead,
|
|
100
|
+
* for reconstructing a chip from server-persisted attachment metadata
|
|
101
|
+
* (e.g. after a page reload, when no real `File` object exists any more).
|
|
102
|
+
*
|
|
103
|
+
* `file` always wins when both are present — see each accessor's own doc.
|
|
104
|
+
* The image thumbnail for a real `File` is a lazily-created (only once the
|
|
105
|
+
* thumbnail is actually about to render, not eagerly on assignment)
|
|
106
|
+
* `URL.createObjectURL()` blob URL, revoked automatically once `file`
|
|
107
|
+
* changes away from the object it was created for, and on disconnect — this
|
|
108
|
+
* component never leaks a blob URL.
|
|
109
|
+
*
|
|
110
|
+
* Identifying *which* attachment a `lyra-remove`/`lyra-retry` event is about:
|
|
111
|
+
* this deliberately reuses the platform's own `id`/`id` attribute (every
|
|
112
|
+
* element already has one; there's no need to shadow it with a second,
|
|
113
|
+
* differently-named Lit property, unlike e.g. `<lyra-tool-call-chip>`'s
|
|
114
|
+
* `call-id` which identifies a *call*, a concept distinct from the chip
|
|
115
|
+
* element itself). Set `id="..."` when you have a stable server-side
|
|
116
|
+
* attachment id. When `id` is left unset and `file` is set, a stable id is
|
|
117
|
+
* derived from `` `${file.name}:${file.size}:${file.lastModified}` `` — stable
|
|
118
|
+
* across re-renders of the *same* `File` object without requiring the
|
|
119
|
+
* consumer to invent one. When neither is available, a generated internal id
|
|
120
|
+
* is used as a last resort so the event always has *some* id.
|
|
121
|
+
*
|
|
122
|
+
* @customElement lyra-attachment-chip
|
|
123
|
+
* @event lyra-remove - The user activated the remove (×) button. `detail: { id }`. Only rendered while `removable`.
|
|
124
|
+
* @event lyra-retry - The user activated the retry button. `detail: { id }`. Only rendered while `status="error"`.
|
|
125
|
+
* @csspart base - The chip's root container.
|
|
126
|
+
* @csspart thumbnail - The leading image thumbnail / generic file glyph.
|
|
127
|
+
* @csspart meta - Wrapper around `name` and `size`.
|
|
128
|
+
* @csspart name - The filename (ellipsis-truncated via CSS; the untruncated name is always available via the native `title` tooltip).
|
|
129
|
+
* @csspart size - The human-readable formatted file size. Hidden when no size is known.
|
|
130
|
+
* @csspart status-text - The visible text twin of the status accent color — carries the state in text, not just color. Empty/hidden for `pending`/`done`.
|
|
131
|
+
* @csspart progress - The numeric upload progress bar (`role="progressbar"`), shown only while `status="uploading"` and `progress` is a meaningful (>0) number.
|
|
132
|
+
* @csspart progress-fill - The filled portion of `progress`.
|
|
133
|
+
* @csspart spinner - The indeterminate upload spinner, shown instead of `progress` while `status="uploading"` and `progress` is unset/0.
|
|
134
|
+
* @csspart retry-button - The retry affordance, only rendered while `status="error"`.
|
|
135
|
+
* @csspart remove-button - The remove (×) affordance, only rendered while `removable`.
|
|
136
|
+
*/
|
|
137
|
+
export class LyraAttachmentChip extends LyraElement {
|
|
138
|
+
constructor() {
|
|
139
|
+
super(...arguments);
|
|
140
|
+
/** Filename, used only while `file` is unset. */
|
|
141
|
+
this.name = '';
|
|
142
|
+
/** File size in bytes, used only while `file` is unset. */
|
|
143
|
+
this.size = 0;
|
|
144
|
+
/** MIME type, used only while `file` is unset. */
|
|
145
|
+
this.mimeType = '';
|
|
146
|
+
/** Thumbnail image URL, used only while `file` is unset (a real `File`'s
|
|
147
|
+
* thumbnail always comes from a generated object URL instead — see the
|
|
148
|
+
* class doc). Unlike the other independent props this one has no
|
|
149
|
+
* `file`-derived equivalent to defer to for a non-image file; it's simply
|
|
150
|
+
* rendered whenever present. */
|
|
151
|
+
this.thumbnailSrc = '';
|
|
152
|
+
/** Lifecycle state — drives the accent tint and which of `progress`/`spinner`/`retry-button` renders. */
|
|
153
|
+
this.status = 'pending';
|
|
154
|
+
/** Upload completion, 0-100. Only meaningful while `status="uploading"`;
|
|
155
|
+
* a value of 0 (the default) or `NaN` falls back to the indeterminate spinner. */
|
|
156
|
+
this.progress = 0;
|
|
157
|
+
/** Shows the remove (×) button. */
|
|
158
|
+
this.removable = true;
|
|
159
|
+
// Last-resort id, generated once per instance -- see the class doc's
|
|
160
|
+
// "Identifying which attachment..." section.
|
|
161
|
+
this.fallbackId = nextId('attachment-chip');
|
|
162
|
+
this.onRemoveClick = () => {
|
|
163
|
+
this.emit('lyra-remove', { id: this.resolvedId });
|
|
164
|
+
};
|
|
165
|
+
this.onRetryClick = () => {
|
|
166
|
+
this.emit('lyra-retry', { id: this.resolvedId });
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
static { this.styles = [LyraElement.styles, styles]; }
|
|
170
|
+
get effectiveName() {
|
|
171
|
+
return this.file ? this.file.name : this.name;
|
|
172
|
+
}
|
|
173
|
+
get effectiveSize() {
|
|
174
|
+
return this.file ? this.file.size : this.size;
|
|
175
|
+
}
|
|
176
|
+
get effectiveMimeType() {
|
|
177
|
+
return this.file ? this.file.type : this.mimeType;
|
|
178
|
+
}
|
|
179
|
+
get resolvedId() {
|
|
180
|
+
if (this.id)
|
|
181
|
+
return this.id;
|
|
182
|
+
if (this.file)
|
|
183
|
+
return `${this.file.name}:${this.file.size}:${this.file.lastModified}`;
|
|
184
|
+
return this.fallbackId;
|
|
185
|
+
}
|
|
186
|
+
get hasNumericProgress() {
|
|
187
|
+
return this.status === 'uploading' && Number.isFinite(this.progress) && this.progress > 0;
|
|
188
|
+
}
|
|
189
|
+
get clampedProgress() {
|
|
190
|
+
return Math.min(100, Math.max(0, this.progress));
|
|
191
|
+
}
|
|
192
|
+
/** Returns (creating or reusing as needed) the object URL for `file`'s
|
|
193
|
+
* image thumbnail. Only ever called from `render()`, i.e. only once a
|
|
194
|
+
* thumbnail is actually about to be painted -- never eagerly from a
|
|
195
|
+
* `file`/`willUpdate`/`updated` property-change hook -- so a `file` that's
|
|
196
|
+
* reassigned several times before the next paint never creates URLs that
|
|
197
|
+
* are immediately thrown away unused. */
|
|
198
|
+
ensureObjectUrl(file) {
|
|
199
|
+
if (this.objectUrlFile === file && this.objectUrl)
|
|
200
|
+
return this.objectUrl;
|
|
201
|
+
this.revokeObjectUrl();
|
|
202
|
+
this.objectUrl = URL.createObjectURL(file);
|
|
203
|
+
this.objectUrlFile = file;
|
|
204
|
+
return this.objectUrl;
|
|
205
|
+
}
|
|
206
|
+
revokeObjectUrl() {
|
|
207
|
+
if (this.objectUrl)
|
|
208
|
+
URL.revokeObjectURL(this.objectUrl);
|
|
209
|
+
this.objectUrl = undefined;
|
|
210
|
+
this.objectUrlFile = undefined;
|
|
211
|
+
}
|
|
212
|
+
updated(changed) {
|
|
213
|
+
// `file` changed to a different object (including to `undefined`) since
|
|
214
|
+
// the URL currently held was created -- it no longer represents anything
|
|
215
|
+
// this chip still shows, so revoke it now rather than waiting for a
|
|
216
|
+
// render that may never again call `ensureObjectUrl()` (e.g. the new
|
|
217
|
+
// `file` isn't an image, or is unset).
|
|
218
|
+
if (changed.has('file') && this.objectUrlFile && this.objectUrlFile !== this.file) {
|
|
219
|
+
this.revokeObjectUrl();
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
disconnectedCallback() {
|
|
223
|
+
super.disconnectedCallback();
|
|
224
|
+
this.revokeObjectUrl();
|
|
225
|
+
}
|
|
226
|
+
renderThumbnail() {
|
|
227
|
+
if (this.file) {
|
|
228
|
+
return this.effectiveMimeType.startsWith('image/')
|
|
229
|
+
? html `<img src=${this.ensureObjectUrl(this.file)} alt="" />`
|
|
230
|
+
: html `${fileGlyph()}`;
|
|
231
|
+
}
|
|
232
|
+
// No `file`: `thumbnail-src` is used whenever present, regardless of
|
|
233
|
+
// `mime-type` -- a server-generated preview thumbnail (e.g. a rendered
|
|
234
|
+
// first page of a PDF) is itself always an image, independent of the
|
|
235
|
+
// *source* file's own MIME type.
|
|
236
|
+
return this.thumbnailSrc ? html `<img src=${this.thumbnailSrc} alt="" />` : html `${fileGlyph()}`;
|
|
237
|
+
}
|
|
238
|
+
render() {
|
|
239
|
+
const name = this.effectiveName;
|
|
240
|
+
const displayName = name || 'Untitled file';
|
|
241
|
+
// A `0`-byte size reads the same as "unknown" here (there's no prop to
|
|
242
|
+
// distinguish a genuinely empty file from a size that was simply never
|
|
243
|
+
// supplied) -- hide the part entirely rather than show a literal "0 B".
|
|
244
|
+
const sizeText = this.effectiveSize > 0 ? formatFileSize(this.effectiveSize) : '';
|
|
245
|
+
const text = statusText(this.status, this.progress);
|
|
246
|
+
const uploading = this.status === 'uploading';
|
|
247
|
+
return html `
|
|
248
|
+
<div part="base">
|
|
249
|
+
<span part="thumbnail" aria-hidden="true">${this.renderThumbnail()}</span>
|
|
250
|
+
<span part="meta">
|
|
251
|
+
<span part="name" title=${name || 'Untitled file'}>${displayName}</span>
|
|
252
|
+
<span part="size" ?hidden=${!sizeText}>${sizeText || nothing}</span>
|
|
253
|
+
<span part="status-text" ?hidden=${!text}>${text || nothing}</span>
|
|
254
|
+
</span>
|
|
255
|
+
${uploading
|
|
256
|
+
? this.hasNumericProgress
|
|
257
|
+
? html `
|
|
258
|
+
<div
|
|
259
|
+
part="progress"
|
|
260
|
+
role="progressbar"
|
|
261
|
+
aria-valuenow=${Math.round(this.clampedProgress)}
|
|
262
|
+
aria-valuemin="0"
|
|
263
|
+
aria-valuemax="100"
|
|
264
|
+
aria-label=${`Uploading ${displayName}`}
|
|
265
|
+
>
|
|
266
|
+
<div part="progress-fill" style=${`inline-size:${this.clampedProgress}%`}></div>
|
|
267
|
+
</div>
|
|
268
|
+
`
|
|
269
|
+
: html `<span part="spinner" role="status" aria-label=${`Uploading ${displayName}`}></span>`
|
|
270
|
+
: nothing}
|
|
271
|
+
${this.status === 'error'
|
|
272
|
+
? html `<button part="retry-button" type="button" aria-label=${`Retry ${displayName}`} @click=${this.onRetryClick}>
|
|
273
|
+
${retryIcon()}
|
|
274
|
+
</button>`
|
|
275
|
+
: nothing}
|
|
276
|
+
${this.removable
|
|
277
|
+
? html `<button part="remove-button" type="button" aria-label=${`Remove ${displayName}`} @click=${this.onRemoveClick}>
|
|
278
|
+
${closeIcon()}
|
|
279
|
+
</button>`
|
|
280
|
+
: nothing}
|
|
281
|
+
</div>
|
|
282
|
+
`;
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
__decorate([
|
|
286
|
+
property({ attribute: false })
|
|
287
|
+
], LyraAttachmentChip.prototype, "file", void 0);
|
|
288
|
+
__decorate([
|
|
289
|
+
property()
|
|
290
|
+
], LyraAttachmentChip.prototype, "name", void 0);
|
|
291
|
+
__decorate([
|
|
292
|
+
property({ type: Number })
|
|
293
|
+
], LyraAttachmentChip.prototype, "size", void 0);
|
|
294
|
+
__decorate([
|
|
295
|
+
property({ attribute: 'mime-type' })
|
|
296
|
+
], LyraAttachmentChip.prototype, "mimeType", void 0);
|
|
297
|
+
__decorate([
|
|
298
|
+
property({ attribute: 'thumbnail-src' })
|
|
299
|
+
], LyraAttachmentChip.prototype, "thumbnailSrc", void 0);
|
|
300
|
+
__decorate([
|
|
301
|
+
property({ reflect: true })
|
|
302
|
+
], LyraAttachmentChip.prototype, "status", void 0);
|
|
303
|
+
__decorate([
|
|
304
|
+
property({ type: Number })
|
|
305
|
+
], LyraAttachmentChip.prototype, "progress", void 0);
|
|
306
|
+
__decorate([
|
|
307
|
+
property({ type: Boolean, reflect: true })
|
|
308
|
+
], LyraAttachmentChip.prototype, "removable", void 0);
|
|
309
|
+
__decorate([
|
|
310
|
+
state()
|
|
311
|
+
], LyraAttachmentChip.prototype, "objectUrl", void 0);
|
|
312
|
+
defineElement('attachment-chip', LyraAttachmentChip);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const styles: import("lit").CSSResult;
|