@aceshooting/lyra-ui 1.2.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +98 -14
- package/custom-elements.json +30279 -12124
- package/dist/components/app-rail/app-rail-item.d.ts +30 -0
- package/dist/components/app-rail/app-rail-item.js +68 -0
- package/dist/components/app-rail/app-rail-item.styles.d.ts +1 -0
- package/dist/components/app-rail/app-rail-item.styles.js +65 -0
- package/dist/components/app-rail/app-rail.d.ts +168 -0
- package/dist/components/app-rail/app-rail.js +419 -0
- package/dist/components/app-rail/app-rail.styles.d.ts +1 -0
- package/dist/components/app-rail/app-rail.styles.js +128 -0
- package/dist/components/attachment-chip/attachment-chip.d.ts +141 -0
- package/dist/components/attachment-chip/attachment-chip.js +356 -0
- package/dist/components/attachment-chip/attachment-chip.styles.d.ts +1 -0
- package/dist/components/attachment-chip/attachment-chip.styles.js +184 -0
- package/dist/components/attachment-trigger/attachment-trigger.d.ts +96 -0
- package/dist/components/attachment-trigger/attachment-trigger.js +270 -0
- package/dist/components/attachment-trigger/attachment-trigger.styles.d.ts +1 -0
- package/dist/components/attachment-trigger/attachment-trigger.styles.js +90 -0
- package/dist/components/chart/bar-chart.js +2 -18
- package/dist/components/chart/box-plot.d.ts +25 -1
- package/dist/components/chart/box-plot.js +147 -7
- package/dist/components/chart/box-plot.styles.js +13 -0
- package/dist/components/chart/bubble-chart.js +2 -18
- package/dist/components/chart/chart-loader.d.ts +44 -13
- package/dist/components/chart/chart-loader.js +65 -18
- package/dist/components/chart/chart.d.ts +55 -12
- package/dist/components/chart/chart.js +247 -49
- package/dist/components/chart/doughnut-chart.js +2 -18
- package/dist/components/chart/histogram-bin.d.ts +7 -1
- package/dist/components/chart/histogram-bin.js +32 -14
- package/dist/components/chart/histogram.js +8 -16
- package/dist/components/chart/line-chart.js +2 -18
- package/dist/components/chart/lite-chart.d.ts +134 -3
- package/dist/components/chart/lite-chart.js +382 -67
- package/dist/components/chart/lite-chart.styles.js +9 -0
- package/dist/components/chart/pie-chart.js +2 -18
- package/dist/components/chart/polar-area-chart.js +2 -18
- package/dist/components/chart/radar-chart.js +2 -18
- package/dist/components/chart/scatter-chart.js +2 -18
- package/dist/components/chat-composer/chat-composer.d.ts +133 -0
- package/dist/components/chat-composer/chat-composer.js +366 -0
- package/dist/components/chat-composer/chat-composer.styles.d.ts +1 -0
- package/dist/components/chat-composer/chat-composer.styles.js +145 -0
- package/dist/components/chat-message/chat-message.d.ts +141 -0
- package/dist/components/chat-message/chat-message.js +331 -0
- package/dist/components/chat-message/chat-message.styles.d.ts +1 -0
- package/dist/components/chat-message/chat-message.styles.js +203 -0
- package/dist/components/checkbox/checkbox.d.ts +117 -0
- package/dist/components/checkbox/checkbox.js +353 -0
- package/dist/components/checkbox/checkbox.styles.d.ts +1 -0
- package/dist/components/checkbox/checkbox.styles.js +77 -0
- package/dist/components/chip/chip-group.d.ts +56 -0
- package/dist/components/chip/chip-group.js +130 -0
- package/dist/components/chip/chip-group.styles.d.ts +1 -0
- package/dist/components/chip/chip-group.styles.js +57 -0
- package/dist/components/chip/chip.d.ts +64 -0
- package/dist/components/chip/chip.js +122 -0
- package/dist/components/chip/chip.styles.d.ts +1 -0
- package/dist/components/chip/chip.styles.js +115 -0
- package/dist/components/citation-badge/citation-badge.d.ts +113 -0
- package/dist/components/citation-badge/citation-badge.js +318 -0
- package/dist/components/citation-badge/citation-badge.styles.d.ts +1 -0
- package/dist/components/citation-badge/citation-badge.styles.js +96 -0
- package/dist/components/code-block/code-block.d.ts +127 -0
- package/dist/components/code-block/code-block.js +382 -0
- package/dist/components/code-block/code-block.styles.d.ts +1 -0
- package/dist/components/code-block/code-block.styles.js +187 -0
- package/dist/components/code-block/code-loader.d.ts +87 -0
- package/dist/components/code-block/code-loader.js +142 -0
- package/dist/components/combobox/combobox.d.ts +65 -6
- package/dist/components/combobox/combobox.js +258 -48
- package/dist/components/combobox/combobox.styles.js +3 -3
- package/dist/components/combobox/option.d.ts +5 -1
- package/dist/components/combobox/option.js +35 -0
- package/dist/components/context-meter/context-meter.d.ts +53 -0
- package/dist/components/context-meter/context-meter.js +159 -0
- package/dist/components/context-meter/context-meter.styles.d.ts +1 -0
- package/dist/components/context-meter/context-meter.styles.js +114 -0
- package/dist/components/conversation-item/conversation-item.d.ts +125 -0
- package/dist/components/conversation-item/conversation-item.js +331 -0
- package/dist/components/conversation-item/conversation-item.styles.d.ts +1 -0
- package/dist/components/conversation-item/conversation-item.styles.js +155 -0
- package/dist/components/date-picker/calendar-core.d.ts +24 -0
- package/dist/components/date-picker/calendar-core.js +51 -4
- package/dist/components/date-picker/date-input.d.ts +100 -9
- package/dist/components/date-picker/date-input.js +383 -66
- package/dist/components/date-picker/date-picker.d.ts +35 -4
- package/dist/components/date-picker/date-picker.js +171 -44
- package/dist/components/dialog/confirm.d.ts +40 -0
- package/dist/components/dialog/confirm.js +76 -0
- package/dist/components/dialog/dialog.d.ts +129 -0
- package/dist/components/dialog/dialog.js +288 -0
- package/dist/components/dialog/dialog.styles.d.ts +1 -0
- package/dist/components/dialog/dialog.styles.js +96 -0
- package/dist/components/dock-panel/dock-panel.d.ts +142 -0
- package/dist/components/dock-panel/dock-panel.js +359 -0
- package/dist/components/dock-panel/dock-panel.styles.d.ts +1 -0
- package/dist/components/dock-panel/dock-panel.styles.js +159 -0
- package/dist/components/document-preview/document-preview.d.ts +143 -0
- package/dist/components/document-preview/document-preview.js +388 -0
- package/dist/components/document-preview/document-preview.styles.d.ts +1 -0
- package/dist/components/document-preview/document-preview.styles.js +191 -0
- package/dist/components/empty/empty.d.ts +1 -2
- package/dist/components/empty/empty.js +18 -12
- package/dist/components/empty/empty.styles.js +0 -3
- package/dist/components/export-button/csv.js +1 -1
- package/dist/components/export-button/export-button.d.ts +12 -0
- package/dist/components/export-button/export-button.js +35 -5
- package/dist/components/export-button/export-button.styles.js +5 -1
- package/dist/components/file-input/accept.js +2 -0
- package/dist/components/file-input/file-input.d.ts +10 -1
- package/dist/components/file-input/file-input.js +36 -5
- package/dist/components/flag/flag.d.ts +29 -13
- package/dist/components/flag/flag.js +54 -14
- package/dist/components/flag/flag.styles.js +1 -1
- package/dist/components/flag/language-map.d.ts +4 -1
- package/dist/components/flag/language-map.js +6 -3
- package/dist/components/gauge/gauge.d.ts +10 -1
- package/dist/components/gauge/gauge.js +41 -13
- package/dist/components/generation-status/generation-status.d.ts +117 -0
- package/dist/components/generation-status/generation-status.js +327 -0
- package/dist/components/generation-status/generation-status.styles.d.ts +1 -0
- package/dist/components/generation-status/generation-status.styles.js +84 -0
- package/dist/components/graph/graph.d.ts +37 -3
- package/dist/components/graph/graph.js +132 -20
- package/dist/components/heatmap/calendar-grid.d.ts +19 -7
- package/dist/components/heatmap/calendar-grid.js +42 -18
- package/dist/components/heatmap/heatmap-scale.d.ts +11 -1
- package/dist/components/heatmap/heatmap-scale.js +14 -2
- package/dist/components/heatmap/heatmap.d.ts +227 -12
- package/dist/components/heatmap/heatmap.js +488 -93
- package/dist/components/json-viewer/json-viewer.d.ts +70 -0
- package/dist/components/json-viewer/json-viewer.js +361 -0
- package/dist/components/json-viewer/json-viewer.styles.d.ts +1 -0
- package/dist/components/json-viewer/json-viewer.styles.js +177 -0
- package/dist/components/kbd/kbd.d.ts +77 -0
- package/dist/components/kbd/kbd.js +231 -0
- package/dist/components/kbd/kbd.styles.d.ts +1 -0
- package/dist/components/kbd/kbd.styles.js +52 -0
- package/dist/components/live-region/live-region.d.ts +90 -0
- package/dist/components/live-region/live-region.js +189 -0
- package/dist/components/live-region/live-region.styles.d.ts +1 -0
- package/dist/components/live-region/live-region.styles.js +10 -0
- package/dist/components/map/map.d.ts +32 -7
- package/dist/components/map/map.js +133 -32
- package/dist/components/markdown/markdown-loader.d.ts +58 -0
- package/dist/components/markdown/markdown-loader.js +77 -0
- package/dist/components/markdown/markdown.d.ts +119 -0
- package/dist/components/markdown/markdown.js +389 -0
- package/dist/components/markdown/markdown.styles.d.ts +1 -0
- package/dist/components/markdown/markdown.styles.js +88 -0
- package/dist/components/media-card/media-card.d.ts +130 -0
- package/dist/components/media-card/media-card.js +273 -0
- package/dist/components/media-card/media-card.styles.d.ts +1 -0
- package/dist/components/media-card/media-card.styles.js +132 -0
- package/dist/components/mention-popover/mention-popover.d.ts +203 -0
- package/dist/components/mention-popover/mention-popover.js +493 -0
- package/dist/components/mention-popover/mention-popover.styles.d.ts +1 -0
- package/dist/components/mention-popover/mention-popover.styles.js +101 -0
- package/dist/components/menu/menu-item.d.ts +91 -0
- package/dist/components/menu/menu-item.js +206 -0
- package/dist/components/menu/menu-item.styles.d.ts +1 -0
- package/dist/components/menu/menu-item.styles.js +75 -0
- package/dist/components/menu/menu.d.ts +167 -0
- package/dist/components/menu/menu.js +461 -0
- package/dist/components/menu/menu.styles.d.ts +1 -0
- package/dist/components/menu/menu.styles.js +67 -0
- package/dist/components/model-select/model-select.d.ts +170 -0
- package/dist/components/model-select/model-select.js +588 -0
- package/dist/components/model-select/model-select.styles.d.ts +1 -0
- package/dist/components/model-select/model-select.styles.js +203 -0
- package/dist/components/model-settings-panel/model-settings-panel.d.ts +93 -0
- package/dist/components/model-settings-panel/model-settings-panel.js +209 -0
- package/dist/components/model-settings-panel/model-settings-panel.styles.d.ts +1 -0
- package/dist/components/model-settings-panel/model-settings-panel.styles.js +82 -0
- package/dist/components/playback/playback.d.ts +19 -3
- package/dist/components/playback/playback.js +109 -33
- package/dist/components/playback/playback.styles.js +6 -1
- package/dist/components/responsive-panel/responsive-panel.d.ts +163 -0
- package/dist/components/responsive-panel/responsive-panel.js +363 -0
- package/dist/components/responsive-panel/responsive-panel.styles.d.ts +1 -0
- package/dist/components/responsive-panel/responsive-panel.styles.js +103 -0
- package/dist/components/result-card/result-card.d.ts +50 -0
- package/dist/components/result-card/result-card.js +89 -0
- package/dist/components/result-card/result-card.styles.d.ts +1 -0
- package/dist/components/result-card/result-card.styles.js +49 -0
- package/dist/components/result-card/result-field.d.ts +36 -0
- package/dist/components/result-card/result-field.js +87 -0
- package/dist/components/result-card/result-field.styles.d.ts +1 -0
- package/dist/components/result-card/result-field.styles.js +32 -0
- package/dist/components/select/select.d.ts +84 -4
- package/dist/components/select/select.js +251 -36
- package/dist/components/skeleton/skeleton.d.ts +3 -0
- package/dist/components/skeleton/skeleton.js +7 -1
- package/dist/components/skeleton/skeleton.styles.js +5 -4
- package/dist/components/slider/slider.d.ts +141 -0
- package/dist/components/slider/slider.js +467 -0
- package/dist/components/slider/slider.styles.d.ts +1 -0
- package/dist/components/slider/slider.styles.js +87 -0
- package/dist/components/source-card/source-card.d.ts +104 -0
- package/dist/components/source-card/source-card.js +195 -0
- package/dist/components/source-card/source-card.styles.d.ts +1 -0
- package/dist/components/source-card/source-card.styles.js +69 -0
- package/dist/components/source-list/source-list.d.ts +63 -0
- package/dist/components/source-list/source-list.js +130 -0
- package/dist/components/source-list/source-list.styles.d.ts +1 -0
- package/dist/components/source-list/source-list.styles.js +59 -0
- package/dist/components/sparkline/sparkline.js +58 -20
- package/dist/components/split/split.d.ts +224 -5
- package/dist/components/split/split.js +617 -43
- package/dist/components/split/split.styles.js +47 -0
- package/dist/components/stat/stat.d.ts +15 -4
- package/dist/components/stat/stat.js +53 -12
- package/dist/components/stream-status/stream-status.d.ts +126 -0
- package/dist/components/stream-status/stream-status.js +292 -0
- package/dist/components/stream-status/stream-status.styles.d.ts +1 -0
- package/dist/components/stream-status/stream-status.styles.js +103 -0
- package/dist/components/streaming-text/streaming-text.d.ts +104 -0
- package/dist/components/streaming-text/streaming-text.js +224 -0
- package/dist/components/streaming-text/streaming-text.styles.d.ts +1 -0
- package/dist/components/streaming-text/streaming-text.styles.js +63 -0
- package/dist/components/switch/switch.d.ts +103 -0
- package/dist/components/switch/switch.js +250 -0
- package/dist/components/switch/switch.styles.d.ts +1 -0
- package/dist/components/switch/switch.styles.js +75 -0
- package/dist/components/table/table.d.ts +89 -5
- package/dist/components/table/table.js +243 -26
- package/dist/components/table/table.styles.js +6 -1
- package/dist/components/tabs/tabs.d.ts +74 -0
- package/dist/components/tabs/tabs.js +254 -0
- package/dist/components/tabs/tabs.styles.d.ts +1 -0
- package/dist/components/tabs/tabs.styles.js +74 -0
- package/dist/components/thinking-panel/thinking-panel.d.ts +123 -0
- package/dist/components/thinking-panel/thinking-panel.js +260 -0
- package/dist/components/thinking-panel/thinking-panel.styles.d.ts +1 -0
- package/dist/components/thinking-panel/thinking-panel.styles.js +123 -0
- package/dist/components/time-range/time-range.d.ts +59 -2
- package/dist/components/time-range/time-range.js +163 -67
- package/dist/components/toast/toast-item.d.ts +12 -2
- package/dist/components/toast/toast-item.js +106 -44
- package/dist/components/toast/toast-item.styles.js +59 -28
- package/dist/components/toast/toast.js +17 -5
- package/dist/components/toast/toaster.js +10 -1
- package/dist/components/tool-approval-dialog/tool-approval-dialog.d.ts +131 -0
- package/dist/components/tool-approval-dialog/tool-approval-dialog.js +329 -0
- package/dist/components/tool-approval-dialog/tool-approval-dialog.styles.d.ts +1 -0
- package/dist/components/tool-approval-dialog/tool-approval-dialog.styles.js +160 -0
- package/dist/components/tool-call-chip/tool-call-chip.d.ts +105 -0
- package/dist/components/tool-call-chip/tool-call-chip.js +349 -0
- package/dist/components/tool-call-chip/tool-call-chip.styles.d.ts +1 -0
- package/dist/components/tool-call-chip/tool-call-chip.styles.js +203 -0
- package/dist/components/tool-param-form/tool-param-form.d.ts +206 -0
- package/dist/components/tool-param-form/tool-param-form.js +610 -0
- package/dist/components/tool-param-form/tool-param-form.styles.d.ts +1 -0
- package/dist/components/tool-param-form/tool-param-form.styles.js +75 -0
- package/dist/components/tool-result-dialog/tool-result-dialog.d.ts +122 -0
- package/dist/components/tool-result-dialog/tool-result-dialog.js +358 -0
- package/dist/components/tool-result-dialog/tool-result-dialog.styles.d.ts +1 -0
- package/dist/components/tool-result-dialog/tool-result-dialog.styles.js +176 -0
- package/dist/components/tool-result-view/registry.d.ts +73 -0
- package/dist/components/tool-result-view/registry.js +89 -0
- package/dist/components/tool-result-view/tool-result-view.d.ts +58 -0
- package/dist/components/tool-result-view/tool-result-view.js +152 -0
- package/dist/components/tool-result-view/tool-result-view.styles.d.ts +1 -0
- package/dist/components/tool-result-view/tool-result-view.styles.js +13 -0
- package/dist/components/tool-select-dialog/tool-select-dialog.d.ts +151 -0
- package/dist/components/tool-select-dialog/tool-select-dialog.js +350 -0
- package/dist/components/tool-select-dialog/tool-select-dialog.styles.d.ts +1 -0
- package/dist/components/tool-select-dialog/tool-select-dialog.styles.js +191 -0
- package/dist/components/tree/tree-node.d.ts +15 -3
- package/dist/components/tree/tree-node.js +20 -7
- package/dist/components/tree/tree.d.ts +25 -10
- package/dist/components/tree/tree.js +39 -31
- package/dist/components/typing-indicator/typing-indicator.d.ts +70 -0
- package/dist/components/typing-indicator/typing-indicator.js +108 -0
- package/dist/components/typing-indicator/typing-indicator.styles.d.ts +1 -0
- package/dist/components/typing-indicator/typing-indicator.styles.js +132 -0
- package/dist/components/virtual-list/virtual-list.d.ts +210 -0
- package/dist/components/virtual-list/virtual-list.js +607 -0
- package/dist/components/virtual-list/virtual-list.styles.d.ts +1 -0
- package/dist/components/virtual-list/virtual-list.styles.js +56 -0
- package/dist/components/widget/widget.d.ts +5 -4
- package/dist/components/widget/widget.js +54 -120
- package/dist/components/widget/widget.styles.js +8 -2
- package/dist/components/word-cloud/word-cloud-layout.d.ts +7 -0
- package/dist/components/word-cloud/word-cloud-layout.js +29 -2
- package/dist/components/word-cloud/word-cloud.d.ts +28 -2
- package/dist/components/word-cloud/word-cloud.js +69 -19
- package/dist/components/word-cloud/word-cloud.styles.js +16 -3
- package/dist/internal/anchored-validity.d.ts +1 -0
- package/dist/internal/anchored-validity.js +86 -0
- package/dist/internal/announcer.d.ts +57 -0
- package/dist/internal/announcer.js +71 -0
- package/dist/internal/form-associated.d.ts +8 -0
- package/dist/internal/form-associated.js +98 -15
- package/dist/internal/group-by-recency.d.ts +50 -0
- package/dist/internal/group-by-recency.js +80 -0
- package/dist/internal/numbers.d.ts +12 -0
- package/dist/internal/numbers.js +26 -0
- package/dist/internal/overlay-manager.d.ts +51 -0
- package/dist/internal/overlay-manager.js +523 -0
- package/dist/internal/positioner.js +27 -3
- package/dist/internal/rtl.d.ts +23 -0
- package/dist/internal/rtl.js +28 -0
- package/dist/internal/safe-url.d.ts +12 -0
- package/dist/internal/safe-url.js +41 -0
- package/dist/internal/scroll-lock.d.ts +10 -5
- package/dist/internal/scroll-lock.js +30 -14
- package/dist/internal/tokens.styles.js +22 -10
- package/dist/lyra.d.ts +133 -31
- package/dist/lyra.js +96 -26
- package/llms-full.txt +4546 -183
- package/llms.txt +21 -5
- package/package.json +41 -6
- package/dist/components/chart/bar-chart.stories.d.ts +0 -5
- package/dist/components/chart/bar-chart.stories.js +0 -20
- package/dist/components/chart/box-plot.stories.d.ts +0 -5
- package/dist/components/chart/box-plot.stories.js +0 -29
- package/dist/components/chart/bubble-chart.stories.d.ts +0 -5
- package/dist/components/chart/bubble-chart.stories.js +0 -26
- package/dist/components/chart/chart.stories.d.ts +0 -32
- package/dist/components/chart/chart.stories.js +0 -141
- package/dist/components/chart/doughnut-chart.stories.d.ts +0 -5
- package/dist/components/chart/doughnut-chart.stories.js +0 -26
- package/dist/components/chart/histogram.stories.d.ts +0 -5
- package/dist/components/chart/histogram.stories.js +0 -17
- package/dist/components/chart/line-chart.stories.d.ts +0 -22
- package/dist/components/chart/line-chart.stories.js +0 -99
- package/dist/components/chart/lite-chart.stories.d.ts +0 -14
- package/dist/components/chart/lite-chart.stories.js +0 -114
- package/dist/components/chart/pie-chart.stories.d.ts +0 -5
- package/dist/components/chart/pie-chart.stories.js +0 -26
- package/dist/components/chart/polar-area-chart.stories.d.ts +0 -5
- package/dist/components/chart/polar-area-chart.stories.js +0 -20
- package/dist/components/chart/radar-chart.stories.d.ts +0 -5
- package/dist/components/chart/radar-chart.stories.js +0 -20
- package/dist/components/chart/scatter-chart.stories.d.ts +0 -5
- package/dist/components/chart/scatter-chart.stories.js +0 -31
- package/dist/components/combobox/combobox.stories.d.ts +0 -24
- package/dist/components/combobox/combobox.stories.js +0 -102
- package/dist/components/date-picker/date-input.stories.d.ts +0 -10
- package/dist/components/date-picker/date-input.stories.js +0 -48
- package/dist/components/date-picker/date-picker.stories.d.ts +0 -10
- package/dist/components/date-picker/date-picker.stories.js +0 -25
- package/dist/components/empty/empty.stories.d.ts +0 -7
- package/dist/components/empty/empty.stories.js +0 -34
- package/dist/components/export-button/export-button.stories.d.ts +0 -7
- package/dist/components/export-button/export-button.stories.js +0 -37
- package/dist/components/file-input/file-input.stories.d.ts +0 -7
- package/dist/components/file-input/file-input.stories.js +0 -19
- package/dist/components/flag/flag.stories.d.ts +0 -6
- package/dist/components/flag/flag.stories.js +0 -31
- package/dist/components/gauge/gauge.stories.d.ts +0 -8
- package/dist/components/gauge/gauge.stories.js +0 -19
- package/dist/components/graph/graph.stories.d.ts +0 -8
- package/dist/components/graph/graph.stories.js +0 -68
- package/dist/components/heatmap/heatmap.stories.d.ts +0 -27
- package/dist/components/heatmap/heatmap.stories.js +0 -179
- package/dist/components/map/map.stories.d.ts +0 -15
- package/dist/components/map/map.stories.js +0 -135
- package/dist/components/playback/playback.stories.d.ts +0 -7
- package/dist/components/playback/playback.stories.js +0 -16
- package/dist/components/select/select.stories.d.ts +0 -21
- package/dist/components/select/select.stories.js +0 -91
- package/dist/components/skeleton/skeleton.stories.d.ts +0 -5
- package/dist/components/skeleton/skeleton.stories.js +0 -16
- package/dist/components/sparkline/sparkline.stories.d.ts +0 -11
- package/dist/components/sparkline/sparkline.stories.js +0 -39
- package/dist/components/split/split.stories.d.ts +0 -7
- package/dist/components/split/split.stories.js +0 -36
- package/dist/components/stat/stat.stories.d.ts +0 -9
- package/dist/components/stat/stat.stories.js +0 -81
- package/dist/components/table/table.stories.d.ts +0 -12
- package/dist/components/table/table.stories.js +0 -67
- package/dist/components/time-range/time-range.stories.d.ts +0 -8
- package/dist/components/time-range/time-range.stories.js +0 -26
- package/dist/components/toast/toast.stories.d.ts +0 -8
- package/dist/components/toast/toast.stories.js +0 -72
- package/dist/components/tree/tree.stories.d.ts +0 -9
- package/dist/components/tree/tree.stories.js +0 -52
- package/dist/components/widget/widget.stories.d.ts +0 -9
- package/dist/components/widget/widget.stories.js +0 -74
- package/dist/components/word-cloud/word-cloud.stories.d.ts +0 -10
- package/dist/components/word-cloud/word-cloud.stories.js +0 -55
|
@@ -4,6 +4,7 @@ import '../skeleton/skeleton.js';
|
|
|
4
4
|
export interface GraphNode {
|
|
5
5
|
id: string;
|
|
6
6
|
label?: string;
|
|
7
|
+
/** Clamped to [6, 24] (a non-finite/missing value uses the midpoint, 15) — never rendered smaller/larger. */
|
|
7
8
|
radius?: number;
|
|
8
9
|
color?: string;
|
|
9
10
|
}
|
|
@@ -19,12 +20,24 @@ export interface GraphLink {
|
|
|
19
20
|
*
|
|
20
21
|
* Set `seed` for a deterministic layout: node initial positions become
|
|
21
22
|
* reproducible (keyed by node id) and the settle happens synchronously
|
|
22
|
-
* instead of animating, like `prefers-reduced-motion`.
|
|
23
|
+
* instead of animating, like `prefers-reduced-motion`. `seed` only takes
|
|
24
|
+
* effect on the update that first populates `nodes`/`links` (or a later
|
|
25
|
+
* update that adds genuinely new node ids) — willUpdate() only reads it from
|
|
26
|
+
* inside rebuildSimulation(), which itself only ever assigns x/y to nodes
|
|
27
|
+
* that don't already have a settled position, so changing `seed` on an
|
|
28
|
+
* already-rendered graph is a no-op; nothing re-derives already-positioned
|
|
29
|
+
* nodes' x/y from the new value.
|
|
23
30
|
*
|
|
24
31
|
* @customElement lyra-graph
|
|
25
32
|
* @event lyra-node-click - `detail: { id }`.
|
|
26
33
|
* @event lyra-link-click - `detail: { source, target }`.
|
|
27
|
-
* @csspart base
|
|
34
|
+
* @csspart base - The graph wrapper.
|
|
35
|
+
* @csspart svg - The graph SVG.
|
|
36
|
+
* @csspart node - A graph node.
|
|
37
|
+
* @csspart link - A graph link.
|
|
38
|
+
* @csspart label - A node label.
|
|
39
|
+
* @csspart live-region - The current graph item announcement.
|
|
40
|
+
* @csspart data-list - A visually hidden list alternative for graph data.
|
|
28
41
|
*/
|
|
29
42
|
export declare class LyraGraph extends LyraElement {
|
|
30
43
|
static styles: import("lit").CSSResultGroup[];
|
|
@@ -38,12 +51,20 @@ export declare class LyraGraph extends LyraElement {
|
|
|
38
51
|
maxZoom: number;
|
|
39
52
|
/** When set, seeds each node's initial x/y deterministically (keyed by
|
|
40
53
|
* node id, not array index) instead of forceSimulation()'s own random
|
|
41
|
-
* start, and settles the simulation synchronously — see rebuildSimulation().
|
|
54
|
+
* start, and settles the simulation synchronously — see rebuildSimulation().
|
|
55
|
+
* Only takes effect on the update that first assigns a given node id an
|
|
56
|
+
* x/y (i.e. supplied at/before `nodes`/`links` first populate, or when a
|
|
57
|
+
* later update introduces new node ids) — changing `seed` afterwards does
|
|
58
|
+
* not retroactively reposition already-settled nodes; there is currently
|
|
59
|
+
* no way to make an already-rendered graph reproducible after the fact. */
|
|
42
60
|
seed?: number;
|
|
43
61
|
/** True until the lazy-loaded d3 peer dependencies have settled (success or failure). */
|
|
44
62
|
private loading;
|
|
45
63
|
private simNodes;
|
|
46
64
|
private simLinks;
|
|
65
|
+
/** One roving tab stop across all nodes and links; nodes are the initial entry order. */
|
|
66
|
+
private activeGraphItem;
|
|
67
|
+
private graphLiveText;
|
|
47
68
|
private simulation?;
|
|
48
69
|
/** The live charge/link force objects, kept so chargeStrength/linkDistance
|
|
49
70
|
* changes can retune them in place (see updated()) instead of requiring a
|
|
@@ -73,6 +94,13 @@ export declare class LyraGraph extends LyraElement {
|
|
|
73
94
|
private linkEls;
|
|
74
95
|
connectedCallback(): void;
|
|
75
96
|
disconnectedCallback(): void;
|
|
97
|
+
/**
|
|
98
|
+
* A caller-supplied `radius` is clamped to [MIN_RADIUS, MAX_RADIUS] (and a
|
|
99
|
+
* non-finite/NaN value falls back to the same default average as an unset
|
|
100
|
+
* one) — an unclamped 0/negative radius would render an invisibly small
|
|
101
|
+
* `<circle>` that's still `role="button" tabindex="0"`, an invisible,
|
|
102
|
+
* focusable/clickable control with no visible focus indicator.
|
|
103
|
+
*/
|
|
76
104
|
private nodeRadius;
|
|
77
105
|
protected willUpdate(changed: PropertyValues): void;
|
|
78
106
|
protected updated(changed: PropertyValues): void;
|
|
@@ -114,6 +142,12 @@ export declare class LyraGraph extends LyraElement {
|
|
|
114
142
|
private rebuildSimulation;
|
|
115
143
|
private onNodeClick;
|
|
116
144
|
private onLinkClick;
|
|
145
|
+
private graphItemCount;
|
|
146
|
+
private normalizedGraphItem;
|
|
147
|
+
private graphItemText;
|
|
148
|
+
private onGraphItemFocus;
|
|
149
|
+
private focusGraphItem;
|
|
150
|
+
private onGraphKeyDown;
|
|
117
151
|
render(): TemplateResult;
|
|
118
152
|
}
|
|
119
153
|
declare global {
|
|
@@ -9,6 +9,7 @@ import { property, state } from 'lit/decorators.js';
|
|
|
9
9
|
import { styleMap } from 'lit/directives/style-map.js';
|
|
10
10
|
import { LyraElement } from '../../internal/lyra-element.js';
|
|
11
11
|
import { defineElement } from '../../internal/prefix.js';
|
|
12
|
+
import { srOnly } from '../../internal/a11y.js';
|
|
12
13
|
import { styles } from './graph.styles.js';
|
|
13
14
|
import { loadD3 } from './graph-loader.js';
|
|
14
15
|
import '../skeleton/skeleton.js';
|
|
@@ -67,12 +68,24 @@ function sanitizeNodeColor(color) {
|
|
|
67
68
|
*
|
|
68
69
|
* Set `seed` for a deterministic layout: node initial positions become
|
|
69
70
|
* reproducible (keyed by node id) and the settle happens synchronously
|
|
70
|
-
* instead of animating, like `prefers-reduced-motion`.
|
|
71
|
+
* instead of animating, like `prefers-reduced-motion`. `seed` only takes
|
|
72
|
+
* effect on the update that first populates `nodes`/`links` (or a later
|
|
73
|
+
* update that adds genuinely new node ids) — willUpdate() only reads it from
|
|
74
|
+
* inside rebuildSimulation(), which itself only ever assigns x/y to nodes
|
|
75
|
+
* that don't already have a settled position, so changing `seed` on an
|
|
76
|
+
* already-rendered graph is a no-op; nothing re-derives already-positioned
|
|
77
|
+
* nodes' x/y from the new value.
|
|
71
78
|
*
|
|
72
79
|
* @customElement lyra-graph
|
|
73
80
|
* @event lyra-node-click - `detail: { id }`.
|
|
74
81
|
* @event lyra-link-click - `detail: { source, target }`.
|
|
75
|
-
* @csspart base
|
|
82
|
+
* @csspart base - The graph wrapper.
|
|
83
|
+
* @csspart svg - The graph SVG.
|
|
84
|
+
* @csspart node - A graph node.
|
|
85
|
+
* @csspart link - A graph link.
|
|
86
|
+
* @csspart label - A node label.
|
|
87
|
+
* @csspart live-region - The current graph item announcement.
|
|
88
|
+
* @csspart data-list - A visually hidden list alternative for graph data.
|
|
76
89
|
*/
|
|
77
90
|
export class LyraGraph extends LyraElement {
|
|
78
91
|
constructor() {
|
|
@@ -89,6 +102,9 @@ export class LyraGraph extends LyraElement {
|
|
|
89
102
|
this.loading = true;
|
|
90
103
|
this.simNodes = [];
|
|
91
104
|
this.simLinks = [];
|
|
105
|
+
/** One roving tab stop across all nodes and links; nodes are the initial entry order. */
|
|
106
|
+
this.activeGraphItem = 0;
|
|
107
|
+
this.graphLiveText = '';
|
|
92
108
|
/** Node `<circle>`s already wired up with d3-drag; cleared on every simulation rebuild
|
|
93
109
|
* so DOM elements Lit reuses across a rebuild get rebound to their fresh datum. */
|
|
94
110
|
this.boundNodeEls = new WeakSet();
|
|
@@ -100,9 +116,22 @@ export class LyraGraph extends LyraElement {
|
|
|
100
116
|
this.nodeLabelEls = [];
|
|
101
117
|
this.linkEls = [];
|
|
102
118
|
}
|
|
103
|
-
static { this.styles = [LyraElement.styles, styles]; }
|
|
119
|
+
static { this.styles = [LyraElement.styles, styles, srOnly]; }
|
|
104
120
|
connectedCallback() {
|
|
105
121
|
super.connectedCallback();
|
|
122
|
+
// A reconnect (e.g. a drag-and-drop reparent that keeps this same
|
|
123
|
+
// element instance) fires disconnectedCallback then connectedCallback
|
|
124
|
+
// synchronously with no update in between — this.d3 is already set from
|
|
125
|
+
// the initial mount, and the live simulation/DOM are still intact
|
|
126
|
+
// (disconnectedCallback only stops the simulation's timer, it doesn't
|
|
127
|
+
// tear anything down). Redoing the lazy-load + rebuildSimulation() here
|
|
128
|
+
// would discard every already-settled node's position and restart the
|
|
129
|
+
// whole ~300-tick alpha=1 settle animation for no reason — just resume
|
|
130
|
+
// the existing simulation in place instead.
|
|
131
|
+
if (this.d3) {
|
|
132
|
+
this.simulation?.restart();
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
106
135
|
void loadD3().then((mods) => {
|
|
107
136
|
this.loading = false;
|
|
108
137
|
// The element may have been removed from the DOM while the dynamic
|
|
@@ -118,8 +147,16 @@ export class LyraGraph extends LyraElement {
|
|
|
118
147
|
super.disconnectedCallback();
|
|
119
148
|
this.simulation?.stop();
|
|
120
149
|
}
|
|
150
|
+
/**
|
|
151
|
+
* A caller-supplied `radius` is clamped to [MIN_RADIUS, MAX_RADIUS] (and a
|
|
152
|
+
* non-finite/NaN value falls back to the same default average as an unset
|
|
153
|
+
* one) — an unclamped 0/negative radius would render an invisibly small
|
|
154
|
+
* `<circle>` that's still `role="button" tabindex="0"`, an invisible,
|
|
155
|
+
* focusable/clickable control with no visible focus indicator.
|
|
156
|
+
*/
|
|
121
157
|
nodeRadius(n) {
|
|
122
|
-
|
|
158
|
+
const r = n.radius ?? (MIN_RADIUS + MAX_RADIUS) / 2;
|
|
159
|
+
return Number.isFinite(r) ? Math.min(MAX_RADIUS, Math.max(MIN_RADIUS, r)) : (MIN_RADIUS + MAX_RADIUS) / 2;
|
|
123
160
|
}
|
|
124
161
|
willUpdate(changed) {
|
|
125
162
|
// rebuildSimulation() (re)assigns the simNodes/simLinks reactive
|
|
@@ -355,6 +392,69 @@ export class LyraGraph extends LyraElement {
|
|
|
355
392
|
const target = typeof link.target === 'object' ? link.target.id : String(link.target);
|
|
356
393
|
this.emit('lyra-link-click', { source, target });
|
|
357
394
|
}
|
|
395
|
+
graphItemCount() {
|
|
396
|
+
return this.simNodes.length + this.simLinks.length;
|
|
397
|
+
}
|
|
398
|
+
normalizedGraphItem(index = this.activeGraphItem) {
|
|
399
|
+
const count = this.graphItemCount();
|
|
400
|
+
return count ? Math.min(Math.max(index, 0), count - 1) : -1;
|
|
401
|
+
}
|
|
402
|
+
graphItemText(index) {
|
|
403
|
+
if (index < this.simNodes.length) {
|
|
404
|
+
const node = this.simNodes[index];
|
|
405
|
+
return node ? `Node ${node.label ?? node.id}` : '';
|
|
406
|
+
}
|
|
407
|
+
const link = this.simLinks[index - this.simNodes.length];
|
|
408
|
+
if (!link)
|
|
409
|
+
return '';
|
|
410
|
+
const source = typeof link.source === 'object' ? link.source.label ?? link.source.id : String(link.source);
|
|
411
|
+
const target = typeof link.target === 'object' ? link.target.label ?? link.target.id : String(link.target);
|
|
412
|
+
return `Link from ${source} to ${target}`;
|
|
413
|
+
}
|
|
414
|
+
onGraphItemFocus(index) {
|
|
415
|
+
if (this.normalizedGraphItem(index) < 0)
|
|
416
|
+
return;
|
|
417
|
+
this.activeGraphItem = index;
|
|
418
|
+
this.graphLiveText = `${this.graphItemText(index)} (${index + 1} of ${this.graphItemCount()})`;
|
|
419
|
+
}
|
|
420
|
+
focusGraphItem(index) {
|
|
421
|
+
const normalized = this.normalizedGraphItem(index);
|
|
422
|
+
if (normalized < 0)
|
|
423
|
+
return;
|
|
424
|
+
this.activeGraphItem = normalized;
|
|
425
|
+
this.graphLiveText = `${this.graphItemText(normalized)} (${normalized + 1} of ${this.graphItemCount()})`;
|
|
426
|
+
void this.updateComplete.then(() => {
|
|
427
|
+
const items = [
|
|
428
|
+
...Array.from(this.renderRoot.querySelectorAll('[part="node"]')),
|
|
429
|
+
...Array.from(this.renderRoot.querySelectorAll('[part="link"]')),
|
|
430
|
+
];
|
|
431
|
+
items[normalized]?.focus();
|
|
432
|
+
});
|
|
433
|
+
}
|
|
434
|
+
onGraphKeyDown(e, index, activate) {
|
|
435
|
+
if (e.key === 'Enter' || e.key === ' ') {
|
|
436
|
+
e.preventDefault();
|
|
437
|
+
this.onGraphItemFocus(index);
|
|
438
|
+
activate();
|
|
439
|
+
return;
|
|
440
|
+
}
|
|
441
|
+
const count = this.graphItemCount();
|
|
442
|
+
if (!count)
|
|
443
|
+
return;
|
|
444
|
+
let next = index;
|
|
445
|
+
if (e.key === 'ArrowRight' || e.key === 'ArrowDown')
|
|
446
|
+
next = Math.min(count - 1, index + 1);
|
|
447
|
+
else if (e.key === 'ArrowLeft' || e.key === 'ArrowUp')
|
|
448
|
+
next = Math.max(0, index - 1);
|
|
449
|
+
else if (e.key === 'Home')
|
|
450
|
+
next = 0;
|
|
451
|
+
else if (e.key === 'End')
|
|
452
|
+
next = count - 1;
|
|
453
|
+
else
|
|
454
|
+
return;
|
|
455
|
+
e.preventDefault();
|
|
456
|
+
this.focusGraphItem(next);
|
|
457
|
+
}
|
|
358
458
|
render() {
|
|
359
459
|
if (this.loading) {
|
|
360
460
|
return html `
|
|
@@ -373,15 +473,17 @@ export class LyraGraph extends LyraElement {
|
|
|
373
473
|
role="group"
|
|
374
474
|
aria-label="Node-link diagram with ${this.simNodes.length} nodes and ${this.simLinks.length} links"
|
|
375
475
|
viewBox="0 0 ${this.width} ${this.height}"
|
|
476
|
+
tabindex=${this.graphItemCount() ? '-1' : '0'}
|
|
376
477
|
>
|
|
377
478
|
<g transform="">
|
|
378
|
-
${this.simLinks.map((l) => {
|
|
479
|
+
${this.simLinks.map((l, linkIndex) => {
|
|
379
480
|
const source = l.source;
|
|
380
481
|
const target = l.target;
|
|
482
|
+
const itemIndex = this.simNodes.length + linkIndex;
|
|
381
483
|
return svg `<line
|
|
382
484
|
part="link"
|
|
383
485
|
role="button"
|
|
384
|
-
tabindex
|
|
486
|
+
tabindex=${this.normalizedGraphItem() === itemIndex ? '0' : '-1'}
|
|
385
487
|
aria-label="Link from ${source.label ?? source.id} to ${target.label ?? target.id}"
|
|
386
488
|
stroke-width=${l.width ?? 1.5}
|
|
387
489
|
x1=${source.x ?? 0}
|
|
@@ -389,33 +491,26 @@ export class LyraGraph extends LyraElement {
|
|
|
389
491
|
x2=${target.x ?? 0}
|
|
390
492
|
y2=${target.y ?? 0}
|
|
391
493
|
@click=${() => this.onLinkClick(l)}
|
|
392
|
-
@
|
|
393
|
-
|
|
394
|
-
e.preventDefault();
|
|
395
|
-
this.onLinkClick(l);
|
|
396
|
-
}
|
|
397
|
-
}}
|
|
494
|
+
@focus=${() => this.onGraphItemFocus(itemIndex)}
|
|
495
|
+
@keydown=${(e) => this.onGraphKeyDown(e, itemIndex, () => this.onLinkClick(l))}
|
|
398
496
|
></line>`;
|
|
399
497
|
})}
|
|
400
|
-
${this.simNodes.map((n) => {
|
|
498
|
+
${this.simNodes.map((n, nodeIndex) => {
|
|
401
499
|
const fill = sanitizeNodeColor(n.color);
|
|
500
|
+
const itemIndex = nodeIndex;
|
|
402
501
|
return svg `<g>
|
|
403
502
|
<circle
|
|
404
503
|
part="node"
|
|
405
504
|
role="button"
|
|
406
|
-
tabindex
|
|
505
|
+
tabindex=${this.normalizedGraphItem() === itemIndex ? '0' : '-1'}
|
|
407
506
|
aria-label=${n.label ?? n.id}
|
|
408
507
|
r=${this.nodeRadius(n)}
|
|
409
508
|
cx=${n.x ?? 0}
|
|
410
509
|
cy=${n.y ?? 0}
|
|
411
510
|
style=${styleMap(fill ? { '--lyra-node-fill': fill } : {})}
|
|
412
511
|
@click=${() => this.onNodeClick(n)}
|
|
413
|
-
@
|
|
414
|
-
|
|
415
|
-
e.preventDefault();
|
|
416
|
-
this.onNodeClick(n);
|
|
417
|
-
}
|
|
418
|
-
}}
|
|
512
|
+
@focus=${() => this.onGraphItemFocus(itemIndex)}
|
|
513
|
+
@keydown=${(e) => this.onGraphKeyDown(e, itemIndex, () => this.onNodeClick(n))}
|
|
419
514
|
></circle>
|
|
420
515
|
${n.label
|
|
421
516
|
? svg `<text part="label" aria-hidden="true" x=${(n.x ?? 0) + this.nodeRadius(n) + 2} y=${n.y ?? 0}>${n.label}</text>`
|
|
@@ -424,6 +519,17 @@ export class LyraGraph extends LyraElement {
|
|
|
424
519
|
})}
|
|
425
520
|
</g>
|
|
426
521
|
</svg>
|
|
522
|
+
<div part="live-region" class="sr-only" role="status" aria-live="polite" aria-atomic="true">
|
|
523
|
+
${this.graphLiveText || (this.normalizedGraphItem() >= 0 ? `${this.graphItemText(this.normalizedGraphItem())} (1 of ${this.graphItemCount()})` : '')}
|
|
524
|
+
</div>
|
|
525
|
+
<ul part="data-list" class="sr-only" aria-label="Graph data">
|
|
526
|
+
${this.simNodes.map((node) => html `<li>Node ${node.label ?? node.id}</li>`)}
|
|
527
|
+
${this.simLinks.map((link) => {
|
|
528
|
+
const source = link.source;
|
|
529
|
+
const target = link.target;
|
|
530
|
+
return html `<li>Link from ${source.label ?? source.id} to ${target.label ?? target.id}</li>`;
|
|
531
|
+
})}
|
|
532
|
+
</ul>
|
|
427
533
|
</div>
|
|
428
534
|
`;
|
|
429
535
|
}
|
|
@@ -464,4 +570,10 @@ __decorate([
|
|
|
464
570
|
__decorate([
|
|
465
571
|
state()
|
|
466
572
|
], LyraGraph.prototype, "simLinks", void 0);
|
|
573
|
+
__decorate([
|
|
574
|
+
state()
|
|
575
|
+
], LyraGraph.prototype, "activeGraphItem", void 0);
|
|
576
|
+
__decorate([
|
|
577
|
+
state()
|
|
578
|
+
], LyraGraph.prototype, "graphLiveText", void 0);
|
|
467
579
|
defineElement('graph', LyraGraph);
|
|
@@ -6,26 +6,38 @@ export interface CalendarDay {
|
|
|
6
6
|
export interface CalendarCell {
|
|
7
7
|
date: string;
|
|
8
8
|
value: number;
|
|
9
|
-
/** 0-based week column, counting from the grid's first (earliest-containing)
|
|
9
|
+
/** 0-based week column, counting from the grid's first (earliest-containing) anchor week — see `buildCalendarGrid()`'s `firstDayOfWeek` parameter. */
|
|
10
10
|
week: number;
|
|
11
|
-
/**
|
|
11
|
+
/**
|
|
12
|
+
* Day-of-week position within the row, relative to `firstDayOfWeek`: 0 for
|
|
13
|
+
* the anchor weekday itself, up to 6 for the day immediately before it.
|
|
14
|
+
* With the default `firstDayOfWeek` of 0, this is the familiar 0 (Sunday)
|
|
15
|
+
* .. 6 (Saturday) numbering, unchanged from before `firstDayOfWeek` existed.
|
|
16
|
+
*/
|
|
12
17
|
weekday: number;
|
|
13
18
|
}
|
|
14
19
|
/** Parses a `yyyy-mm-dd` string as UTC midnight, avoiding local-timezone day-boundary drift. */
|
|
15
20
|
export declare function parseIsoDate(iso: string): Date;
|
|
16
21
|
/**
|
|
17
|
-
* Lays `days` out onto a GitHub-style
|
|
18
|
-
*
|
|
19
|
-
*
|
|
22
|
+
* Lays `days` out onto a GitHub-style week grid, 7 rows deep. `days` need not
|
|
23
|
+
* be sorted or contiguous; the grid spans from the earliest to the latest
|
|
24
|
+
* date present, anchored at the `firstDayOfWeek`-weekday on/before the
|
|
25
|
+
* earliest date (`firstDayOfWeek` is 0–6, Sunday-first by default — same
|
|
26
|
+
* numbering as `CalendarCell.weekday`). With the default `firstDayOfWeek` of
|
|
27
|
+
* 0, this is the Sunday on/before the earliest date, exactly as before this
|
|
28
|
+
* parameter existed.
|
|
20
29
|
*
|
|
21
30
|
* An entry whose `date` doesn't parse to a valid calendar date (e.g. `''` or
|
|
22
31
|
* `'2026-03'`) is dropped rather than included: `parseIsoDate` on a malformed
|
|
23
32
|
* string yields an `Invalid Date` (`getTime()` is `NaN`), and letting that
|
|
24
33
|
* single `NaN` reach the min/max below would poison `firstWeekStart` (and
|
|
25
34
|
* therefore every cell's `week`) for the whole grid instead of just the bad
|
|
26
|
-
* entry.
|
|
35
|
+
* entry. Likewise, an entry whose `date` is numerically well-formed but
|
|
36
|
+
* calendar-invalid (e.g. `'2026-02-30'`, which `Date.UTC` silently rolls
|
|
37
|
+
* over into March) is dropped rather than silently renormalized — see
|
|
38
|
+
* `isCalendarValid()`.
|
|
27
39
|
*/
|
|
28
|
-
export declare function buildCalendarGrid(days: CalendarDay[]): {
|
|
40
|
+
export declare function buildCalendarGrid(days: CalendarDay[], firstDayOfWeek?: number): {
|
|
29
41
|
cells: CalendarCell[];
|
|
30
42
|
weekCount: number;
|
|
31
43
|
firstWeekStart: Date;
|
|
@@ -5,47 +5,71 @@ export function parseIsoDate(iso) {
|
|
|
5
5
|
const [y, m, d] = iso.split('-').map(Number);
|
|
6
6
|
return new Date(Date.UTC(y, m - 1, d));
|
|
7
7
|
}
|
|
8
|
+
/** Whether `iso` (already run through parseIsoDate) actually round-trips —
|
|
9
|
+
* Date.UTC silently rolls e.g. day 30 of a 28-day February into March. */
|
|
10
|
+
function isCalendarValid(iso, parsed) {
|
|
11
|
+
const [y, m, d] = iso.split('-').map(Number);
|
|
12
|
+
return parsed.getUTCFullYear() === y && parsed.getUTCMonth() === m - 1 && parsed.getUTCDate() === d;
|
|
13
|
+
}
|
|
8
14
|
/**
|
|
9
|
-
* Lays `days` out onto a GitHub-style
|
|
10
|
-
*
|
|
11
|
-
*
|
|
15
|
+
* Lays `days` out onto a GitHub-style week grid, 7 rows deep. `days` need not
|
|
16
|
+
* be sorted or contiguous; the grid spans from the earliest to the latest
|
|
17
|
+
* date present, anchored at the `firstDayOfWeek`-weekday on/before the
|
|
18
|
+
* earliest date (`firstDayOfWeek` is 0–6, Sunday-first by default — same
|
|
19
|
+
* numbering as `CalendarCell.weekday`). With the default `firstDayOfWeek` of
|
|
20
|
+
* 0, this is the Sunday on/before the earliest date, exactly as before this
|
|
21
|
+
* parameter existed.
|
|
12
22
|
*
|
|
13
23
|
* An entry whose `date` doesn't parse to a valid calendar date (e.g. `''` or
|
|
14
24
|
* `'2026-03'`) is dropped rather than included: `parseIsoDate` on a malformed
|
|
15
25
|
* string yields an `Invalid Date` (`getTime()` is `NaN`), and letting that
|
|
16
26
|
* single `NaN` reach the min/max below would poison `firstWeekStart` (and
|
|
17
27
|
* therefore every cell's `week`) for the whole grid instead of just the bad
|
|
18
|
-
* entry.
|
|
28
|
+
* entry. Likewise, an entry whose `date` is numerically well-formed but
|
|
29
|
+
* calendar-invalid (e.g. `'2026-02-30'`, which `Date.UTC` silently rolls
|
|
30
|
+
* over into March) is dropped rather than silently renormalized — see
|
|
31
|
+
* `isCalendarValid()`.
|
|
19
32
|
*/
|
|
20
|
-
export function buildCalendarGrid(days) {
|
|
33
|
+
export function buildCalendarGrid(days, firstDayOfWeek = 0) {
|
|
21
34
|
const parsed = days
|
|
22
35
|
.map((d) => ({ ...d, dateObj: parseIsoDate(d.date) }))
|
|
23
|
-
.filter((d) => !Number.isNaN(d.dateObj.getTime()));
|
|
36
|
+
.filter((d) => !Number.isNaN(d.dateObj.getTime()) && isCalendarValid(d.date, d.dateObj));
|
|
24
37
|
if (parsed.length === 0) {
|
|
25
38
|
return { cells: [], weekCount: 0, firstWeekStart: new Date(0), monthLabels: [] };
|
|
26
39
|
}
|
|
27
40
|
const timeBounds = minMax(parsed.map((d) => d.dateObj.getTime()));
|
|
28
41
|
const min = new Date(timeBounds[0]);
|
|
29
|
-
|
|
42
|
+
// Days back from `min` to the nearest `firstDayOfWeek`-weekday on/before
|
|
43
|
+
// it — with the default firstDayOfWeek of 0, this reduces to
|
|
44
|
+
// `min.getUTCDay()` exactly, i.e. today's original Sunday anchor.
|
|
45
|
+
const daysBackToAnchor = (min.getUTCDay() - firstDayOfWeek + 7) % 7;
|
|
46
|
+
const firstWeekStart = new Date(Date.UTC(min.getUTCFullYear(), min.getUTCMonth(), min.getUTCDate() - daysBackToAnchor));
|
|
30
47
|
const cells = parsed.map((d) => {
|
|
31
|
-
|
|
48
|
+
// Relative to the anchor weekday (see `CalendarCell.weekday`'s doc
|
|
49
|
+
// comment) — with the default firstDayOfWeek of 0 this is just
|
|
50
|
+
// `d.dateObj.getUTCDay()`, unchanged from before.
|
|
51
|
+
const weekday = (d.dateObj.getUTCDay() - firstDayOfWeek + 7) % 7;
|
|
32
52
|
const daysSinceStart = Math.round((d.dateObj.getTime() - firstWeekStart.getTime()) / MS_PER_DAY);
|
|
33
53
|
const week = Math.floor(daysSinceStart / 7);
|
|
34
54
|
return { date: d.date, value: d.value, week, weekday };
|
|
35
55
|
});
|
|
36
56
|
const weekCount = minMax(cells.map((c) => c.week))[1] + 1;
|
|
57
|
+
// Label every distinct (year, month) present in the data, not just months
|
|
58
|
+
// that happen to contain a Sunday-anchored cell — a sparse calendar (few
|
|
59
|
+
// days per month, none landing on a Sunday) would otherwise render zero
|
|
60
|
+
// month labels for months that do have data.
|
|
37
61
|
const monthLabels = [];
|
|
38
|
-
|
|
39
|
-
for (const cell of cells.slice().sort((a, b) => a.week - b.week)) {
|
|
62
|
+
const seenMonths = new Set();
|
|
63
|
+
for (const cell of cells.slice().sort((a, b) => a.week - b.week || a.weekday - b.weekday)) {
|
|
40
64
|
const cellDate = parseIsoDate(cell.date);
|
|
41
|
-
const
|
|
42
|
-
if (
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
})
|
|
48
|
-
}
|
|
65
|
+
const key = `${cellDate.getUTCFullYear()}-${cellDate.getUTCMonth()}`;
|
|
66
|
+
if (seenMonths.has(key))
|
|
67
|
+
continue;
|
|
68
|
+
seenMonths.add(key);
|
|
69
|
+
monthLabels.push({
|
|
70
|
+
week: cell.week,
|
|
71
|
+
label: cellDate.toLocaleString(undefined, { month: 'short', timeZone: 'UTC' }),
|
|
72
|
+
});
|
|
49
73
|
}
|
|
50
74
|
return { cells, weekCount, firstWeekStart, monthLabels };
|
|
51
75
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** Maps `value` in `[lo, hi]` to a 0.1
|
|
1
|
+
/** Maps `value` in `[lo, hi]` to a 0.1-1.0 alpha so the lowest real value still reads as faintly present rather than invisible. */
|
|
2
2
|
export declare function linearAlpha(value: number, lo: number, hi: number): number;
|
|
3
3
|
/**
|
|
4
4
|
* Computes `[min, max]` of `values` via a linear scan, or `null` for an
|
|
@@ -12,5 +12,15 @@ export declare function minMax(values: number[]): [number, number] | null;
|
|
|
12
12
|
* Square-root-scaled bucket index in `[0, steps-1]`, or `-1` for no-data.
|
|
13
13
|
* Compresses large counts so a single heavy cell doesn't wash out the rest
|
|
14
14
|
* of a sequential color ramp.
|
|
15
|
+
*
|
|
16
|
+
* Only a negative `count` means "no data" here — the true no-data sentinel
|
|
17
|
+
* (`v < 0 || !Number.isFinite(v)`) is already filtered out by the caller
|
|
18
|
+
* (`drawMatrix()`) before `sqrtStep` is ever invoked, so a real `count === 0`
|
|
19
|
+
* (e.g. "zero events that day") reaches this function and must bucket to the
|
|
20
|
+
* lowest ramp step like any other legitimate value, not render as no-data.
|
|
21
|
+
* Likewise, `max <= 0` means every real value in the dataset is zero (a
|
|
22
|
+
* legitimate "zero events everywhere" dataset, not an absence of data) — the
|
|
23
|
+
* whole range collapses to a single point, so `count` (itself necessarily 0)
|
|
24
|
+
* buckets to the lowest step rather than being misread as no-data.
|
|
15
25
|
*/
|
|
16
26
|
export declare function sqrtStep(count: number, max: number, steps: number): number;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** Maps `value` in `[lo, hi]` to a 0.1
|
|
1
|
+
/** Maps `value` in `[lo, hi]` to a 0.1-1.0 alpha so the lowest real value still reads as faintly present rather than invisible. */
|
|
2
2
|
export function linearAlpha(value, lo, hi) {
|
|
3
3
|
const span = hi - lo || 1;
|
|
4
4
|
const t = (value - lo) / span;
|
|
@@ -29,10 +29,22 @@ export function minMax(values) {
|
|
|
29
29
|
* Square-root-scaled bucket index in `[0, steps-1]`, or `-1` for no-data.
|
|
30
30
|
* Compresses large counts so a single heavy cell doesn't wash out the rest
|
|
31
31
|
* of a sequential color ramp.
|
|
32
|
+
*
|
|
33
|
+
* Only a negative `count` means "no data" here — the true no-data sentinel
|
|
34
|
+
* (`v < 0 || !Number.isFinite(v)`) is already filtered out by the caller
|
|
35
|
+
* (`drawMatrix()`) before `sqrtStep` is ever invoked, so a real `count === 0`
|
|
36
|
+
* (e.g. "zero events that day") reaches this function and must bucket to the
|
|
37
|
+
* lowest ramp step like any other legitimate value, not render as no-data.
|
|
38
|
+
* Likewise, `max <= 0` means every real value in the dataset is zero (a
|
|
39
|
+
* legitimate "zero events everywhere" dataset, not an absence of data) — the
|
|
40
|
+
* whole range collapses to a single point, so `count` (itself necessarily 0)
|
|
41
|
+
* buckets to the lowest step rather than being misread as no-data.
|
|
32
42
|
*/
|
|
33
43
|
export function sqrtStep(count, max, steps) {
|
|
34
|
-
if (count
|
|
44
|
+
if (count < 0)
|
|
35
45
|
return -1;
|
|
46
|
+
if (max <= 0)
|
|
47
|
+
return 0;
|
|
36
48
|
const ratio = Math.sqrt(count) / Math.sqrt(max);
|
|
37
49
|
return Math.min(steps - 1, Math.floor(ratio * steps));
|
|
38
50
|
}
|