@aceshooting/lyra-ui 1.1.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -1
- package/custom-elements.json +21460 -8489
- package/dist/components/app-rail/app-rail.d.ts +171 -0
- package/dist/components/app-rail/app-rail.js +483 -0
- package/dist/components/app-rail/app-rail.styles.d.ts +1 -0
- package/dist/components/app-rail/app-rail.styles.js +125 -0
- package/dist/components/attachment-chip/attachment-chip.d.ts +114 -0
- package/dist/components/attachment-chip/attachment-chip.js +312 -0
- package/dist/components/attachment-chip/attachment-chip.styles.d.ts +1 -0
- package/dist/components/attachment-chip/attachment-chip.styles.js +184 -0
- package/dist/components/attachment-trigger/attachment-trigger.d.ts +83 -0
- package/dist/components/attachment-trigger/attachment-trigger.js +258 -0
- package/dist/components/attachment-trigger/attachment-trigger.styles.d.ts +1 -0
- package/dist/components/attachment-trigger/attachment-trigger.styles.js +68 -0
- package/dist/components/chart/box-plot.js +11 -1
- package/dist/components/chart/chart-loader.d.ts +44 -13
- package/dist/components/chart/chart-loader.js +65 -18
- package/dist/components/chart/chart.d.ts +12 -2
- package/dist/components/chart/chart.js +121 -14
- package/dist/components/chart/histogram-bin.d.ts +4 -1
- package/dist/components/chart/histogram-bin.js +24 -14
- package/dist/components/chart/lite-chart.d.ts +63 -0
- package/dist/components/chart/lite-chart.js +181 -23
- package/dist/components/chart/lite-chart.styles.js +9 -0
- package/dist/components/chat-composer/chat-composer.d.ts +92 -0
- package/dist/components/chat-composer/chat-composer.js +285 -0
- package/dist/components/chat-composer/chat-composer.styles.d.ts +1 -0
- package/dist/components/chat-composer/chat-composer.styles.js +135 -0
- package/dist/components/chat-message/chat-message.d.ts +113 -0
- package/dist/components/chat-message/chat-message.js +291 -0
- package/dist/components/chat-message/chat-message.styles.d.ts +1 -0
- package/dist/components/chat-message/chat-message.styles.js +203 -0
- package/dist/components/checkbox/checkbox.d.ts +59 -0
- package/dist/components/checkbox/checkbox.js +230 -0
- package/dist/components/checkbox/checkbox.styles.d.ts +1 -0
- package/dist/components/checkbox/checkbox.styles.js +70 -0
- package/dist/components/chip/chip-group.d.ts +56 -0
- package/dist/components/chip/chip-group.js +124 -0
- package/dist/components/chip/chip-group.styles.d.ts +1 -0
- package/dist/components/chip/chip-group.styles.js +57 -0
- package/dist/components/chip/chip.d.ts +64 -0
- package/dist/components/chip/chip.js +115 -0
- package/dist/components/chip/chip.styles.d.ts +1 -0
- package/dist/components/chip/chip.styles.js +115 -0
- package/dist/components/citation-badge/citation-badge.d.ts +113 -0
- package/dist/components/citation-badge/citation-badge.js +300 -0
- package/dist/components/citation-badge/citation-badge.styles.d.ts +1 -0
- package/dist/components/citation-badge/citation-badge.styles.js +96 -0
- package/dist/components/code-block/code-block.d.ts +89 -0
- package/dist/components/code-block/code-block.js +317 -0
- package/dist/components/code-block/code-block.styles.d.ts +1 -0
- package/dist/components/code-block/code-block.styles.js +187 -0
- package/dist/components/code-block/code-loader.d.ts +44 -0
- package/dist/components/code-block/code-loader.js +79 -0
- package/dist/components/combobox/combobox.d.ts +19 -1
- package/dist/components/combobox/combobox.js +84 -14
- package/dist/components/combobox/option.d.ts +5 -1
- package/dist/components/combobox/option.js +35 -0
- package/dist/components/context-meter/context-meter.d.ts +53 -0
- package/dist/components/context-meter/context-meter.js +150 -0
- package/dist/components/context-meter/context-meter.styles.d.ts +1 -0
- package/dist/components/context-meter/context-meter.styles.js +120 -0
- package/dist/components/conversation-item/conversation-item.d.ts +128 -0
- package/dist/components/conversation-item/conversation-item.js +322 -0
- package/dist/components/conversation-item/conversation-item.styles.d.ts +1 -0
- package/dist/components/conversation-item/conversation-item.styles.js +155 -0
- package/dist/components/date-picker/date-input.d.ts +24 -0
- package/dist/components/date-picker/date-input.js +134 -22
- package/dist/components/date-picker/date-picker.d.ts +7 -0
- package/dist/components/date-picker/date-picker.js +85 -16
- package/dist/components/dialog/confirm.d.ts +40 -0
- package/dist/components/dialog/confirm.js +79 -0
- package/dist/components/dialog/dialog.d.ts +85 -0
- package/dist/components/dialog/dialog.js +272 -0
- package/dist/components/dialog/dialog.styles.d.ts +1 -0
- package/dist/components/dialog/dialog.styles.js +52 -0
- package/dist/components/dock-panel/dock-panel.d.ts +134 -0
- package/dist/components/dock-panel/dock-panel.js +345 -0
- package/dist/components/dock-panel/dock-panel.styles.d.ts +1 -0
- package/dist/components/dock-panel/dock-panel.styles.js +145 -0
- package/dist/components/document-preview/document-preview.d.ts +135 -0
- package/dist/components/document-preview/document-preview.js +372 -0
- package/dist/components/document-preview/document-preview.styles.d.ts +1 -0
- package/dist/components/document-preview/document-preview.styles.js +191 -0
- package/dist/components/export-button/csv.js +1 -1
- package/dist/components/export-button/export-button.js +2 -0
- package/dist/components/flag/flag.d.ts +42 -5
- package/dist/components/flag/flag.js +70 -3
- package/dist/components/gauge/gauge.js +19 -10
- package/dist/components/generation-status/generation-status.d.ts +109 -0
- package/dist/components/generation-status/generation-status.js +273 -0
- package/dist/components/generation-status/generation-status.styles.d.ts +1 -0
- package/dist/components/generation-status/generation-status.styles.js +84 -0
- package/dist/components/heatmap/calendar-grid.d.ts +4 -1
- package/dist/components/heatmap/calendar-grid.js +25 -12
- package/dist/components/heatmap/heatmap-scale.d.ts +6 -0
- package/dist/components/heatmap/heatmap-scale.js +7 -1
- package/dist/components/heatmap/heatmap.d.ts +89 -3
- package/dist/components/heatmap/heatmap.js +158 -29
- package/dist/components/json-viewer/json-viewer.d.ts +53 -0
- package/dist/components/json-viewer/json-viewer.js +283 -0
- package/dist/components/json-viewer/json-viewer.styles.d.ts +1 -0
- package/dist/components/json-viewer/json-viewer.styles.js +176 -0
- package/dist/components/kbd/kbd.d.ts +77 -0
- package/dist/components/kbd/kbd.js +214 -0
- package/dist/components/kbd/kbd.styles.d.ts +1 -0
- package/dist/components/kbd/kbd.styles.js +52 -0
- package/dist/components/live-region/live-region.d.ts +81 -0
- package/dist/components/live-region/live-region.js +153 -0
- package/dist/components/live-region/live-region.styles.d.ts +1 -0
- package/dist/components/live-region/live-region.styles.js +10 -0
- package/dist/components/map/map.d.ts +8 -6
- package/dist/components/map/map.js +44 -8
- package/dist/components/markdown/markdown-loader.d.ts +34 -0
- package/dist/components/markdown/markdown-loader.js +43 -0
- package/dist/components/markdown/markdown.d.ts +81 -0
- package/dist/components/markdown/markdown.js +284 -0
- package/dist/components/markdown/markdown.styles.d.ts +1 -0
- package/dist/components/markdown/markdown.styles.js +82 -0
- package/dist/components/media-card/media-card.d.ts +122 -0
- package/dist/components/media-card/media-card.js +295 -0
- package/dist/components/media-card/media-card.styles.d.ts +1 -0
- package/dist/components/media-card/media-card.styles.js +132 -0
- package/dist/components/mention-popover/mention-popover.d.ts +200 -0
- package/dist/components/mention-popover/mention-popover.js +475 -0
- package/dist/components/mention-popover/mention-popover.styles.d.ts +1 -0
- package/dist/components/mention-popover/mention-popover.styles.js +101 -0
- package/dist/components/menu/menu-item.d.ts +62 -0
- package/dist/components/menu/menu-item.js +119 -0
- package/dist/components/menu/menu-item.styles.d.ts +1 -0
- package/dist/components/menu/menu-item.styles.js +67 -0
- package/dist/components/menu/menu.d.ts +143 -0
- package/dist/components/menu/menu.js +365 -0
- package/dist/components/menu/menu.styles.d.ts +1 -0
- package/dist/components/menu/menu.styles.js +66 -0
- package/dist/components/model-select/model-select.d.ts +125 -0
- package/dist/components/model-select/model-select.js +490 -0
- package/dist/components/model-select/model-select.styles.d.ts +1 -0
- package/dist/components/model-select/model-select.styles.js +189 -0
- package/dist/components/model-settings-panel/model-settings-panel.d.ts +69 -0
- package/dist/components/model-settings-panel/model-settings-panel.js +145 -0
- package/dist/components/model-settings-panel/model-settings-panel.styles.d.ts +1 -0
- package/dist/components/model-settings-panel/model-settings-panel.styles.js +82 -0
- package/dist/components/playback/playback.d.ts +13 -1
- package/dist/components/playback/playback.js +47 -14
- package/dist/components/responsive-panel/responsive-panel.d.ts +150 -0
- package/dist/components/responsive-panel/responsive-panel.js +365 -0
- package/dist/components/responsive-panel/responsive-panel.styles.d.ts +1 -0
- package/dist/components/responsive-panel/responsive-panel.styles.js +103 -0
- package/dist/components/result-card/result-card.d.ts +44 -0
- package/dist/components/result-card/result-card.js +83 -0
- package/dist/components/result-card/result-card.styles.d.ts +1 -0
- package/dist/components/result-card/result-card.styles.js +50 -0
- package/dist/components/result-card/result-field.d.ts +36 -0
- package/dist/components/result-card/result-field.js +87 -0
- package/dist/components/result-card/result-field.styles.d.ts +1 -0
- package/dist/components/result-card/result-field.styles.js +32 -0
- package/dist/components/select/select.d.ts +45 -1
- package/dist/components/select/select.js +114 -17
- package/dist/components/select/select.styles.js +26 -2
- package/dist/components/slider/slider.d.ts +89 -0
- package/dist/components/slider/slider.js +352 -0
- package/dist/components/slider/slider.styles.d.ts +1 -0
- package/dist/components/slider/slider.styles.js +87 -0
- package/dist/components/source-card/source-card.d.ts +92 -0
- package/dist/components/source-card/source-card.js +148 -0
- package/dist/components/source-card/source-card.styles.d.ts +1 -0
- package/dist/components/source-card/source-card.styles.js +69 -0
- package/dist/components/source-list/source-list.d.ts +63 -0
- package/dist/components/source-list/source-list.js +122 -0
- package/dist/components/source-list/source-list.styles.d.ts +1 -0
- package/dist/components/source-list/source-list.styles.js +59 -0
- package/dist/components/sparkline/sparkline.js +27 -13
- package/dist/components/split/split.d.ts +93 -1
- package/dist/components/split/split.js +284 -15
- package/dist/components/split/split.styles.js +30 -0
- package/dist/components/stat/stat.d.ts +22 -1
- package/dist/components/stat/stat.js +49 -3
- package/dist/components/stat/stat.styles.js +20 -0
- package/dist/components/stream-status/stream-status.d.ts +110 -0
- package/dist/components/stream-status/stream-status.js +210 -0
- package/dist/components/stream-status/stream-status.styles.d.ts +1 -0
- package/dist/components/stream-status/stream-status.styles.js +103 -0
- package/dist/components/streaming-text/streaming-text.d.ts +98 -0
- package/dist/components/streaming-text/streaming-text.js +209 -0
- package/dist/components/streaming-text/streaming-text.styles.d.ts +1 -0
- package/dist/components/streaming-text/streaming-text.styles.js +62 -0
- package/dist/components/switch/switch.d.ts +58 -0
- package/dist/components/switch/switch.js +179 -0
- package/dist/components/switch/switch.styles.d.ts +1 -0
- package/dist/components/switch/switch.styles.js +75 -0
- package/dist/components/table/table.d.ts +73 -4
- package/dist/components/table/table.js +169 -20
- package/dist/components/table/table.styles.js +6 -1
- package/dist/components/tabs/tabs.d.ts +51 -0
- package/dist/components/tabs/tabs.js +190 -0
- package/dist/components/tabs/tabs.styles.d.ts +1 -0
- package/dist/components/tabs/tabs.styles.js +63 -0
- package/dist/components/thinking-panel/thinking-panel.d.ts +121 -0
- package/dist/components/thinking-panel/thinking-panel.js +235 -0
- package/dist/components/thinking-panel/thinking-panel.styles.d.ts +1 -0
- package/dist/components/thinking-panel/thinking-panel.styles.js +117 -0
- package/dist/components/toast/toast-item.d.ts +1 -0
- package/dist/components/toast/toast-item.js +31 -6
- package/dist/components/tool-approval-dialog/tool-approval-dialog.d.ts +130 -0
- package/dist/components/tool-approval-dialog/tool-approval-dialog.js +403 -0
- package/dist/components/tool-approval-dialog/tool-approval-dialog.styles.d.ts +1 -0
- package/dist/components/tool-approval-dialog/tool-approval-dialog.styles.js +160 -0
- package/dist/components/tool-call-chip/tool-call-chip.d.ts +89 -0
- package/dist/components/tool-call-chip/tool-call-chip.js +288 -0
- package/dist/components/tool-call-chip/tool-call-chip.styles.d.ts +1 -0
- package/dist/components/tool-call-chip/tool-call-chip.styles.js +203 -0
- package/dist/components/tool-param-form/tool-param-form.d.ts +145 -0
- package/dist/components/tool-param-form/tool-param-form.js +366 -0
- package/dist/components/tool-param-form/tool-param-form.styles.d.ts +1 -0
- package/dist/components/tool-param-form/tool-param-form.styles.js +75 -0
- package/dist/components/tool-result-dialog/tool-result-dialog.d.ts +102 -0
- package/dist/components/tool-result-dialog/tool-result-dialog.js +393 -0
- package/dist/components/tool-result-dialog/tool-result-dialog.styles.d.ts +1 -0
- package/dist/components/tool-result-dialog/tool-result-dialog.styles.js +176 -0
- package/dist/components/tool-result-view/registry.d.ts +81 -0
- package/dist/components/tool-result-view/registry.js +84 -0
- package/dist/components/tool-result-view/tool-result-view.d.ts +55 -0
- package/dist/components/tool-result-view/tool-result-view.js +138 -0
- package/dist/components/tool-result-view/tool-result-view.styles.d.ts +1 -0
- package/dist/components/tool-result-view/tool-result-view.styles.js +13 -0
- package/dist/components/tool-select-dialog/tool-select-dialog.d.ts +151 -0
- package/dist/components/tool-select-dialog/tool-select-dialog.js +439 -0
- package/dist/components/tool-select-dialog/tool-select-dialog.styles.d.ts +1 -0
- package/dist/components/tool-select-dialog/tool-select-dialog.styles.js +182 -0
- package/dist/components/tree/tree-node.d.ts +11 -2
- package/dist/components/tree/tree-node.js +16 -6
- package/dist/components/tree/tree.d.ts +8 -2
- package/dist/components/tree/tree.js +18 -11
- package/dist/components/typing-indicator/typing-indicator.d.ts +60 -0
- package/dist/components/typing-indicator/typing-indicator.js +96 -0
- package/dist/components/typing-indicator/typing-indicator.styles.d.ts +1 -0
- package/dist/components/typing-indicator/typing-indicator.styles.js +132 -0
- package/dist/components/virtual-list/virtual-list.d.ts +173 -0
- package/dist/components/virtual-list/virtual-list.js +461 -0
- package/dist/components/virtual-list/virtual-list.styles.d.ts +1 -0
- package/dist/components/virtual-list/virtual-list.styles.js +44 -0
- package/dist/components/widget/widget.d.ts +10 -0
- package/dist/components/widget/widget.js +24 -1
- package/dist/components/widget/widget.styles.js +9 -2
- package/dist/components/word-cloud/word-cloud-layout.js +14 -1
- package/dist/components/word-cloud/word-cloud.d.ts +6 -0
- package/dist/components/word-cloud/word-cloud.js +25 -14
- package/dist/components/word-cloud/word-cloud.styles.js +4 -2
- package/dist/internal/announcer.d.ts +57 -0
- package/dist/internal/announcer.js +71 -0
- package/dist/internal/form-associated.d.ts +1 -0
- package/dist/internal/form-associated.js +55 -11
- package/dist/internal/group-by-recency.d.ts +50 -0
- package/dist/internal/group-by-recency.js +80 -0
- package/dist/internal/rtl.d.ts +23 -0
- package/dist/internal/rtl.js +28 -0
- package/dist/internal/scroll-lock.d.ts +10 -5
- package/dist/internal/scroll-lock.js +30 -14
- package/dist/internal/tokens.styles.js +6 -0
- package/dist/lyra.d.ts +130 -31
- package/dist/lyra.js +94 -26
- package/llms-full.txt +3921 -32
- package/llms.txt +16 -1
- package/package.json +23 -5
- package/dist/components/chart/bar-chart.stories.d.ts +0 -5
- package/dist/components/chart/bar-chart.stories.js +0 -20
- package/dist/components/chart/box-plot.stories.d.ts +0 -5
- package/dist/components/chart/box-plot.stories.js +0 -29
- package/dist/components/chart/bubble-chart.stories.d.ts +0 -5
- package/dist/components/chart/bubble-chart.stories.js +0 -26
- package/dist/components/chart/chart.stories.d.ts +0 -32
- package/dist/components/chart/chart.stories.js +0 -141
- package/dist/components/chart/doughnut-chart.stories.d.ts +0 -5
- package/dist/components/chart/doughnut-chart.stories.js +0 -26
- package/dist/components/chart/histogram.stories.d.ts +0 -5
- package/dist/components/chart/histogram.stories.js +0 -17
- package/dist/components/chart/line-chart.stories.d.ts +0 -22
- package/dist/components/chart/line-chart.stories.js +0 -99
- package/dist/components/chart/lite-chart.stories.d.ts +0 -12
- package/dist/components/chart/lite-chart.stories.js +0 -98
- 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 -5
- package/dist/components/flag/flag.stories.js +0 -17
- 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 -22
- package/dist/components/heatmap/heatmap.stories.js +0 -154
- 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 -19
- package/dist/components/select/select.stories.js +0 -75
- 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 -8
- package/dist/components/stat/stat.stories.js +0 -64
- 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 -7
- package/dist/components/widget/widget.stories.js +0 -41
- 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,187 @@
|
|
|
1
|
+
import { css } from 'lit';
|
|
2
|
+
export const styles = css `
|
|
3
|
+
:host {
|
|
4
|
+
display: block;
|
|
5
|
+
/* Consumer-tunable scroll cap -- 'none' means the block grows with its
|
|
6
|
+
content, matching every other block-level component in this library
|
|
7
|
+
until a caller opts in via the max-height attribute (same convention
|
|
8
|
+
as --lyra-json-viewer-max-height). */
|
|
9
|
+
--lyra-code-block-max-height: none;
|
|
10
|
+
/* Contained here rather than left as a bare font-family literal so a
|
|
11
|
+
host page can retheme it -- same rationale as --lyra-markdown-font-mono
|
|
12
|
+
and --lyra-json-viewer-font, no shared --wa-*/--lyra-* monospace token
|
|
13
|
+
exists to resolve through. */
|
|
14
|
+
--lyra-code-block-font: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
|
|
15
|
+
font-size: 0.8125rem;
|
|
16
|
+
}
|
|
17
|
+
[part='base'] {
|
|
18
|
+
border: 1px solid var(--lyra-color-border);
|
|
19
|
+
border-radius: var(--lyra-radius);
|
|
20
|
+
background: var(--lyra-color-surface);
|
|
21
|
+
overflow: hidden;
|
|
22
|
+
}
|
|
23
|
+
[part='header'] {
|
|
24
|
+
display: flex;
|
|
25
|
+
align-items: center;
|
|
26
|
+
gap: var(--lyra-space-xs);
|
|
27
|
+
padding: var(--lyra-space-xs) var(--lyra-space-s);
|
|
28
|
+
border-block-end: 1px solid var(--lyra-color-border);
|
|
29
|
+
/* --lyra-color-surface (not -brand-quiet) -- pairing
|
|
30
|
+
--lyra-color-text-quiet (the toggle/copy-button color below) against
|
|
31
|
+
--lyra-color-brand-quiet fails WCAG AA contrast in this token
|
|
32
|
+
palette; --lyra-color-surface is the same header background
|
|
33
|
+
lyra-json-viewer's own toolbar already uses with that same text
|
|
34
|
+
color. */
|
|
35
|
+
background: var(--lyra-color-surface);
|
|
36
|
+
font-family: var(--lyra-font);
|
|
37
|
+
}
|
|
38
|
+
[part='toggle'] {
|
|
39
|
+
/* Deliberately smaller than the shared --lyra-icon-button-size (2.5rem,
|
|
40
|
+
meant for a standalone icon-only button) -- this sits inline in a
|
|
41
|
+
dense header row, same reasoning as lyra-json-viewer's own toggle. */
|
|
42
|
+
inline-size: 1.25rem;
|
|
43
|
+
block-size: 1.25rem;
|
|
44
|
+
flex: 0 0 auto;
|
|
45
|
+
display: inline-flex;
|
|
46
|
+
align-items: center;
|
|
47
|
+
justify-content: center;
|
|
48
|
+
padding: 0;
|
|
49
|
+
border: none;
|
|
50
|
+
background: none;
|
|
51
|
+
color: var(--lyra-color-text-quiet);
|
|
52
|
+
border-radius: var(--lyra-radius);
|
|
53
|
+
cursor: pointer;
|
|
54
|
+
}
|
|
55
|
+
[part='toggle']:hover {
|
|
56
|
+
background: var(--lyra-color-brand-quiet);
|
|
57
|
+
color: var(--lyra-color-brand);
|
|
58
|
+
}
|
|
59
|
+
[part='toggle'] .chevron {
|
|
60
|
+
display: inline-flex;
|
|
61
|
+
transition: transform var(--lyra-transition-fast);
|
|
62
|
+
}
|
|
63
|
+
/* Chevron points at the content: rotated (pointing down) while expanded,
|
|
64
|
+
resting (pointing right) while collapsed -- same rotation direction as
|
|
65
|
+
lyra-thinking-panel's and lyra-json-viewer's own toggles. */
|
|
66
|
+
:host(:not([collapsed])) [part='toggle'] .chevron {
|
|
67
|
+
transform: rotate(90deg);
|
|
68
|
+
}
|
|
69
|
+
[part='filename'] {
|
|
70
|
+
flex: 1 1 auto;
|
|
71
|
+
min-inline-size: 0;
|
|
72
|
+
overflow: hidden;
|
|
73
|
+
text-overflow: ellipsis;
|
|
74
|
+
white-space: nowrap;
|
|
75
|
+
font-family: var(--lyra-code-block-font);
|
|
76
|
+
font-size: 0.75rem;
|
|
77
|
+
font-weight: 600;
|
|
78
|
+
color: var(--lyra-color-text);
|
|
79
|
+
}
|
|
80
|
+
[part='language'] {
|
|
81
|
+
flex: 0 0 auto;
|
|
82
|
+
padding: 0.0625rem 0.4375rem;
|
|
83
|
+
border-radius: 999px;
|
|
84
|
+
/* --lyra-color-brand + -brand-quiet (not -text-quiet + -surface) --
|
|
85
|
+
this pill needs to read as distinct from the [part="header"]
|
|
86
|
+
background it sits on (also -surface as of the comment above), and
|
|
87
|
+
-brand on -brand-quiet is a pairing already relied on elsewhere in
|
|
88
|
+
this library (e.g. hover states below) that passes contrast, unlike
|
|
89
|
+
-text-quiet on -brand-quiet. */
|
|
90
|
+
background: var(--lyra-color-brand-quiet);
|
|
91
|
+
color: var(--lyra-color-brand);
|
|
92
|
+
font-size: 0.6875rem;
|
|
93
|
+
line-height: 1.4;
|
|
94
|
+
text-transform: uppercase;
|
|
95
|
+
letter-spacing: 0.02em;
|
|
96
|
+
}
|
|
97
|
+
/* Pushed to the end of the header whether or not filename/language
|
|
98
|
+
precede it -- margin-inline-start:auto works whether this is the first
|
|
99
|
+
flex child (copyable alone) or the last of several. */
|
|
100
|
+
[part='copy-button'] {
|
|
101
|
+
flex: 0 0 auto;
|
|
102
|
+
margin-inline-start: auto;
|
|
103
|
+
border: none;
|
|
104
|
+
background: none;
|
|
105
|
+
color: var(--lyra-color-text-quiet);
|
|
106
|
+
font: inherit;
|
|
107
|
+
font-size: 0.75rem;
|
|
108
|
+
line-height: 1;
|
|
109
|
+
padding: 0.1875rem var(--lyra-space-xs);
|
|
110
|
+
border-radius: var(--lyra-radius);
|
|
111
|
+
cursor: pointer;
|
|
112
|
+
}
|
|
113
|
+
[part='copy-button']:hover {
|
|
114
|
+
background: var(--lyra-color-brand-quiet);
|
|
115
|
+
color: var(--lyra-color-brand);
|
|
116
|
+
}
|
|
117
|
+
[part='toggle']:focus-visible,
|
|
118
|
+
[part='copy-button']:focus-visible {
|
|
119
|
+
outline: var(--lyra-focus-ring-width) solid var(--lyra-focus-ring-color);
|
|
120
|
+
outline-offset: var(--lyra-focus-ring-offset);
|
|
121
|
+
}
|
|
122
|
+
[part='body'] {
|
|
123
|
+
display: block;
|
|
124
|
+
max-block-size: var(--lyra-code-block-max-height);
|
|
125
|
+
overflow: auto;
|
|
126
|
+
}
|
|
127
|
+
[part='body'][hidden] {
|
|
128
|
+
display: none;
|
|
129
|
+
}
|
|
130
|
+
[part='body']:focus-visible {
|
|
131
|
+
outline: var(--lyra-focus-ring-width) solid var(--lyra-focus-ring-color);
|
|
132
|
+
/* Negative (inward) so the ring isn't clipped by this element's own
|
|
133
|
+
overflow:auto -- same reasoning as lyra-virtual-list's [part="base"]. */
|
|
134
|
+
outline-offset: calc(-1 * var(--lyra-focus-ring-offset));
|
|
135
|
+
}
|
|
136
|
+
[part='body'] lyra-skeleton {
|
|
137
|
+
display: block;
|
|
138
|
+
padding: var(--lyra-space-s) var(--lyra-space-m);
|
|
139
|
+
--lyra-skeleton-w: 100%;
|
|
140
|
+
--lyra-skeleton-h: 8rem;
|
|
141
|
+
}
|
|
142
|
+
[part='pre'] {
|
|
143
|
+
margin: 0;
|
|
144
|
+
padding: var(--lyra-space-s) var(--lyra-space-m);
|
|
145
|
+
/* A default background so the plain-fallback path still reads as a
|
|
146
|
+
proper code block -- shiki's own inline background-color (part of the
|
|
147
|
+
generated-token-colors exception documented in code-block.ts's
|
|
148
|
+
tokenize()) silently overrides this the moment highlighting succeeds,
|
|
149
|
+
since an element's own style attribute always wins over an external
|
|
150
|
+
stylesheet rule at equal or lower specificity. */
|
|
151
|
+
background: var(--lyra-color-surface);
|
|
152
|
+
font-family: var(--lyra-code-block-font);
|
|
153
|
+
font-size: inherit;
|
|
154
|
+
line-height: 1.5;
|
|
155
|
+
white-space: pre;
|
|
156
|
+
}
|
|
157
|
+
[part='code'] {
|
|
158
|
+
font-family: inherit;
|
|
159
|
+
}
|
|
160
|
+
/*
|
|
161
|
+
* Activates shiki's "dual themes" dark variant. codeToHtml() (see
|
|
162
|
+
* tokenize() in code-block.ts) renders every token with its *light* color
|
|
163
|
+
* as a plain inline color/background-color and its *dark* color stashed in
|
|
164
|
+
* the --shiki-dark/--shiki-dark-bg custom properties shiki itself defines
|
|
165
|
+
* inline on the same elements -- shiki's own documented pattern for
|
|
166
|
+
* toggling them is exactly this: an external stylesheet rule that
|
|
167
|
+
* reassigns color/background-color from those variables. This requires
|
|
168
|
+
* !important because an inline style="..." attribute always outranks an
|
|
169
|
+
* external stylesheet at any selector specificity short of !important --
|
|
170
|
+
* there's no other way for a page-level rule to override an element's own
|
|
171
|
+
* style attribute. This is the one legitimate exception to "every color is
|
|
172
|
+
* a --lyra-* token" in this file: these values come from shiki's theme
|
|
173
|
+
* data, not this library's design tokens.
|
|
174
|
+
*/
|
|
175
|
+
@media (prefers-color-scheme: dark) {
|
|
176
|
+
[part='pre'],
|
|
177
|
+
[part='pre'] span {
|
|
178
|
+
color: var(--shiki-dark, inherit) !important;
|
|
179
|
+
background-color: var(--shiki-dark-bg, transparent) !important;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
@media (prefers-reduced-motion: reduce) {
|
|
183
|
+
[part='toggle'] .chevron {
|
|
184
|
+
transition: none !important;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
`;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { Highlighter, BundledTheme } from 'shiki';
|
|
2
|
+
/** Re-exported under a component-scoped name so importers don't need their
|
|
3
|
+
* own `import type { Highlighter } from 'shiki'`. */
|
|
4
|
+
export type ShikiHighlighter = Highlighter;
|
|
5
|
+
/**
|
|
6
|
+
* The two bundled themes every highlighter instance is seeded with, so a
|
|
7
|
+
* single `codeToHtml()` call can emit a light *and* dark rendering at once
|
|
8
|
+
* (shiki's "dual themes" feature — https://shiki.style/guide/dual-themes —
|
|
9
|
+
* rather than maintaining two separately-highlighted copies). `github-light`/
|
|
10
|
+
* `github-dark` are well-known, reasonably neutral, and already part of
|
|
11
|
+
* shiki's bundled theme set, so picking them costs no extra install. See the
|
|
12
|
+
* `prefers-color-scheme` block in `code-block.styles.ts` for how the dark
|
|
13
|
+
* variant actually activates.
|
|
14
|
+
*/
|
|
15
|
+
export declare const SHIKI_LIGHT_THEME: BundledTheme;
|
|
16
|
+
export declare const SHIKI_DARK_THEME: BundledTheme;
|
|
17
|
+
/** Passed directly as `codeToHtml()`'s `themes` option — see `tokenize()` in `code-block.ts`. */
|
|
18
|
+
export declare const SHIKI_THEMES: Record<'light' | 'dark', BundledTheme>;
|
|
19
|
+
/**
|
|
20
|
+
* Lazily loads the optional peer dependency `shiki` once per page and builds
|
|
21
|
+
* (and caches) a single `Highlighter` instance seeded with `SHIKI_THEMES` and
|
|
22
|
+
* *zero* language grammars. Creating the highlighter — compiling its regex
|
|
23
|
+
* engine, parsing the seed themes — is the expensive part, not the dynamic
|
|
24
|
+
* `import()` itself, so the created instance is what's cached here rather
|
|
25
|
+
* than just the resolved module (one level deeper than `map-loader.ts`'s
|
|
26
|
+
* single-dependency cached-promise shape, which this otherwise mirrors).
|
|
27
|
+
* Resolves to `null` (with a one-time `console.warn`) if shiki isn't
|
|
28
|
+
* installed — `<lyra-code-block>` falls back to plain unhighlighted text in
|
|
29
|
+
* that case, which is a fully supported default, not a degraded mode. No
|
|
30
|
+
* language grammar is loaded up front; `loadShikiLanguage()` below loads each
|
|
31
|
+
* one incrementally the first time a `language` value actually requests it.
|
|
32
|
+
*/
|
|
33
|
+
export declare function loadShikiHighlighter(): Promise<ShikiHighlighter | null>;
|
|
34
|
+
/**
|
|
35
|
+
* Ensures `lang` is loaded into `hl`, loading it on demand the first time
|
|
36
|
+
* it's requested rather than bundling every possible grammar up front —
|
|
37
|
+
* shiki supports this incrementally via `Highlighter.loadLanguage()`, which
|
|
38
|
+
* is what keeps this lazy instead of defeating the point of lazy-loading the
|
|
39
|
+
* peer at all. Resolves `false` (and remembers not to retry) when `lang`
|
|
40
|
+
* isn't a shiki-recognized grammar id or alias at all, so a caller can fall
|
|
41
|
+
* back to plain-text rendering instead of retrying an id that can never
|
|
42
|
+
* succeed on every future render.
|
|
43
|
+
*/
|
|
44
|
+
export declare function loadShikiLanguage(hl: ShikiHighlighter, lang: string): Promise<boolean>;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The two bundled themes every highlighter instance is seeded with, so a
|
|
3
|
+
* single `codeToHtml()` call can emit a light *and* dark rendering at once
|
|
4
|
+
* (shiki's "dual themes" feature — https://shiki.style/guide/dual-themes —
|
|
5
|
+
* rather than maintaining two separately-highlighted copies). `github-light`/
|
|
6
|
+
* `github-dark` are well-known, reasonably neutral, and already part of
|
|
7
|
+
* shiki's bundled theme set, so picking them costs no extra install. See the
|
|
8
|
+
* `prefers-color-scheme` block in `code-block.styles.ts` for how the dark
|
|
9
|
+
* variant actually activates.
|
|
10
|
+
*/
|
|
11
|
+
export const SHIKI_LIGHT_THEME = 'github-light';
|
|
12
|
+
export const SHIKI_DARK_THEME = 'github-dark';
|
|
13
|
+
/** Passed directly as `codeToHtml()`'s `themes` option — see `tokenize()` in `code-block.ts`. */
|
|
14
|
+
export const SHIKI_THEMES = {
|
|
15
|
+
light: SHIKI_LIGHT_THEME,
|
|
16
|
+
dark: SHIKI_DARK_THEME,
|
|
17
|
+
};
|
|
18
|
+
let highlighter;
|
|
19
|
+
/** Language ids that have already failed `loadLanguage()` once — avoids
|
|
20
|
+
* retrying (and re-throwing on) the same unrecognized `language` value on
|
|
21
|
+
* every re-render of every `<lyra-code-block>` that requests it. Shared
|
|
22
|
+
* across every highlighter instance the page ever creates (there's only
|
|
23
|
+
* ever one, see `loadShikiHighlighter()` below), so this never needs
|
|
24
|
+
* resetting alongside it. */
|
|
25
|
+
const unsupportedLanguages = new Set();
|
|
26
|
+
/**
|
|
27
|
+
* Lazily loads the optional peer dependency `shiki` once per page and builds
|
|
28
|
+
* (and caches) a single `Highlighter` instance seeded with `SHIKI_THEMES` and
|
|
29
|
+
* *zero* language grammars. Creating the highlighter — compiling its regex
|
|
30
|
+
* engine, parsing the seed themes — is the expensive part, not the dynamic
|
|
31
|
+
* `import()` itself, so the created instance is what's cached here rather
|
|
32
|
+
* than just the resolved module (one level deeper than `map-loader.ts`'s
|
|
33
|
+
* single-dependency cached-promise shape, which this otherwise mirrors).
|
|
34
|
+
* Resolves to `null` (with a one-time `console.warn`) if shiki isn't
|
|
35
|
+
* installed — `<lyra-code-block>` falls back to plain unhighlighted text in
|
|
36
|
+
* that case, which is a fully supported default, not a degraded mode. No
|
|
37
|
+
* language grammar is loaded up front; `loadShikiLanguage()` below loads each
|
|
38
|
+
* one incrementally the first time a `language` value actually requests it.
|
|
39
|
+
*/
|
|
40
|
+
export function loadShikiHighlighter() {
|
|
41
|
+
if (!highlighter) {
|
|
42
|
+
highlighter = import('shiki')
|
|
43
|
+
.then((mod) => mod.createHighlighter({ themes: [SHIKI_LIGHT_THEME, SHIKI_DARK_THEME], langs: [] }))
|
|
44
|
+
.catch((err) => {
|
|
45
|
+
console.warn('<lyra-code-block> needs the optional peer dependency `shiki` for syntax highlighting — install it ' +
|
|
46
|
+
'with `pnpm add shiki`. Code still renders, just unhighlighted, without it:', err);
|
|
47
|
+
return null;
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
return highlighter;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Ensures `lang` is loaded into `hl`, loading it on demand the first time
|
|
54
|
+
* it's requested rather than bundling every possible grammar up front —
|
|
55
|
+
* shiki supports this incrementally via `Highlighter.loadLanguage()`, which
|
|
56
|
+
* is what keeps this lazy instead of defeating the point of lazy-loading the
|
|
57
|
+
* peer at all. Resolves `false` (and remembers not to retry) when `lang`
|
|
58
|
+
* isn't a shiki-recognized grammar id or alias at all, so a caller can fall
|
|
59
|
+
* back to plain-text rendering instead of retrying an id that can never
|
|
60
|
+
* succeed on every future render.
|
|
61
|
+
*/
|
|
62
|
+
export async function loadShikiLanguage(hl, lang) {
|
|
63
|
+
if (hl.getLoadedLanguages().includes(lang))
|
|
64
|
+
return true;
|
|
65
|
+
if (unsupportedLanguages.has(lang))
|
|
66
|
+
return false;
|
|
67
|
+
try {
|
|
68
|
+
await hl.loadLanguage(lang);
|
|
69
|
+
return true;
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
// Not a shiki-recognized grammar id/alias, or the grammar failed to
|
|
73
|
+
// load for some other reason — either way, <lyra-code-block> treats an
|
|
74
|
+
// unrecognized language the same as an unset one (plain text), and
|
|
75
|
+
// there's nothing more specific a caller could do with the reason.
|
|
76
|
+
unsupportedLanguages.add(lang);
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
@@ -54,12 +54,15 @@ export declare class LyraCombobox extends LyraElement {
|
|
|
54
54
|
value: {
|
|
55
55
|
noAccessor: boolean;
|
|
56
56
|
};
|
|
57
|
+
name: {
|
|
58
|
+
reflect: boolean;
|
|
59
|
+
noAccessor: boolean;
|
|
60
|
+
};
|
|
57
61
|
};
|
|
58
62
|
multiple: boolean;
|
|
59
63
|
placeholder: string;
|
|
60
64
|
disabled: boolean;
|
|
61
65
|
required: boolean;
|
|
62
|
-
name: string;
|
|
63
66
|
label: string;
|
|
64
67
|
hint: string;
|
|
65
68
|
errorText: string;
|
|
@@ -84,6 +87,7 @@ export declare class LyraCombobox extends LyraElement {
|
|
|
84
87
|
private _selectedLabelCache;
|
|
85
88
|
private _rowsByValue;
|
|
86
89
|
private internals;
|
|
90
|
+
private _fieldsetDisabled;
|
|
87
91
|
private listId;
|
|
88
92
|
private inputId;
|
|
89
93
|
private cleanup?;
|
|
@@ -91,20 +95,34 @@ export declare class LyraCombobox extends LyraElement {
|
|
|
91
95
|
private _selected;
|
|
92
96
|
private _defaultSelected;
|
|
93
97
|
private _defaultCaptured;
|
|
98
|
+
private _name;
|
|
94
99
|
constructor();
|
|
95
100
|
connectedCallback(): void;
|
|
96
101
|
protected willUpdate(): void;
|
|
102
|
+
get name(): string;
|
|
103
|
+
set name(next: string);
|
|
97
104
|
/** The selected value(s): a string in single mode, a string[] in `multiple` mode. */
|
|
98
105
|
get value(): string | string[];
|
|
99
106
|
set value(next: string | string[]);
|
|
100
107
|
private updateValidity;
|
|
101
108
|
private syncFormValue;
|
|
109
|
+
/** Effective disabled state: this element's own `disabled` OR an ancestor
|
|
110
|
+
* `<fieldset disabled>`'s inherited state -- mirrors native `<input>`, whose
|
|
111
|
+
* own `disabled` IDL property/attribute is never mutated by a fieldset. */
|
|
112
|
+
get effectiveDisabled(): boolean;
|
|
102
113
|
formResetCallback(): void;
|
|
114
|
+
/**
|
|
115
|
+
* Called by the browser when an ancestor `<fieldset disabled>` toggles.
|
|
116
|
+
* Tracked separately from the consumer's own `disabled` (see
|
|
117
|
+
* `effectiveDisabled`) so a consumer's explicit `disabled` survives the
|
|
118
|
+
* fieldset re-enabling instead of being permanently overwritten.
|
|
119
|
+
*/
|
|
103
120
|
formDisabledCallback(disabled: boolean): void;
|
|
104
121
|
checkValidity(): boolean;
|
|
105
122
|
reportValidity(): boolean;
|
|
106
123
|
disconnectedCallback(): void;
|
|
107
124
|
private collectOptions;
|
|
125
|
+
private onOptionChange;
|
|
108
126
|
private reflectSelected;
|
|
109
127
|
private labelFor;
|
|
110
128
|
/** The current row set in a source-agnostic shape, before capping. */
|
|
@@ -4,7 +4,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
4
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
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
|
-
import { html } from 'lit';
|
|
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
10
|
import { defineElement } from '../../internal/prefix.js';
|
|
@@ -54,6 +54,7 @@ export class LyraCombobox extends LyraElement {
|
|
|
54
54
|
static { this.styles = [LyraElement.styles, styles]; }
|
|
55
55
|
static { this.properties = {
|
|
56
56
|
value: { noAccessor: true },
|
|
57
|
+
name: { reflect: true, noAccessor: true },
|
|
57
58
|
}; }
|
|
58
59
|
constructor() {
|
|
59
60
|
super();
|
|
@@ -61,7 +62,6 @@ export class LyraCombobox extends LyraElement {
|
|
|
61
62
|
this.placeholder = '';
|
|
62
63
|
this.disabled = false;
|
|
63
64
|
this.required = false;
|
|
64
|
-
this.name = '';
|
|
65
65
|
this.label = '';
|
|
66
66
|
this.hint = '';
|
|
67
67
|
this.errorText = '';
|
|
@@ -97,6 +97,11 @@ export class LyraCombobox extends LyraElement {
|
|
|
97
97
|
// handlers' data-value lookup below, instead of each option row closing
|
|
98
98
|
// over its own row object.
|
|
99
99
|
this._rowsByValue = new Map();
|
|
100
|
+
// Tracked separately from the consumer's own `disabled` -- a native
|
|
101
|
+
// `<input>`'s own `disabled` IDL property/attribute is never mutated by
|
|
102
|
+
// fieldset cascading, so a consumer's explicit `disabled` must survive the
|
|
103
|
+
// fieldset re-enabling (see `formDisabledCallback` below).
|
|
104
|
+
this._fieldsetDisabled = false;
|
|
100
105
|
this.listId = nextId('combobox-list');
|
|
101
106
|
this.inputId = nextId('combobox-input');
|
|
102
107
|
this._isFirstUpdate = true;
|
|
@@ -111,6 +116,15 @@ export class LyraCombobox extends LyraElement {
|
|
|
111
116
|
// property assignment never does).
|
|
112
117
|
this._defaultSelected = [];
|
|
113
118
|
this._defaultCaptured = false;
|
|
119
|
+
// Hand-written accessor (mirrors the `value` accessor below, and Task 2's
|
|
120
|
+
// `FormAssociated.name` in `../../internal/form-associated.ts`): a
|
|
121
|
+
// form-associated custom element's submitted entry name is resolved by the
|
|
122
|
+
// browser from the live `name` *content attribute*, read synchronously at
|
|
123
|
+
// FormData-construction/submit time (see `syncFormValue()` below) -- Lit's
|
|
124
|
+
// async (microtask-deferred) `reflect: true` alone would leave a
|
|
125
|
+
// property-only assignment like `el.name = 'b'` invisible to a same-tick
|
|
126
|
+
// `new FormData(form)`/submit, so the attribute write happens here instead.
|
|
127
|
+
this._name = '';
|
|
114
128
|
this.collectOptions = (e) => {
|
|
115
129
|
const slot = e.target;
|
|
116
130
|
const previous = new Set(this.options);
|
|
@@ -149,6 +163,14 @@ export class LyraCombobox extends LyraElement {
|
|
|
149
163
|
}
|
|
150
164
|
this.reflectSelected();
|
|
151
165
|
};
|
|
166
|
+
this.onOptionChange = () => {
|
|
167
|
+
// Touch the `options` array reference so Lit's change-detection sees a
|
|
168
|
+
// "new" value and re-renders `renderRows()`/`filtered`/`labelFor()` off
|
|
169
|
+
// the options' now-current data -- the *set* of options is unchanged,
|
|
170
|
+
// only one member's own properties are, so this skips
|
|
171
|
+
// collectOptions()'s selection-seeding logic entirely.
|
|
172
|
+
this.options = [...this.options];
|
|
173
|
+
};
|
|
152
174
|
this.onDocPointer = (e) => {
|
|
153
175
|
if (!e.composedPath().includes(this))
|
|
154
176
|
this.hide();
|
|
@@ -226,7 +248,7 @@ export class LyraCombobox extends LyraElement {
|
|
|
226
248
|
}
|
|
227
249
|
};
|
|
228
250
|
this.onComboMouseDown = (e) => {
|
|
229
|
-
if (this.
|
|
251
|
+
if (this.effectiveDisabled)
|
|
230
252
|
return;
|
|
231
253
|
if (e.target.closest('button'))
|
|
232
254
|
return;
|
|
@@ -268,6 +290,20 @@ export class LyraCombobox extends LyraElement {
|
|
|
268
290
|
this.hasLabelSlot = Array.from(this.children).some((el) => el.getAttribute('slot') === 'label');
|
|
269
291
|
}
|
|
270
292
|
}
|
|
293
|
+
get name() {
|
|
294
|
+
return this._name;
|
|
295
|
+
}
|
|
296
|
+
set name(next) {
|
|
297
|
+
const old = this._name;
|
|
298
|
+
this._name = next ?? '';
|
|
299
|
+
if (this._name) {
|
|
300
|
+
this.setAttribute('name', this._name);
|
|
301
|
+
}
|
|
302
|
+
else {
|
|
303
|
+
this.removeAttribute('name');
|
|
304
|
+
}
|
|
305
|
+
this.requestUpdate('name', old);
|
|
306
|
+
}
|
|
271
307
|
/** The selected value(s): a string in single mode, a string[] in `multiple` mode. */
|
|
272
308
|
get value() {
|
|
273
309
|
return this.multiple ? [...this._selected] : (this._selected[0] ?? '');
|
|
@@ -309,12 +345,25 @@ export class LyraCombobox extends LyraElement {
|
|
|
309
345
|
this.internals.setFormValue(this._selected[0] ?? '');
|
|
310
346
|
}
|
|
311
347
|
}
|
|
348
|
+
/** Effective disabled state: this element's own `disabled` OR an ancestor
|
|
349
|
+
* `<fieldset disabled>`'s inherited state -- mirrors native `<input>`, whose
|
|
350
|
+
* own `disabled` IDL property/attribute is never mutated by a fieldset. */
|
|
351
|
+
get effectiveDisabled() {
|
|
352
|
+
return this.disabled || this._fieldsetDisabled;
|
|
353
|
+
}
|
|
312
354
|
formResetCallback() {
|
|
313
355
|
this.value = [...this._defaultSelected];
|
|
314
356
|
this.query = '';
|
|
315
357
|
}
|
|
358
|
+
/**
|
|
359
|
+
* Called by the browser when an ancestor `<fieldset disabled>` toggles.
|
|
360
|
+
* Tracked separately from the consumer's own `disabled` (see
|
|
361
|
+
* `effectiveDisabled`) so a consumer's explicit `disabled` survives the
|
|
362
|
+
* fieldset re-enabling instead of being permanently overwritten.
|
|
363
|
+
*/
|
|
316
364
|
formDisabledCallback(disabled) {
|
|
317
|
-
this.
|
|
365
|
+
this._fieldsetDisabled = disabled;
|
|
366
|
+
this.requestUpdate();
|
|
318
367
|
}
|
|
319
368
|
checkValidity() {
|
|
320
369
|
return this.internals.checkValidity();
|
|
@@ -325,8 +374,15 @@ export class LyraCombobox extends LyraElement {
|
|
|
325
374
|
disconnectedCallback() {
|
|
326
375
|
super.disconnectedCallback();
|
|
327
376
|
this.cleanup?.();
|
|
377
|
+
this.cleanup = undefined;
|
|
328
378
|
clearTimeout(this.sourceTimer);
|
|
329
379
|
document.removeEventListener('pointerdown', this.onDocPointer);
|
|
380
|
+
// Reset so a reconnect (e.g. a drag-drop reparent) re-triggers
|
|
381
|
+
// `updated()`'s `open`-driven branch -- without this, `open` stays
|
|
382
|
+
// `true` across the disconnect/reconnect and `changed.has('open')` never
|
|
383
|
+
// fires again, leaving the listbox rendered open with no positioning and
|
|
384
|
+
// no outside-click listener.
|
|
385
|
+
this.open = false;
|
|
330
386
|
}
|
|
331
387
|
reflectSelected() {
|
|
332
388
|
const sel = new Set(this._selected);
|
|
@@ -381,7 +437,7 @@ export class LyraCombobox extends LyraElement {
|
|
|
381
437
|
return this._selected[0] ? this.labelFor(this._selected[0]) : '';
|
|
382
438
|
}
|
|
383
439
|
show() {
|
|
384
|
-
if (this.open || this.
|
|
440
|
+
if (this.open || this.effectiveDisabled)
|
|
385
441
|
return;
|
|
386
442
|
this.open = true;
|
|
387
443
|
}
|
|
@@ -422,6 +478,8 @@ export class LyraCombobox extends LyraElement {
|
|
|
422
478
|
}
|
|
423
479
|
if (changed.has('required'))
|
|
424
480
|
this.updateValidity();
|
|
481
|
+
if (changed.has('name') || changed.has('multiple'))
|
|
482
|
+
this.syncFormValue();
|
|
425
483
|
if (changed.has('touched') || changed.has('required') || changed.has('value')) {
|
|
426
484
|
this.toggleAttribute('data-invalid', this.touched && !this.internals.validity.valid);
|
|
427
485
|
}
|
|
@@ -469,11 +527,22 @@ export class LyraCombobox extends LyraElement {
|
|
|
469
527
|
this.sourceTimer = setTimeout(() => {
|
|
470
528
|
const token = ++this.sourceToken;
|
|
471
529
|
this.loading = true;
|
|
472
|
-
this.source(query)
|
|
530
|
+
// `Promise.resolve().then(() => this.source!(query))` moves the call
|
|
531
|
+
// itself inside a `.then()` callback, so a *synchronous* throw from
|
|
532
|
+
// `this.source(query)` becomes a normal promise rejection the
|
|
533
|
+
// following `.catch()` handles, instead of escaping this `setTimeout`
|
|
534
|
+
// callback as an uncaught exception.
|
|
535
|
+
Promise.resolve()
|
|
536
|
+
.then(() => this.source(query))
|
|
473
537
|
.then((rows) => {
|
|
474
538
|
if (token !== this.sourceToken || !this.isConnected)
|
|
475
539
|
return;
|
|
476
540
|
this.asyncRows = rows;
|
|
541
|
+
})
|
|
542
|
+
.catch((err) => {
|
|
543
|
+
if (token !== this.sourceToken || !this.isConnected)
|
|
544
|
+
return;
|
|
545
|
+
console.warn('<lyra-combobox> source() rejected:', err);
|
|
477
546
|
})
|
|
478
547
|
.finally(() => {
|
|
479
548
|
if (token === this.sourceToken)
|
|
@@ -523,6 +592,7 @@ export class LyraCombobox extends LyraElement {
|
|
|
523
592
|
const hasHint = this.hasHintSlot || this.hint.length > 0;
|
|
524
593
|
const hasError = this.hasErrorSlot || this.errorText.length > 0;
|
|
525
594
|
const hasLabel = this.hasLabelSlot || this.label.length > 0;
|
|
595
|
+
const describedBy = [hasError ? 'combobox-error' : '', hasHint ? 'combobox-hint' : ''].filter(Boolean).join(' ');
|
|
526
596
|
return html `
|
|
527
597
|
<div part="form-control">
|
|
528
598
|
<label part="form-control-label" for=${this.inputId} ?hidden=${!hasLabel}>
|
|
@@ -534,6 +604,7 @@ export class LyraCombobox extends LyraElement {
|
|
|
534
604
|
>${this.labelFor(v)}<button
|
|
535
605
|
part="tag__remove-button"
|
|
536
606
|
type="button"
|
|
607
|
+
?disabled=${this.effectiveDisabled}
|
|
537
608
|
aria-label="Remove ${this.labelFor(v)}"
|
|
538
609
|
@click=${(e) => {
|
|
539
610
|
e.stopPropagation();
|
|
@@ -549,7 +620,8 @@ export class LyraCombobox extends LyraElement {
|
|
|
549
620
|
id=${this.inputId}
|
|
550
621
|
part="combobox-input"
|
|
551
622
|
role="combobox"
|
|
552
|
-
aria-label=${this.label || this.placeholder || 'Combobox'}
|
|
623
|
+
aria-label=${this.getAttribute('aria-label') || (hasLabel ? nothing : this.placeholder || 'Combobox')}
|
|
624
|
+
aria-describedby=${describedBy || nothing}
|
|
553
625
|
aria-expanded=${this.open ? 'true' : 'false'}
|
|
554
626
|
aria-controls=${this.listId}
|
|
555
627
|
aria-activedescendant=${activeId}
|
|
@@ -559,7 +631,7 @@ export class LyraCombobox extends LyraElement {
|
|
|
559
631
|
autocomplete="off"
|
|
560
632
|
.value=${this.displayValue}
|
|
561
633
|
placeholder=${hasValue && !this.multiple ? '' : this.placeholder}
|
|
562
|
-
?disabled=${this.
|
|
634
|
+
?disabled=${this.effectiveDisabled}
|
|
563
635
|
@input=${this.onInput}
|
|
564
636
|
@keydown=${this.onKeyDown}
|
|
565
637
|
@focus=${() => this.show()}
|
|
@@ -569,6 +641,7 @@ export class LyraCombobox extends LyraElement {
|
|
|
569
641
|
? html `<button
|
|
570
642
|
part="clear-button"
|
|
571
643
|
type="button"
|
|
644
|
+
?disabled=${this.effectiveDisabled}
|
|
572
645
|
aria-label="Clear"
|
|
573
646
|
@click=${(e) => {
|
|
574
647
|
e.stopPropagation();
|
|
@@ -597,14 +670,14 @@ export class LyraCombobox extends LyraElement {
|
|
|
597
670
|
? html `<div part="option-overflow">+${overflow} more — refine your search</div>`
|
|
598
671
|
: ''}`}
|
|
599
672
|
</div>
|
|
600
|
-
<div part="error" ?hidden=${!hasError}>
|
|
673
|
+
<div id="combobox-error" part="error" ?hidden=${!hasError}>
|
|
601
674
|
${this.errorText}<slot name="error" @slotchange=${this.onErrorSlotChange}></slot>
|
|
602
675
|
</div>
|
|
603
|
-
<div part="hint" ?hidden=${!hasHint}>
|
|
676
|
+
<div id="combobox-hint" part="hint" ?hidden=${!hasHint}>
|
|
604
677
|
${this.hint}<slot name="hint" @slotchange=${this.onHintSlotChange}></slot>
|
|
605
678
|
</div>
|
|
606
679
|
</div>
|
|
607
|
-
<slot @slotchange=${this.collectOptions} hidden></slot>
|
|
680
|
+
<slot @slotchange=${this.collectOptions} @lyra-option-change=${this.onOptionChange} hidden></slot>
|
|
608
681
|
`;
|
|
609
682
|
}
|
|
610
683
|
}
|
|
@@ -620,9 +693,6 @@ __decorate([
|
|
|
620
693
|
__decorate([
|
|
621
694
|
property({ type: Boolean, reflect: true })
|
|
622
695
|
], LyraCombobox.prototype, "required", void 0);
|
|
623
|
-
__decorate([
|
|
624
|
-
property()
|
|
625
|
-
], LyraCombobox.prototype, "name", void 0);
|
|
626
696
|
__decorate([
|
|
627
697
|
property()
|
|
628
698
|
], LyraCombobox.prototype, "label", void 0);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type TemplateResult } from 'lit';
|
|
1
|
+
import { type TemplateResult, type PropertyValues } from 'lit';
|
|
2
2
|
import { LyraElement } from '../../internal/lyra-element.js';
|
|
3
3
|
/**
|
|
4
4
|
* `<lyra-option>` — a selectable option for `<lyra-combobox>`.
|
|
@@ -27,6 +27,10 @@ export declare class LyraOption extends LyraElement {
|
|
|
27
27
|
dotColor: string;
|
|
28
28
|
/** Resolved label: explicit non-empty `label` attribute wins, else trimmed text content. */
|
|
29
29
|
get label(): string;
|
|
30
|
+
private labelObserver?;
|
|
31
|
+
connectedCallback(): void;
|
|
32
|
+
disconnectedCallback(): void;
|
|
33
|
+
protected updated(changed: PropertyValues): void;
|
|
30
34
|
render(): TemplateResult;
|
|
31
35
|
}
|
|
32
36
|
declare global {
|
|
@@ -48,6 +48,41 @@ export class LyraOption extends LyraElement {
|
|
|
48
48
|
const attr = this.getAttribute('label');
|
|
49
49
|
return (attr ? attr : (this.textContent ?? '')).trim();
|
|
50
50
|
}
|
|
51
|
+
connectedCallback() {
|
|
52
|
+
super.connectedCallback();
|
|
53
|
+
// `label` is derived from either the `label` attribute or `textContent` --
|
|
54
|
+
// neither is a Lit reactive property, so a direct mutation of either
|
|
55
|
+
// (e.g. `option.textContent = 'New label'`) needs its own observer to
|
|
56
|
+
// notify the parent combobox/select that its cached row data is stale.
|
|
57
|
+
this.labelObserver = new MutationObserver(() => this.emit('lyra-option-change'));
|
|
58
|
+
this.labelObserver.observe(this, {
|
|
59
|
+
attributes: true,
|
|
60
|
+
attributeFilter: ['label'],
|
|
61
|
+
childList: true,
|
|
62
|
+
characterData: true,
|
|
63
|
+
subtree: true,
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
disconnectedCallback() {
|
|
67
|
+
super.disconnectedCallback();
|
|
68
|
+
this.labelObserver?.disconnect();
|
|
69
|
+
this.labelObserver = undefined;
|
|
70
|
+
}
|
|
71
|
+
updated(changed) {
|
|
72
|
+
// `selected` is deliberately excluded -- the parent combobox/select
|
|
73
|
+
// already sets `selected` itself as *part of* rendering the current
|
|
74
|
+
// selection, so echoing that back as a `lyra-option-change` notification
|
|
75
|
+
// would trigger a redundant re-render on every selection change, rather
|
|
76
|
+
// than signal a genuine "this option's own data changed externally".
|
|
77
|
+
if (changed.has('value') ||
|
|
78
|
+
changed.has('disabled') ||
|
|
79
|
+
changed.has('group') ||
|
|
80
|
+
changed.has('searchText') ||
|
|
81
|
+
changed.has('sub') ||
|
|
82
|
+
changed.has('dotColor')) {
|
|
83
|
+
this.emit('lyra-option-change');
|
|
84
|
+
}
|
|
85
|
+
}
|
|
51
86
|
render() {
|
|
52
87
|
return html `<slot></slot>`;
|
|
53
88
|
}
|