@aceshooting/lyra-ui 1.2.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +98 -14
- package/custom-elements.json +30279 -12124
- package/dist/components/app-rail/app-rail-item.d.ts +30 -0
- package/dist/components/app-rail/app-rail-item.js +68 -0
- package/dist/components/app-rail/app-rail-item.styles.d.ts +1 -0
- package/dist/components/app-rail/app-rail-item.styles.js +65 -0
- package/dist/components/app-rail/app-rail.d.ts +168 -0
- package/dist/components/app-rail/app-rail.js +419 -0
- package/dist/components/app-rail/app-rail.styles.d.ts +1 -0
- package/dist/components/app-rail/app-rail.styles.js +128 -0
- package/dist/components/attachment-chip/attachment-chip.d.ts +141 -0
- package/dist/components/attachment-chip/attachment-chip.js +356 -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 +96 -0
- package/dist/components/attachment-trigger/attachment-trigger.js +270 -0
- package/dist/components/attachment-trigger/attachment-trigger.styles.d.ts +1 -0
- package/dist/components/attachment-trigger/attachment-trigger.styles.js +90 -0
- package/dist/components/chart/bar-chart.js +2 -18
- package/dist/components/chart/box-plot.d.ts +25 -1
- package/dist/components/chart/box-plot.js +147 -7
- package/dist/components/chart/box-plot.styles.js +13 -0
- package/dist/components/chart/bubble-chart.js +2 -18
- 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 +55 -12
- package/dist/components/chart/chart.js +247 -49
- package/dist/components/chart/doughnut-chart.js +2 -18
- package/dist/components/chart/histogram-bin.d.ts +7 -1
- package/dist/components/chart/histogram-bin.js +32 -14
- package/dist/components/chart/histogram.js +8 -16
- package/dist/components/chart/line-chart.js +2 -18
- package/dist/components/chart/lite-chart.d.ts +134 -3
- package/dist/components/chart/lite-chart.js +382 -67
- package/dist/components/chart/lite-chart.styles.js +9 -0
- package/dist/components/chart/pie-chart.js +2 -18
- package/dist/components/chart/polar-area-chart.js +2 -18
- package/dist/components/chart/radar-chart.js +2 -18
- package/dist/components/chart/scatter-chart.js +2 -18
- package/dist/components/chat-composer/chat-composer.d.ts +133 -0
- package/dist/components/chat-composer/chat-composer.js +366 -0
- package/dist/components/chat-composer/chat-composer.styles.d.ts +1 -0
- package/dist/components/chat-composer/chat-composer.styles.js +145 -0
- package/dist/components/chat-message/chat-message.d.ts +141 -0
- package/dist/components/chat-message/chat-message.js +331 -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 +117 -0
- package/dist/components/checkbox/checkbox.js +353 -0
- package/dist/components/checkbox/checkbox.styles.d.ts +1 -0
- package/dist/components/checkbox/checkbox.styles.js +77 -0
- package/dist/components/chip/chip-group.d.ts +56 -0
- package/dist/components/chip/chip-group.js +130 -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 +122 -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 +318 -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 +127 -0
- package/dist/components/code-block/code-block.js +382 -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 +87 -0
- package/dist/components/code-block/code-loader.js +142 -0
- package/dist/components/combobox/combobox.d.ts +65 -6
- package/dist/components/combobox/combobox.js +258 -48
- package/dist/components/combobox/combobox.styles.js +3 -3
- 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 +159 -0
- package/dist/components/context-meter/context-meter.styles.d.ts +1 -0
- package/dist/components/context-meter/context-meter.styles.js +114 -0
- package/dist/components/conversation-item/conversation-item.d.ts +125 -0
- package/dist/components/conversation-item/conversation-item.js +331 -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/calendar-core.d.ts +24 -0
- package/dist/components/date-picker/calendar-core.js +51 -4
- package/dist/components/date-picker/date-input.d.ts +100 -9
- package/dist/components/date-picker/date-input.js +383 -66
- package/dist/components/date-picker/date-picker.d.ts +35 -4
- package/dist/components/date-picker/date-picker.js +171 -44
- package/dist/components/dialog/confirm.d.ts +40 -0
- package/dist/components/dialog/confirm.js +76 -0
- package/dist/components/dialog/dialog.d.ts +129 -0
- package/dist/components/dialog/dialog.js +288 -0
- package/dist/components/dialog/dialog.styles.d.ts +1 -0
- package/dist/components/dialog/dialog.styles.js +96 -0
- package/dist/components/dock-panel/dock-panel.d.ts +142 -0
- package/dist/components/dock-panel/dock-panel.js +359 -0
- package/dist/components/dock-panel/dock-panel.styles.d.ts +1 -0
- package/dist/components/dock-panel/dock-panel.styles.js +159 -0
- package/dist/components/document-preview/document-preview.d.ts +143 -0
- package/dist/components/document-preview/document-preview.js +388 -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/empty/empty.d.ts +1 -2
- package/dist/components/empty/empty.js +18 -12
- package/dist/components/empty/empty.styles.js +0 -3
- package/dist/components/export-button/csv.js +1 -1
- package/dist/components/export-button/export-button.d.ts +12 -0
- package/dist/components/export-button/export-button.js +35 -5
- package/dist/components/export-button/export-button.styles.js +5 -1
- package/dist/components/file-input/accept.js +2 -0
- package/dist/components/file-input/file-input.d.ts +10 -1
- package/dist/components/file-input/file-input.js +36 -5
- package/dist/components/flag/flag.d.ts +29 -13
- package/dist/components/flag/flag.js +54 -14
- package/dist/components/flag/flag.styles.js +1 -1
- package/dist/components/flag/language-map.d.ts +4 -1
- package/dist/components/flag/language-map.js +6 -3
- package/dist/components/gauge/gauge.d.ts +10 -1
- package/dist/components/gauge/gauge.js +41 -13
- package/dist/components/generation-status/generation-status.d.ts +117 -0
- package/dist/components/generation-status/generation-status.js +327 -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/graph/graph.d.ts +37 -3
- package/dist/components/graph/graph.js +132 -20
- package/dist/components/heatmap/calendar-grid.d.ts +19 -7
- package/dist/components/heatmap/calendar-grid.js +42 -18
- package/dist/components/heatmap/heatmap-scale.d.ts +11 -1
- package/dist/components/heatmap/heatmap-scale.js +14 -2
- package/dist/components/heatmap/heatmap.d.ts +227 -12
- package/dist/components/heatmap/heatmap.js +488 -93
- package/dist/components/json-viewer/json-viewer.d.ts +70 -0
- package/dist/components/json-viewer/json-viewer.js +361 -0
- package/dist/components/json-viewer/json-viewer.styles.d.ts +1 -0
- package/dist/components/json-viewer/json-viewer.styles.js +177 -0
- package/dist/components/kbd/kbd.d.ts +77 -0
- package/dist/components/kbd/kbd.js +231 -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 +90 -0
- package/dist/components/live-region/live-region.js +189 -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 +32 -7
- package/dist/components/map/map.js +133 -32
- package/dist/components/markdown/markdown-loader.d.ts +58 -0
- package/dist/components/markdown/markdown-loader.js +77 -0
- package/dist/components/markdown/markdown.d.ts +119 -0
- package/dist/components/markdown/markdown.js +389 -0
- package/dist/components/markdown/markdown.styles.d.ts +1 -0
- package/dist/components/markdown/markdown.styles.js +88 -0
- package/dist/components/media-card/media-card.d.ts +130 -0
- package/dist/components/media-card/media-card.js +273 -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 +203 -0
- package/dist/components/mention-popover/mention-popover.js +493 -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 +91 -0
- package/dist/components/menu/menu-item.js +206 -0
- package/dist/components/menu/menu-item.styles.d.ts +1 -0
- package/dist/components/menu/menu-item.styles.js +75 -0
- package/dist/components/menu/menu.d.ts +167 -0
- package/dist/components/menu/menu.js +461 -0
- package/dist/components/menu/menu.styles.d.ts +1 -0
- package/dist/components/menu/menu.styles.js +67 -0
- package/dist/components/model-select/model-select.d.ts +170 -0
- package/dist/components/model-select/model-select.js +588 -0
- package/dist/components/model-select/model-select.styles.d.ts +1 -0
- package/dist/components/model-select/model-select.styles.js +203 -0
- package/dist/components/model-settings-panel/model-settings-panel.d.ts +93 -0
- package/dist/components/model-settings-panel/model-settings-panel.js +209 -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 +19 -3
- package/dist/components/playback/playback.js +109 -33
- package/dist/components/playback/playback.styles.js +6 -1
- package/dist/components/responsive-panel/responsive-panel.d.ts +163 -0
- package/dist/components/responsive-panel/responsive-panel.js +363 -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 +50 -0
- package/dist/components/result-card/result-card.js +89 -0
- package/dist/components/result-card/result-card.styles.d.ts +1 -0
- package/dist/components/result-card/result-card.styles.js +49 -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 +84 -4
- package/dist/components/select/select.js +251 -36
- package/dist/components/skeleton/skeleton.d.ts +3 -0
- package/dist/components/skeleton/skeleton.js +7 -1
- package/dist/components/skeleton/skeleton.styles.js +5 -4
- package/dist/components/slider/slider.d.ts +141 -0
- package/dist/components/slider/slider.js +467 -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 +104 -0
- package/dist/components/source-card/source-card.js +195 -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 +130 -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 +58 -20
- package/dist/components/split/split.d.ts +224 -5
- package/dist/components/split/split.js +617 -43
- package/dist/components/split/split.styles.js +47 -0
- package/dist/components/stat/stat.d.ts +15 -4
- package/dist/components/stat/stat.js +53 -12
- package/dist/components/stream-status/stream-status.d.ts +126 -0
- package/dist/components/stream-status/stream-status.js +292 -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 +104 -0
- package/dist/components/streaming-text/streaming-text.js +224 -0
- package/dist/components/streaming-text/streaming-text.styles.d.ts +1 -0
- package/dist/components/streaming-text/streaming-text.styles.js +63 -0
- package/dist/components/switch/switch.d.ts +103 -0
- package/dist/components/switch/switch.js +250 -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 +89 -5
- package/dist/components/table/table.js +243 -26
- package/dist/components/table/table.styles.js +6 -1
- package/dist/components/tabs/tabs.d.ts +74 -0
- package/dist/components/tabs/tabs.js +254 -0
- package/dist/components/tabs/tabs.styles.d.ts +1 -0
- package/dist/components/tabs/tabs.styles.js +74 -0
- package/dist/components/thinking-panel/thinking-panel.d.ts +123 -0
- package/dist/components/thinking-panel/thinking-panel.js +260 -0
- package/dist/components/thinking-panel/thinking-panel.styles.d.ts +1 -0
- package/dist/components/thinking-panel/thinking-panel.styles.js +123 -0
- package/dist/components/time-range/time-range.d.ts +59 -2
- package/dist/components/time-range/time-range.js +163 -67
- package/dist/components/toast/toast-item.d.ts +12 -2
- package/dist/components/toast/toast-item.js +106 -44
- package/dist/components/toast/toast-item.styles.js +59 -28
- package/dist/components/toast/toast.js +17 -5
- package/dist/components/toast/toaster.js +10 -1
- package/dist/components/tool-approval-dialog/tool-approval-dialog.d.ts +131 -0
- package/dist/components/tool-approval-dialog/tool-approval-dialog.js +329 -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 +105 -0
- package/dist/components/tool-call-chip/tool-call-chip.js +349 -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 +206 -0
- package/dist/components/tool-param-form/tool-param-form.js +610 -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 +122 -0
- package/dist/components/tool-result-dialog/tool-result-dialog.js +358 -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 +73 -0
- package/dist/components/tool-result-view/registry.js +89 -0
- package/dist/components/tool-result-view/tool-result-view.d.ts +58 -0
- package/dist/components/tool-result-view/tool-result-view.js +152 -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 +350 -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 +191 -0
- package/dist/components/tree/tree-node.d.ts +15 -3
- package/dist/components/tree/tree-node.js +20 -7
- package/dist/components/tree/tree.d.ts +25 -10
- package/dist/components/tree/tree.js +39 -31
- package/dist/components/typing-indicator/typing-indicator.d.ts +70 -0
- package/dist/components/typing-indicator/typing-indicator.js +108 -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 +210 -0
- package/dist/components/virtual-list/virtual-list.js +607 -0
- package/dist/components/virtual-list/virtual-list.styles.d.ts +1 -0
- package/dist/components/virtual-list/virtual-list.styles.js +56 -0
- package/dist/components/widget/widget.d.ts +5 -4
- package/dist/components/widget/widget.js +54 -120
- package/dist/components/widget/widget.styles.js +8 -2
- package/dist/components/word-cloud/word-cloud-layout.d.ts +7 -0
- package/dist/components/word-cloud/word-cloud-layout.js +29 -2
- package/dist/components/word-cloud/word-cloud.d.ts +28 -2
- package/dist/components/word-cloud/word-cloud.js +69 -19
- package/dist/components/word-cloud/word-cloud.styles.js +16 -3
- package/dist/internal/anchored-validity.d.ts +1 -0
- package/dist/internal/anchored-validity.js +86 -0
- package/dist/internal/announcer.d.ts +57 -0
- package/dist/internal/announcer.js +71 -0
- package/dist/internal/form-associated.d.ts +8 -0
- package/dist/internal/form-associated.js +98 -15
- package/dist/internal/group-by-recency.d.ts +50 -0
- package/dist/internal/group-by-recency.js +80 -0
- package/dist/internal/numbers.d.ts +12 -0
- package/dist/internal/numbers.js +26 -0
- package/dist/internal/overlay-manager.d.ts +51 -0
- package/dist/internal/overlay-manager.js +523 -0
- package/dist/internal/positioner.js +27 -3
- package/dist/internal/rtl.d.ts +23 -0
- package/dist/internal/rtl.js +28 -0
- package/dist/internal/safe-url.d.ts +12 -0
- package/dist/internal/safe-url.js +41 -0
- package/dist/internal/scroll-lock.d.ts +10 -5
- package/dist/internal/scroll-lock.js +30 -14
- package/dist/internal/tokens.styles.js +22 -10
- package/dist/lyra.d.ts +133 -31
- package/dist/lyra.js +96 -26
- package/llms-full.txt +4546 -183
- package/llms.txt +21 -5
- package/package.json +41 -6
- 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,389 @@
|
|
|
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 } from 'lit';
|
|
8
|
+
import { property, state } from 'lit/decorators.js';
|
|
9
|
+
import { unsafeHTML } from 'lit/directives/unsafe-html.js';
|
|
10
|
+
import { LyraElement } from '../../internal/lyra-element.js';
|
|
11
|
+
import { defineElement } from '../../internal/prefix.js';
|
|
12
|
+
import { loadMarkdownDeps, getMarkdownDepsIfLoaded } from './markdown-loader.js';
|
|
13
|
+
import { styles } from './markdown.styles.js';
|
|
14
|
+
const HTML_ESCAPES = {
|
|
15
|
+
'&': '&',
|
|
16
|
+
'<': '<',
|
|
17
|
+
'>': '>',
|
|
18
|
+
'"': '"',
|
|
19
|
+
"'": ''',
|
|
20
|
+
};
|
|
21
|
+
function escapeHtml(text) {
|
|
22
|
+
return text.replace(/[&<>"']/g, (ch) => HTML_ESCAPES[ch] ?? ch);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Mirrors marked's own default `link()` renderer's `cleanUrl()`: a malformed
|
|
26
|
+
* percent-escape or lone UTF-16 surrogate in the raw href throws inside
|
|
27
|
+
* `encodeURI`, and marked's default renderer responds by dropping the anchor
|
|
28
|
+
* (rendering the link text alone) rather than emitting a broken `href` —
|
|
29
|
+
* returning `null` here lets the caller do the same. The
|
|
30
|
+
* `.replace(/%25/g, '%')` compensates for `encodeURI` re-escaping the `%` of
|
|
31
|
+
* an href that was already percent-encoded (the common case for a real
|
|
32
|
+
* markdown link) — without it, every existing `%XX` escape would become
|
|
33
|
+
* `%25XX`, double-encoding it.
|
|
34
|
+
*/
|
|
35
|
+
function cleanHref(href) {
|
|
36
|
+
try {
|
|
37
|
+
return encodeURI(href).replace(/%25/g, '%');
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* `<lyra-markdown>` — sanitized Markdown-to-HTML rendering (GFM tables,
|
|
45
|
+
* fenced code blocks, links, blockquotes) built on the optional peer
|
|
46
|
+
* dependencies `marked` (parsing) and `dompurify` (sanitizing), both
|
|
47
|
+
* lazy-loaded via `markdown-loader.ts` on first connect.
|
|
48
|
+
*
|
|
49
|
+
* Rendering never ships unsanitized or broken markup silently:
|
|
50
|
+
* - If `marked` fails to load, or throws while parsing malformed input, the
|
|
51
|
+
* component falls back to plain text (`white-space: pre-wrap`, no HTML
|
|
52
|
+
* parsing at all) and fires `lyra-render-error`.
|
|
53
|
+
* - If `sanitize` is `true` (the default) and `dompurify` fails to load, the
|
|
54
|
+
* component *also* falls back to plain text + `lyra-render-error` — it
|
|
55
|
+
* never renders marked's raw HTML output when sanitization was requested
|
|
56
|
+
* (or defaulted to) but is unavailable, even though `marked` itself loaded
|
|
57
|
+
* fine.
|
|
58
|
+
* - If `sanitize` is explicitly `false`, marked's raw output renders as-is
|
|
59
|
+
* regardless of whether `dompurify` is installed — the consumer opted out
|
|
60
|
+
* of sanitization, so `dompurify`'s absence is irrelevant to that path.
|
|
61
|
+
*
|
|
62
|
+
* That same plain-text fallback rendering (`data-fallback` on the `content`
|
|
63
|
+
* part) is also, unconditionally and by default, a brief *transient* state on
|
|
64
|
+
* every connect, not just a failure path: `connectedCallback()`'s dynamic
|
|
65
|
+
* `import()` of `marked`/`dompurify` (see `markdown-loader.ts`) is
|
|
66
|
+
* asynchronous, so the very first paint of any `<lyra-markdown>` on a page
|
|
67
|
+
* shows plain text for at least one microtask — even when both peers are
|
|
68
|
+
* already installed and load without error — until that import resolves and
|
|
69
|
+
* a second render replaces it with the real Markdown output. Set
|
|
70
|
+
* `eager-load` to skip that window once the shared dependency cache is
|
|
71
|
+
* already warm; see that property's doc for exactly what "warm" requires.
|
|
72
|
+
*
|
|
73
|
+
* `heading`/`code`/`blockquote`/`table`/`link`/`image` tokens are rendered
|
|
74
|
+
* through a `marked` renderer override that injects `part="..."` attributes
|
|
75
|
+
* directly into the produced HTML — a single pass, not a second DOM walk
|
|
76
|
+
* after insertion.
|
|
77
|
+
*
|
|
78
|
+
* @customElement lyra-markdown
|
|
79
|
+
* @event lyra-link-click - Fired (and the click prevented) when a rendered
|
|
80
|
+
* link's `href` starts with `internal-link-prefix`. `detail: { href:
|
|
81
|
+
* string, internal: true }`. Ordinary external links navigate normally
|
|
82
|
+
* (in `link-target`) and never fire this event.
|
|
83
|
+
* @event lyra-render-error - Fired whenever rendering falls back to plain
|
|
84
|
+
* text. `detail: { error: unknown }`.
|
|
85
|
+
* @csspart content - The wrapper around the rendered (or plain-text
|
|
86
|
+
* fallback) output.
|
|
87
|
+
* @csspart heading - Every rendered `<h1>`–`<h6>` (shifted by
|
|
88
|
+
* `heading-offset`).
|
|
89
|
+
* @csspart code-block - Every rendered fenced/indented `<pre>`.
|
|
90
|
+
* @csspart link - Every rendered `<a>`.
|
|
91
|
+
* @csspart table - Every rendered `<table>`.
|
|
92
|
+
* @csspart blockquote - Every rendered `<blockquote>`.
|
|
93
|
+
* @csspart img - Every rendered `<img>`.
|
|
94
|
+
*/
|
|
95
|
+
export class LyraMarkdown extends LyraElement {
|
|
96
|
+
constructor() {
|
|
97
|
+
super(...arguments);
|
|
98
|
+
/** The Markdown source to render. */
|
|
99
|
+
this.content = '';
|
|
100
|
+
/** Sanitize marked's HTML output with DOMPurify before rendering. See the
|
|
101
|
+
* class doc for what happens when this is `true` (the default) but the
|
|
102
|
+
* `dompurify` peer isn't installed. */
|
|
103
|
+
this.sanitize = true;
|
|
104
|
+
/** Enable GitHub-flavored Markdown (tables, strikethrough, autolinks, task lists). */
|
|
105
|
+
this.gfm = true;
|
|
106
|
+
/** `target` applied to every rendered `<a>`, with `rel="noopener
|
|
107
|
+
* noreferrer"` always added alongside it whenever a `target` is emitted.
|
|
108
|
+
* `'_blank'` (the default) preserves today's exact output. Set to `null`
|
|
109
|
+
* (or the empty string, e.g. via the `link-target=""` attribute) to omit
|
|
110
|
+
* `target`/`rel` entirely, so rendered links open in the same tab. */
|
|
111
|
+
this.linkTarget = '_blank';
|
|
112
|
+
/** When set, a rendered link whose `href` starts with this prefix is
|
|
113
|
+
* treated as internal — its click is intercepted and reported via
|
|
114
|
+
* `lyra-link-click` instead of navigating. Empty (the default) means
|
|
115
|
+
* every link is treated as external. */
|
|
116
|
+
this.internalLinkPrefix = '';
|
|
117
|
+
/** Added to every rendered heading's source `token.depth` before emitting
|
|
118
|
+
* `<h${depth}>` — e.g. `heading-offset="2"` renders a source `#` as
|
|
119
|
+
* `<h3>` and a source `##` as `<h4>`. The result is clamped to `[1, 6]`
|
|
120
|
+
* (a source `######` with a positive offset stays at `<h6>` rather than
|
|
121
|
+
* overflowing past the HTML heading levels; the floor at `1` is
|
|
122
|
+
* defensive, since this property is meant to be additive-only). `0`
|
|
123
|
+
* (the default) preserves today's exact `<h${token.depth}>` output. */
|
|
124
|
+
this.headingOffset = 0;
|
|
125
|
+
/** When `true`, `connectedCallback()` skips awaiting `loadMarkdownDeps()`'s
|
|
126
|
+
* dynamic `import()` if the shared `marked`/`dompurify` module cache (see
|
|
127
|
+
* `markdown-loader.ts`'s `getMarkdownDepsIfLoaded()`) has *already*
|
|
128
|
+
* resolved — e.g. because an earlier `<lyra-markdown>` instance on the
|
|
129
|
+
* page already finished loading, or the consumer primed the cache
|
|
130
|
+
* directly by calling `loadMarkdownDeps()` themselves at startup — and
|
|
131
|
+
* renders synchronously instead. When the cache isn't warm yet (most
|
|
132
|
+
* notably: the very first `<lyra-markdown>` ever connected on a page,
|
|
133
|
+
* since nothing has called `loadMarkdownDeps()` before it), this still
|
|
134
|
+
* falls back to the normal async path — a dynamic `import()` can't be
|
|
135
|
+
* made synchronous, so this is a fast path for the common "already warm"
|
|
136
|
+
* case, not a hard guarantee. `false` (the default) is byte-identical to
|
|
137
|
+
* today: always the async `import()`, fallback-text window included. */
|
|
138
|
+
this.eagerLoad = false;
|
|
139
|
+
/** Forward-compatible hint for a dedicated streaming renderer expected to
|
|
140
|
+
* build on this component later (coalescing partial tokens as they
|
|
141
|
+
* arrive) — setting it has no rendering effect yet. Reflects so a
|
|
142
|
+
* consumer can already target `lyra-markdown[streaming]` in CSS ahead of
|
|
143
|
+
* that behavior landing. */
|
|
144
|
+
this.streaming = false;
|
|
145
|
+
// `null` covers both "the optional peers are still loading" and "a render
|
|
146
|
+
// attempt just fell back after a failure" — the two states intentionally
|
|
147
|
+
// look identical (plain text, see render()) since a consumer distinguishes
|
|
148
|
+
// them via `lyra-render-error`, not a visual difference.
|
|
149
|
+
this.renderedHtml = null;
|
|
150
|
+
// A single delegated listener on the content wrapper (not one per <a>) —
|
|
151
|
+
// the rendered markup is fully replaced on every content change, so a
|
|
152
|
+
// per-anchor listener would need re-attaching on every render anyway.
|
|
153
|
+
this.onContentClick = (e) => {
|
|
154
|
+
const prefix = this.internalLinkPrefix;
|
|
155
|
+
if (!prefix)
|
|
156
|
+
return;
|
|
157
|
+
const anchor = e.composedPath().find((el) => el instanceof HTMLAnchorElement);
|
|
158
|
+
if (!anchor)
|
|
159
|
+
return;
|
|
160
|
+
// Compared against the raw `href` *attribute*, not the `.href` IDL
|
|
161
|
+
// property — the property is always browser-resolved to an absolute URL
|
|
162
|
+
// (e.g. "https://example.com/docs") even for a relative/prefixed path,
|
|
163
|
+
// which would never match a relative `internal-link-prefix`.
|
|
164
|
+
const href = anchor.getAttribute('href') ?? '';
|
|
165
|
+
if (!href.startsWith(prefix))
|
|
166
|
+
return;
|
|
167
|
+
e.preventDefault();
|
|
168
|
+
this.emit('lyra-link-click', { href, internal: true });
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
static { this.styles = [LyraElement.styles, styles]; }
|
|
172
|
+
connectedCallback() {
|
|
173
|
+
super.connectedCallback();
|
|
174
|
+
if (this.eagerLoad) {
|
|
175
|
+
// Only takes this synchronous path when the shared module cache has
|
|
176
|
+
// *already* settled (see getMarkdownDepsIfLoaded()'s doc) -- otherwise
|
|
177
|
+
// falls through to the same async path as the default below, since a
|
|
178
|
+
// dynamic import() can't be made synchronous from scratch.
|
|
179
|
+
const alreadyLoaded = getMarkdownDepsIfLoaded();
|
|
180
|
+
if (alreadyLoaded) {
|
|
181
|
+
this.deps = alreadyLoaded;
|
|
182
|
+
this.renderMarkdown();
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
void loadMarkdownDeps().then((resolved) => {
|
|
187
|
+
// The (module-cached, page-lifetime) loadMarkdownDeps() promise can
|
|
188
|
+
// resolve after this instance was removed from the DOM -- e.g. an
|
|
189
|
+
// <lyra-markdown> inside a conditionally-rendered chat message or a
|
|
190
|
+
// virtualized list. Without this guard, a detached instance would
|
|
191
|
+
// still have its `deps` set and renderMarkdown() called, mutating the
|
|
192
|
+
// @state() renderedHtml property and scheduling a Lit update no one
|
|
193
|
+
// will ever see. Mirrors chart.ts's own connectedCallback() guard for
|
|
194
|
+
// the identical race.
|
|
195
|
+
if (!this.isConnected)
|
|
196
|
+
return;
|
|
197
|
+
this.deps = resolved;
|
|
198
|
+
this.renderMarkdown();
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
// Runs before render (not updated()) so mutating the `renderedHtml` state
|
|
202
|
+
// property below is absorbed into the *same* update cycle instead of
|
|
203
|
+
// scheduling a second one -- Lit's documented pattern for deriving one
|
|
204
|
+
// reactive property from a change to others.
|
|
205
|
+
willUpdate(changed) {
|
|
206
|
+
if (!this.deps) {
|
|
207
|
+
// Still loading the optional peers — the connectedCallback promise
|
|
208
|
+
// above calls renderMarkdown() itself once they resolve, using
|
|
209
|
+
// whatever property values are current at that time.
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
if (changed.has('content') ||
|
|
213
|
+
changed.has('sanitize') ||
|
|
214
|
+
changed.has('gfm') ||
|
|
215
|
+
changed.has('linkTarget') ||
|
|
216
|
+
changed.has('headingOffset')) {
|
|
217
|
+
this.renderMarkdown();
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
updated() {
|
|
221
|
+
if (this.deps) {
|
|
222
|
+
this.removeAttribute('aria-busy');
|
|
223
|
+
}
|
|
224
|
+
else {
|
|
225
|
+
this.setAttribute('aria-busy', 'true');
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
renderMarkdown() {
|
|
229
|
+
const deps = this.deps;
|
|
230
|
+
if (!deps)
|
|
231
|
+
return;
|
|
232
|
+
if (!deps.marked) {
|
|
233
|
+
// markdown-loader.ts already logged the specific import failure.
|
|
234
|
+
this.applyFallback(new Error('<lyra-markdown> could not render: the "marked" peer dependency failed to load.'));
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
let rawHtml;
|
|
238
|
+
try {
|
|
239
|
+
rawHtml = this.parseMarkdown(deps.marked);
|
|
240
|
+
}
|
|
241
|
+
catch (error) {
|
|
242
|
+
this.applyFallback(error);
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
if (!this.sanitize) {
|
|
246
|
+
// Consumer explicitly opted out of sanitization — dompurify's
|
|
247
|
+
// presence or absence is irrelevant to this path.
|
|
248
|
+
this.renderedHtml = rawHtml;
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
if (!deps.DOMPurify) {
|
|
252
|
+
const error = new Error('<lyra-markdown> could not render: sanitize is enabled (the default) but the "dompurify" peer ' +
|
|
253
|
+
'dependency failed to load — refusing to render unsanitized HTML. Install it with `pnpm add ' +
|
|
254
|
+
'dompurify`, or set sanitize="false" to explicitly opt out of sanitization.');
|
|
255
|
+
console.warn(error.message);
|
|
256
|
+
this.applyFallback(error);
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
// `target` is not in DOMPurify's default attribute allowlist (unlike
|
|
260
|
+
// `part`/`rel`/`class`, which already are) — without ADD_ATTR here,
|
|
261
|
+
// every rendered link's target="..." would be silently stripped even
|
|
262
|
+
// though the anchor itself survives sanitization.
|
|
263
|
+
this.renderedHtml = deps.DOMPurify.sanitize(rawHtml, { ADD_ATTR: ['target'] });
|
|
264
|
+
}
|
|
265
|
+
applyFallback(error) {
|
|
266
|
+
this.renderedHtml = null;
|
|
267
|
+
this.emit('lyra-render-error', { error });
|
|
268
|
+
}
|
|
269
|
+
parseMarkdown(marked) {
|
|
270
|
+
// Falsy (`null` or `''`) means the consumer explicitly opted out of
|
|
271
|
+
// target="..."/rel="..." on rendered links -- see the linkTarget doc.
|
|
272
|
+
// The default '_blank' is already truthy, so this preserves today's
|
|
273
|
+
// exact output when the property is left unset.
|
|
274
|
+
const linkTarget = this.linkTarget;
|
|
275
|
+
const headingOffset = this.headingOffset;
|
|
276
|
+
const instance = new marked.Marked();
|
|
277
|
+
// A fresh renderer per parse (rather than a shared/cached one) so it
|
|
278
|
+
// always closes over the *current* `linkTarget`/`headingOffset` — these
|
|
279
|
+
// properties can change between renders, and marked's `.use()` otherwise
|
|
280
|
+
// persists whatever renderer it was given for the lifetime of the
|
|
281
|
+
// instance.
|
|
282
|
+
instance.use({
|
|
283
|
+
renderer: {
|
|
284
|
+
heading(token) {
|
|
285
|
+
// Clamped to [1, 6]: a positive offset can never push a heading
|
|
286
|
+
// past <h6> (there is no <h7>), and the floor at 1 is defensive
|
|
287
|
+
// since headingOffset is meant to be additive-only (0 is the only
|
|
288
|
+
// documented non-positive value).
|
|
289
|
+
const depth = Math.min(6, Math.max(1, token.depth + headingOffset));
|
|
290
|
+
return `<h${depth} part="heading">${this.parser.parseInline(token.tokens)}</h${depth}>\n`;
|
|
291
|
+
},
|
|
292
|
+
code(token) {
|
|
293
|
+
const lang = (token.lang ?? '').trim().split(/\s+/)[0] ?? '';
|
|
294
|
+
const body = `${token.text.replace(/\n$/, '')}\n`;
|
|
295
|
+
const text = token.escaped ? body : escapeHtml(body);
|
|
296
|
+
const cls = lang ? ` class="language-${escapeHtml(lang)}"` : '';
|
|
297
|
+
return `<pre part="code-block"><code${cls}>${text}</code></pre>\n`;
|
|
298
|
+
},
|
|
299
|
+
blockquote(token) {
|
|
300
|
+
return `<blockquote part="blockquote">\n${this.parser.parse(token.tokens)}</blockquote>\n`;
|
|
301
|
+
},
|
|
302
|
+
table(token) {
|
|
303
|
+
// Built directly here (rather than delegating to the inherited
|
|
304
|
+
// tablecell()) so a scope="col" can be added -- marked's own
|
|
305
|
+
// default tablecell() never emits it, and without it a screen
|
|
306
|
+
// reader can't reliably associate a data cell with its column
|
|
307
|
+
// header beyond the simplest table.
|
|
308
|
+
let headerRow = '';
|
|
309
|
+
for (const cell of token.header) {
|
|
310
|
+
const text = this.parser.parseInline(cell.tokens);
|
|
311
|
+
const alignAttr = cell.align ? ` align="${cell.align}"` : '';
|
|
312
|
+
headerRow += `<th scope="col"${alignAttr}>${text}</th>`;
|
|
313
|
+
}
|
|
314
|
+
let bodyRows = '';
|
|
315
|
+
for (const row of token.rows) {
|
|
316
|
+
let rowHtml = '';
|
|
317
|
+
for (const cell of row)
|
|
318
|
+
rowHtml += this.tablecell(cell);
|
|
319
|
+
bodyRows += this.tablerow({ text: rowHtml });
|
|
320
|
+
}
|
|
321
|
+
const thead = `<thead>\n${this.tablerow({ text: headerRow })}</thead>\n`;
|
|
322
|
+
const tbody = bodyRows ? `<tbody>${bodyRows}</tbody>\n` : '';
|
|
323
|
+
return `<table part="table">\n${thead}${tbody}</table>\n`;
|
|
324
|
+
},
|
|
325
|
+
link(token) {
|
|
326
|
+
const text = this.parser.parseInline(token.tokens);
|
|
327
|
+
const href = cleanHref(token.href);
|
|
328
|
+
if (href === null)
|
|
329
|
+
return text;
|
|
330
|
+
const titleAttr = token.title ? ` title="${escapeHtml(token.title)}"` : '';
|
|
331
|
+
const targetAttr = linkTarget
|
|
332
|
+
? ` target="${escapeHtml(linkTarget)}" rel="noopener noreferrer"`
|
|
333
|
+
: '';
|
|
334
|
+
return `<a part="link" href="${escapeHtml(href)}"${titleAttr}${targetAttr}>${text}</a>`;
|
|
335
|
+
},
|
|
336
|
+
image(token) {
|
|
337
|
+
// Mirrors marked's own default image() renderer (alt text
|
|
338
|
+
// re-rendered through the plain textRenderer so nested emphasis/
|
|
339
|
+
// strong/etc. inside the alt collapses to plain text, href run
|
|
340
|
+
// through the same cleanHref() the link() override above uses)
|
|
341
|
+
// with a part="img" added.
|
|
342
|
+
const altText = this.parser.parseInline(token.tokens, this.parser.textRenderer);
|
|
343
|
+
const href = cleanHref(token.href);
|
|
344
|
+
if (href === null)
|
|
345
|
+
return escapeHtml(altText);
|
|
346
|
+
const titleAttr = token.title ? ` title="${escapeHtml(token.title)}"` : '';
|
|
347
|
+
return `<img part="img" src="${escapeHtml(href)}" alt="${escapeHtml(altText)}"${titleAttr}>`;
|
|
348
|
+
},
|
|
349
|
+
},
|
|
350
|
+
});
|
|
351
|
+
return instance.parse(this.content, { gfm: this.gfm, async: false });
|
|
352
|
+
}
|
|
353
|
+
render() {
|
|
354
|
+
const isFallback = this.renderedHtml === null;
|
|
355
|
+
return html `
|
|
356
|
+
<div part="content" ?data-fallback=${isFallback} @click=${this.onContentClick}>
|
|
357
|
+
${isFallback ? this.content : unsafeHTML(this.renderedHtml)}
|
|
358
|
+
</div>
|
|
359
|
+
`;
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
__decorate([
|
|
363
|
+
property()
|
|
364
|
+
], LyraMarkdown.prototype, "content", void 0);
|
|
365
|
+
__decorate([
|
|
366
|
+
property({ type: Boolean })
|
|
367
|
+
], LyraMarkdown.prototype, "sanitize", void 0);
|
|
368
|
+
__decorate([
|
|
369
|
+
property({ type: Boolean })
|
|
370
|
+
], LyraMarkdown.prototype, "gfm", void 0);
|
|
371
|
+
__decorate([
|
|
372
|
+
property({ attribute: 'link-target' })
|
|
373
|
+
], LyraMarkdown.prototype, "linkTarget", void 0);
|
|
374
|
+
__decorate([
|
|
375
|
+
property({ attribute: 'internal-link-prefix' })
|
|
376
|
+
], LyraMarkdown.prototype, "internalLinkPrefix", void 0);
|
|
377
|
+
__decorate([
|
|
378
|
+
property({ type: Number, attribute: 'heading-offset' })
|
|
379
|
+
], LyraMarkdown.prototype, "headingOffset", void 0);
|
|
380
|
+
__decorate([
|
|
381
|
+
property({ type: Boolean, attribute: 'eager-load' })
|
|
382
|
+
], LyraMarkdown.prototype, "eagerLoad", void 0);
|
|
383
|
+
__decorate([
|
|
384
|
+
property({ type: Boolean, reflect: true })
|
|
385
|
+
], LyraMarkdown.prototype, "streaming", void 0);
|
|
386
|
+
__decorate([
|
|
387
|
+
state()
|
|
388
|
+
], LyraMarkdown.prototype, "renderedHtml", void 0);
|
|
389
|
+
defineElement('markdown', LyraMarkdown);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const styles: import("lit").CSSResult;
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { css } from 'lit';
|
|
2
|
+
export const styles = css `
|
|
3
|
+
:host {
|
|
4
|
+
display: block;
|
|
5
|
+
/* Contained here (rather than left as a bare font-family literal) so a
|
|
6
|
+
host page can retheme it -- same rationale as lyra-json-viewer's
|
|
7
|
+
identical --lyra-json-viewer-font, no shared --wa-*/--lyra-*
|
|
8
|
+
monospace token exists to resolve through. */
|
|
9
|
+
--lyra-markdown-font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
|
|
10
|
+
line-height: 1.6;
|
|
11
|
+
}
|
|
12
|
+
[part='content'] {
|
|
13
|
+
overflow-wrap: break-word;
|
|
14
|
+
}
|
|
15
|
+
/* Shared by both the "still loading" and "fell back after a failure"
|
|
16
|
+
states -- see the renderedHtml field doc in markdown.ts. */
|
|
17
|
+
[part='content'][data-fallback] {
|
|
18
|
+
white-space: pre-wrap;
|
|
19
|
+
font-family: inherit;
|
|
20
|
+
}
|
|
21
|
+
[part='content'] > :first-child {
|
|
22
|
+
margin-block-start: 0;
|
|
23
|
+
}
|
|
24
|
+
[part='content'] > :last-child {
|
|
25
|
+
margin-block-end: 0;
|
|
26
|
+
}
|
|
27
|
+
[part='heading'] {
|
|
28
|
+
line-height: 1.25;
|
|
29
|
+
margin-block: var(--lyra-space-l) var(--lyra-space-s);
|
|
30
|
+
}
|
|
31
|
+
[part='content'] p,
|
|
32
|
+
[part='content'] ul,
|
|
33
|
+
[part='content'] ol {
|
|
34
|
+
margin-block: 0 var(--lyra-space-s);
|
|
35
|
+
}
|
|
36
|
+
[part='content'] code {
|
|
37
|
+
font-family: var(--lyra-markdown-font-mono);
|
|
38
|
+
font-size: 0.875em;
|
|
39
|
+
background: var(--lyra-color-brand-quiet);
|
|
40
|
+
border-radius: calc(var(--lyra-radius) * 0.5);
|
|
41
|
+
padding: 0.125rem 0.3125rem;
|
|
42
|
+
}
|
|
43
|
+
[part='code-block'] {
|
|
44
|
+
margin-block: 0 var(--lyra-space-s);
|
|
45
|
+
padding: var(--lyra-space-s) var(--lyra-space-m);
|
|
46
|
+
border-radius: var(--lyra-radius);
|
|
47
|
+
background: var(--lyra-color-brand-quiet);
|
|
48
|
+
overflow-x: auto;
|
|
49
|
+
}
|
|
50
|
+
[part='code-block'] code {
|
|
51
|
+
padding: 0;
|
|
52
|
+
background: none;
|
|
53
|
+
font-size: 0.8125rem;
|
|
54
|
+
line-height: 1.5;
|
|
55
|
+
}
|
|
56
|
+
[part='link'] {
|
|
57
|
+
color: var(--lyra-color-brand);
|
|
58
|
+
text-underline-offset: 0.125rem;
|
|
59
|
+
}
|
|
60
|
+
/* Keeps an oversized source image from overflowing the content wrapper --
|
|
61
|
+
matches the overflow-wrap: break-word guard on [part='content'] above,
|
|
62
|
+
which only covers text, not replaced elements like <img>. */
|
|
63
|
+
[part='img'] {
|
|
64
|
+
max-width: 100%;
|
|
65
|
+
}
|
|
66
|
+
[part='blockquote'] {
|
|
67
|
+
margin-block: 0 var(--lyra-space-s);
|
|
68
|
+
margin-inline: 0;
|
|
69
|
+
padding-inline-start: var(--lyra-space-m);
|
|
70
|
+
border-inline-start: 3px solid var(--lyra-color-border);
|
|
71
|
+
color: var(--lyra-color-text-quiet);
|
|
72
|
+
}
|
|
73
|
+
[part='table'] {
|
|
74
|
+
border-collapse: collapse;
|
|
75
|
+
margin-block: 0 var(--lyra-space-s);
|
|
76
|
+
inline-size: 100%;
|
|
77
|
+
}
|
|
78
|
+
[part='table'] th,
|
|
79
|
+
[part='table'] td {
|
|
80
|
+
border: 1px solid var(--lyra-color-border);
|
|
81
|
+
padding: var(--lyra-space-xs) var(--lyra-space-s);
|
|
82
|
+
text-align: start;
|
|
83
|
+
}
|
|
84
|
+
[part='table'] th {
|
|
85
|
+
background: var(--lyra-color-brand-quiet);
|
|
86
|
+
font-weight: 600;
|
|
87
|
+
}
|
|
88
|
+
`;
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { type TemplateResult } from 'lit';
|
|
2
|
+
import { LyraElement } from '../../internal/lyra-element.js';
|
|
3
|
+
export type MediaCardKind = 'image' | 'video' | 'file';
|
|
4
|
+
export interface MediaCardOpenDetail {
|
|
5
|
+
src: string;
|
|
6
|
+
filename: string;
|
|
7
|
+
}
|
|
8
|
+
/** Validates `url` for an `<img>`/`<video>` source. Kept as a public wrapper
|
|
9
|
+
* so existing imports and generated API metadata remain stable. */
|
|
10
|
+
export declare function safeMediaSrc(url: string): string | null;
|
|
11
|
+
/** Validates `url` for the library's download/open link sinks. Kept as a
|
|
12
|
+
* public wrapper so existing imports and generated API metadata remain stable. */
|
|
13
|
+
export declare function safeLinkHref(url: string): string | null;
|
|
14
|
+
/**
|
|
15
|
+
* `<lyra-media-card>` — a lightweight inline preview for one already-sent,
|
|
16
|
+
* already-available attachment inside a rendered chat message body (e.g.
|
|
17
|
+
* plugged into `<lyra-chat-message>`'s `attachments` slot, or embedded
|
|
18
|
+
* directly by a markdown/message renderer). Distinct from two other,
|
|
19
|
+
* similarly-named components in this family: `<lyra-document-preview>` is a
|
|
20
|
+
* fuller viewer with header chrome and an async server-side-conversion
|
|
21
|
+
* state machine (`status="converting"`), and `<lyra-attachment-chip>` is a
|
|
22
|
+
* pre-send queued-file chip with upload progress. This component has
|
|
23
|
+
* neither concern — it only ever shows a `src` that's already final.
|
|
24
|
+
*
|
|
25
|
+
* **Format dispatch.** `kind` selects `'image'` (a plain `<img>`), `'video'`
|
|
26
|
+
* (a plain `<video controls>`), or `'file'` (an icon + filename chip with a
|
|
27
|
+
* download/open affordance). Leave `kind` unset to auto-detect from
|
|
28
|
+
* `mime-type` (`image/*` / `video/*` / anything else -> `'file'`);
|
|
29
|
+
* explicitly setting `kind` always wins over detection.
|
|
30
|
+
*
|
|
31
|
+
* **Safe-URL checking.** `src` is validated before it's ever assigned to an
|
|
32
|
+
* `<img>`/`<video>` `src` or an `<a href>` — only `http:`/`https:`/`blob:`
|
|
33
|
+
* (plus `data:` for a *media* `src` only) or a scheme-relative/relative URL
|
|
34
|
+
* with no scheme at all pass; anything else (`javascript:`, `vbscript:`,
|
|
35
|
+
* and similarly suspicious schemes) is rejected. `safeMediaSrc()` and
|
|
36
|
+
* `safeLinkHref()` share a platform-URL-based validator; their sink-specific
|
|
37
|
+
* allowlists explain why `data:` gets two different answers depending on
|
|
38
|
+
* where it is used. An `image`/`video` `kind` whose `src` fails the
|
|
39
|
+
* media-src check falls back to the generic file-chip rendering — this is
|
|
40
|
+
* the "plain preview unavailable state" a dangerous URL degrades to, rather
|
|
41
|
+
* than ever reaching a real media/anchor sink. That fallback also re-checks
|
|
42
|
+
* `src` against the stricter href allowlist for its own download affordance,
|
|
43
|
+
* but since the href allowlist is a strict subset of the media-src allowlist,
|
|
44
|
+
* that re-check can only ever change the outcome for a direct/auto-detected
|
|
45
|
+
* `kind="file"` `src` — an `image`/`video` `src` that already failed the
|
|
46
|
+
* wider media-src check necessarily fails the narrower href check too, so
|
|
47
|
+
* the fallback for those two kinds is always the plain, unclickable `span`.
|
|
48
|
+
*
|
|
49
|
+
* **The `video` case renders its open affordance separately from `base`.**
|
|
50
|
+
* `image`/`file` wrap their *entire* card in one native `<button>`/`<a>` —
|
|
51
|
+
* safe because an `<img>` and a plain icon+text chip have no interactive
|
|
52
|
+
* content of their own to conflict with. A `<video controls>` element is
|
|
53
|
+
* itself interactive content (its own play/seek/volume controls), and HTML
|
|
54
|
+
* forbids nesting interactive content inside a `<button>`/`<a>` — doing so
|
|
55
|
+
* anyway would also make every click on the video's own controls bubble up
|
|
56
|
+
* and spuriously fire `lyra-open`. So for `kind="video"`, `base` is a plain,
|
|
57
|
+
* non-interactive wrapper around `[part="media"]`, and a small separate
|
|
58
|
+
* `[part="open-button"]` (not one of this component's originally-scoped
|
|
59
|
+
* parts, added as the "explicit view/open affordance" the class is free to
|
|
60
|
+
* provide) is the thing that actually fires `lyra-open`.
|
|
61
|
+
*
|
|
62
|
+
* **Navigation.** This component never navigates on its own for `image`/
|
|
63
|
+
* `video` — activating the card only fires `lyra-open`; a host decides what
|
|
64
|
+
* "open" means (a lightbox, a new tab, whatever). The `file`-chip case is
|
|
65
|
+
* the one exception: when `src` passes the (stricter) href safety check, the
|
|
66
|
+
* chip is a real `<a href download>` so a bare drop-in still does something
|
|
67
|
+
* useful — but `lyra-open` fires first and is `cancelable`; a host that
|
|
68
|
+
* calls `preventDefault()` on it suppresses that default download/open so it
|
|
69
|
+
* can substitute its own handling instead.
|
|
70
|
+
*
|
|
71
|
+
* @customElement lyra-media-card
|
|
72
|
+
* @event lyra-open - The card (or, for `kind="video"`, its `open-button`)
|
|
73
|
+
* was activated. `detail: { src, filename }`. Cancelable — see the class
|
|
74
|
+
* doc's "Navigation" section for what calling `preventDefault()` on it does
|
|
75
|
+
* in the `file`-chip case.
|
|
76
|
+
* @csspart base - The root interactive/container element. A `<button>` for
|
|
77
|
+
* `kind="image"`, a plain wrapper `<div>` for `kind="video"`, and either an
|
|
78
|
+
* `<a>` (when `src` passes the href safety check) or a plain `<span>`
|
|
79
|
+
* (otherwise) for the `file`-chip fallback.
|
|
80
|
+
* @csspart media - The `<img>` or `<video>` element.
|
|
81
|
+
* @csspart file-icon - The generic file glyph, shown only in the file-chip fallback.
|
|
82
|
+
* @csspart filename - The filename text, shown only in the file-chip fallback.
|
|
83
|
+
* @csspart open-button - The explicit "open" affordance rendered next to
|
|
84
|
+
* `[part="media"]` for `kind="video"` only — see the class doc.
|
|
85
|
+
*/
|
|
86
|
+
export declare class LyraMediaCard extends LyraElement {
|
|
87
|
+
static styles: import("lit").CSSResultGroup[];
|
|
88
|
+
/** The media URL. Always re-validated against a safe-scheme allowlist
|
|
89
|
+
* before use — see the class doc. */
|
|
90
|
+
src: string;
|
|
91
|
+
/** Explicit format dispatch. Leave unset to auto-detect from `mime-type`. */
|
|
92
|
+
kind?: MediaCardKind;
|
|
93
|
+
/** Drives auto-detection when `kind` is unset. */
|
|
94
|
+
mimeType: string;
|
|
95
|
+
/** Shown in the file-chip fallback, used as the download link's suggested
|
|
96
|
+
* filename, and folded into the accessible name of the whole card. */
|
|
97
|
+
filename: string;
|
|
98
|
+
/** Alt text for the image case (and reused as a video label fallback).
|
|
99
|
+
* Falls back to `filename`, then a generic per-kind description. */
|
|
100
|
+
alt: string;
|
|
101
|
+
/** A CSS length (e.g. `"16rem"`); once set, overrides the
|
|
102
|
+
* `--lyra-media-card-max-height` custom property for this instance only —
|
|
103
|
+
* same contract as `<lyra-document-preview>`'s identically-named prop. */
|
|
104
|
+
maxHeight: string;
|
|
105
|
+
/** Effective kind used for rendering — `kind` if explicitly set,
|
|
106
|
+
* otherwise detected from `mime-type`. */
|
|
107
|
+
private get resolvedKind();
|
|
108
|
+
private get displayFilename();
|
|
109
|
+
/** Accessible name for the card's own actionable element (`base` or, for
|
|
110
|
+
* video, `open-button`) — always phrased as the action it performs. */
|
|
111
|
+
private get accessibleLabel();
|
|
112
|
+
private get imgAlt();
|
|
113
|
+
private get videoLabel();
|
|
114
|
+
/** Per-instance override for `--lyra-media-card-max-height`, applied
|
|
115
|
+
* inline on `[part="base"]` -- the only mechanism that reliably wins
|
|
116
|
+
* over the `:host{}`-declared default from outside the shadow root. */
|
|
117
|
+
private get baseStyle();
|
|
118
|
+
private emitOpen;
|
|
119
|
+
private onActivate;
|
|
120
|
+
private onLinkClick;
|
|
121
|
+
private renderImage;
|
|
122
|
+
private renderVideo;
|
|
123
|
+
private renderFileFallback;
|
|
124
|
+
render(): TemplateResult;
|
|
125
|
+
}
|
|
126
|
+
declare global {
|
|
127
|
+
interface HTMLElementTagNameMap {
|
|
128
|
+
'lyra-media-card': LyraMediaCard;
|
|
129
|
+
}
|
|
130
|
+
}
|