@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,283 @@
|
|
|
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 { repeat } from 'lit/directives/repeat.js';
|
|
10
|
+
import { LyraElement } from '../../internal/lyra-element.js';
|
|
11
|
+
import { defineElement } from '../../internal/prefix.js';
|
|
12
|
+
import { chevronIcon } from '../../internal/icons.js';
|
|
13
|
+
import { styles } from './json-viewer.styles.js';
|
|
14
|
+
const EMPTY_SEARCH = {
|
|
15
|
+
keyMatches: new Set(),
|
|
16
|
+
valueMatches: new Set(),
|
|
17
|
+
forceExpand: new Set(),
|
|
18
|
+
};
|
|
19
|
+
function isPlainContainer(value) {
|
|
20
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
21
|
+
}
|
|
22
|
+
/** `[key, value]` pairs for an object's own enumerable properties or an array's indices; `[]` for anything else. */
|
|
23
|
+
function entriesOf(value) {
|
|
24
|
+
if (Array.isArray(value))
|
|
25
|
+
return value.map((v, i) => [i, v]);
|
|
26
|
+
if (isPlainContainer(value))
|
|
27
|
+
return Object.entries(value);
|
|
28
|
+
return [];
|
|
29
|
+
}
|
|
30
|
+
function valueType(value) {
|
|
31
|
+
if (value === null)
|
|
32
|
+
return 'null';
|
|
33
|
+
if (value === undefined)
|
|
34
|
+
return 'undefined';
|
|
35
|
+
if (Array.isArray(value))
|
|
36
|
+
return 'array';
|
|
37
|
+
const t = typeof value;
|
|
38
|
+
if (t === 'string' || t === 'number' || t === 'boolean')
|
|
39
|
+
return t;
|
|
40
|
+
if (t === 'object')
|
|
41
|
+
return 'object';
|
|
42
|
+
// function/symbol/bigint -- not valid JSON, but rendering *something*
|
|
43
|
+
// sensible beats throwing on a value a caller handed us by mistake.
|
|
44
|
+
return 'string';
|
|
45
|
+
}
|
|
46
|
+
function formatPrimitive(value, type) {
|
|
47
|
+
switch (type) {
|
|
48
|
+
case 'string':
|
|
49
|
+
return JSON.stringify(value);
|
|
50
|
+
case 'null':
|
|
51
|
+
return 'null';
|
|
52
|
+
case 'undefined':
|
|
53
|
+
return 'undefined';
|
|
54
|
+
default:
|
|
55
|
+
return String(value);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
function previewText(value, type, count) {
|
|
59
|
+
if (type === 'array')
|
|
60
|
+
return `${count} ${count === 1 ? 'item' : 'items'}`;
|
|
61
|
+
return `${count} ${count === 1 ? 'key' : 'keys'}`;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* `<lyra-json-viewer>` — a collapsible, copyable tree view for an arbitrary
|
|
65
|
+
* JSON-serializable value (object/array/string/number/boolean/null/
|
|
66
|
+
* undefined). Serves as the fallback renderer wherever a raw payload (tool
|
|
67
|
+
* call arguments, a tool result, an API response) needs inspecting without a
|
|
68
|
+
* bespoke view.
|
|
69
|
+
*
|
|
70
|
+
* Expand/collapse state is keyed by structural path (not by object identity),
|
|
71
|
+
* so it survives a `data` reassignment that keeps the same shape -- e.g. a
|
|
72
|
+
* streaming tool result being patched in place.
|
|
73
|
+
*
|
|
74
|
+
* @customElement lyra-json-viewer
|
|
75
|
+
* @event lyra-copy - `detail: { text }` -- fired by the top-level copy button or a per-node one. Fires even when `navigator.clipboard` silently failed or is unavailable (insecure context, older browser, stubbed-out test environment), so a consumer can still observe copy *intent*.
|
|
76
|
+
* @csspart base - The root scroll container; respects `max-height`.
|
|
77
|
+
* @csspart toolbar - The wrapper around the top-level copy button (only rendered when `copyable`).
|
|
78
|
+
* @csspart tree - The wrapper around the rendered node tree.
|
|
79
|
+
* @csspart key - An object property key or array index label.
|
|
80
|
+
* @csspart value - A primitive value's text -- carries `data-type` (`string`/`number`/`boolean`/`null`/`undefined`) for per-type coloring, and `data-match` while it matches `search`.
|
|
81
|
+
* @csspart bracket - A `{`, `}`, `[`, or `]` delimiter.
|
|
82
|
+
* @csspart toggle - A container node's expand/collapse button (hidden, but present for row alignment, on leaf/empty nodes).
|
|
83
|
+
* @csspart copy-button - A copy-to-clipboard button -- the top-level one (in `toolbar`) or a per-node one (only rendered when `copyable`).
|
|
84
|
+
*/
|
|
85
|
+
export class LyraJsonViewer extends LyraElement {
|
|
86
|
+
constructor() {
|
|
87
|
+
super(...arguments);
|
|
88
|
+
/** A CSS length (e.g. `"20rem"`); once set, the viewer scrolls internally past this height instead of growing the page. */
|
|
89
|
+
this.maxHeight = '';
|
|
90
|
+
/** Shows copy-to-clipboard affordances: one for the whole value, plus one per node. */
|
|
91
|
+
this.copyable = false;
|
|
92
|
+
/** Case-insensitive substring match against keys/values; matches are highlighted and their ancestors auto-expanded. */
|
|
93
|
+
this.search = '';
|
|
94
|
+
/** Per-path (`JSON.stringify(path)`) explicit expand/collapse, overriding the `collapsedDepth`/search defaults once a node's toggle has been used. */
|
|
95
|
+
this.expandedOverrides = new Map();
|
|
96
|
+
}
|
|
97
|
+
static { this.styles = [LyraElement.styles, styles]; }
|
|
98
|
+
isExpanded(pathKey, depth, forceExpand) {
|
|
99
|
+
const override = this.expandedOverrides.get(pathKey);
|
|
100
|
+
if (override !== undefined)
|
|
101
|
+
return override;
|
|
102
|
+
if (forceExpand.has(pathKey))
|
|
103
|
+
return true;
|
|
104
|
+
if (this.collapsedDepth !== undefined && depth >= this.collapsedDepth)
|
|
105
|
+
return false;
|
|
106
|
+
return true;
|
|
107
|
+
}
|
|
108
|
+
toggleNode(pathKey, currentlyExpanded) {
|
|
109
|
+
const next = new Map(this.expandedOverrides);
|
|
110
|
+
next.set(pathKey, !currentlyExpanded);
|
|
111
|
+
this.expandedOverrides = next;
|
|
112
|
+
}
|
|
113
|
+
writeClipboard(text) {
|
|
114
|
+
try {
|
|
115
|
+
// navigator.clipboard is absent in insecure contexts / older browsers,
|
|
116
|
+
// and some engines throw synchronously rather than rejecting -- either
|
|
117
|
+
// way this is best-effort; copy() below always emits lyra-copy
|
|
118
|
+
// regardless of whether the OS clipboard was actually reached.
|
|
119
|
+
void navigator.clipboard?.writeText(text)?.catch(() => { });
|
|
120
|
+
}
|
|
121
|
+
catch {
|
|
122
|
+
// see above
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
copy(value) {
|
|
126
|
+
const text = value === undefined ? 'undefined' : JSON.stringify(value, null, 2);
|
|
127
|
+
this.writeClipboard(text);
|
|
128
|
+
this.emit('lyra-copy', { text });
|
|
129
|
+
}
|
|
130
|
+
/** Builds the key/value-match sets and the ancestor-paths-of-a-match set that `search` drives. */
|
|
131
|
+
computeSearch() {
|
|
132
|
+
const query = this.search.trim().toLowerCase();
|
|
133
|
+
if (!query)
|
|
134
|
+
return EMPTY_SEARCH;
|
|
135
|
+
const keyMatches = new Set();
|
|
136
|
+
const valueMatches = new Set();
|
|
137
|
+
const forceExpand = new Set();
|
|
138
|
+
const markAncestors = (path) => {
|
|
139
|
+
for (let i = path.length - 1; i >= 0; i--)
|
|
140
|
+
forceExpand.add(JSON.stringify(path.slice(0, i)));
|
|
141
|
+
};
|
|
142
|
+
const walk = (value, path, keyLabel) => {
|
|
143
|
+
const pathKey = JSON.stringify(path);
|
|
144
|
+
let hit = false;
|
|
145
|
+
if (keyLabel !== undefined && keyLabel.toLowerCase().includes(query)) {
|
|
146
|
+
keyMatches.add(pathKey);
|
|
147
|
+
hit = true;
|
|
148
|
+
}
|
|
149
|
+
const type = valueType(value);
|
|
150
|
+
if (type !== 'object' && type !== 'array' && formatPrimitive(value, type).toLowerCase().includes(query)) {
|
|
151
|
+
valueMatches.add(pathKey);
|
|
152
|
+
hit = true;
|
|
153
|
+
}
|
|
154
|
+
if (hit)
|
|
155
|
+
markAncestors(path);
|
|
156
|
+
for (const [k, v] of entriesOf(value))
|
|
157
|
+
walk(v, [...path, k], String(k));
|
|
158
|
+
};
|
|
159
|
+
walk(this.data, []);
|
|
160
|
+
return { keyMatches, valueMatches, forceExpand };
|
|
161
|
+
}
|
|
162
|
+
renderCopyButton(value) {
|
|
163
|
+
if (!this.copyable)
|
|
164
|
+
return nothing;
|
|
165
|
+
return html `
|
|
166
|
+
<button
|
|
167
|
+
part="copy-button"
|
|
168
|
+
type="button"
|
|
169
|
+
aria-label="Copy value"
|
|
170
|
+
@click=${(e) => {
|
|
171
|
+
e.stopPropagation();
|
|
172
|
+
this.copy(value);
|
|
173
|
+
}}
|
|
174
|
+
>
|
|
175
|
+
Copy
|
|
176
|
+
</button>
|
|
177
|
+
`;
|
|
178
|
+
}
|
|
179
|
+
renderNode(value, path, keyLabel, depth, search) {
|
|
180
|
+
const pathKey = JSON.stringify(path);
|
|
181
|
+
const type = valueType(value);
|
|
182
|
+
const isContainer = type === 'object' || type === 'array';
|
|
183
|
+
const entries = isContainer ? entriesOf(value) : [];
|
|
184
|
+
const hasEntries = entries.length > 0;
|
|
185
|
+
const expanded = hasEntries && this.isExpanded(pathKey, depth, search.forceExpand);
|
|
186
|
+
const indentStyle = `padding-inline-start:calc(${depth} * var(--lyra-space-l))`;
|
|
187
|
+
const toggleLabel = keyLabel ?? (type === 'array' ? 'array' : type === 'object' ? 'object' : 'value');
|
|
188
|
+
const openBracket = type === 'array' ? '[' : '{';
|
|
189
|
+
const closeBracket = type === 'array' ? ']' : '}';
|
|
190
|
+
const headRow = html `
|
|
191
|
+
<div class="row" style=${indentStyle}>
|
|
192
|
+
<button
|
|
193
|
+
part="toggle"
|
|
194
|
+
type="button"
|
|
195
|
+
?hidden=${!hasEntries}
|
|
196
|
+
tabindex=${hasEntries ? nothing : -1}
|
|
197
|
+
aria-hidden=${hasEntries ? nothing : 'true'}
|
|
198
|
+
aria-expanded=${hasEntries ? (expanded ? 'true' : 'false') : nothing}
|
|
199
|
+
aria-label=${hasEntries ? `${expanded ? 'Collapse' : 'Expand'} ${toggleLabel}` : nothing}
|
|
200
|
+
@click=${() => hasEntries && this.toggleNode(pathKey, expanded)}
|
|
201
|
+
>
|
|
202
|
+
<span class="chevron" style=${`transform:rotate(${expanded ? '90deg' : '0deg'})`}>${chevronIcon()}</span>
|
|
203
|
+
</button>
|
|
204
|
+
${keyLabel !== undefined
|
|
205
|
+
? html `<span part="key" ?data-match=${search.keyMatches.has(pathKey)}>${keyLabel}</span
|
|
206
|
+
><span class="colon">:</span>`
|
|
207
|
+
: nothing}
|
|
208
|
+
${isContainer
|
|
209
|
+
? html `
|
|
210
|
+
<span part="bracket">${openBracket}</span>
|
|
211
|
+
${hasEntries && !expanded
|
|
212
|
+
? html `<span class="preview">${previewText(value, type, entries.length)}</span>`
|
|
213
|
+
: nothing}
|
|
214
|
+
${!expanded ? html `<span part="bracket">${closeBracket}</span>` : nothing}
|
|
215
|
+
`
|
|
216
|
+
: html `<span part="value" data-type=${type} ?data-match=${search.valueMatches.has(pathKey)}
|
|
217
|
+
>${formatPrimitive(value, type)}</span
|
|
218
|
+
>`}
|
|
219
|
+
${this.renderCopyButton(value)}
|
|
220
|
+
</div>
|
|
221
|
+
`;
|
|
222
|
+
// Always returned from this one call site, with a single conditional
|
|
223
|
+
// hole for the children block -- switching between *returning headRow
|
|
224
|
+
// bare* and *wrapping it in a bigger template* (two different template
|
|
225
|
+
// shapes at the same tree position) would make lit-html tear down and
|
|
226
|
+
// recreate the whole subtree on every expand/collapse instead of
|
|
227
|
+
// patching in place, destroying the toggle button's DOM identity (and
|
|
228
|
+
// with it, real DOM focus) on every click.
|
|
229
|
+
return html `
|
|
230
|
+
${headRow}
|
|
231
|
+
${isContainer && expanded
|
|
232
|
+
? html `
|
|
233
|
+
<div class="children">
|
|
234
|
+
${repeat(entries, ([k]) => JSON.stringify([...path, k]), ([k, v]) => this.renderNode(v, [...path, k], String(k), depth + 1, search))}
|
|
235
|
+
</div>
|
|
236
|
+
<div class="row" style=${indentStyle}>
|
|
237
|
+
<span class="toggle-space" aria-hidden="true"></span>
|
|
238
|
+
<span part="bracket">${closeBracket}</span>
|
|
239
|
+
</div>
|
|
240
|
+
`
|
|
241
|
+
: nothing}
|
|
242
|
+
`;
|
|
243
|
+
}
|
|
244
|
+
render() {
|
|
245
|
+
const search = this.computeSearch();
|
|
246
|
+
return html `
|
|
247
|
+
<div part="base" style=${this.maxHeight ? `--lyra-json-viewer-max-height:${this.maxHeight}` : nothing}>
|
|
248
|
+
${this.copyable
|
|
249
|
+
? html `<div part="toolbar">
|
|
250
|
+
<button
|
|
251
|
+
part="copy-button"
|
|
252
|
+
type="button"
|
|
253
|
+
aria-label="Copy JSON to clipboard"
|
|
254
|
+
@click=${() => this.copy(this.data)}
|
|
255
|
+
>
|
|
256
|
+
Copy
|
|
257
|
+
</button>
|
|
258
|
+
</div>`
|
|
259
|
+
: nothing}
|
|
260
|
+
<div part="tree">${this.renderNode(this.data, [], undefined, 0, search)}</div>
|
|
261
|
+
</div>
|
|
262
|
+
`;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
__decorate([
|
|
266
|
+
property({ attribute: false })
|
|
267
|
+
], LyraJsonViewer.prototype, "data", void 0);
|
|
268
|
+
__decorate([
|
|
269
|
+
property({ type: Number, attribute: 'collapsed-depth' })
|
|
270
|
+
], LyraJsonViewer.prototype, "collapsedDepth", void 0);
|
|
271
|
+
__decorate([
|
|
272
|
+
property({ attribute: 'max-height' })
|
|
273
|
+
], LyraJsonViewer.prototype, "maxHeight", void 0);
|
|
274
|
+
__decorate([
|
|
275
|
+
property({ type: Boolean, reflect: true })
|
|
276
|
+
], LyraJsonViewer.prototype, "copyable", void 0);
|
|
277
|
+
__decorate([
|
|
278
|
+
property()
|
|
279
|
+
], LyraJsonViewer.prototype, "search", void 0);
|
|
280
|
+
__decorate([
|
|
281
|
+
state()
|
|
282
|
+
], LyraJsonViewer.prototype, "expandedOverrides", void 0);
|
|
283
|
+
defineElement('json-viewer', LyraJsonViewer);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const styles: import("lit").CSSResult;
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { css } from 'lit';
|
|
2
|
+
export const styles = css `
|
|
3
|
+
:host {
|
|
4
|
+
display: block;
|
|
5
|
+
/* Consumer-tunable scroll cap -- 'none' means the viewer grows with its
|
|
6
|
+
content, matching every other block-level component in this library
|
|
7
|
+
until a caller opts into an internal scrollbar via the max-height
|
|
8
|
+
attribute. */
|
|
9
|
+
--lyra-json-viewer-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-widget-overlay-color
|
|
12
|
+
in widget.styles.ts -- no shared --wa-*/--lyra-* monospace token exists
|
|
13
|
+
to resolve through. */
|
|
14
|
+
--lyra-json-viewer-font: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
|
|
15
|
+
font-family: var(--lyra-json-viewer-font);
|
|
16
|
+
font-size: 0.8125rem;
|
|
17
|
+
line-height: 1.6;
|
|
18
|
+
}
|
|
19
|
+
[part='base'] {
|
|
20
|
+
display: block;
|
|
21
|
+
max-block-size: var(--lyra-json-viewer-max-height);
|
|
22
|
+
overflow: auto;
|
|
23
|
+
border: 1px solid var(--lyra-color-border);
|
|
24
|
+
border-radius: var(--lyra-radius);
|
|
25
|
+
background: var(--lyra-color-surface);
|
|
26
|
+
}
|
|
27
|
+
[part='toolbar'] {
|
|
28
|
+
position: sticky;
|
|
29
|
+
inset-block-start: 0;
|
|
30
|
+
z-index: 1;
|
|
31
|
+
display: flex;
|
|
32
|
+
justify-content: flex-end;
|
|
33
|
+
padding: var(--lyra-space-xs) var(--lyra-space-s);
|
|
34
|
+
border-block-end: 1px solid var(--lyra-color-border);
|
|
35
|
+
background: var(--lyra-color-surface);
|
|
36
|
+
}
|
|
37
|
+
[part='tree'] {
|
|
38
|
+
padding: var(--lyra-space-s);
|
|
39
|
+
}
|
|
40
|
+
.row {
|
|
41
|
+
display: flex;
|
|
42
|
+
align-items: flex-start;
|
|
43
|
+
gap: var(--lyra-space-xs);
|
|
44
|
+
min-inline-size: 0;
|
|
45
|
+
border-radius: var(--lyra-radius);
|
|
46
|
+
}
|
|
47
|
+
.row:hover {
|
|
48
|
+
background: var(--lyra-color-brand-quiet);
|
|
49
|
+
}
|
|
50
|
+
.row:hover [part='copy-button'],
|
|
51
|
+
.row:focus-within [part='copy-button'] {
|
|
52
|
+
opacity: 1;
|
|
53
|
+
}
|
|
54
|
+
[part='toggle'] {
|
|
55
|
+
/* Deliberately smaller than the shared --lyra-icon-button-size (2.5rem,
|
|
56
|
+
meant for a standalone icon-only button) -- this sits inline in a
|
|
57
|
+
dense, arbitrarily-deep tree row, same reasoning as lyra-tree-node's
|
|
58
|
+
own toggle. */
|
|
59
|
+
inline-size: 1.25rem;
|
|
60
|
+
block-size: 1.25rem;
|
|
61
|
+
margin-block-start: 0.1875rem;
|
|
62
|
+
flex: 0 0 auto;
|
|
63
|
+
display: inline-flex;
|
|
64
|
+
align-items: center;
|
|
65
|
+
justify-content: center;
|
|
66
|
+
padding: 0;
|
|
67
|
+
border: none;
|
|
68
|
+
background: none;
|
|
69
|
+
color: var(--lyra-color-text-quiet);
|
|
70
|
+
border-radius: var(--lyra-radius);
|
|
71
|
+
cursor: pointer;
|
|
72
|
+
}
|
|
73
|
+
/* The UA '[hidden] { display: none }' rule is author-overridable by any
|
|
74
|
+
same-origin declaration for that element regardless of specificity --
|
|
75
|
+
author rules always win over user-agent rules unless !important is
|
|
76
|
+
involved -- so this only needs to add visibility, not re-declare
|
|
77
|
+
display. Keeping the box (rather than display:none) preserves this
|
|
78
|
+
leaf/empty row's alignment with sibling rows that do have a chevron. */
|
|
79
|
+
[part='toggle'][hidden] {
|
|
80
|
+
visibility: hidden;
|
|
81
|
+
}
|
|
82
|
+
[part='toggle'] .chevron {
|
|
83
|
+
display: inline-flex;
|
|
84
|
+
transition: transform var(--lyra-transition-fast);
|
|
85
|
+
}
|
|
86
|
+
[part='toggle']:not([hidden]):hover {
|
|
87
|
+
background: var(--lyra-color-brand-quiet);
|
|
88
|
+
color: var(--lyra-color-brand);
|
|
89
|
+
}
|
|
90
|
+
[part='toggle']:focus-visible,
|
|
91
|
+
[part='copy-button']:focus-visible {
|
|
92
|
+
outline: var(--lyra-focus-ring-width) solid var(--lyra-focus-ring-color);
|
|
93
|
+
outline-offset: var(--lyra-focus-ring-offset);
|
|
94
|
+
}
|
|
95
|
+
.toggle-space {
|
|
96
|
+
inline-size: 1.25rem;
|
|
97
|
+
flex: 0 0 auto;
|
|
98
|
+
}
|
|
99
|
+
[part='key'] {
|
|
100
|
+
flex: 0 0 auto;
|
|
101
|
+
font-weight: 600;
|
|
102
|
+
color: var(--lyra-color-text);
|
|
103
|
+
}
|
|
104
|
+
.colon {
|
|
105
|
+
flex: 0 0 auto;
|
|
106
|
+
color: var(--lyra-color-text-quiet);
|
|
107
|
+
margin-inline-end: var(--lyra-space-xs);
|
|
108
|
+
}
|
|
109
|
+
[part='bracket'] {
|
|
110
|
+
flex: 0 0 auto;
|
|
111
|
+
color: var(--lyra-color-text-quiet);
|
|
112
|
+
}
|
|
113
|
+
[part='key'][data-match],
|
|
114
|
+
[part='value'][data-match] {
|
|
115
|
+
background: var(--lyra-color-warning-quiet);
|
|
116
|
+
border-radius: 0.1875rem;
|
|
117
|
+
box-shadow: 0 0 0 0.125rem var(--lyra-color-warning-quiet);
|
|
118
|
+
}
|
|
119
|
+
[part='value'] {
|
|
120
|
+
min-inline-size: 0;
|
|
121
|
+
overflow-wrap: anywhere;
|
|
122
|
+
word-break: break-word;
|
|
123
|
+
white-space: pre-wrap;
|
|
124
|
+
}
|
|
125
|
+
[part='value'][data-type='string'] {
|
|
126
|
+
color: var(--lyra-color-success);
|
|
127
|
+
}
|
|
128
|
+
[part='value'][data-type='number'] {
|
|
129
|
+
color: var(--lyra-color-brand);
|
|
130
|
+
}
|
|
131
|
+
[part='value'][data-type='boolean'] {
|
|
132
|
+
color: var(--lyra-color-warning);
|
|
133
|
+
}
|
|
134
|
+
[part='value'][data-type='null'],
|
|
135
|
+
[part='value'][data-type='undefined'] {
|
|
136
|
+
color: var(--lyra-color-text-quiet);
|
|
137
|
+
font-style: italic;
|
|
138
|
+
}
|
|
139
|
+
.preview {
|
|
140
|
+
flex: 0 0 auto;
|
|
141
|
+
color: var(--lyra-color-text-quiet);
|
|
142
|
+
font-style: italic;
|
|
143
|
+
margin-inline: var(--lyra-space-xs);
|
|
144
|
+
}
|
|
145
|
+
[part='copy-button'] {
|
|
146
|
+
flex: 0 0 auto;
|
|
147
|
+
margin-inline-start: auto;
|
|
148
|
+
border: none;
|
|
149
|
+
background: none;
|
|
150
|
+
color: var(--lyra-color-text-quiet);
|
|
151
|
+
font: inherit;
|
|
152
|
+
font-size: 0.75rem;
|
|
153
|
+
line-height: 1;
|
|
154
|
+
padding: 0.125rem var(--lyra-space-xs);
|
|
155
|
+
border-radius: var(--lyra-radius);
|
|
156
|
+
cursor: pointer;
|
|
157
|
+
}
|
|
158
|
+
[part='copy-button']:hover {
|
|
159
|
+
background: var(--lyra-color-brand-quiet);
|
|
160
|
+
color: var(--lyra-color-brand);
|
|
161
|
+
}
|
|
162
|
+
/* Per-node copy buttons stay out of the way until the row is actually
|
|
163
|
+
being interacted with -- the toolbar's own top-level copy button is
|
|
164
|
+
exempt (it has no ancestor .row, so this rule never matches it). */
|
|
165
|
+
.row [part='copy-button'] {
|
|
166
|
+
opacity: 0;
|
|
167
|
+
}
|
|
168
|
+
.row [part='copy-button']:focus-visible {
|
|
169
|
+
opacity: 1;
|
|
170
|
+
}
|
|
171
|
+
@media (prefers-reduced-motion: reduce) {
|
|
172
|
+
[part='toggle'] .chevron {
|
|
173
|
+
transition: none !important;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
`;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { type TemplateResult } from 'lit';
|
|
2
|
+
import { LyraElement } from '../../internal/lyra-element.js';
|
|
3
|
+
/** A single rendered key token: the compact glyph shown in the key cap, and
|
|
4
|
+
* the spelled-out word used in the chip's `aria-label` (glyphs like `⌘`/
|
|
5
|
+
* `⇧`/`⌥` are not reliably announced across every screen reader/platform
|
|
6
|
+
* combination, so the accessible name always spells them out in full). */
|
|
7
|
+
export interface KbdKeyLabel {
|
|
8
|
+
visual: string;
|
|
9
|
+
word: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Resolves one `+`-separated token of a `keys` string to its rendered glyph
|
|
13
|
+
* and spelled-out word, given whether the shortcut is being shown on macOS.
|
|
14
|
+
*
|
|
15
|
+
* Exported as a pure function (parameterized on `isMac` rather than reading
|
|
16
|
+
* the module-scope platform constant directly) so both the macOS and
|
|
17
|
+
* non-macOS branches are directly unit-testable without having to spoof
|
|
18
|
+
* `navigator` in a browser test environment that only ever runs as one
|
|
19
|
+
* platform.
|
|
20
|
+
*/
|
|
21
|
+
export declare function shortcutTokenLabel(rawToken: string, isMac: boolean): KbdKeyLabel;
|
|
22
|
+
/** Splits a `keys` string (e.g. `'mod+shift+p'`) into its resolved token
|
|
23
|
+
* labels, dropping empty segments from stray/leading/trailing `+`s. */
|
|
24
|
+
export declare function parseShortcut(keys: string, isMac: boolean): KbdKeyLabel[];
|
|
25
|
+
/**
|
|
26
|
+
* `<lyra-kbd>` — a small chip representing a keyboard shortcut, rendering
|
|
27
|
+
* the platform-appropriate glyph for cross-platform modifier keys (⌘ on
|
|
28
|
+
* macOS, "Ctrl" elsewhere) from a single platform-neutral `keys` string.
|
|
29
|
+
*
|
|
30
|
+
* `keys` is a `+`-separated sequence of tokens, e.g. `"mod+k"` or
|
|
31
|
+
* `"mod+shift+p"`. Recognized modifier tokens: `mod` (the platform-neutral
|
|
32
|
+
* primary modifier — ⌘ on macOS, "Ctrl" elsewhere), `alt` (⌥ / "Alt"),
|
|
33
|
+
* `shift` (⇧ on every platform), and `ctrl` (always the literal Control
|
|
34
|
+
* key, distinct from `mod`, for a shortcut that's specifically Ctrl even on
|
|
35
|
+
* macOS). Any other token renders as typed, except a bare single
|
|
36
|
+
* letter/digit which is upper-cased, with a small built-in map of friendly
|
|
37
|
+
* labels for common named keys (`enter` → `↵`, `esc` → "Esc", the four
|
|
38
|
+
* arrow keys → arrow glyphs, plus `tab`/`space`/`backspace`/`delete`/`home`/
|
|
39
|
+
* `end`/`pageup`/`pagedown`/`plus`/`minus`). `enter` renders as its `↵`
|
|
40
|
+
* glyph (not the word "Enter") to match the other single-glyph modifier/
|
|
41
|
+
* arrow keys visually — its spelled-out word form still appears in the
|
|
42
|
+
* computed `aria-label`.
|
|
43
|
+
*
|
|
44
|
+
* Each token renders as its own key cap (`part="key"`); consecutive caps
|
|
45
|
+
* are joined by a small "+" separator between them, matching how most
|
|
46
|
+
* cross-platform shortcut documentation (including on macOS, despite the
|
|
47
|
+
* OS's own native shortcut hints usually running the glyphs together with
|
|
48
|
+
* no separator) reads unambiguously regardless of how many/which glyphs are
|
|
49
|
+
* involved.
|
|
50
|
+
*
|
|
51
|
+
* The default slot is not used for the normal glyph rendering above — it's
|
|
52
|
+
* an escape hatch for fully custom content (e.g. an icon instead of a text
|
|
53
|
+
* glyph) that, when non-empty, replaces the `keys`-driven rendering
|
|
54
|
+
* entirely and stops this component from asserting its own `aria-label`,
|
|
55
|
+
* leaving the slotted content to carry its own accessible name.
|
|
56
|
+
*
|
|
57
|
+
* @customElement lyra-kbd
|
|
58
|
+
* @slot - Optional override for fully custom key-cap content, replacing the
|
|
59
|
+
* `keys`-driven rendering. Leave empty to use `keys`.
|
|
60
|
+
* @csspart base - The chip's root element.
|
|
61
|
+
* @csspart key - Each rendered key cap (one per token in `keys`).
|
|
62
|
+
*/
|
|
63
|
+
export declare class LyraKbd extends LyraElement {
|
|
64
|
+
static styles: import("lit").CSSResultGroup[];
|
|
65
|
+
/** A `+`-separated shortcut, e.g. `'mod+k'`. See the class doc for the
|
|
66
|
+
* full token grammar. */
|
|
67
|
+
keys: string;
|
|
68
|
+
private hasCustomContent;
|
|
69
|
+
protected willUpdate(): void;
|
|
70
|
+
private onSlotChange;
|
|
71
|
+
render(): TemplateResult;
|
|
72
|
+
}
|
|
73
|
+
declare global {
|
|
74
|
+
interface HTMLElementTagNameMap {
|
|
75
|
+
'lyra-kbd': LyraKbd;
|
|
76
|
+
}
|
|
77
|
+
}
|