@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
|
@@ -42,18 +42,19 @@ export declare class LyraWidget extends LyraElement {
|
|
|
42
42
|
compact: boolean;
|
|
43
43
|
private hasActionsSlot;
|
|
44
44
|
private releaseScrollLock?;
|
|
45
|
-
private
|
|
45
|
+
private overlayHandle?;
|
|
46
|
+
private explicitTrigger?;
|
|
46
47
|
private readonly bodyId;
|
|
47
48
|
protected willUpdate(changed: PropertyValues): void;
|
|
48
49
|
protected updated(changed: PropertyValues): void;
|
|
49
50
|
connectedCallback(): void;
|
|
50
51
|
disconnectedCallback(): void;
|
|
52
|
+
private activateFullscreenOverlay;
|
|
53
|
+
private deactivateFullscreenOverlay;
|
|
51
54
|
private onActionsSlotChange;
|
|
52
55
|
private toggleCollapsed;
|
|
53
56
|
private toggleFullscreen;
|
|
54
|
-
private
|
|
55
|
-
private getFocusableElements;
|
|
56
|
-
private getActiveElement;
|
|
57
|
+
private dismissFullscreen;
|
|
57
58
|
private onBackdropClick;
|
|
58
59
|
render(): TemplateResult;
|
|
59
60
|
}
|
|
@@ -7,47 +7,12 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
7
7
|
import { html, nothing } from 'lit';
|
|
8
8
|
import { property, state } from 'lit/decorators.js';
|
|
9
9
|
import { LyraElement } from '../../internal/lyra-element.js';
|
|
10
|
+
import { activateOverlay, collectFocusableElements, deepActiveElement, } from '../../internal/overlay-manager.js';
|
|
10
11
|
import { defineElement } from '../../internal/prefix.js';
|
|
11
12
|
import { lockScroll } from '../../internal/scroll-lock.js';
|
|
12
13
|
import { nextId } from '../../internal/a11y.js';
|
|
13
14
|
import { chevronIcon, closeIcon, expandIcon } from '../../internal/icons.js';
|
|
14
15
|
import { styles } from './widget.styles.js';
|
|
15
|
-
const FOCUSABLE_SELECTOR = 'a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';
|
|
16
|
-
// Shadow-piercing so a slotted custom element's real focusable target (e.g.
|
|
17
|
-
// an <input> inside its own shadow root) is found even though the host tag
|
|
18
|
-
// itself doesn't match FOCUSABLE_SELECTOR.
|
|
19
|
-
function collectFocusable(el) {
|
|
20
|
-
const result = [];
|
|
21
|
-
if (el.matches(FOCUSABLE_SELECTOR)) {
|
|
22
|
-
result.push(el);
|
|
23
|
-
}
|
|
24
|
-
if (el instanceof HTMLSlotElement) {
|
|
25
|
-
for (const assigned of el.assignedElements({ flatten: true })) {
|
|
26
|
-
result.push(...collectFocusable(assigned));
|
|
27
|
-
}
|
|
28
|
-
return result;
|
|
29
|
-
}
|
|
30
|
-
const container = el.shadowRoot ?? el;
|
|
31
|
-
for (const child of Array.from(container.children)) {
|
|
32
|
-
result.push(...collectFocusable(child));
|
|
33
|
-
}
|
|
34
|
-
return result;
|
|
35
|
-
}
|
|
36
|
-
/**
|
|
37
|
-
* Whether `el` is actually laid out/paintable — used to drop e.g. a
|
|
38
|
-
* `[collapsed]` body's slotted content from the fullscreen tab order.
|
|
39
|
-
* `el.offsetParent !== null` is the usual shorthand for this, but it's
|
|
40
|
-
* unreliable here: it resolves `null` for an element whose nearest
|
|
41
|
-
* *positioned* ancestor (fullscreen's `[part="base"] { position: fixed }`)
|
|
42
|
-
* lives across a slot-projection boundary from the element itself (true for
|
|
43
|
-
* every element this scans, since they're all slotted content), even though
|
|
44
|
-
* the element is genuinely rendered. `checkVisibility()` (falling back to
|
|
45
|
-
* `getClientRects().length` on engines without it) correctly follows
|
|
46
|
-
* flattened-tree/slot assignment instead.
|
|
47
|
-
*/
|
|
48
|
-
function isRendered(el) {
|
|
49
|
-
return el.checkVisibility ? el.checkVisibility() : el.getClientRects().length > 0;
|
|
50
|
-
}
|
|
51
16
|
/**
|
|
52
17
|
* `<lyra-widget>` — a titled panel shell with an optional collapse toggle and
|
|
53
18
|
* an optional fullscreen-expand toggle. Fullscreen promotes the same host
|
|
@@ -99,48 +64,19 @@ export class LyraWidget extends LyraElement {
|
|
|
99
64
|
this.emit('lyra-collapse-change', this.collapsed);
|
|
100
65
|
};
|
|
101
66
|
this.toggleFullscreen = (e) => {
|
|
102
|
-
this.
|
|
67
|
+
if (!this.fullscreen)
|
|
68
|
+
this.explicitTrigger = e.currentTarget;
|
|
103
69
|
this.fullscreen = !this.fullscreen;
|
|
104
70
|
this.emit('lyra-fullscreen-change', this.fullscreen);
|
|
105
|
-
if (!this.fullscreen) {
|
|
106
|
-
this.lastTrigger?.focus();
|
|
107
|
-
}
|
|
108
71
|
};
|
|
109
|
-
this.
|
|
110
|
-
if (!this.fullscreen)
|
|
111
|
-
return;
|
|
112
|
-
if (e.key === 'Escape') {
|
|
113
|
-
e.preventDefault();
|
|
114
|
-
this.fullscreen = false;
|
|
115
|
-
this.emit('lyra-fullscreen-change', false);
|
|
116
|
-
this.lastTrigger?.focus();
|
|
117
|
-
return;
|
|
118
|
-
}
|
|
119
|
-
if (e.key !== 'Tab')
|
|
120
|
-
return;
|
|
121
|
-
const focusable = this.getFocusableElements();
|
|
122
|
-
if (focusable.length === 0) {
|
|
123
|
-
e.preventDefault();
|
|
124
|
-
return;
|
|
125
|
-
}
|
|
126
|
-
const first = focusable[0];
|
|
127
|
-
const last = focusable[focusable.length - 1];
|
|
128
|
-
const active = this.getActiveElement();
|
|
129
|
-
if (e.shiftKey && active === first) {
|
|
130
|
-
e.preventDefault();
|
|
131
|
-
last.focus();
|
|
132
|
-
}
|
|
133
|
-
else if (!e.shiftKey && active === last) {
|
|
134
|
-
e.preventDefault();
|
|
135
|
-
first.focus();
|
|
136
|
-
}
|
|
137
|
-
};
|
|
138
|
-
this.onBackdropClick = () => {
|
|
72
|
+
this.dismissFullscreen = () => {
|
|
139
73
|
if (!this.fullscreen)
|
|
140
74
|
return;
|
|
141
75
|
this.fullscreen = false;
|
|
142
76
|
this.emit('lyra-fullscreen-change', false);
|
|
143
|
-
|
|
77
|
+
};
|
|
78
|
+
this.onBackdropClick = () => {
|
|
79
|
+
this.overlayHandle?.dismissBackdrop();
|
|
144
80
|
};
|
|
145
81
|
}
|
|
146
82
|
static { this.styles = [LyraElement.styles, styles]; }
|
|
@@ -150,13 +86,10 @@ export class LyraWidget extends LyraElement {
|
|
|
150
86
|
}
|
|
151
87
|
if (changed.has('fullscreen')) {
|
|
152
88
|
if (this.fullscreen) {
|
|
153
|
-
this.
|
|
154
|
-
document.addEventListener('keydown', this.onDocKeyDown);
|
|
89
|
+
this.activateFullscreenOverlay();
|
|
155
90
|
}
|
|
156
91
|
else {
|
|
157
|
-
this.
|
|
158
|
-
this.releaseScrollLock = undefined;
|
|
159
|
-
document.removeEventListener('keydown', this.onDocKeyDown);
|
|
92
|
+
this.deactivateFullscreenOverlay();
|
|
160
93
|
}
|
|
161
94
|
}
|
|
162
95
|
}
|
|
@@ -167,14 +100,23 @@ export class LyraWidget extends LyraElement {
|
|
|
167
100
|
// because a mouse click natively focuses the button that triggered it --
|
|
168
101
|
// not true for a directly-set `fullscreen` property, and not guaranteed
|
|
169
102
|
// for every input method/browser even in the click case.
|
|
103
|
+
//
|
|
104
|
+
// The `collapsed` branch covers the same modal-focus-trap requirement for
|
|
105
|
+
// a second case: collapsing the body while fullscreen hides (display:none)
|
|
106
|
+
// whatever was focused inside it, which the browser resolves by silently
|
|
107
|
+
// moving focus outside the panel. The shared manager then reclaims it while
|
|
108
|
+
// preserving focus that is still on one of the visible header controls.
|
|
170
109
|
updated(changed) {
|
|
171
110
|
if (changed.has('fullscreen') && this.fullscreen) {
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
111
|
+
this.overlayHandle?.focusInitial();
|
|
112
|
+
}
|
|
113
|
+
else if (changed.has('collapsed') && this.fullscreen) {
|
|
114
|
+
const panel = this.shadowRoot?.querySelector('[part="base"]');
|
|
115
|
+
const active = deepActiveElement(this.ownerDocument);
|
|
116
|
+
if (panel && !collectFocusableElements(panel).includes(active)) {
|
|
117
|
+
if (active && typeof active.blur === 'function')
|
|
118
|
+
active.blur();
|
|
119
|
+
this.overlayHandle?.focusInitial();
|
|
178
120
|
}
|
|
179
121
|
}
|
|
180
122
|
}
|
|
@@ -183,49 +125,42 @@ export class LyraWidget extends LyraElement {
|
|
|
183
125
|
// A reconnect (e.g. a drag-and-drop reparent that keeps this same
|
|
184
126
|
// element instance) fires disconnectedCallback then connectedCallback
|
|
185
127
|
// synchronously with no update in between, so willUpdate never reruns
|
|
186
|
-
// to notice `fullscreen` is still true. Restore the
|
|
187
|
-
//
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
128
|
+
// to notice `fullscreen` is still true. Restore the shared overlay
|
|
129
|
+
// registration and scroll lock it dropped.
|
|
130
|
+
if (this.hasUpdated && this.fullscreen) {
|
|
131
|
+
if (this.overlayHandle?.isActive()) {
|
|
132
|
+
this.overlayHandle.resume();
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
this.activateFullscreenOverlay();
|
|
136
|
+
}
|
|
137
|
+
if (!this.releaseScrollLock)
|
|
138
|
+
this.releaseScrollLock = lockScroll(this.ownerDocument);
|
|
139
|
+
queueMicrotask(() => this.overlayHandle?.focusInitial());
|
|
192
140
|
}
|
|
193
141
|
}
|
|
194
142
|
disconnectedCallback() {
|
|
195
143
|
super.disconnectedCallback();
|
|
196
144
|
this.releaseScrollLock?.();
|
|
197
145
|
this.releaseScrollLock = undefined;
|
|
198
|
-
|
|
146
|
+
this.overlayHandle?.suspend();
|
|
199
147
|
}
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
const slot = root.querySelector(selector);
|
|
211
|
-
return slot ? slot.assignedElements({ flatten: true }).flatMap(collectFocusable) : [];
|
|
212
|
-
};
|
|
213
|
-
const shadowButtons = Array.from(root.querySelectorAll('[part="collapse-button"], [part="fullscreen-button"]'));
|
|
214
|
-
return [
|
|
215
|
-
...fromSlot('slot[name="actions"]'),
|
|
216
|
-
...shadowButtons,
|
|
217
|
-
...fromSlot('[part="body"] slot:not([name])'),
|
|
218
|
-
].filter(isRendered);
|
|
148
|
+
activateFullscreenOverlay() {
|
|
149
|
+
this.releaseScrollLock ??= lockScroll(this.ownerDocument);
|
|
150
|
+
this.overlayHandle = activateOverlay({
|
|
151
|
+
host: this,
|
|
152
|
+
panel: () => this.shadowRoot?.querySelector('[part="base"]') ?? null,
|
|
153
|
+
onEscape: this.dismissFullscreen,
|
|
154
|
+
onBackdrop: this.dismissFullscreen,
|
|
155
|
+
restoreFocusTo: this.explicitTrigger,
|
|
156
|
+
});
|
|
157
|
+
this.explicitTrigger = undefined;
|
|
219
158
|
}
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
break;
|
|
226
|
-
active = inner;
|
|
227
|
-
}
|
|
228
|
-
return active;
|
|
159
|
+
deactivateFullscreenOverlay() {
|
|
160
|
+
this.releaseScrollLock?.();
|
|
161
|
+
this.releaseScrollLock = undefined;
|
|
162
|
+
this.overlayHandle?.deactivate();
|
|
163
|
+
this.overlayHandle = undefined;
|
|
229
164
|
}
|
|
230
165
|
render() {
|
|
231
166
|
const hasLabel = this.label.length > 0;
|
|
@@ -261,11 +196,10 @@ export class LyraWidget extends LyraElement {
|
|
|
261
196
|
aria-expanded=${this.collapsed ? 'false' : 'true'}
|
|
262
197
|
aria-label=${this.collapsed ? 'Expand panel' : 'Collapse panel'}
|
|
263
198
|
aria-controls=${this.bodyId}
|
|
199
|
+
style="transform:rotate(${this.collapsed ? '0deg' : '90deg'})"
|
|
264
200
|
@click=${this.toggleCollapsed}
|
|
265
201
|
>
|
|
266
|
-
|
|
267
|
-
>${chevronIcon()}</span
|
|
268
|
-
>
|
|
202
|
+
${chevronIcon()}
|
|
269
203
|
</button>`
|
|
270
204
|
: nothing}
|
|
271
205
|
${this.expandable
|
|
@@ -29,6 +29,12 @@ export const styles = css `
|
|
|
29
29
|
flex: 1 1 auto;
|
|
30
30
|
min-inline-size: 0;
|
|
31
31
|
}
|
|
32
|
+
[part='label'],
|
|
33
|
+
[part='sublabel'] {
|
|
34
|
+
overflow: hidden;
|
|
35
|
+
text-overflow: ellipsis;
|
|
36
|
+
white-space: nowrap;
|
|
37
|
+
}
|
|
32
38
|
[part='label'] {
|
|
33
39
|
font-weight: 600;
|
|
34
40
|
}
|
|
@@ -80,12 +86,12 @@ export const styles = css `
|
|
|
80
86
|
position: fixed;
|
|
81
87
|
inset: var(--lyra-widget-fullscreen-inset, 0);
|
|
82
88
|
background: var(--lyra-widget-overlay-color);
|
|
83
|
-
z-index:
|
|
89
|
+
z-index: var(--lyra-overlay-stack-index, 1000);
|
|
84
90
|
}
|
|
85
91
|
:host([fullscreen]) [part='base'] {
|
|
86
92
|
position: fixed;
|
|
87
93
|
inset: var(--lyra-widget-fullscreen-inset);
|
|
88
|
-
z-index: 1000;
|
|
94
|
+
z-index: calc(var(--lyra-overlay-stack-index, 1000) + 1);
|
|
89
95
|
box-shadow: var(--lyra-shadow);
|
|
90
96
|
}
|
|
91
97
|
:host([fullscreen]) [part='body'] {
|
|
@@ -52,6 +52,13 @@ export interface WordCloudLayoutResult {
|
|
|
52
52
|
}
|
|
53
53
|
/** DOM-node/compute-time safety cap — mirrors lyra-sparkline's `MAX_BARS`. */
|
|
54
54
|
export declare const MAX_WORDS = 150;
|
|
55
|
+
/** Largest accepted font size in CSS pixels. This keeps measurement and
|
|
56
|
+
* placement geometry finite enough for an interactive render even when a
|
|
57
|
+
* caller supplies an otherwise-valid but impractically large number. */
|
|
58
|
+
export declare const MAX_FONT_SIZE_PX = 512;
|
|
59
|
+
/** Maximum number of candidate positions tested for any one word. Together
|
|
60
|
+
* with `MAX_WORDS`, this puts a hard upper bound on spiral-search work. */
|
|
61
|
+
export declare const MAX_SPIRAL_ITERATIONS = 4096;
|
|
55
62
|
/** Minimum gap enforced both between placed words and around the returned bounding box. */
|
|
56
63
|
export declare const GAP = 3;
|
|
57
64
|
/**
|
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
/** DOM-node/compute-time safety cap — mirrors lyra-sparkline's `MAX_BARS`. */
|
|
2
2
|
export const MAX_WORDS = 150;
|
|
3
|
+
/** Largest accepted font size in CSS pixels. This keeps measurement and
|
|
4
|
+
* placement geometry finite enough for an interactive render even when a
|
|
5
|
+
* caller supplies an otherwise-valid but impractically large number. */
|
|
6
|
+
export const MAX_FONT_SIZE_PX = 512;
|
|
7
|
+
/** Maximum number of candidate positions tested for any one word. Together
|
|
8
|
+
* with `MAX_WORDS`, this puts a hard upper bound on spiral-search work. */
|
|
9
|
+
export const MAX_SPIRAL_ITERATIONS = 4096;
|
|
3
10
|
/** Minimum gap enforced both between placed words and around the returned bounding box. */
|
|
4
11
|
export const GAP = 3;
|
|
5
12
|
const ROTATE_PROBABILITY = 0.25;
|
|
@@ -9,6 +16,23 @@ const RADIUS_STEP_PER_RADIAN = 3;
|
|
|
9
16
|
* generous enough that only a pathological input (e.g. one giant word
|
|
10
17
|
* repeated many times) ever exhausts it. */
|
|
11
18
|
const MAX_RADIUS_AREA_FACTOR = 6;
|
|
19
|
+
/** Fallback used by `resolveFontSizeBounds()` for any non-finite/non-positive
|
|
20
|
+
* `minFontSize`/`maxFontSize` input. */
|
|
21
|
+
const MIN_SANE_FONT_SIZE = 1;
|
|
22
|
+
/** Normalizes possibly-invalid minFontSize/maxFontSize into a finite,
|
|
23
|
+
* positive, bounded, correctly-ordered pair — non-finite/negative inputs
|
|
24
|
+
* fall back to MIN_SANE_FONT_SIZE, huge finite values are capped, and a
|
|
25
|
+
* reversed pair (max < min) is swapped rather than left to invert the
|
|
26
|
+
* weight-to-size mapping. */
|
|
27
|
+
function resolveFontSizeBounds(minFontSize, maxFontSize) {
|
|
28
|
+
const min = Number.isFinite(minFontSize) && minFontSize > 0
|
|
29
|
+
? Math.min(minFontSize, MAX_FONT_SIZE_PX)
|
|
30
|
+
: MIN_SANE_FONT_SIZE;
|
|
31
|
+
const max = Number.isFinite(maxFontSize) && maxFontSize > 0
|
|
32
|
+
? Math.min(maxFontSize, MAX_FONT_SIZE_PX)
|
|
33
|
+
: MIN_SANE_FONT_SIZE;
|
|
34
|
+
return min <= max ? [min, max] : [max, min];
|
|
35
|
+
}
|
|
12
36
|
/** Clamps a (possibly negative/non-finite) input weight for scale math only —
|
|
13
37
|
* never fed back to callers, who should still see their own original `weight`. */
|
|
14
38
|
function effectiveWeight(weight) {
|
|
@@ -29,7 +53,8 @@ function rectsOverlap(ax, ay, aw, ah, bx, by, bw, bh) {
|
|
|
29
53
|
* any word already placed). Deterministic given a deterministic `random`.
|
|
30
54
|
*/
|
|
31
55
|
export function layoutWordCloud(words, options) {
|
|
32
|
-
const {
|
|
56
|
+
const { scale, orientations, measureText } = options;
|
|
57
|
+
const [minFontSize, maxFontSize] = resolveFontSizeBounds(options.minFontSize, options.maxFontSize);
|
|
33
58
|
const random = options.random ?? Math.random;
|
|
34
59
|
const skipped = [];
|
|
35
60
|
const decorated = words
|
|
@@ -76,7 +101,9 @@ export function layoutWordCloud(words, options) {
|
|
|
76
101
|
let x = 0;
|
|
77
102
|
let y = 0;
|
|
78
103
|
let foundSpot = placed.length === 0;
|
|
79
|
-
|
|
104
|
+
let iterations = 0;
|
|
105
|
+
while (!foundSpot && radius < maxRadius && iterations < MAX_SPIRAL_ITERATIONS) {
|
|
106
|
+
iterations++;
|
|
80
107
|
x = radius * Math.cos(theta);
|
|
81
108
|
y = radius * Math.sin(theta);
|
|
82
109
|
let collides = false;
|
|
@@ -16,12 +16,19 @@ export type { WordCloudWord };
|
|
|
16
16
|
* Instead, like `lyra-heatmap`'s cells, the whole `[part="svg"]` is one tab
|
|
17
17
|
* stop with roving arrow-key focus (Home/End jump to the first/last word,
|
|
18
18
|
* Enter/Space activates the focused one), a drawn `[part="focus-ring"]`, and
|
|
19
|
-
* a visually-hidden `aria-live="polite"` status announcement.
|
|
19
|
+
* a visually-hidden `aria-live="polite"` status announcement. The SVG focus
|
|
20
|
+
* target carries the group role and accessible name so the semantics follow
|
|
21
|
+
* the element a keyboard user actually focuses.
|
|
20
22
|
*
|
|
21
23
|
* @customElement lyra-word-cloud
|
|
22
24
|
* @event lyra-word-click - Fired on click, or Enter/Space on the focused word.
|
|
23
25
|
* `detail: { text, weight, group }`.
|
|
24
|
-
* @csspart base
|
|
26
|
+
* @csspart base - The word-cloud wrapper.
|
|
27
|
+
* @csspart svg - The word-cloud SVG.
|
|
28
|
+
* @csspart word - A rendered word.
|
|
29
|
+
* @csspart focus-ring - The keyboard focus ring.
|
|
30
|
+
* @csspart live-region - The visually hidden announcement region.
|
|
31
|
+
* @csspart empty - The empty-state message.
|
|
25
32
|
*/
|
|
26
33
|
export declare class LyraWordCloud extends LyraElement {
|
|
27
34
|
static styles: import("lit").CSSResultGroup[];
|
|
@@ -43,6 +50,19 @@ export declare class LyraWordCloud extends LyraElement {
|
|
|
43
50
|
private focusedIndex;
|
|
44
51
|
/** Text of the visually-hidden `aria-live="polite"` status announcement. */
|
|
45
52
|
private liveText;
|
|
53
|
+
/**
|
|
54
|
+
* Whether `role`/`aria-label` were present on the host *before* this
|
|
55
|
+
* element's own code ever wrote to them -- snapshotted once, in the very
|
|
56
|
+
* first `willUpdate()` (guarded by `hasUpdated`, which Lit only flips to
|
|
57
|
+
* `true` after that first update commits). Re-checking `hasAttribute()` on
|
|
58
|
+
* every update instead would self-poison: once this element writes its own
|
|
59
|
+
* default `aria-label` on the first render, `hasAttribute('aria-label')` is
|
|
60
|
+
* permanently `true` afterwards, which would wrongly look like an
|
|
61
|
+
* author-supplied value and freeze the label instead of refreshing it as
|
|
62
|
+
* `words` changes on later updates.
|
|
63
|
+
*/
|
|
64
|
+
private authorSuppliedRole;
|
|
65
|
+
private authorSuppliedAriaLabel;
|
|
46
66
|
private measureText;
|
|
47
67
|
private fontFamily;
|
|
48
68
|
private paletteColors;
|
|
@@ -50,6 +70,12 @@ export declare class LyraWordCloud extends LyraElement {
|
|
|
50
70
|
* independent of the weight-sorted placement order. */
|
|
51
71
|
private navOrder;
|
|
52
72
|
protected willUpdate(changed: PropertyValues): void;
|
|
73
|
+
private relayout;
|
|
74
|
+
/** Forces a relayout so the font-family theme token (`--lyra-font`) is
|
|
75
|
+
* re-read from computed style — mirrors `lyra-chart`'s `refreshTheme()`.
|
|
76
|
+
* No global theme-broadcast event exists in lyra-ui to subscribe to
|
|
77
|
+
* automatically; call this from a consumer's own theme-toggle handler. */
|
|
78
|
+
refreshTheme(): void;
|
|
53
79
|
private activate;
|
|
54
80
|
private announce;
|
|
55
81
|
private onWordClick;
|
|
@@ -53,12 +53,19 @@ function warnSkippedWords(count) {
|
|
|
53
53
|
* Instead, like `lyra-heatmap`'s cells, the whole `[part="svg"]` is one tab
|
|
54
54
|
* stop with roving arrow-key focus (Home/End jump to the first/last word,
|
|
55
55
|
* Enter/Space activates the focused one), a drawn `[part="focus-ring"]`, and
|
|
56
|
-
* a visually-hidden `aria-live="polite"` status announcement.
|
|
56
|
+
* a visually-hidden `aria-live="polite"` status announcement. The SVG focus
|
|
57
|
+
* target carries the group role and accessible name so the semantics follow
|
|
58
|
+
* the element a keyboard user actually focuses.
|
|
57
59
|
*
|
|
58
60
|
* @customElement lyra-word-cloud
|
|
59
61
|
* @event lyra-word-click - Fired on click, or Enter/Space on the focused word.
|
|
60
62
|
* `detail: { text, weight, group }`.
|
|
61
|
-
* @csspart base
|
|
63
|
+
* @csspart base - The word-cloud wrapper.
|
|
64
|
+
* @csspart svg - The word-cloud SVG.
|
|
65
|
+
* @csspart word - A rendered word.
|
|
66
|
+
* @csspart focus-ring - The keyboard focus ring.
|
|
67
|
+
* @csspart live-region - The visually hidden announcement region.
|
|
68
|
+
* @csspart empty - The empty-state message.
|
|
62
69
|
*/
|
|
63
70
|
export class LyraWordCloud extends LyraElement {
|
|
64
71
|
constructor() {
|
|
@@ -78,6 +85,19 @@ export class LyraWordCloud extends LyraElement {
|
|
|
78
85
|
this.focusedIndex = null;
|
|
79
86
|
/** Text of the visually-hidden `aria-live="polite"` status announcement. */
|
|
80
87
|
this.liveText = '';
|
|
88
|
+
/**
|
|
89
|
+
* Whether `role`/`aria-label` were present on the host *before* this
|
|
90
|
+
* element's own code ever wrote to them -- snapshotted once, in the very
|
|
91
|
+
* first `willUpdate()` (guarded by `hasUpdated`, which Lit only flips to
|
|
92
|
+
* `true` after that first update commits). Re-checking `hasAttribute()` on
|
|
93
|
+
* every update instead would self-poison: once this element writes its own
|
|
94
|
+
* default `aria-label` on the first render, `hasAttribute('aria-label')` is
|
|
95
|
+
* permanently `true` afterwards, which would wrongly look like an
|
|
96
|
+
* author-supplied value and freeze the label instead of refreshing it as
|
|
97
|
+
* `words` changes on later updates.
|
|
98
|
+
*/
|
|
99
|
+
this.authorSuppliedRole = false;
|
|
100
|
+
this.authorSuppliedAriaLabel = false;
|
|
81
101
|
this.measureText = (text, fontSize) => {
|
|
82
102
|
const ctx = getScratchCtx();
|
|
83
103
|
if (!ctx)
|
|
@@ -150,22 +170,44 @@ export class LyraWordCloud extends LyraElement {
|
|
|
150
170
|
changed.has('maxFontSize') ||
|
|
151
171
|
changed.has('scale') ||
|
|
152
172
|
changed.has('orientations')) {
|
|
153
|
-
this.
|
|
154
|
-
minFontSize: this.minFontSize,
|
|
155
|
-
maxFontSize: this.maxFontSize,
|
|
156
|
-
scale: this.scale,
|
|
157
|
-
orientations: this.orientations,
|
|
158
|
-
measureText: this.measureText,
|
|
159
|
-
});
|
|
160
|
-
if (this.cachedLayout.skipped.length > 0)
|
|
161
|
-
warnSkippedWords(this.cachedLayout.skipped.length);
|
|
162
|
-
// The previous focus cursor may no longer address a real word once the
|
|
163
|
-
// data changes out from under it.
|
|
164
|
-
this.focusedIndex = null;
|
|
165
|
-
this.liveText = '';
|
|
173
|
+
this.relayout();
|
|
166
174
|
}
|
|
167
|
-
this.
|
|
168
|
-
|
|
175
|
+
if (!this.hasUpdated) {
|
|
176
|
+
this.authorSuppliedRole = this.hasAttribute('role');
|
|
177
|
+
this.authorSuppliedAriaLabel = this.hasAttribute('aria-label');
|
|
178
|
+
}
|
|
179
|
+
// Only default role/aria-label when the author hasn't already supplied
|
|
180
|
+
// one -- unconditionally overwriting them on every update (including
|
|
181
|
+
// ones triggered purely by a `words` re-layout) would silently clobber a
|
|
182
|
+
// host's own accessible name/role on the very next data refresh.
|
|
183
|
+
if (!this.authorSuppliedRole)
|
|
184
|
+
this.setAttribute('role', 'group');
|
|
185
|
+
if (!this.authorSuppliedAriaLabel) {
|
|
186
|
+
this.setAttribute('aria-label', `Word cloud of ${this.cachedLayout.placed.length} word${this.cachedLayout.placed.length === 1 ? '' : 's'}`);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
relayout() {
|
|
190
|
+
this.cachedLayout = layoutWordCloud(this.words, {
|
|
191
|
+
minFontSize: this.minFontSize,
|
|
192
|
+
maxFontSize: this.maxFontSize,
|
|
193
|
+
scale: this.scale,
|
|
194
|
+
orientations: this.orientations,
|
|
195
|
+
measureText: this.measureText,
|
|
196
|
+
});
|
|
197
|
+
if (this.cachedLayout.skipped.length > 0)
|
|
198
|
+
warnSkippedWords(this.cachedLayout.skipped.length);
|
|
199
|
+
// The previous focus cursor may no longer address a real word once the
|
|
200
|
+
// data changes out from under it.
|
|
201
|
+
this.focusedIndex = null;
|
|
202
|
+
this.liveText = '';
|
|
203
|
+
}
|
|
204
|
+
/** Forces a relayout so the font-family theme token (`--lyra-font`) is
|
|
205
|
+
* re-read from computed style — mirrors `lyra-chart`'s `refreshTheme()`.
|
|
206
|
+
* No global theme-broadcast event exists in lyra-ui to subscribe to
|
|
207
|
+
* automatically; call this from a consumer's own theme-toggle handler. */
|
|
208
|
+
refreshTheme() {
|
|
209
|
+
this.relayout();
|
|
210
|
+
this.requestUpdate();
|
|
169
211
|
}
|
|
170
212
|
activate(word) {
|
|
171
213
|
this.emit('lyra-word-click', { text: word.text, weight: word.weight, group: word.group });
|
|
@@ -206,7 +248,15 @@ export class LyraWordCloud extends LyraElement {
|
|
|
206
248
|
const ring = focused ? this.focusRingRect(focused) : undefined;
|
|
207
249
|
return html `
|
|
208
250
|
<div part="base">
|
|
209
|
-
<svg
|
|
251
|
+
<svg
|
|
252
|
+
part="svg"
|
|
253
|
+
role="group"
|
|
254
|
+
aria-label=${this.getAttribute('aria-label') ?? nothing}
|
|
255
|
+
aria-describedby="live-region"
|
|
256
|
+
tabindex="0"
|
|
257
|
+
viewBox="0 0 ${layout.width} ${layout.height}"
|
|
258
|
+
@keydown=${this.onKeyDown}
|
|
259
|
+
>
|
|
210
260
|
${layout.placed.map((w) => svg `<text
|
|
211
261
|
part="word"
|
|
212
262
|
x=${w.x}
|
|
@@ -220,7 +270,7 @@ export class LyraWordCloud extends LyraElement {
|
|
|
220
270
|
? svg `<rect part="focus-ring" x=${ring.x} y=${ring.y} width=${ring.width} height=${ring.height}></rect>`
|
|
221
271
|
: ''}
|
|
222
272
|
</svg>
|
|
223
|
-
<div part="live-region" class="sr-only" role="status" aria-live="polite">${this.liveText}</div>
|
|
273
|
+
<div id="live-region" part="live-region" class="sr-only" role="status" aria-live="polite">${this.liveText}</div>
|
|
224
274
|
</div>
|
|
225
275
|
`;
|
|
226
276
|
}
|
|
@@ -16,6 +16,18 @@ export const styles = css `
|
|
|
16
16
|
--lyra-word-cloud-color-7: #0a7d91;
|
|
17
17
|
--lyra-word-cloud-color-8: #57606a;
|
|
18
18
|
}
|
|
19
|
+
@media (prefers-color-scheme: dark) {
|
|
20
|
+
:host {
|
|
21
|
+
--lyra-word-cloud-color-1: var(--wa-color-brand-fill-loud, #4ea0f0);
|
|
22
|
+
--lyra-word-cloud-color-2: var(--wa-color-success-fill-loud, #3fb950);
|
|
23
|
+
--lyra-word-cloud-color-3: var(--wa-color-warning-fill-loud, #d29922);
|
|
24
|
+
--lyra-word-cloud-color-4: var(--wa-color-danger-fill-loud, #fa524a);
|
|
25
|
+
--lyra-word-cloud-color-5: #b083f5;
|
|
26
|
+
--lyra-word-cloud-color-6: #f470b8;
|
|
27
|
+
--lyra-word-cloud-color-7: #52d6e8;
|
|
28
|
+
--lyra-word-cloud-color-8: #c9d1d9;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
19
31
|
[part='base'] {
|
|
20
32
|
display: flex;
|
|
21
33
|
flex-direction: column;
|
|
@@ -37,15 +49,16 @@ export const styles = css `
|
|
|
37
49
|
font-weight: 600;
|
|
38
50
|
text-anchor: middle;
|
|
39
51
|
dominant-baseline: middle;
|
|
40
|
-
transition:
|
|
52
|
+
transition: text-decoration-color var(--lyra-transition-fast);
|
|
53
|
+
text-decoration: underline transparent;
|
|
41
54
|
}
|
|
42
55
|
[part='word']:hover {
|
|
43
|
-
|
|
56
|
+
text-decoration-color: currentColor;
|
|
44
57
|
}
|
|
45
58
|
[part='focus-ring'] {
|
|
46
59
|
fill: none;
|
|
47
60
|
stroke: var(--lyra-focus-ring-color);
|
|
48
|
-
stroke-width:
|
|
61
|
+
stroke-width: var(--lyra-focus-ring-width);
|
|
49
62
|
pointer-events: none;
|
|
50
63
|
}
|
|
51
64
|
[part='empty'] {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|