@aceshooting/lyra-ui 1.2.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -0
- package/custom-elements.json +23341 -11202
- package/dist/components/app-rail/app-rail.d.ts +171 -0
- package/dist/components/app-rail/app-rail.js +483 -0
- package/dist/components/app-rail/app-rail.styles.d.ts +1 -0
- package/dist/components/app-rail/app-rail.styles.js +125 -0
- package/dist/components/attachment-chip/attachment-chip.d.ts +114 -0
- package/dist/components/attachment-chip/attachment-chip.js +312 -0
- package/dist/components/attachment-chip/attachment-chip.styles.d.ts +1 -0
- package/dist/components/attachment-chip/attachment-chip.styles.js +184 -0
- package/dist/components/attachment-trigger/attachment-trigger.d.ts +83 -0
- package/dist/components/attachment-trigger/attachment-trigger.js +258 -0
- package/dist/components/attachment-trigger/attachment-trigger.styles.d.ts +1 -0
- package/dist/components/attachment-trigger/attachment-trigger.styles.js +68 -0
- package/dist/components/chart/box-plot.js +11 -1
- package/dist/components/chart/chart-loader.d.ts +44 -13
- package/dist/components/chart/chart-loader.js +65 -18
- package/dist/components/chart/chart.d.ts +1 -2
- package/dist/components/chart/chart.js +67 -12
- package/dist/components/chart/histogram-bin.d.ts +4 -1
- package/dist/components/chart/histogram-bin.js +24 -14
- package/dist/components/chart/lite-chart.d.ts +54 -0
- package/dist/components/chart/lite-chart.js +140 -22
- package/dist/components/chart/lite-chart.styles.js +9 -0
- package/dist/components/chat-composer/chat-composer.d.ts +92 -0
- package/dist/components/chat-composer/chat-composer.js +285 -0
- package/dist/components/chat-composer/chat-composer.styles.d.ts +1 -0
- package/dist/components/chat-composer/chat-composer.styles.js +135 -0
- package/dist/components/chat-message/chat-message.d.ts +113 -0
- package/dist/components/chat-message/chat-message.js +291 -0
- package/dist/components/chat-message/chat-message.styles.d.ts +1 -0
- package/dist/components/chat-message/chat-message.styles.js +203 -0
- package/dist/components/checkbox/checkbox.d.ts +59 -0
- package/dist/components/checkbox/checkbox.js +230 -0
- package/dist/components/checkbox/checkbox.styles.d.ts +1 -0
- package/dist/components/checkbox/checkbox.styles.js +70 -0
- package/dist/components/chip/chip-group.d.ts +56 -0
- package/dist/components/chip/chip-group.js +124 -0
- package/dist/components/chip/chip-group.styles.d.ts +1 -0
- package/dist/components/chip/chip-group.styles.js +57 -0
- package/dist/components/chip/chip.d.ts +64 -0
- package/dist/components/chip/chip.js +115 -0
- package/dist/components/chip/chip.styles.d.ts +1 -0
- package/dist/components/chip/chip.styles.js +115 -0
- package/dist/components/citation-badge/citation-badge.d.ts +113 -0
- package/dist/components/citation-badge/citation-badge.js +300 -0
- package/dist/components/citation-badge/citation-badge.styles.d.ts +1 -0
- package/dist/components/citation-badge/citation-badge.styles.js +96 -0
- package/dist/components/code-block/code-block.d.ts +89 -0
- package/dist/components/code-block/code-block.js +317 -0
- package/dist/components/code-block/code-block.styles.d.ts +1 -0
- package/dist/components/code-block/code-block.styles.js +187 -0
- package/dist/components/code-block/code-loader.d.ts +44 -0
- package/dist/components/code-block/code-loader.js +79 -0
- package/dist/components/combobox/combobox.d.ts +19 -1
- package/dist/components/combobox/combobox.js +84 -14
- package/dist/components/combobox/option.d.ts +5 -1
- package/dist/components/combobox/option.js +35 -0
- package/dist/components/context-meter/context-meter.d.ts +53 -0
- package/dist/components/context-meter/context-meter.js +150 -0
- package/dist/components/context-meter/context-meter.styles.d.ts +1 -0
- package/dist/components/context-meter/context-meter.styles.js +120 -0
- package/dist/components/conversation-item/conversation-item.d.ts +128 -0
- package/dist/components/conversation-item/conversation-item.js +322 -0
- package/dist/components/conversation-item/conversation-item.styles.d.ts +1 -0
- package/dist/components/conversation-item/conversation-item.styles.js +155 -0
- package/dist/components/date-picker/date-input.d.ts +24 -0
- package/dist/components/date-picker/date-input.js +134 -22
- package/dist/components/date-picker/date-picker.d.ts +7 -0
- package/dist/components/date-picker/date-picker.js +85 -16
- package/dist/components/dialog/confirm.d.ts +40 -0
- package/dist/components/dialog/confirm.js +79 -0
- package/dist/components/dialog/dialog.d.ts +85 -0
- package/dist/components/dialog/dialog.js +272 -0
- package/dist/components/dialog/dialog.styles.d.ts +1 -0
- package/dist/components/dialog/dialog.styles.js +52 -0
- package/dist/components/dock-panel/dock-panel.d.ts +134 -0
- package/dist/components/dock-panel/dock-panel.js +345 -0
- package/dist/components/dock-panel/dock-panel.styles.d.ts +1 -0
- package/dist/components/dock-panel/dock-panel.styles.js +145 -0
- package/dist/components/document-preview/document-preview.d.ts +135 -0
- package/dist/components/document-preview/document-preview.js +372 -0
- package/dist/components/document-preview/document-preview.styles.d.ts +1 -0
- package/dist/components/document-preview/document-preview.styles.js +191 -0
- package/dist/components/export-button/csv.js +1 -1
- package/dist/components/export-button/export-button.js +2 -0
- package/dist/components/flag/flag.d.ts +29 -13
- package/dist/components/flag/flag.js +39 -13
- package/dist/components/gauge/gauge.js +19 -10
- package/dist/components/generation-status/generation-status.d.ts +109 -0
- package/dist/components/generation-status/generation-status.js +273 -0
- package/dist/components/generation-status/generation-status.styles.d.ts +1 -0
- package/dist/components/generation-status/generation-status.styles.js +84 -0
- package/dist/components/heatmap/calendar-grid.d.ts +4 -1
- package/dist/components/heatmap/calendar-grid.js +25 -12
- package/dist/components/heatmap/heatmap-scale.d.ts +6 -0
- package/dist/components/heatmap/heatmap-scale.js +7 -1
- package/dist/components/heatmap/heatmap.d.ts +74 -0
- package/dist/components/heatmap/heatmap.js +135 -23
- package/dist/components/json-viewer/json-viewer.d.ts +53 -0
- package/dist/components/json-viewer/json-viewer.js +283 -0
- package/dist/components/json-viewer/json-viewer.styles.d.ts +1 -0
- package/dist/components/json-viewer/json-viewer.styles.js +176 -0
- package/dist/components/kbd/kbd.d.ts +77 -0
- package/dist/components/kbd/kbd.js +214 -0
- package/dist/components/kbd/kbd.styles.d.ts +1 -0
- package/dist/components/kbd/kbd.styles.js +52 -0
- package/dist/components/live-region/live-region.d.ts +81 -0
- package/dist/components/live-region/live-region.js +153 -0
- package/dist/components/live-region/live-region.styles.d.ts +1 -0
- package/dist/components/live-region/live-region.styles.js +10 -0
- package/dist/components/map/map.d.ts +8 -6
- package/dist/components/map/map.js +44 -8
- package/dist/components/markdown/markdown-loader.d.ts +34 -0
- package/dist/components/markdown/markdown-loader.js +43 -0
- package/dist/components/markdown/markdown.d.ts +81 -0
- package/dist/components/markdown/markdown.js +284 -0
- package/dist/components/markdown/markdown.styles.d.ts +1 -0
- package/dist/components/markdown/markdown.styles.js +82 -0
- package/dist/components/media-card/media-card.d.ts +122 -0
- package/dist/components/media-card/media-card.js +295 -0
- package/dist/components/media-card/media-card.styles.d.ts +1 -0
- package/dist/components/media-card/media-card.styles.js +132 -0
- package/dist/components/mention-popover/mention-popover.d.ts +200 -0
- package/dist/components/mention-popover/mention-popover.js +475 -0
- package/dist/components/mention-popover/mention-popover.styles.d.ts +1 -0
- package/dist/components/mention-popover/mention-popover.styles.js +101 -0
- package/dist/components/menu/menu-item.d.ts +62 -0
- package/dist/components/menu/menu-item.js +119 -0
- package/dist/components/menu/menu-item.styles.d.ts +1 -0
- package/dist/components/menu/menu-item.styles.js +67 -0
- package/dist/components/menu/menu.d.ts +143 -0
- package/dist/components/menu/menu.js +365 -0
- package/dist/components/menu/menu.styles.d.ts +1 -0
- package/dist/components/menu/menu.styles.js +66 -0
- package/dist/components/model-select/model-select.d.ts +125 -0
- package/dist/components/model-select/model-select.js +490 -0
- package/dist/components/model-select/model-select.styles.d.ts +1 -0
- package/dist/components/model-select/model-select.styles.js +189 -0
- package/dist/components/model-settings-panel/model-settings-panel.d.ts +69 -0
- package/dist/components/model-settings-panel/model-settings-panel.js +145 -0
- package/dist/components/model-settings-panel/model-settings-panel.styles.d.ts +1 -0
- package/dist/components/model-settings-panel/model-settings-panel.styles.js +82 -0
- package/dist/components/playback/playback.d.ts +13 -1
- package/dist/components/playback/playback.js +47 -14
- package/dist/components/responsive-panel/responsive-panel.d.ts +150 -0
- package/dist/components/responsive-panel/responsive-panel.js +365 -0
- package/dist/components/responsive-panel/responsive-panel.styles.d.ts +1 -0
- package/dist/components/responsive-panel/responsive-panel.styles.js +103 -0
- package/dist/components/result-card/result-card.d.ts +44 -0
- package/dist/components/result-card/result-card.js +83 -0
- package/dist/components/result-card/result-card.styles.d.ts +1 -0
- package/dist/components/result-card/result-card.styles.js +50 -0
- package/dist/components/result-card/result-field.d.ts +36 -0
- package/dist/components/result-card/result-field.js +87 -0
- package/dist/components/result-card/result-field.styles.d.ts +1 -0
- package/dist/components/result-card/result-field.styles.js +32 -0
- package/dist/components/select/select.d.ts +43 -2
- package/dist/components/select/select.js +150 -17
- package/dist/components/slider/slider.d.ts +89 -0
- package/dist/components/slider/slider.js +352 -0
- package/dist/components/slider/slider.styles.d.ts +1 -0
- package/dist/components/slider/slider.styles.js +87 -0
- package/dist/components/source-card/source-card.d.ts +92 -0
- package/dist/components/source-card/source-card.js +148 -0
- package/dist/components/source-card/source-card.styles.d.ts +1 -0
- package/dist/components/source-card/source-card.styles.js +69 -0
- package/dist/components/source-list/source-list.d.ts +63 -0
- package/dist/components/source-list/source-list.js +122 -0
- package/dist/components/source-list/source-list.styles.d.ts +1 -0
- package/dist/components/source-list/source-list.styles.js +59 -0
- package/dist/components/sparkline/sparkline.js +27 -13
- package/dist/components/split/split.d.ts +93 -1
- package/dist/components/split/split.js +284 -15
- package/dist/components/split/split.styles.js +30 -0
- package/dist/components/stat/stat.d.ts +6 -1
- package/dist/components/stat/stat.js +8 -2
- package/dist/components/stream-status/stream-status.d.ts +110 -0
- package/dist/components/stream-status/stream-status.js +210 -0
- package/dist/components/stream-status/stream-status.styles.d.ts +1 -0
- package/dist/components/stream-status/stream-status.styles.js +103 -0
- package/dist/components/streaming-text/streaming-text.d.ts +98 -0
- package/dist/components/streaming-text/streaming-text.js +209 -0
- package/dist/components/streaming-text/streaming-text.styles.d.ts +1 -0
- package/dist/components/streaming-text/streaming-text.styles.js +62 -0
- package/dist/components/switch/switch.d.ts +58 -0
- package/dist/components/switch/switch.js +179 -0
- package/dist/components/switch/switch.styles.d.ts +1 -0
- package/dist/components/switch/switch.styles.js +75 -0
- package/dist/components/table/table.d.ts +73 -4
- package/dist/components/table/table.js +169 -20
- package/dist/components/table/table.styles.js +6 -1
- package/dist/components/tabs/tabs.d.ts +51 -0
- package/dist/components/tabs/tabs.js +190 -0
- package/dist/components/tabs/tabs.styles.d.ts +1 -0
- package/dist/components/tabs/tabs.styles.js +63 -0
- package/dist/components/thinking-panel/thinking-panel.d.ts +121 -0
- package/dist/components/thinking-panel/thinking-panel.js +235 -0
- package/dist/components/thinking-panel/thinking-panel.styles.d.ts +1 -0
- package/dist/components/thinking-panel/thinking-panel.styles.js +117 -0
- package/dist/components/toast/toast-item.d.ts +1 -0
- package/dist/components/toast/toast-item.js +31 -6
- package/dist/components/tool-approval-dialog/tool-approval-dialog.d.ts +130 -0
- package/dist/components/tool-approval-dialog/tool-approval-dialog.js +403 -0
- package/dist/components/tool-approval-dialog/tool-approval-dialog.styles.d.ts +1 -0
- package/dist/components/tool-approval-dialog/tool-approval-dialog.styles.js +160 -0
- package/dist/components/tool-call-chip/tool-call-chip.d.ts +89 -0
- package/dist/components/tool-call-chip/tool-call-chip.js +288 -0
- package/dist/components/tool-call-chip/tool-call-chip.styles.d.ts +1 -0
- package/dist/components/tool-call-chip/tool-call-chip.styles.js +203 -0
- package/dist/components/tool-param-form/tool-param-form.d.ts +145 -0
- package/dist/components/tool-param-form/tool-param-form.js +366 -0
- package/dist/components/tool-param-form/tool-param-form.styles.d.ts +1 -0
- package/dist/components/tool-param-form/tool-param-form.styles.js +75 -0
- package/dist/components/tool-result-dialog/tool-result-dialog.d.ts +102 -0
- package/dist/components/tool-result-dialog/tool-result-dialog.js +393 -0
- package/dist/components/tool-result-dialog/tool-result-dialog.styles.d.ts +1 -0
- package/dist/components/tool-result-dialog/tool-result-dialog.styles.js +176 -0
- package/dist/components/tool-result-view/registry.d.ts +81 -0
- package/dist/components/tool-result-view/registry.js +84 -0
- package/dist/components/tool-result-view/tool-result-view.d.ts +55 -0
- package/dist/components/tool-result-view/tool-result-view.js +138 -0
- package/dist/components/tool-result-view/tool-result-view.styles.d.ts +1 -0
- package/dist/components/tool-result-view/tool-result-view.styles.js +13 -0
- package/dist/components/tool-select-dialog/tool-select-dialog.d.ts +151 -0
- package/dist/components/tool-select-dialog/tool-select-dialog.js +439 -0
- package/dist/components/tool-select-dialog/tool-select-dialog.styles.d.ts +1 -0
- package/dist/components/tool-select-dialog/tool-select-dialog.styles.js +182 -0
- package/dist/components/tree/tree-node.d.ts +11 -2
- package/dist/components/tree/tree-node.js +16 -6
- package/dist/components/tree/tree.d.ts +8 -2
- package/dist/components/tree/tree.js +18 -11
- package/dist/components/typing-indicator/typing-indicator.d.ts +60 -0
- package/dist/components/typing-indicator/typing-indicator.js +96 -0
- package/dist/components/typing-indicator/typing-indicator.styles.d.ts +1 -0
- package/dist/components/typing-indicator/typing-indicator.styles.js +132 -0
- package/dist/components/virtual-list/virtual-list.d.ts +173 -0
- package/dist/components/virtual-list/virtual-list.js +461 -0
- package/dist/components/virtual-list/virtual-list.styles.d.ts +1 -0
- package/dist/components/virtual-list/virtual-list.styles.js +44 -0
- package/dist/components/word-cloud/word-cloud-layout.js +14 -1
- package/dist/components/word-cloud/word-cloud.d.ts +6 -0
- package/dist/components/word-cloud/word-cloud.js +25 -14
- package/dist/components/word-cloud/word-cloud.styles.js +3 -2
- package/dist/internal/announcer.d.ts +57 -0
- package/dist/internal/announcer.js +71 -0
- package/dist/internal/form-associated.d.ts +1 -0
- package/dist/internal/form-associated.js +55 -11
- package/dist/internal/group-by-recency.d.ts +50 -0
- package/dist/internal/group-by-recency.js +80 -0
- package/dist/internal/rtl.d.ts +23 -0
- package/dist/internal/rtl.js +28 -0
- package/dist/internal/scroll-lock.d.ts +10 -5
- package/dist/internal/scroll-lock.js +30 -14
- package/dist/internal/tokens.styles.js +6 -0
- package/dist/lyra.d.ts +130 -31
- package/dist/lyra.js +94 -26
- package/llms-full.txt +3836 -17
- package/llms.txt +16 -1
- package/package.json +23 -5
- package/dist/components/chart/bar-chart.stories.d.ts +0 -5
- package/dist/components/chart/bar-chart.stories.js +0 -20
- package/dist/components/chart/box-plot.stories.d.ts +0 -5
- package/dist/components/chart/box-plot.stories.js +0 -29
- package/dist/components/chart/bubble-chart.stories.d.ts +0 -5
- package/dist/components/chart/bubble-chart.stories.js +0 -26
- package/dist/components/chart/chart.stories.d.ts +0 -32
- package/dist/components/chart/chart.stories.js +0 -141
- package/dist/components/chart/doughnut-chart.stories.d.ts +0 -5
- package/dist/components/chart/doughnut-chart.stories.js +0 -26
- package/dist/components/chart/histogram.stories.d.ts +0 -5
- package/dist/components/chart/histogram.stories.js +0 -17
- package/dist/components/chart/line-chart.stories.d.ts +0 -22
- package/dist/components/chart/line-chart.stories.js +0 -99
- package/dist/components/chart/lite-chart.stories.d.ts +0 -14
- package/dist/components/chart/lite-chart.stories.js +0 -114
- package/dist/components/chart/pie-chart.stories.d.ts +0 -5
- package/dist/components/chart/pie-chart.stories.js +0 -26
- package/dist/components/chart/polar-area-chart.stories.d.ts +0 -5
- package/dist/components/chart/polar-area-chart.stories.js +0 -20
- package/dist/components/chart/radar-chart.stories.d.ts +0 -5
- package/dist/components/chart/radar-chart.stories.js +0 -20
- package/dist/components/chart/scatter-chart.stories.d.ts +0 -5
- package/dist/components/chart/scatter-chart.stories.js +0 -31
- package/dist/components/combobox/combobox.stories.d.ts +0 -24
- package/dist/components/combobox/combobox.stories.js +0 -102
- package/dist/components/date-picker/date-input.stories.d.ts +0 -10
- package/dist/components/date-picker/date-input.stories.js +0 -48
- package/dist/components/date-picker/date-picker.stories.d.ts +0 -10
- package/dist/components/date-picker/date-picker.stories.js +0 -25
- package/dist/components/empty/empty.stories.d.ts +0 -7
- package/dist/components/empty/empty.stories.js +0 -34
- package/dist/components/export-button/export-button.stories.d.ts +0 -7
- package/dist/components/export-button/export-button.stories.js +0 -37
- package/dist/components/file-input/file-input.stories.d.ts +0 -7
- package/dist/components/file-input/file-input.stories.js +0 -19
- package/dist/components/flag/flag.stories.d.ts +0 -6
- package/dist/components/flag/flag.stories.js +0 -31
- package/dist/components/gauge/gauge.stories.d.ts +0 -8
- package/dist/components/gauge/gauge.stories.js +0 -19
- package/dist/components/graph/graph.stories.d.ts +0 -8
- package/dist/components/graph/graph.stories.js +0 -68
- package/dist/components/heatmap/heatmap.stories.d.ts +0 -27
- package/dist/components/heatmap/heatmap.stories.js +0 -179
- package/dist/components/map/map.stories.d.ts +0 -15
- package/dist/components/map/map.stories.js +0 -135
- package/dist/components/playback/playback.stories.d.ts +0 -7
- package/dist/components/playback/playback.stories.js +0 -16
- package/dist/components/select/select.stories.d.ts +0 -21
- package/dist/components/select/select.stories.js +0 -91
- package/dist/components/skeleton/skeleton.stories.d.ts +0 -5
- package/dist/components/skeleton/skeleton.stories.js +0 -16
- package/dist/components/sparkline/sparkline.stories.d.ts +0 -11
- package/dist/components/sparkline/sparkline.stories.js +0 -39
- package/dist/components/split/split.stories.d.ts +0 -7
- package/dist/components/split/split.stories.js +0 -36
- package/dist/components/stat/stat.stories.d.ts +0 -9
- package/dist/components/stat/stat.stories.js +0 -81
- package/dist/components/table/table.stories.d.ts +0 -12
- package/dist/components/table/table.stories.js +0 -67
- package/dist/components/time-range/time-range.stories.d.ts +0 -8
- package/dist/components/time-range/time-range.stories.js +0 -26
- package/dist/components/toast/toast.stories.d.ts +0 -8
- package/dist/components/toast/toast.stories.js +0 -72
- package/dist/components/tree/tree.stories.d.ts +0 -9
- package/dist/components/tree/tree.stories.js +0 -52
- package/dist/components/widget/widget.stories.d.ts +0 -9
- package/dist/components/widget/widget.stories.js +0 -74
- package/dist/components/word-cloud/word-cloud.stories.d.ts +0 -10
- package/dist/components/word-cloud/word-cloud.stories.js +0 -55
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { html, nothing } from 'lit';
|
|
8
|
+
import { property, state } from 'lit/decorators.js';
|
|
9
|
+
import { LyraElement } from '../../internal/lyra-element.js';
|
|
10
|
+
import { defineElement } from '../../internal/prefix.js';
|
|
11
|
+
import { nextId } from '../../internal/a11y.js';
|
|
12
|
+
import { styles } from './source-card.styles.js';
|
|
13
|
+
/**
|
|
14
|
+
* `<lyra-source-card>` — one citation/source entry, meant to be a direct
|
|
15
|
+
* light-DOM child of `<lyra-source-list>` (though it renders and functions
|
|
16
|
+
* fine standalone). Shows a title/page heading, an always-visible `excerpt`
|
|
17
|
+
* slot, and an optional `full` slot revealed behind its own independent
|
|
18
|
+
* "Show more" toggle — unrelated to the parent `<lyra-source-list>`'s own
|
|
19
|
+
* expand/collapse, which only ever hides/shows the *set* of cards, never a
|
|
20
|
+
* single card's own content.
|
|
21
|
+
*
|
|
22
|
+
* `source-id` is this card's stable identity, meant to match a
|
|
23
|
+
* `<lyra-citation-badge>` (a sibling component) elsewhere on the page. This
|
|
24
|
+
* component doesn't implement any scroll-to/highlight behavior itself — that
|
|
25
|
+
* lives at the app level, wiring a citation badge's activation event to this
|
|
26
|
+
* card's `id`/`source-id`. See the `@example` below.
|
|
27
|
+
*
|
|
28
|
+
* @customElement lyra-source-card
|
|
29
|
+
* @slot excerpt - A short preview, always visible.
|
|
30
|
+
* @slot full - The complete source text/chunk, hidden behind the "Show
|
|
31
|
+
* more"/"Show less" toggle. When left empty, no toggle renders at all — a
|
|
32
|
+
* card with no `full` content simply has no expand affordance.
|
|
33
|
+
* @event lyra-expand - The per-card "Show more"/"Show less" toggle was
|
|
34
|
+
* activated. `detail: { sourceId, expanded }`.
|
|
35
|
+
* @event lyra-open - The title was activated. `detail: { sourceId, href }` —
|
|
36
|
+
* `href` may be `undefined`. This component never navigates on its own
|
|
37
|
+
* (staying a controlled component, the same convention
|
|
38
|
+
* `<lyra-tool-call-chip>`'s `lyra-tool-chip-select` follows); a listener
|
|
39
|
+
* decides what "open" means (open `href` in a new tab, open an in-app
|
|
40
|
+
* viewer, etc).
|
|
41
|
+
* @csspart base - The outer container.
|
|
42
|
+
* @csspart title - The clickable title/page heading (`<button>`).
|
|
43
|
+
* @csspart excerpt - The wrapper around the `excerpt` slot.
|
|
44
|
+
* @csspart full - The wrapper around the `full` slot, `hidden` while collapsed.
|
|
45
|
+
* @csspart toggle - The "Show more"/"Show less" button. Only rendered when the `full` slot has content.
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* ```html
|
|
49
|
+
* <lyra-source-list label-plural="2 sources">
|
|
50
|
+
* <lyra-source-card source-id="doc-1" title="annual_report.pdf" page="12">
|
|
51
|
+
* <span slot="excerpt">Revenue grew 12% year over year...</span>
|
|
52
|
+
* <span slot="full">Revenue grew 12% year over year, driven primarily by...</span>
|
|
53
|
+
* </lyra-source-card>
|
|
54
|
+
* </lyra-source-list>
|
|
55
|
+
* ```
|
|
56
|
+
* ```js
|
|
57
|
+
* // Elsewhere, a <lyra-citation-badge>'s activation handler can scroll to
|
|
58
|
+
* // and highlight the matching card -- this component needs no extra API
|
|
59
|
+
* // surface for that, only its existing source-id to be targeted by:
|
|
60
|
+
* document.addEventListener('lyra-citation-activate', (e) => {
|
|
61
|
+
* const card = document.querySelector(`lyra-source-card[source-id="${e.detail.sourceId}"]`);
|
|
62
|
+
* card?.scrollIntoView({ behavior: 'smooth', block: 'center' });
|
|
63
|
+
* card?.classList.add('is-highlighted'); // consumer-defined CSS, e.g. a brief background flash
|
|
64
|
+
* setTimeout(() => card?.classList.remove('is-highlighted'), 2000);
|
|
65
|
+
* });
|
|
66
|
+
* ```
|
|
67
|
+
*/
|
|
68
|
+
export class LyraSourceCard extends LyraElement {
|
|
69
|
+
constructor() {
|
|
70
|
+
super(...arguments);
|
|
71
|
+
/** Stable identifier matching a `<lyra-citation-badge>` elsewhere on the page. */
|
|
72
|
+
this.sourceId = '';
|
|
73
|
+
/** The source's display title, e.g. a filename. */
|
|
74
|
+
this.title = '';
|
|
75
|
+
// See `<lyra-widget>`'s `hasActionsSlot` for the identical
|
|
76
|
+
// presence-tracking convention -- a `[part]` always contains a literal
|
|
77
|
+
// `<slot>` child regardless of assigned content, so CSS `:empty` never
|
|
78
|
+
// matches; real emptiness is tracked in JS instead.
|
|
79
|
+
this.hasFullSlot = false;
|
|
80
|
+
this.fullExpanded = false;
|
|
81
|
+
this.fullId = nextId('source-card-full');
|
|
82
|
+
this.onFullSlotChange = (e) => {
|
|
83
|
+
this.hasFullSlot = e.target.assignedElements({ flatten: true }).length > 0;
|
|
84
|
+
};
|
|
85
|
+
this.onTitleClick = () => {
|
|
86
|
+
this.emit('lyra-open', { sourceId: this.sourceId, href: this.href });
|
|
87
|
+
};
|
|
88
|
+
this.toggleFull = () => {
|
|
89
|
+
this.fullExpanded = !this.fullExpanded;
|
|
90
|
+
this.emit('lyra-expand', { sourceId: this.sourceId, expanded: this.fullExpanded });
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
static { this.styles = [LyraElement.styles, styles]; }
|
|
94
|
+
willUpdate() {
|
|
95
|
+
if (!this.hasUpdated) {
|
|
96
|
+
this.hasFullSlot = Array.from(this.children).some((el) => el.getAttribute('slot') === 'full');
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
firstUpdated() {
|
|
100
|
+
const slot = this.shadowRoot.querySelector('slot[name="full"]');
|
|
101
|
+
this.hasFullSlot = slot.assignedElements({ flatten: true }).length > 0;
|
|
102
|
+
}
|
|
103
|
+
get titleText() {
|
|
104
|
+
const base = this.title || 'Untitled source';
|
|
105
|
+
return this.page == null || this.page === '' ? base : `${base} — p. ${this.page}`;
|
|
106
|
+
}
|
|
107
|
+
render() {
|
|
108
|
+
return html `
|
|
109
|
+
<div part="base">
|
|
110
|
+
<button part="title" type="button" @click=${this.onTitleClick}>${this.titleText}</button>
|
|
111
|
+
<div part="excerpt"><slot name="excerpt"></slot></div>
|
|
112
|
+
${this.hasFullSlot
|
|
113
|
+
? html `<button
|
|
114
|
+
part="toggle"
|
|
115
|
+
type="button"
|
|
116
|
+
aria-expanded=${this.fullExpanded ? 'true' : 'false'}
|
|
117
|
+
aria-controls=${this.fullId}
|
|
118
|
+
@click=${this.toggleFull}
|
|
119
|
+
>
|
|
120
|
+
${this.fullExpanded ? 'Show less' : 'Show more'}
|
|
121
|
+
</button>`
|
|
122
|
+
: nothing}
|
|
123
|
+
<div part="full" id=${this.fullId} ?hidden=${!this.fullExpanded}>
|
|
124
|
+
<slot name="full" @slotchange=${this.onFullSlotChange}></slot>
|
|
125
|
+
</div>
|
|
126
|
+
</div>
|
|
127
|
+
`;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
__decorate([
|
|
131
|
+
property({ attribute: 'source-id' })
|
|
132
|
+
], LyraSourceCard.prototype, "sourceId", void 0);
|
|
133
|
+
__decorate([
|
|
134
|
+
property()
|
|
135
|
+
], LyraSourceCard.prototype, "title", void 0);
|
|
136
|
+
__decorate([
|
|
137
|
+
property()
|
|
138
|
+
], LyraSourceCard.prototype, "page", void 0);
|
|
139
|
+
__decorate([
|
|
140
|
+
property()
|
|
141
|
+
], LyraSourceCard.prototype, "href", void 0);
|
|
142
|
+
__decorate([
|
|
143
|
+
state()
|
|
144
|
+
], LyraSourceCard.prototype, "hasFullSlot", void 0);
|
|
145
|
+
__decorate([
|
|
146
|
+
state()
|
|
147
|
+
], LyraSourceCard.prototype, "fullExpanded", void 0);
|
|
148
|
+
defineElement('source-card', LyraSourceCard);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const styles: import("lit").CSSResult;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { css } from 'lit';
|
|
2
|
+
export const styles = css `
|
|
3
|
+
:host {
|
|
4
|
+
display: block;
|
|
5
|
+
}
|
|
6
|
+
[part='base'] {
|
|
7
|
+
display: flex;
|
|
8
|
+
flex-direction: column;
|
|
9
|
+
gap: var(--lyra-space-xs);
|
|
10
|
+
padding: var(--lyra-space-s);
|
|
11
|
+
border: 1px solid var(--lyra-color-border);
|
|
12
|
+
border-radius: var(--lyra-radius);
|
|
13
|
+
background: var(--lyra-color-surface);
|
|
14
|
+
}
|
|
15
|
+
[part='title'] {
|
|
16
|
+
align-self: flex-start;
|
|
17
|
+
border: none;
|
|
18
|
+
background: none;
|
|
19
|
+
padding: 0;
|
|
20
|
+
margin: 0;
|
|
21
|
+
color: var(--lyra-color-brand);
|
|
22
|
+
font: inherit;
|
|
23
|
+
font-weight: 600;
|
|
24
|
+
font-size: 0.875rem;
|
|
25
|
+
text-align: start;
|
|
26
|
+
cursor: pointer;
|
|
27
|
+
}
|
|
28
|
+
[part='title']:hover {
|
|
29
|
+
text-decoration: underline;
|
|
30
|
+
}
|
|
31
|
+
[part='title']:focus-visible,
|
|
32
|
+
[part='toggle']:focus-visible {
|
|
33
|
+
outline: var(--lyra-focus-ring-width) solid var(--lyra-focus-ring-color);
|
|
34
|
+
outline-offset: var(--lyra-focus-ring-offset);
|
|
35
|
+
}
|
|
36
|
+
[part='excerpt'] {
|
|
37
|
+
color: var(--lyra-color-text-quiet);
|
|
38
|
+
font-size: 0.8125rem;
|
|
39
|
+
line-height: 1.4;
|
|
40
|
+
}
|
|
41
|
+
[part='excerpt']:empty {
|
|
42
|
+
display: none;
|
|
43
|
+
}
|
|
44
|
+
[part='toggle'] {
|
|
45
|
+
align-self: flex-start;
|
|
46
|
+
border: none;
|
|
47
|
+
background: none;
|
|
48
|
+
padding: 0;
|
|
49
|
+
margin: 0;
|
|
50
|
+
color: var(--lyra-color-brand);
|
|
51
|
+
font: inherit;
|
|
52
|
+
font-size: 0.75rem;
|
|
53
|
+
font-weight: 600;
|
|
54
|
+
cursor: pointer;
|
|
55
|
+
}
|
|
56
|
+
[part='toggle']:hover {
|
|
57
|
+
text-decoration: underline;
|
|
58
|
+
}
|
|
59
|
+
[part='full'] {
|
|
60
|
+
padding-block-start: var(--lyra-space-xs);
|
|
61
|
+
border-block-start: 1px solid var(--lyra-color-border);
|
|
62
|
+
color: var(--lyra-color-text);
|
|
63
|
+
font-size: 0.8125rem;
|
|
64
|
+
line-height: 1.4;
|
|
65
|
+
}
|
|
66
|
+
[part='full'][hidden] {
|
|
67
|
+
display: none;
|
|
68
|
+
}
|
|
69
|
+
`;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { type TemplateResult } from 'lit';
|
|
2
|
+
import { LyraElement } from '../../internal/lyra-element.js';
|
|
3
|
+
export interface SourceListToggleDetail {
|
|
4
|
+
expanded: boolean;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* `<lyra-source-list>` — a collapsible "Sources" panel for one chat message,
|
|
8
|
+
* grouping a set of `<lyra-source-card>` children (its default-slot light-DOM
|
|
9
|
+
* children, plain composition — no `.items` array prop, the same shape
|
|
10
|
+
* `<lyra-split>`'s panels take) behind a single clickable header.
|
|
11
|
+
*
|
|
12
|
+
* This library has no built-in i18n/pluralization (see `<lyra-empty>`'s plain
|
|
13
|
+
* `description` prop for the same stance), so the header text is entirely
|
|
14
|
+
* consumer-supplied: `label-plural` (e.g. `"3 sources"`) wins when set,
|
|
15
|
+
* falling back to `label`, falling back to the literal word `"Sources"` — see
|
|
16
|
+
* each property's own doc. `sourceCount` (a read-only, live-updated count of
|
|
17
|
+
* the currently-slotted children) is exposed for a consumer who wants to
|
|
18
|
+
* build that string reactively instead of hand-counting DOM children.
|
|
19
|
+
*
|
|
20
|
+
* The card list is removed from the accessibility tree (not just visually
|
|
21
|
+
* hidden) while collapsed, via the native `hidden` attribute on
|
|
22
|
+
* `[part="list"]` — a screen reader user tabbing past the header never lands
|
|
23
|
+
* on off-screen source cards they can't currently see.
|
|
24
|
+
*
|
|
25
|
+
* @customElement lyra-source-list
|
|
26
|
+
* @slot - `<lyra-source-card>` elements (or any content, though the card
|
|
27
|
+
* pairing is the intended usage).
|
|
28
|
+
* @event lyra-toggle - The header was activated, expanding or collapsing the
|
|
29
|
+
* list. `detail: { expanded }`.
|
|
30
|
+
* @csspart base - The outer container.
|
|
31
|
+
* @csspart header - The clickable header (`<button>`) toggling `expanded`.
|
|
32
|
+
* @csspart toggle - The chevron indicator inside the header.
|
|
33
|
+
* @csspart list - The wrapper around the default slot, `hidden` while collapsed.
|
|
34
|
+
*/
|
|
35
|
+
export declare class LyraSourceList extends LyraElement {
|
|
36
|
+
static styles: import("lit").CSSResultGroup[];
|
|
37
|
+
/** Whether the card list is currently shown. Starts collapsed by default
|
|
38
|
+
* so a message's sources don't eat vertical space until asked for. */
|
|
39
|
+
expanded: boolean;
|
|
40
|
+
/** Header text used when `label-plural` isn't set, e.g. `"Sources"`. */
|
|
41
|
+
label: string;
|
|
42
|
+
/** Fully consumer-built, already-pluralized header summary, e.g. `"3 sources"`
|
|
43
|
+
* or `"1 source"` — this component never counts or pluralizes on its own
|
|
44
|
+
* (see the class doc). Takes precedence over `label` when both are set. */
|
|
45
|
+
labelPlural: string;
|
|
46
|
+
private slottedCount;
|
|
47
|
+
private readonly listId;
|
|
48
|
+
protected willUpdate(): void;
|
|
49
|
+
firstUpdated(): void;
|
|
50
|
+
/** Read-only, live-updated count of the currently-slotted children —
|
|
51
|
+
* handy for building a `label-plural` string that stays in sync with
|
|
52
|
+
* what's actually slotted without hand-counting DOM children, e.g.
|
|
53
|
+
* `list.labelPlural = \`${list.sourceCount} sources\`;`. */
|
|
54
|
+
get sourceCount(): number;
|
|
55
|
+
private onSlotChange;
|
|
56
|
+
private toggle;
|
|
57
|
+
render(): TemplateResult;
|
|
58
|
+
}
|
|
59
|
+
declare global {
|
|
60
|
+
interface HTMLElementTagNameMap {
|
|
61
|
+
'lyra-source-list': LyraSourceList;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { html } from 'lit';
|
|
8
|
+
import { property, state } from 'lit/decorators.js';
|
|
9
|
+
import { LyraElement } from '../../internal/lyra-element.js';
|
|
10
|
+
import { defineElement } from '../../internal/prefix.js';
|
|
11
|
+
import { nextId } from '../../internal/a11y.js';
|
|
12
|
+
import { chevronIcon } from '../../internal/icons.js';
|
|
13
|
+
import { styles } from './source-list.styles.js';
|
|
14
|
+
/**
|
|
15
|
+
* `<lyra-source-list>` — a collapsible "Sources" panel for one chat message,
|
|
16
|
+
* grouping a set of `<lyra-source-card>` children (its default-slot light-DOM
|
|
17
|
+
* children, plain composition — no `.items` array prop, the same shape
|
|
18
|
+
* `<lyra-split>`'s panels take) behind a single clickable header.
|
|
19
|
+
*
|
|
20
|
+
* This library has no built-in i18n/pluralization (see `<lyra-empty>`'s plain
|
|
21
|
+
* `description` prop for the same stance), so the header text is entirely
|
|
22
|
+
* consumer-supplied: `label-plural` (e.g. `"3 sources"`) wins when set,
|
|
23
|
+
* falling back to `label`, falling back to the literal word `"Sources"` — see
|
|
24
|
+
* each property's own doc. `sourceCount` (a read-only, live-updated count of
|
|
25
|
+
* the currently-slotted children) is exposed for a consumer who wants to
|
|
26
|
+
* build that string reactively instead of hand-counting DOM children.
|
|
27
|
+
*
|
|
28
|
+
* The card list is removed from the accessibility tree (not just visually
|
|
29
|
+
* hidden) while collapsed, via the native `hidden` attribute on
|
|
30
|
+
* `[part="list"]` — a screen reader user tabbing past the header never lands
|
|
31
|
+
* on off-screen source cards they can't currently see.
|
|
32
|
+
*
|
|
33
|
+
* @customElement lyra-source-list
|
|
34
|
+
* @slot - `<lyra-source-card>` elements (or any content, though the card
|
|
35
|
+
* pairing is the intended usage).
|
|
36
|
+
* @event lyra-toggle - The header was activated, expanding or collapsing the
|
|
37
|
+
* list. `detail: { expanded }`.
|
|
38
|
+
* @csspart base - The outer container.
|
|
39
|
+
* @csspart header - The clickable header (`<button>`) toggling `expanded`.
|
|
40
|
+
* @csspart toggle - The chevron indicator inside the header.
|
|
41
|
+
* @csspart list - The wrapper around the default slot, `hidden` while collapsed.
|
|
42
|
+
*/
|
|
43
|
+
export class LyraSourceList extends LyraElement {
|
|
44
|
+
constructor() {
|
|
45
|
+
super(...arguments);
|
|
46
|
+
/** Whether the card list is currently shown. Starts collapsed by default
|
|
47
|
+
* so a message's sources don't eat vertical space until asked for. */
|
|
48
|
+
this.expanded = false;
|
|
49
|
+
/** Header text used when `label-plural` isn't set, e.g. `"Sources"`. */
|
|
50
|
+
this.label = '';
|
|
51
|
+
/** Fully consumer-built, already-pluralized header summary, e.g. `"3 sources"`
|
|
52
|
+
* or `"1 source"` — this component never counts or pluralizes on its own
|
|
53
|
+
* (see the class doc). Takes precedence over `label` when both are set. */
|
|
54
|
+
this.labelPlural = '';
|
|
55
|
+
// Tracks the default slot's assigned-element count purely for the
|
|
56
|
+
// `sourceCount` convenience getter below -- unlike `<lyra-split>`'s
|
|
57
|
+
// `panelCount` this never drives layout math, so it's plain @state rather
|
|
58
|
+
// than something read back out of `updated()`.
|
|
59
|
+
this.slottedCount = 0;
|
|
60
|
+
this.listId = nextId('source-list-region');
|
|
61
|
+
this.onSlotChange = (e) => {
|
|
62
|
+
this.slottedCount = e.target.assignedElements({ flatten: true }).length;
|
|
63
|
+
};
|
|
64
|
+
this.toggle = () => {
|
|
65
|
+
this.expanded = !this.expanded;
|
|
66
|
+
this.emit('lyra-toggle', { expanded: this.expanded });
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
static { this.styles = [LyraElement.styles, styles]; }
|
|
70
|
+
willUpdate() {
|
|
71
|
+
if (!this.hasUpdated) {
|
|
72
|
+
this.slottedCount = this.children.length;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
firstUpdated() {
|
|
76
|
+
// Fallback reconciliation for slot-forwarding / engines that don't fire
|
|
77
|
+
// `slotchange` for content present at parse time -- same idiom as
|
|
78
|
+
// `<lyra-empty>`'s `firstUpdated`.
|
|
79
|
+
const slot = this.shadowRoot.querySelector('slot');
|
|
80
|
+
this.slottedCount = slot.assignedElements({ flatten: true }).length;
|
|
81
|
+
}
|
|
82
|
+
/** Read-only, live-updated count of the currently-slotted children —
|
|
83
|
+
* handy for building a `label-plural` string that stays in sync with
|
|
84
|
+
* what's actually slotted without hand-counting DOM children, e.g.
|
|
85
|
+
* `list.labelPlural = \`${list.sourceCount} sources\`;`. */
|
|
86
|
+
get sourceCount() {
|
|
87
|
+
return this.slottedCount;
|
|
88
|
+
}
|
|
89
|
+
render() {
|
|
90
|
+
const headerText = this.labelPlural || this.label || 'Sources';
|
|
91
|
+
return html `
|
|
92
|
+
<div part="base">
|
|
93
|
+
<button
|
|
94
|
+
part="header"
|
|
95
|
+
type="button"
|
|
96
|
+
aria-expanded=${this.expanded ? 'true' : 'false'}
|
|
97
|
+
aria-controls=${this.listId}
|
|
98
|
+
@click=${this.toggle}
|
|
99
|
+
>
|
|
100
|
+
<span part="toggle" aria-hidden="true">${chevronIcon()}</span>
|
|
101
|
+
<span>${headerText}</span>
|
|
102
|
+
</button>
|
|
103
|
+
<div part="list" id=${this.listId} ?hidden=${!this.expanded}>
|
|
104
|
+
<slot @slotchange=${this.onSlotChange}></slot>
|
|
105
|
+
</div>
|
|
106
|
+
</div>
|
|
107
|
+
`;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
__decorate([
|
|
111
|
+
property({ type: Boolean, reflect: true })
|
|
112
|
+
], LyraSourceList.prototype, "expanded", void 0);
|
|
113
|
+
__decorate([
|
|
114
|
+
property()
|
|
115
|
+
], LyraSourceList.prototype, "label", void 0);
|
|
116
|
+
__decorate([
|
|
117
|
+
property({ attribute: 'label-plural' })
|
|
118
|
+
], LyraSourceList.prototype, "labelPlural", void 0);
|
|
119
|
+
__decorate([
|
|
120
|
+
state()
|
|
121
|
+
], LyraSourceList.prototype, "slottedCount", void 0);
|
|
122
|
+
defineElement('source-list', LyraSourceList);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const styles: import("lit").CSSResult;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { css } from 'lit';
|
|
2
|
+
export const styles = css `
|
|
3
|
+
:host {
|
|
4
|
+
display: block;
|
|
5
|
+
}
|
|
6
|
+
[part='base'] {
|
|
7
|
+
border: 1px solid var(--lyra-color-border);
|
|
8
|
+
border-radius: var(--lyra-radius);
|
|
9
|
+
background: var(--lyra-color-surface);
|
|
10
|
+
overflow: hidden;
|
|
11
|
+
}
|
|
12
|
+
[part='header'] {
|
|
13
|
+
display: flex;
|
|
14
|
+
align-items: center;
|
|
15
|
+
gap: var(--lyra-space-xs);
|
|
16
|
+
inline-size: 100%;
|
|
17
|
+
padding: var(--lyra-space-s) var(--lyra-space-m);
|
|
18
|
+
border: none;
|
|
19
|
+
background: none;
|
|
20
|
+
color: var(--lyra-color-text);
|
|
21
|
+
font: inherit;
|
|
22
|
+
font-weight: 600;
|
|
23
|
+
font-size: 0.875rem;
|
|
24
|
+
text-align: start;
|
|
25
|
+
cursor: pointer;
|
|
26
|
+
}
|
|
27
|
+
[part='header']:hover {
|
|
28
|
+
background: var(--lyra-color-brand-quiet);
|
|
29
|
+
color: var(--lyra-color-brand);
|
|
30
|
+
}
|
|
31
|
+
[part='header']:focus-visible {
|
|
32
|
+
outline: var(--lyra-focus-ring-width) solid var(--lyra-focus-ring-color);
|
|
33
|
+
outline-offset: calc(-1 * var(--lyra-focus-ring-offset));
|
|
34
|
+
}
|
|
35
|
+
[part='toggle'] {
|
|
36
|
+
display: inline-flex;
|
|
37
|
+
flex: 0 0 auto;
|
|
38
|
+
transition: transform var(--lyra-transition-fast);
|
|
39
|
+
}
|
|
40
|
+
:host([expanded]) [part='toggle'] {
|
|
41
|
+
transform: rotate(90deg);
|
|
42
|
+
}
|
|
43
|
+
[part='list'] {
|
|
44
|
+
display: flex;
|
|
45
|
+
flex-direction: column;
|
|
46
|
+
gap: var(--lyra-space-s);
|
|
47
|
+
padding: 0 var(--lyra-space-m) var(--lyra-space-m);
|
|
48
|
+
border-block-start: 1px solid var(--lyra-color-border);
|
|
49
|
+
padding-block-start: var(--lyra-space-m);
|
|
50
|
+
}
|
|
51
|
+
[part='list'][hidden] {
|
|
52
|
+
display: none;
|
|
53
|
+
}
|
|
54
|
+
@media (prefers-reduced-motion: reduce) {
|
|
55
|
+
[part='toggle'] {
|
|
56
|
+
transition: none !important;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
`;
|
|
@@ -11,13 +11,16 @@ import { defineElement } from '../../internal/prefix.js';
|
|
|
11
11
|
import { styles } from './sparkline.styles.js';
|
|
12
12
|
const VIEW = 100;
|
|
13
13
|
// A <rect> per bar doesn't collapse into one path the way line/area do, so an
|
|
14
|
-
// unbounded `values` array turns directly into that many shadow-DOM nodes
|
|
15
|
-
//
|
|
16
|
-
//
|
|
17
|
-
|
|
14
|
+
// unbounded `values` array turns directly into that many shadow-DOM nodes --
|
|
15
|
+
// and an uncapped line/area path string grows without bound too. Capping the
|
|
16
|
+
// point count up front (shared by every render type) keeps worst-case
|
|
17
|
+
// DOM/compute bounded without affecting any realistically-sized chart.
|
|
18
|
+
const MAX_POINTS = 500; // shared point-count cap for every render type (line/area/bar)
|
|
18
19
|
function decimate(arr, max) {
|
|
19
|
-
|
|
20
|
-
|
|
20
|
+
if (arr.length <= max)
|
|
21
|
+
return [...arr];
|
|
22
|
+
const step = (arr.length - 1) / (max - 1); // anchors both the first AND last sample exactly
|
|
23
|
+
return Array.from({ length: max }, (_, i) => arr[Math.round(i * step)]);
|
|
21
24
|
}
|
|
22
25
|
/**
|
|
23
26
|
* `<lyra-sparkline>` — a zero-dependency inline SVG trend chart.
|
|
@@ -38,10 +41,14 @@ export class LyraSparkline extends LyraElement {
|
|
|
38
41
|
}
|
|
39
42
|
static { this.styles = [LyraElement.styles, styles]; }
|
|
40
43
|
points() {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
44
|
+
// Auto min/max is scanned from the full, pre-decimation `values` -- doing
|
|
45
|
+
// this after decimating would silently narrow the scale to whatever the
|
|
46
|
+
// sampled subset happens to contain, which can clip or misproportion a
|
|
47
|
+
// real extreme value that decimation happened to drop.
|
|
48
|
+
const raw = this.values;
|
|
49
|
+
let autoLo = raw[0];
|
|
50
|
+
let autoHi = raw[0];
|
|
51
|
+
for (const n of raw) {
|
|
45
52
|
if (n < autoLo)
|
|
46
53
|
autoLo = n;
|
|
47
54
|
if (n > autoHi)
|
|
@@ -49,6 +56,7 @@ export class LyraSparkline extends LyraElement {
|
|
|
49
56
|
}
|
|
50
57
|
const lo = this.min ?? autoLo;
|
|
51
58
|
const hi = this.max ?? autoHi;
|
|
59
|
+
const v = raw.length > MAX_POINTS ? decimate(raw, MAX_POINTS) : raw;
|
|
52
60
|
const span = hi - lo;
|
|
53
61
|
return v.map((n, i) => {
|
|
54
62
|
const x = v.length > 1 ? (i / (v.length - 1)) * VIEW : VIEW / 2;
|
|
@@ -68,10 +76,16 @@ export class LyraSparkline extends LyraElement {
|
|
|
68
76
|
}
|
|
69
77
|
const pts = this.points();
|
|
70
78
|
if (this.type === 'bar') {
|
|
71
|
-
|
|
72
|
-
|
|
79
|
+
// Narrow the bar width as the (already decimated-to-MAX_POINTS) point
|
|
80
|
+
// count grows, so bars stop overlapping once there are more than a
|
|
81
|
+
// handful -- VIEW / pts.length is each bar's full "slot" width; keep a
|
|
82
|
+
// small gap between slots by drawing at 70% of it, floored at 1px and
|
|
83
|
+
// capped at the original fixed 4px for small point counts.
|
|
84
|
+
const slot = VIEW / pts.length;
|
|
85
|
+
const barWidth = Math.min(4, Math.max(1, slot * 0.7));
|
|
86
|
+
const bars = pts.map(([x, y]) => {
|
|
73
87
|
const barY = Math.min(y, VIEW);
|
|
74
|
-
return svg `<rect part="bar" x="${x - 2}" y="${barY}" width="
|
|
88
|
+
return svg `<rect part="bar" x="${x - barWidth / 2}" y="${barY}" width="${barWidth}" height="${VIEW - barY}"></rect>`;
|
|
75
89
|
});
|
|
76
90
|
return html `<svg viewBox="0 0 ${VIEW} ${VIEW}" preserveAspectRatio="none" aria-hidden="true">
|
|
77
91
|
${bars}
|
|
@@ -7,15 +7,42 @@ export interface PanelConstraint {
|
|
|
7
7
|
minPx?: number;
|
|
8
8
|
maxPx?: number;
|
|
9
9
|
}
|
|
10
|
+
/** Which pane (if any) participates in responsive collapse (see `collapse`). */
|
|
11
|
+
export type SplitCollapseMode = 'start' | 'end' | 'none';
|
|
12
|
+
/** The collapsing pane's current responsive state — `'wide'` is the normal
|
|
13
|
+
* drag-resizable percent layout (identical to `collapse="none"`); `'rail'`
|
|
14
|
+
* clamps it to `railWidth`; `'floating'` lifts it out of the flex flow as an
|
|
15
|
+
* overlay above the other pane. */
|
|
16
|
+
export type SplitCollapseState = 'wide' | 'rail' | 'floating';
|
|
17
|
+
export interface SplitCollapseChangeDetail {
|
|
18
|
+
state: SplitCollapseState;
|
|
19
|
+
}
|
|
10
20
|
/**
|
|
11
21
|
* `<lyra-split>` — resizable panels for dashboard layouts. Direct light-DOM
|
|
12
22
|
* children are the panels; a divider is auto-inserted between each pair.
|
|
13
23
|
*
|
|
24
|
+
* Optionally, one pane can opt in to responsive collapse via `collapse`
|
|
25
|
+
* (`"start"`/`"end"`, default `"none"` — no behavior change when unset): as
|
|
26
|
+
* the split's own container narrows past `railBreakpoint` that pane clamps
|
|
27
|
+
* to a fixed `railWidth`, and past the narrower `floatBreakpoint` it instead
|
|
28
|
+
* becomes an absolutely-positioned overlay "floating card" above the other
|
|
29
|
+
* pane. This component only handles the width-collapse mechanics and
|
|
30
|
+
* signals the current state — via the `collapseState`-derived
|
|
31
|
+
* `data-collapse-state` attribute (set on both the host and the collapsing
|
|
32
|
+
* panel itself) and the `lyra-split-collapse-change` event — it renders no
|
|
33
|
+
* icon-only/collapsed UI of its own; slotted content is expected to adapt to
|
|
34
|
+
* its own clamped width (e.g. via its own container query).
|
|
35
|
+
*
|
|
14
36
|
* @customElement lyra-split
|
|
15
37
|
* @event lyra-resize - `detail: { sizes }`, fired on every drag step/release
|
|
16
38
|
* and every keyboard step.
|
|
39
|
+
* @event lyra-split-collapse-change - `detail: { state }` (`SplitCollapseChangeDetail`),
|
|
40
|
+
* fired whenever the responsive `collapseState` actually transitions between
|
|
41
|
+
* `'wide'`/`'rail'`/`'floating'`. Only relevant when `collapse` isn't `"none"`;
|
|
42
|
+
* never fires otherwise.
|
|
17
43
|
* @slot - Panels to arrange side by side (or stacked, when `orientation="vertical"`); each direct child becomes one resizable panel.
|
|
18
|
-
* @csspart base
|
|
44
|
+
* @csspart base - The flex layout wrapper (`position: relative`, so the `'floating'` collapse state can anchor to it).
|
|
45
|
+
* @csspart divider - Each divider between two panels; carries `aria-disabled="true"` and is drag/keyboard-inert while its adjacent panel is collapsed (`'rail'`/`'floating'`).
|
|
19
46
|
*/
|
|
20
47
|
export declare class LyraSplit extends LyraElement {
|
|
21
48
|
static styles: import("lit").CSSResultGroup[];
|
|
@@ -29,10 +56,35 @@ export declare class LyraSplit extends LyraElement {
|
|
|
29
56
|
* localStorage persistence stay percent-based regardless — only the
|
|
30
57
|
* effective clamp bounds change for a constrained panel. */
|
|
31
58
|
panelConstraints: (PanelConstraint | null)[];
|
|
59
|
+
/** Opts a pane in to responsive collapse: `'start'` is the first light-DOM
|
|
60
|
+
* panel (index 0), `'end'` is the last. Both are LOGICAL positions, same
|
|
61
|
+
* as CSS `inset-inline-start`/`-end` — see the `collapsingIndex` getter
|
|
62
|
+
* for why that already resolves to the same physical index under RTL for
|
|
63
|
+
* this component (panels are never re-`order`ed for RTL, only the drag
|
|
64
|
+
* delta sign mirrors). Default `'none'`: none of the collapse behavior
|
|
65
|
+
* below applies, and rendering/behavior is identical to before this
|
|
66
|
+
* property existed. */
|
|
67
|
+
collapse: SplitCollapseMode;
|
|
68
|
+
/** Fixed CSS length the collapsing pane clamps to in the `'rail'` state. */
|
|
69
|
+
railWidth: string;
|
|
70
|
+
/** Container width (px, measured on `[part="base"]`) below which the
|
|
71
|
+
* collapsing pane switches from its normal percent width to the fixed
|
|
72
|
+
* `railWidth` (`'rail'` state). Must stay above `floatBreakpoint`. */
|
|
73
|
+
railBreakpoint: number;
|
|
74
|
+
/** Container width (px) below which the collapsing pane instead becomes an
|
|
75
|
+
* absolutely-positioned overlay above the other pane (`'floating'` state). */
|
|
76
|
+
floatBreakpoint: number;
|
|
32
77
|
private panelCount;
|
|
78
|
+
/** The collapsing pane's current responsive state; always `'wide'` (a
|
|
79
|
+
* no-op) while `collapse === 'none'`. */
|
|
80
|
+
private collapseState;
|
|
33
81
|
private drags;
|
|
82
|
+
private stylizedPanels;
|
|
83
|
+
private baseEl?;
|
|
84
|
+
private collapseResizeObserver?;
|
|
34
85
|
connectedCallback(): void;
|
|
35
86
|
disconnectedCallback(): void;
|
|
87
|
+
protected firstUpdated(): void;
|
|
36
88
|
private get storageFullKey();
|
|
37
89
|
private loadPersisted;
|
|
38
90
|
private persist;
|
|
@@ -42,6 +94,46 @@ export declare class LyraSplit extends LyraElement {
|
|
|
42
94
|
* container resize between calls is always picked up — same live read
|
|
43
95
|
* `onPointerMove` already does via `drag.base.clientWidth/clientHeight`. */
|
|
44
96
|
private getContainerSize;
|
|
97
|
+
/** The physical panel index `collapse: 'start' | 'end'` resolves to, or
|
|
98
|
+
* `-1` when collapse is off (`'none'`) or there are fewer than 2 panels
|
|
99
|
+
* to collapse one of. Panels are laid out via ascending inline `order`
|
|
100
|
+
* (see `updated()`) and that ordering is never re-swapped for RTL — only
|
|
101
|
+
* the drag/keyboard *delta sign* mirrors for RTL, exactly like
|
|
102
|
+
* `onPointerMove`/`onDividerKeyDown` — so panel index 0 already renders
|
|
103
|
+
* at the logical inline-start edge under both LTR and RTL (confirmed by
|
|
104
|
+
* the pointer-drag RTL test elsewhere in this file: panel 0 renders on
|
|
105
|
+
* the visual *right*, i.e. the RTL inline-start side). `'start'` therefore
|
|
106
|
+
* always resolves to index 0 and `'end'` to `panelCount - 1`, regardless
|
|
107
|
+
* of `isRtl(this)` — consulting it here would swap collapse onto the
|
|
108
|
+
* panel that visually sits at the *other* logical edge, which would be a
|
|
109
|
+
* bug against this component's own RTL rendering, not a fix for one.
|
|
110
|
+
*/
|
|
111
|
+
private get collapsingIndex();
|
|
112
|
+
/** Whether a pane is actually collapsed (rail or floating) right now —
|
|
113
|
+
* `false` whenever `collapse === 'none'`, since `collapseState` then
|
|
114
|
+
* never leaves its `'wide'` default. */
|
|
115
|
+
private get collapseActive();
|
|
116
|
+
/** Dragging/keyboard-resizing is disabled on the one divider immediately
|
|
117
|
+
* adjacent to the currently-collapsed pane (its other side has nothing
|
|
118
|
+
* meaningful to resize against while the pane is rail/floating-width). */
|
|
119
|
+
private isDividerDisabled;
|
|
120
|
+
/** Classifies a measured container width into the collapsing pane's
|
|
121
|
+
* responsive state and, only on an actual transition, updates
|
|
122
|
+
* `collapseState` and fires `lyra-split-collapse-change`. */
|
|
123
|
+
private updateCollapseState;
|
|
124
|
+
/** Creates (idempotently) and (re-)observes `[part="base"]` with the
|
|
125
|
+
* collapse-state `ResizeObserver` — a no-op until `baseEl` exists (see
|
|
126
|
+
* `firstUpdated()`/`connectedCallback()`). Mirrors lite-chart.ts's own
|
|
127
|
+
* ResizeObserver setup, including reading the box size synchronously
|
|
128
|
+
* once so the very first render doesn't sit at the stale `'wide'` default
|
|
129
|
+
* until the (async) first callback fires — same rationale as
|
|
130
|
+
* lyra-virtual-list's `containerResizeObserver` synchronous initial read. */
|
|
131
|
+
private armCollapseObserver;
|
|
132
|
+
/** Reacts to a live `collapse` property change (as opposed to the
|
|
133
|
+
* connect/first-render arming above): turns the observer on/off, and
|
|
134
|
+
* resets `collapseState` back to its `'wide'` default when collapse is
|
|
135
|
+
* switched off so no stale rail/floating styling survives it. */
|
|
136
|
+
private syncCollapseObserver;
|
|
45
137
|
/** Resolves panel `index`'s effective percent min/max for this clamp pass:
|
|
46
138
|
* a `panelConstraints` entry's px bound converted against the live
|
|
47
139
|
* `containerSize`, or the component's plain percent `min` (no upper
|