basalt-ui 1.26.0 → 1.28.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/AGENTS.md +23 -23
- package/CHANGELOG.md +67 -0
- package/MIGRATING.md +896 -37
- package/README.md +33 -3
- package/agent/rules/basalt-batteries.md +25 -10
- package/agent/rules/basalt-controls.md +73 -43
- package/agent/rules/basalt-mantine.md +17 -6
- package/agent/rules/basalt-state.md +5 -0
- package/agent/rules/basalt-tokens.md +1 -1
- package/configs/oxlint-plugin.js +1286 -73
- package/configs/oxlint-plugin.test.ts +1338 -29
- package/configs/oxlint.json +12 -5
- package/dist/agent/coalesce.d.ts.map +1 -1
- package/dist/agent/coalesce.js +2 -1
- package/dist/agent/merge.d.ts.map +1 -1
- package/dist/agent/merge.js +2 -1
- package/dist/agent/part-list.d.ts.map +1 -1
- package/dist/agent/part-list.js +2 -0
- package/dist/agent/stick-to-bottom.d.ts +3 -6
- package/dist/agent/stick-to-bottom.d.ts.map +1 -1
- package/dist/agent/stick-to-bottom.js +6 -3
- package/dist/agent-chat/composer.d.ts +6 -2
- package/dist/agent-chat/composer.d.ts.map +1 -1
- package/dist/agent-chat/composer.js +49 -33
- package/dist/agent-chat/relative-time.d.ts +0 -9
- package/dist/agent-chat/relative-time.d.ts.map +1 -1
- package/dist/agent-chat/relative-time.js +2 -1
- package/dist/agent-chat/thread-detail-panel.d.ts +3 -2
- package/dist/agent-chat/thread-detail-panel.d.ts.map +1 -1
- package/dist/agent-chat/thread-detail-panel.js +8 -5
- package/dist/agent-chat/thread-feed-row.d.ts +2 -1
- package/dist/agent-chat/thread-feed-row.d.ts.map +1 -1
- package/dist/agent-chat/thread-feed-row.js +92 -92
- package/dist/agent-chat/thread-feed.d.ts +3 -2
- package/dist/agent-chat/thread-feed.d.ts.map +1 -1
- package/dist/agent-chat/thread-feed.js +8 -3
- package/dist/agent-chat/thread-message.d.ts +4 -3
- package/dist/agent-chat/thread-message.d.ts.map +1 -1
- package/dist/agent-chat/thread-message.js +70 -31
- package/dist/agent-chat/thread-outcome-card.d.ts +3 -2
- package/dist/agent-chat/thread-outcome-card.d.ts.map +1 -1
- package/dist/agent-chat/thread-outcome-card.js +9 -2
- package/dist/agent-chat/thread-workspace.d.ts +7 -2
- package/dist/agent-chat/thread-workspace.d.ts.map +1 -1
- package/dist/agent-chat/thread-workspace.js +62 -29
- package/dist/agent-chat/tool-chip.d.ts +3 -2
- package/dist/agent-chat/tool-chip.d.ts.map +1 -1
- package/dist/agent-chat/tool-chip.js +7 -2
- package/dist/charts/hooks/useBandPlot.d.ts.map +1 -1
- package/dist/charts/hooks/useBandPlot.js +15 -8
- package/dist/charts/index.d.ts +8 -7
- package/dist/charts/index.d.ts.map +1 -1
- package/dist/charts/index.js +45 -5
- package/dist/charts/kinds/BandStrip.d.ts +10 -7
- package/dist/charts/kinds/BandStrip.d.ts.map +1 -1
- package/dist/charts/kinds/BandStrip.js +12 -7
- package/dist/charts/kinds/Bars.d.ts +12 -6
- package/dist/charts/kinds/Bars.d.ts.map +1 -1
- package/dist/charts/kinds/Bars.js +37 -11
- package/dist/charts/kinds/Donut.d.ts +6 -5
- package/dist/charts/kinds/Donut.d.ts.map +1 -1
- package/dist/charts/kinds/Donut.js +19 -2
- package/dist/charts/kinds/DualPanel.d.ts +6 -5
- package/dist/charts/kinds/DualPanel.d.ts.map +1 -1
- package/dist/charts/kinds/DualPanel.js +36 -8
- package/dist/charts/kinds/Heatmap.d.ts +10 -6
- package/dist/charts/kinds/Heatmap.d.ts.map +1 -1
- package/dist/charts/kinds/Heatmap.js +58 -31
- package/dist/charts/kinds/MirroredBars.d.ts +6 -5
- package/dist/charts/kinds/MirroredBars.d.ts.map +1 -1
- package/dist/charts/kinds/MirroredBars.js +9 -2
- package/dist/charts/kinds/MultiLine.d.ts +11 -6
- package/dist/charts/kinds/MultiLine.d.ts.map +1 -1
- package/dist/charts/kinds/MultiLine.js +24 -15
- package/dist/charts/kinds/StackedArea.d.ts +18 -8
- package/dist/charts/kinds/StackedArea.d.ts.map +1 -1
- package/dist/charts/kinds/StackedArea.js +29 -4
- package/dist/charts/kinds/ZonedLine.d.ts +12 -8
- package/dist/charts/kinds/ZonedLine.d.ts.map +1 -1
- package/dist/charts/kinds/ZonedLine.js +33 -23
- package/dist/charts/layout/auto-margin.d.ts +65 -8
- package/dist/charts/layout/auto-margin.d.ts.map +1 -1
- package/dist/charts/layout/auto-margin.js +45 -10
- package/dist/charts/layout/log-ticks.d.ts +27 -0
- package/dist/charts/layout/log-ticks.d.ts.map +1 -0
- package/dist/charts/layout/log-ticks.js +42 -0
- package/dist/charts/primitives/Axes.d.ts +11 -2
- package/dist/charts/primitives/Axes.d.ts.map +1 -1
- package/dist/charts/primitives/Axes.js +15 -5
- package/dist/charts/primitives/CartesianChart.d.ts +45 -7
- package/dist/charts/primitives/CartesianChart.d.ts.map +1 -1
- package/dist/charts/primitives/CartesianChart.js +86 -28
- package/dist/charts/primitives/ChartCard.d.ts +27 -2
- package/dist/charts/primitives/ChartCard.d.ts.map +1 -1
- package/dist/charts/primitives/ChartCard.js +37 -17
- package/dist/charts/primitives/ChartFrame.d.ts +30 -4
- package/dist/charts/primitives/ChartFrame.d.ts.map +1 -1
- package/dist/charts/primitives/ChartFrame.js +45 -15
- package/dist/charts/primitives/ChartLegend.d.ts +13 -2
- package/dist/charts/primitives/ChartLegend.d.ts.map +1 -1
- package/dist/charts/primitives/ChartLegend.js +33 -13
- package/dist/charts/primitives/ChartPending.d.ts +77 -4
- package/dist/charts/primitives/ChartPending.d.ts.map +1 -1
- package/dist/charts/primitives/ChartPending.js +100 -6
- package/dist/charts/primitives/ChartTooltip.d.ts +7 -0
- package/dist/charts/primitives/ChartTooltip.d.ts.map +1 -1
- package/dist/charts/primitives/ChartTooltip.js +18 -5
- package/dist/charts/primitives/Crosshair.d.ts +3 -0
- package/dist/charts/primitives/Crosshair.d.ts.map +1 -1
- package/dist/charts/primitives/Crosshair.js +3 -1
- package/dist/charts/primitives/chart-frame-layout.d.ts +95 -0
- package/dist/charts/primitives/chart-frame-layout.d.ts.map +1 -0
- package/dist/charts/primitives/chart-frame-layout.js +89 -0
- package/dist/charts/primitives/chart-tier.d.ts +16 -0
- package/dist/charts/primitives/chart-tier.d.ts.map +1 -0
- package/dist/charts/primitives/chart-tier.js +20 -0
- package/dist/charts/series.d.ts +55 -1
- package/dist/charts/series.d.ts.map +1 -1
- package/dist/charts/series.js +27 -1
- package/dist/charts/sparklines/BarSparkline.d.ts +3 -3
- package/dist/charts/sparklines/BarSparkline.d.ts.map +1 -1
- package/dist/charts/sparklines/BarSparkline.js +9 -3
- package/dist/charts/sparklines/LineSparkline.d.ts +3 -3
- package/dist/charts/sparklines/LineSparkline.d.ts.map +1 -1
- package/dist/charts/sparklines/LineSparkline.js +15 -3
- package/dist/charts/sparklines/index.d.ts +2 -2
- package/dist/charts/sparklines/index.d.ts.map +1 -1
- package/dist/charts/utils/format.d.ts +92 -2
- package/dist/charts/utils/format.d.ts.map +1 -1
- package/dist/charts/utils/format.js +64 -1
- package/dist/charts/utils/ticks.d.ts +81 -2
- package/dist/charts/utils/ticks.d.ts.map +1 -1
- package/dist/charts/utils/ticks.js +54 -4
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +2 -2
- package/dist/commands/ShortcutsHelp.d.ts +3 -2
- package/dist/commands/ShortcutsHelp.d.ts.map +1 -1
- package/dist/commands/ShortcutsHelp.js +8 -2
- package/dist/commands/define-commands.d.ts.map +1 -1
- package/dist/commands/define-commands.js +2 -2
- package/dist/commands/define-overlays.d.ts +102 -0
- package/dist/commands/define-overlays.d.ts.map +1 -1
- package/dist/commands/define-overlays.js +102 -2
- package/dist/commands/index.d.ts +10 -1
- package/dist/commands/index.d.ts.map +1 -1
- package/dist/commands/index.js +3 -1
- package/dist/commands/overlays-mount.d.ts +13 -6
- package/dist/commands/overlays-mount.d.ts.map +1 -1
- package/dist/commands/overlays-mount.js +23 -14
- package/dist/common/errors.d.ts +34 -0
- package/dist/common/errors.d.ts.map +1 -0
- package/dist/common/errors.js +36 -0
- package/dist/common/index.d.ts +15 -0
- package/dist/common/index.d.ts.map +1 -0
- package/dist/common/index.js +29 -0
- package/dist/common/props.d.ts +63 -0
- package/dist/common/props.d.ts.map +1 -0
- package/dist/common/props.js +6 -0
- package/dist/common/query-state-like.d.ts +43 -0
- package/dist/common/query-state-like.d.ts.map +1 -0
- package/dist/common/query-state-like.js +20 -0
- package/dist/common/refs.d.ts +29 -0
- package/dist/common/refs.d.ts.map +1 -0
- package/dist/common/refs.js +29 -0
- package/dist/common/scroll-parent.d.ts +23 -0
- package/dist/common/scroll-parent.d.ts.map +1 -0
- package/dist/common/scroll-parent.js +21 -0
- package/dist/common/validate.d.ts +38 -0
- package/dist/common/validate.d.ts.map +1 -0
- package/dist/common/validate.js +36 -0
- package/dist/connectivity/connectivity-indicator.d.ts +3 -1
- package/dist/connectivity/connectivity-indicator.d.ts.map +1 -1
- package/dist/connectivity/connectivity-indicator.js +3 -1
- package/dist/connectivity/connectivity-provider.d.ts.map +1 -1
- package/dist/connectivity/connectivity-provider.js +4 -1
- package/dist/connectivity/index.d.ts +1 -0
- package/dist/connectivity/index.d.ts.map +1 -1
- package/dist/connectivity/types.d.ts +2 -2
- package/dist/connectivity/types.d.ts.map +1 -1
- package/dist/connectivity/use-connectivity.d.ts.map +1 -1
- package/dist/content/article-layout.module.css +11 -4
- package/dist/content/callout.d.ts +8 -4
- package/dist/content/callout.d.ts.map +1 -1
- package/dist/content/callout.js +15 -8
- package/dist/content/guide.d.ts +5 -4
- package/dist/content/guide.d.ts.map +1 -1
- package/dist/content/guide.js +13 -4
- package/dist/content/heading-anchor.d.ts +24 -2
- package/dist/content/heading-anchor.d.ts.map +1 -1
- package/dist/content/heading-anchor.js +23 -9
- package/dist/content/index.d.ts.map +1 -1
- package/dist/content/markdown.d.ts.map +1 -1
- package/dist/content/markdown.js +2 -0
- package/dist/content/prose.module.css +9 -7
- package/dist/content/reading-progress.d.ts +10 -4
- package/dist/content/reading-progress.d.ts.map +1 -1
- package/dist/content/reading-progress.js +26 -10
- package/dist/content/slug.d.ts +4 -0
- package/dist/content/slug.d.ts.map +1 -1
- package/dist/content/toc.d.ts +11 -0
- package/dist/content/toc.d.ts.map +1 -1
- package/dist/content/toc.js +23 -10
- package/dist/controls/actions.d.ts +49 -6
- package/dist/controls/actions.d.ts.map +1 -1
- package/dist/controls/actions.js +39 -8
- package/dist/controls/compare-filter.d.ts +3 -2
- package/dist/controls/compare-filter.d.ts.map +1 -1
- package/dist/controls/compare-filter.js +17 -2
- package/dist/controls/control-group.d.ts +3 -3
- package/dist/controls/control-group.d.ts.map +1 -1
- package/dist/controls/control-group.js +9 -2
- package/dist/controls/controls.module.css +169 -186
- package/dist/controls/controls.module.css.d.ts +9 -11
- package/dist/controls/enum-filter.d.ts +13 -3
- package/dist/controls/enum-filter.d.ts.map +1 -1
- package/dist/controls/enum-filter.js +32 -15
- package/dist/controls/filter-context.d.ts +15 -6
- package/dist/controls/filter-context.d.ts.map +1 -1
- package/dist/controls/filter-pill.d.ts +3 -3
- package/dist/controls/filter-pill.d.ts.map +1 -1
- package/dist/controls/filter-pill.js +4 -1
- package/dist/controls/filter-set.d.ts +3 -2
- package/dist/controls/filter-set.d.ts.map +1 -1
- package/dist/controls/filter-set.js +66 -41
- package/dist/controls/filter-sheet.d.ts +20 -80
- package/dist/controls/filter-sheet.d.ts.map +1 -1
- package/dist/controls/filter-sheet.js +9 -95
- package/dist/controls/index.d.ts +3 -0
- package/dist/controls/index.d.ts.map +1 -1
- package/dist/controls/index.js +6 -0
- package/dist/controls/multi-select-filter.d.ts +18 -2
- package/dist/controls/multi-select-filter.d.ts.map +1 -1
- package/dist/controls/multi-select-filter.js +124 -22
- package/dist/controls/number-filter.d.ts +28 -0
- package/dist/controls/number-filter.d.ts.map +1 -0
- package/dist/controls/number-filter.js +172 -0
- package/dist/controls/panel-row.d.ts +132 -0
- package/dist/controls/panel-row.d.ts.map +1 -0
- package/dist/controls/panel-row.js +173 -0
- package/dist/controls/panel-row.module.css +86 -0
- package/dist/controls/panel-row.module.css.d.ts +13 -0
- package/dist/controls/range-filter.d.ts +20 -5
- package/dist/controls/range-filter.d.ts.map +1 -1
- package/dist/controls/range-filter.js +75 -38
- package/dist/controls/search-filter.d.ts +3 -2
- package/dist/controls/search-filter.d.ts.map +1 -1
- package/dist/controls/search-filter.js +26 -11
- package/dist/controls/select-filter.d.ts +2 -1
- package/dist/controls/select-filter.d.ts.map +1 -1
- package/dist/controls/select-filter.js +4 -0
- package/dist/controls/slider-control.d.ts +36 -0
- package/dist/controls/slider-control.d.ts.map +1 -0
- package/dist/controls/slider-control.js +64 -0
- package/dist/controls/sync-button.d.ts +3 -2
- package/dist/controls/sync-button.d.ts.map +1 -1
- package/dist/controls/sync-button.js +16 -3
- package/dist/controls/toggle-filter.d.ts +3 -2
- package/dist/controls/toggle-filter.d.ts.map +1 -1
- package/dist/controls/toggle-filter.js +29 -12
- package/dist/controls/view-tabs.d.ts +3 -2
- package/dist/controls/view-tabs.d.ts.map +1 -1
- package/dist/controls/view-tabs.js +43 -11
- package/dist/controls-dates/date-range-picker.d.ts +1 -1
- package/dist/controls-dates/date-range-picker.d.ts.map +1 -1
- package/dist/controls-dates/date-range-picker.js +6 -1
- package/dist/dashboard/delta-badge.d.ts +5 -1
- package/dist/dashboard/delta-badge.d.ts.map +1 -1
- package/dist/dashboard/empty-state.d.ts +10 -3
- package/dist/dashboard/empty-state.d.ts.map +1 -1
- package/dist/dashboard/empty-state.js +37 -6
- package/dist/dashboard/index.d.ts +6 -4
- package/dist/dashboard/index.d.ts.map +1 -1
- package/dist/dashboard/index.js +10 -2
- package/dist/dashboard/query-state.d.ts +48 -27
- package/dist/dashboard/query-state.d.ts.map +1 -1
- package/dist/dashboard/query-state.js +111 -57
- package/dist/dashboard/settings-section.d.ts +19 -9
- package/dist/dashboard/settings-section.d.ts.map +1 -1
- package/dist/dashboard/settings-section.js +74 -25
- package/dist/dashboard/stat-card.d.ts +76 -19
- package/dist/dashboard/stat-card.d.ts.map +1 -1
- package/dist/dashboard/stat-card.js +78 -38
- package/dist/dashboard/stat-card.module.css +112 -26
- package/dist/dashboard/stat-card.module.css.d.ts +5 -0
- package/dist/dashboard/stat-group.d.ts +41 -0
- package/dist/dashboard/stat-group.d.ts.map +1 -0
- package/dist/dashboard/stat-group.js +30 -0
- package/dist/dashboard/stat-group.module.css +66 -0
- package/dist/dashboard/stat-group.module.css.d.ts +8 -0
- package/dist/dashboard/widget-grid.d.ts +27 -0
- package/dist/dashboard/widget-grid.d.ts.map +1 -0
- package/dist/dashboard/widget-grid.js +41 -0
- package/dist/dashboard/widget-grid.module.css +53 -0
- package/dist/dashboard/widget-grid.module.css.d.ts +9 -0
- package/dist/data/data-table.d.ts +151 -12
- package/dist/data/data-table.d.ts.map +1 -1
- package/dist/data/data-table.js +392 -138
- package/dist/data/data-table.module.css +64 -0
- package/dist/data/data-table.module.css.d.ts +11 -0
- package/dist/data/index.d.ts +2 -2
- package/dist/data/index.d.ts.map +1 -1
- package/dist/data/index.js +24 -2
- package/dist/data/query-branch.d.ts +28 -0
- package/dist/data/query-branch.d.ts.map +1 -0
- package/dist/data/query-branch.js +10 -0
- package/dist/data/table.d.ts +2 -2
- package/dist/data/table.d.ts.map +1 -1
- package/dist/data/virtual-list.d.ts +65 -6
- package/dist/data/virtual-list.d.ts.map +1 -1
- package/dist/data/virtual-list.js +89 -38
- package/dist/data/virtual.d.ts +1 -1
- package/dist/data/virtual.d.ts.map +1 -1
- package/dist/forms/FormErrorSummary.d.ts +4 -3
- package/dist/forms/FormErrorSummary.d.ts.map +1 -1
- package/dist/forms/FormErrorSummary.js +6 -4
- package/dist/forms/create-form.d.ts +2 -2
- package/dist/forms/field.d.ts +46 -6
- package/dist/forms/field.d.ts.map +1 -1
- package/dist/forms/field.js +10 -5
- package/dist/forms/form-layout.d.ts +142 -0
- package/dist/forms/form-layout.d.ts.map +1 -0
- package/dist/forms/form-layout.js +110 -0
- package/dist/forms/form-layout.module.css +145 -0
- package/dist/forms/form-layout.module.css.d.ts +20 -0
- package/dist/forms/form-state.d.ts +42 -0
- package/dist/forms/form-state.d.ts.map +1 -0
- package/dist/forms/form-state.js +26 -0
- package/dist/forms/index.d.ts +22 -6
- package/dist/forms/index.d.ts.map +1 -1
- package/dist/forms/index.js +19 -3
- package/dist/forms/use-field-array.d.ts +60 -0
- package/dist/forms/use-field-array.d.ts.map +1 -0
- package/dist/forms/use-field-array.js +20 -0
- package/dist/forms/use-form-draft.d.ts +25 -10
- package/dist/forms/use-form-draft.d.ts.map +1 -1
- package/dist/forms/use-form-draft.js +55 -18
- package/dist/forms/use-form-submit.d.ts +88 -0
- package/dist/forms/use-form-submit.d.ts.map +1 -0
- package/dist/forms/use-form-submit.js +63 -0
- package/dist/guard/index.d.ts +1 -1
- package/dist/guard/index.d.ts.map +1 -1
- package/dist/guard/index.js +27 -11
- package/dist/index.d.ts +10 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +44 -4
- package/dist/nav/types.d.ts +15 -6
- package/dist/nav/types.d.ts.map +1 -1
- package/dist/notifications/bell.d.ts +3 -2
- package/dist/notifications/bell.d.ts.map +1 -1
- package/dist/notifications/bell.js +73 -56
- package/dist/notifications/center.d.ts +15 -4
- package/dist/notifications/center.d.ts.map +1 -1
- package/dist/notifications/center.js +5 -2
- package/dist/notifications/define-notifications.d.ts +56 -14
- package/dist/notifications/define-notifications.d.ts.map +1 -1
- package/dist/notifications/define-notifications.js +2 -1
- package/dist/notifications/index.d.ts +6 -2
- package/dist/notifications/index.d.ts.map +1 -1
- package/dist/notifications/index.js +5 -1
- package/dist/notifications/mount-guard.d.ts +8 -0
- package/dist/notifications/mount-guard.d.ts.map +1 -0
- package/dist/notifications/mount-guard.js +19 -0
- package/dist/notifications/notify.d.ts +58 -1
- package/dist/notifications/notify.d.ts.map +1 -1
- package/dist/notifications/notify.js +46 -2
- package/dist/notifications/overlay.d.ts.map +1 -1
- package/dist/notifications/overlay.js +2 -0
- package/dist/notifications/store.d.ts +7 -0
- package/dist/notifications/store.d.ts.map +1 -1
- package/dist/provider/index.d.ts +37 -5
- package/dist/provider/index.d.ts.map +1 -1
- package/dist/provider/index.js +66 -28
- package/dist/provider/lab-theme.d.ts.map +1 -1
- package/dist/provider/lab-theme.js +2 -1
- package/dist/query/devtools.d.ts.map +1 -1
- package/dist/query/devtools.js +1 -0
- package/dist/router-tanstack/field.d.ts +1 -1
- package/dist/router-tanstack/field.d.ts.map +1 -1
- package/dist/router-tanstack/index.d.ts +1 -1
- package/dist/router-tanstack/index.d.ts.map +1 -1
- package/dist/router-tanstack/search-store.d.ts +4 -1
- package/dist/router-tanstack/search-store.d.ts.map +1 -1
- package/dist/router-tanstack/search-store.js +92 -8
- package/dist/router-tanstack/use-nav.d.ts.map +1 -1
- package/dist/router-tanstack/use-nav.js +1 -1
- package/dist/section/index.d.ts +1 -1
- package/dist/section/index.d.ts.map +1 -1
- package/dist/section/section.d.ts +36 -2
- package/dist/section/section.d.ts.map +1 -1
- package/dist/section/section.js +49 -57
- package/dist/section/section.module.css +11 -0
- package/dist/shell/account-types.d.ts +5 -2
- package/dist/shell/account-types.d.ts.map +1 -1
- package/dist/shell/app-brand.d.ts +13 -0
- package/dist/shell/app-brand.d.ts.map +1 -0
- package/dist/shell/app-brand.js +94 -0
- package/dist/shell/app-brand.module.css +109 -0
- package/dist/shell/app-brand.module.css.d.ts +14 -0
- package/dist/shell/app-breadcrumbs.d.ts +4 -2
- package/dist/shell/app-breadcrumbs.d.ts.map +1 -1
- package/dist/shell/app-breadcrumbs.js +33 -22
- package/dist/shell/app-header.module.css +10 -5
- package/dist/shell/app-main.module.css +107 -0
- package/dist/shell/app-main.module.css.d.ts +11 -0
- package/dist/shell/app-mobile-nav.d.ts +3 -2
- package/dist/shell/app-mobile-nav.d.ts.map +1 -1
- package/dist/shell/app-mobile-nav.js +29 -15
- package/dist/shell/app-mobile-nav.module.css +48 -27
- package/dist/shell/app-mobile-nav.module.css.d.ts +0 -1
- package/dist/shell/app-sidebar-account.d.ts +2 -1
- package/dist/shell/app-sidebar-account.d.ts.map +1 -1
- package/dist/shell/app-sidebar-account.js +57 -22
- package/dist/shell/app-sidebar.d.ts +9 -3
- package/dist/shell/app-sidebar.d.ts.map +1 -1
- package/dist/shell/app-sidebar.js +55 -109
- package/dist/shell/app-sidebar.module.css +53 -96
- package/dist/shell/app-sidebar.module.css.d.ts +0 -5
- package/dist/shell/index.d.ts +14 -6
- package/dist/shell/index.d.ts.map +1 -1
- package/dist/shell/index.js +47 -12
- package/dist/shell/isomorphic-layout-effect.d.ts +14 -0
- package/dist/shell/isomorphic-layout-effect.d.ts.map +1 -0
- package/dist/shell/isomorphic-layout-effect.js +5 -0
- package/dist/shell/mobile-nav-model.d.ts.map +1 -1
- package/dist/shell/mobile-nav-model.js +27 -6
- package/dist/shell/nav-count-badge.d.ts +5 -3
- package/dist/shell/nav-count-badge.d.ts.map +1 -1
- package/dist/shell/nav-count-badge.js +3 -1
- package/dist/shell/page-aside.d.ts +43 -0
- package/dist/shell/page-aside.d.ts.map +1 -0
- package/dist/shell/page-aside.js +202 -0
- package/dist/shell/page-aside.module.css +174 -0
- package/dist/shell/page-aside.module.css.d.ts +14 -0
- package/dist/shell/page-bar.d.ts +55 -15
- package/dist/shell/page-bar.d.ts.map +1 -1
- package/dist/shell/page-bar.js +130 -41
- package/dist/shell/page-bar.module.css +107 -13
- package/dist/shell/page-bar.module.css.d.ts +4 -1
- package/dist/shell/sidebar-search.d.ts +4 -2
- package/dist/shell/sidebar-search.d.ts.map +1 -1
- package/dist/shell/sidebar-search.js +9 -4
- package/dist/shell/sidebar-search.module.css +1 -1
- package/dist/state/fields.d.ts +227 -34
- package/dist/state/fields.d.ts.map +1 -1
- package/dist/state/fields.js +77 -30
- package/dist/state/persisted-or-local.d.ts +9 -0
- package/dist/state/persisted-or-local.d.ts.map +1 -0
- package/dist/state/persisted-or-local.js +24 -0
- package/dist/state/persisted.d.ts +12 -0
- package/dist/state/persisted.d.ts.map +1 -1
- package/dist/state/persisted.js +36 -18
- package/dist/state.d.ts +1 -1
- package/dist/state.d.ts.map +1 -1
- package/dist/state.js +2 -6
- package/dist/surfaces.d.ts +12 -11
- package/dist/surfaces.d.ts.map +1 -1
- package/dist/surfaces.js +43 -12
- package/dist/theme/ctl-theme.d.ts.map +1 -1
- package/dist/theme/index.d.ts.map +1 -1
- package/dist/theme/index.js +102 -17
- package/dist/theme/nav-link.module.css +37 -26
- package/dist/theme/segmented-control.module.css +22 -0
- package/dist/theme/segmented-control.module.css.d.ts +1 -0
- package/dist/theme-lab/boot.d.ts +66 -0
- package/dist/theme-lab/boot.d.ts.map +1 -0
- package/dist/theme-lab/boot.js +82 -0
- package/dist/theme-lab/index.d.ts +4 -43
- package/dist/theme-lab/index.d.ts.map +1 -1
- package/dist/theme-lab/index.js +9 -69
- package/dist/theme-toggle/index.d.ts +3 -2
- package/dist/theme-toggle/index.d.ts.map +1 -1
- package/dist/theme-toggle/index.js +8 -2
- package/dist/tokens/index.d.ts +42 -0
- package/dist/tokens/index.d.ts.map +1 -1
- package/dist/tokens/index.js +35 -6
- package/dist/tokens/palette.d.ts +45 -25
- package/dist/tokens/palette.d.ts.map +1 -1
- package/dist/tokens/palette.js +31 -14
- package/dist/tokens.css +4 -5
- package/dist/utils/is-dev.d.ts +3 -0
- package/dist/utils/is-dev.d.ts.map +1 -0
- package/dist/utils/is-dev.js +6 -0
- package/dist/widget-header/delta-badge.d.ts +7 -1
- package/dist/widget-header/delta-badge.d.ts.map +1 -1
- package/dist/widget-header/delta-badge.js +8 -1
- package/dist/widget-header/index.d.ts +2 -2
- package/dist/widget-header/index.d.ts.map +1 -1
- package/dist/widget-header/index.js +3 -1
- package/dist/widget-header/widget-header.d.ts +99 -4
- package/dist/widget-header/widget-header.d.ts.map +1 -1
- package/dist/widget-header/widget-header.js +45 -18
- package/dist/widget-header/widget-header.module.css +87 -7
- package/dist/widget-header/widget-header.module.css.d.ts +1 -0
- package/llms.txt +6 -6
- package/package.json +49 -25
- package/src/agent/coalesce.ts +2 -1
- package/src/agent/merge.ts +2 -1
- package/src/agent/part-list.tsx +2 -0
- package/src/agent/stick-to-bottom.tsx +9 -11
- package/src/agent-chat/composer.tsx +124 -103
- package/src/agent-chat/relative-time.ts +2 -1
- package/src/agent-chat/thread-detail-panel.tsx +9 -5
- package/src/agent-chat/thread-feed-row.tsx +17 -9
- package/src/agent-chat/thread-feed.tsx +9 -3
- package/src/agent-chat/thread-message.tsx +48 -13
- package/src/agent-chat/thread-outcome-card.tsx +9 -1
- package/src/agent-chat/thread-workspace.tsx +72 -33
- package/src/agent-chat/tool-chip.tsx +8 -2
- package/src/charts/hooks/useBandPlot.ts +26 -8
- package/src/charts/index.ts +39 -4
- package/src/charts/kinds/BandStrip.tsx +36 -14
- package/src/charts/kinds/Bars.tsx +67 -16
- package/src/charts/kinds/Donut.tsx +30 -3
- package/src/charts/kinds/DualPanel.tsx +56 -10
- package/src/charts/kinds/Heatmap.tsx +90 -33
- package/src/charts/kinds/MirroredBars.tsx +21 -3
- package/src/charts/kinds/MultiLine.tsx +61 -18
- package/src/charts/kinds/StackedArea.tsx +77 -6
- package/src/charts/kinds/ZonedLine.tsx +71 -31
- package/src/charts/layout/auto-margin.ts +134 -21
- package/src/charts/layout/log-ticks.ts +90 -0
- package/src/charts/primitives/Axes.tsx +33 -5
- package/src/charts/primitives/CartesianChart.tsx +194 -41
- package/src/charts/primitives/ChartCard.tsx +66 -25
- package/src/charts/primitives/ChartFrame.tsx +107 -26
- package/src/charts/primitives/ChartLegend.tsx +43 -13
- package/src/charts/primitives/ChartPending.tsx +185 -7
- package/src/charts/primitives/ChartTooltip.tsx +37 -5
- package/src/charts/primitives/Crosshair.tsx +6 -3
- package/src/charts/primitives/chart-frame-layout.ts +212 -0
- package/src/charts/primitives/chart-tier.tsx +37 -0
- package/src/charts/series.ts +77 -1
- package/src/charts/sparklines/BarSparkline.tsx +11 -3
- package/src/charts/sparklines/LineSparkline.tsx +18 -4
- package/src/charts/sparklines/index.ts +2 -2
- package/src/charts/utils/format.ts +163 -2
- package/src/charts/utils/ticks.ts +149 -4
- package/src/cli/index.ts +8 -3
- package/src/commands/ShortcutsHelp.tsx +10 -3
- package/src/commands/define-commands.ts +2 -2
- package/src/commands/define-overlays.ts +216 -1
- package/src/commands/index.ts +12 -0
- package/src/commands/overlays-mount.tsx +60 -26
- package/src/common/errors.ts +73 -0
- package/src/common/index.ts +21 -0
- package/src/common/props.ts +71 -0
- package/src/common/query-state-like.ts +64 -0
- package/src/common/refs.ts +58 -0
- package/src/common/scroll-parent.ts +42 -0
- package/src/common/validate.ts +94 -0
- package/src/connectivity/connectivity-indicator.tsx +6 -1
- package/src/connectivity/connectivity-provider.tsx +4 -1
- package/src/connectivity/index.ts +1 -0
- package/src/connectivity/types.ts +5 -2
- package/src/connectivity/use-connectivity.ts +3 -2
- package/src/content/article-layout.module.css +11 -4
- package/src/content/callout.tsx +13 -7
- package/src/content/guide.tsx +14 -4
- package/src/content/heading-anchor.tsx +14 -3
- package/src/content/index.ts +2 -0
- package/src/content/markdown.tsx +2 -0
- package/src/content/prose.module.css +9 -7
- package/src/content/reading-progress.tsx +40 -15
- package/src/content/slug.ts +4 -0
- package/src/content/toc.tsx +47 -10
- package/src/controls/actions.tsx +89 -9
- package/src/controls/compare-filter.tsx +20 -3
- package/src/controls/control-group.tsx +11 -4
- package/src/controls/controls.module.css +169 -186
- package/src/controls/controls.module.css.d.ts +9 -11
- package/src/controls/enum-filter.tsx +46 -19
- package/src/controls/filter-context.tsx +21 -8
- package/src/controls/filter-pill.tsx +6 -3
- package/src/controls/filter-set.tsx +32 -13
- package/src/controls/filter-sheet.tsx +44 -194
- package/src/controls/index.ts +8 -0
- package/src/controls/multi-select-filter.tsx +179 -29
- package/src/controls/number-filter.tsx +329 -0
- package/src/controls/panel-row.module.css +86 -0
- package/src/controls/panel-row.module.css.d.ts +13 -0
- package/src/controls/panel-row.tsx +392 -0
- package/src/controls/range-filter.tsx +133 -43
- package/src/controls/search-filter.tsx +31 -13
- package/src/controls/select-filter.tsx +11 -1
- package/src/controls/slider-control.tsx +159 -0
- package/src/controls/sync-button.tsx +13 -3
- package/src/controls/toggle-filter.tsx +37 -17
- package/src/controls/view-tabs.tsx +63 -11
- package/src/controls-dates/date-range-picker.tsx +8 -1
- package/src/dashboard/delta-badge.tsx +5 -1
- package/src/dashboard/empty-state.tsx +72 -25
- package/src/dashboard/index.ts +19 -2
- package/src/dashboard/query-state.tsx +154 -84
- package/src/dashboard/settings-section.tsx +87 -31
- package/src/dashboard/stat-card.module.css +112 -26
- package/src/dashboard/stat-card.module.css.d.ts +5 -0
- package/src/dashboard/stat-card.tsx +207 -68
- package/src/dashboard/stat-group.module.css +66 -0
- package/src/dashboard/stat-group.module.css.d.ts +8 -0
- package/src/dashboard/stat-group.tsx +74 -0
- package/src/dashboard/widget-grid.module.css +53 -0
- package/src/dashboard/widget-grid.module.css.d.ts +9 -0
- package/src/dashboard/widget-grid.tsx +127 -0
- package/src/data/data-table.module.css +64 -0
- package/src/data/data-table.module.css.d.ts +11 -0
- package/src/data/data-table.tsx +927 -346
- package/src/data/index.ts +30 -2
- package/src/data/query-branch.ts +53 -0
- package/src/data/table.ts +5 -0
- package/src/data/virtual-list.tsx +189 -55
- package/src/data/virtual.ts +5 -1
- package/src/forms/FormErrorSummary.tsx +13 -6
- package/src/forms/create-form.ts +2 -2
- package/src/forms/field.ts +60 -11
- package/src/forms/form-layout.module.css +145 -0
- package/src/forms/form-layout.module.css.d.ts +20 -0
- package/src/forms/form-layout.tsx +305 -0
- package/src/forms/form-state.tsx +94 -0
- package/src/forms/index.ts +38 -7
- package/src/forms/use-field-array.ts +94 -0
- package/src/forms/use-form-draft.ts +145 -53
- package/src/forms/use-form-submit.ts +199 -0
- package/src/guard/index.ts +91 -23
- package/src/index.ts +79 -10
- package/src/nav/types.ts +15 -6
- package/src/notifications/bell.tsx +18 -4
- package/src/notifications/center.tsx +18 -5
- package/src/notifications/define-notifications.ts +64 -18
- package/src/notifications/index.ts +12 -1
- package/src/notifications/mount-guard.ts +41 -0
- package/src/notifications/notify.tsx +122 -3
- package/src/notifications/overlay.tsx +2 -0
- package/src/notifications/store.ts +7 -0
- package/src/provider/index.tsx +101 -13
- package/src/provider/lab-theme.ts +2 -1
- package/src/query/devtools.tsx +1 -0
- package/src/router-tanstack/field.ts +5 -0
- package/src/router-tanstack/index.ts +4 -0
- package/src/router-tanstack/search-store.ts +171 -12
- package/src/router-tanstack/use-nav.ts +18 -13
- package/src/section/index.ts +1 -1
- package/src/section/section.module.css +11 -0
- package/src/section/section.tsx +163 -96
- package/src/shell/account-types.ts +5 -2
- package/src/shell/app-brand.module.css +109 -0
- package/src/shell/app-brand.module.css.d.ts +14 -0
- package/src/shell/app-brand.tsx +140 -0
- package/src/shell/app-breadcrumbs.tsx +19 -9
- package/src/shell/app-header.module.css +10 -5
- package/src/shell/app-main.module.css +107 -0
- package/src/shell/app-main.module.css.d.ts +11 -0
- package/src/shell/app-mobile-nav.module.css +48 -27
- package/src/shell/app-mobile-nav.module.css.d.ts +0 -1
- package/src/shell/app-mobile-nav.tsx +43 -11
- package/src/shell/app-sidebar-account.tsx +29 -6
- package/src/shell/app-sidebar.module.css +53 -96
- package/src/shell/app-sidebar.module.css.d.ts +0 -5
- package/src/shell/app-sidebar.tsx +40 -113
- package/src/shell/index.tsx +156 -65
- package/src/shell/isomorphic-layout-effect.ts +14 -0
- package/src/shell/mobile-nav-model.ts +66 -10
- package/src/shell/nav-count-badge.tsx +6 -1
- package/src/shell/page-aside.module.css +174 -0
- package/src/shell/page-aside.module.css.d.ts +14 -0
- package/src/shell/page-aside.tsx +377 -0
- package/src/shell/page-bar.module.css +107 -13
- package/src/shell/page-bar.module.css.d.ts +4 -1
- package/src/shell/page-bar.tsx +294 -94
- package/src/shell/sidebar-search.module.css +1 -1
- package/src/shell/sidebar-search.tsx +13 -4
- package/src/state/fields.ts +360 -69
- package/src/state/persisted-or-local.ts +50 -0
- package/src/state/persisted.ts +76 -26
- package/src/state.ts +4 -7
- package/src/surfaces.ts +43 -12
- package/src/theme/ctl-theme.tsx +10 -0
- package/src/theme/index.ts +129 -16
- package/src/theme/nav-link.module.css +37 -26
- package/src/theme/segmented-control.module.css +22 -0
- package/src/theme/segmented-control.module.css.d.ts +1 -0
- package/src/theme-lab/boot.ts +140 -0
- package/src/theme-lab/index.tsx +21 -112
- package/src/theme-toggle/index.tsx +10 -3
- package/src/tokens/index.ts +50 -6
- package/src/tokens/palette.ts +58 -30
- package/src/utils/is-dev.ts +4 -0
- package/src/widget-header/delta-badge.tsx +25 -5
- package/src/widget-header/index.ts +10 -2
- package/src/widget-header/widget-header.module.css +87 -7
- package/src/widget-header/widget-header.module.css.d.ts +1 -0
- package/src/widget-header/widget-header.tsx +166 -42
- package/dist/agent/adapter.test.d.ts +0 -2
- package/dist/agent/adapter.test.d.ts.map +0 -1
- package/dist/agent/ai-sdk-transport.test.d.ts +0 -2
- package/dist/agent/ai-sdk-transport.test.d.ts.map +0 -1
- package/dist/agent/coalesce.test.d.ts +0 -2
- package/dist/agent/coalesce.test.d.ts.map +0 -1
- package/dist/agent/foreign.test.d.ts +0 -2
- package/dist/agent/foreign.test.d.ts.map +0 -1
- package/dist/agent/id.test.d.ts +0 -2
- package/dist/agent/id.test.d.ts.map +0 -1
- package/dist/agent/merge.test.d.ts +0 -2
- package/dist/agent/merge.test.d.ts.map +0 -1
- package/dist/agent/part-list.test.d.ts +0 -2
- package/dist/agent/part-list.test.d.ts.map +0 -1
- package/dist/agent/parts.test.d.ts +0 -2
- package/dist/agent/parts.test.d.ts.map +0 -1
- package/dist/agent/thread.test.d.ts +0 -2
- package/dist/agent/thread.test.d.ts.map +0 -1
- package/dist/agent/transport.test.d.ts +0 -2
- package/dist/agent/transport.test.d.ts.map +0 -1
- package/dist/agent/use-agent-stream.test.d.ts +0 -2
- package/dist/agent/use-agent-stream.test.d.ts.map +0 -1
- package/dist/agent/use-agent-thread-runs.foreign.test.d.ts +0 -2
- package/dist/agent/use-agent-thread-runs.foreign.test.d.ts.map +0 -1
- package/dist/agent/use-agent-thread-runs.resume.test.d.ts +0 -2
- package/dist/agent/use-agent-thread-runs.resume.test.d.ts.map +0 -1
- package/dist/agent/use-agent-thread-runs.test.d.ts +0 -2
- package/dist/agent/use-agent-thread-runs.test.d.ts.map +0 -1
- package/dist/agent/use-agent-thread-runs.wedge.test.d.ts +0 -2
- package/dist/agent/use-agent-thread-runs.wedge.test.d.ts.map +0 -1
- package/dist/agent-chat/composer.test.d.ts +0 -2
- package/dist/agent-chat/composer.test.d.ts.map +0 -1
- package/dist/agent-chat/relative-time.test.d.ts +0 -2
- package/dist/agent-chat/relative-time.test.d.ts.map +0 -1
- package/dist/agent-chat/thread-feed-row.test.d.ts +0 -2
- package/dist/agent-chat/thread-feed-row.test.d.ts.map +0 -1
- package/dist/agent-chat/thread-feed.test.d.ts +0 -2
- package/dist/agent-chat/thread-feed.test.d.ts.map +0 -1
- package/dist/agent-chat/thread-message.test.d.ts +0 -2
- package/dist/agent-chat/thread-message.test.d.ts.map +0 -1
- package/dist/agent-chat/thread-workspace.test.d.ts +0 -2
- package/dist/agent-chat/thread-workspace.test.d.ts.map +0 -1
- package/dist/agent-chat/tool-chip.test.d.ts +0 -2
- package/dist/agent-chat/tool-chip.test.d.ts.map +0 -1
- package/dist/agent-chat/virtualize.type-guard.test.d.ts +0 -2
- package/dist/agent-chat/virtualize.type-guard.test.d.ts.map +0 -1
- package/dist/charts/cursor/resolve.test.d.ts +0 -2
- package/dist/charts/cursor/resolve.test.d.ts.map +0 -1
- package/dist/charts/cursor/store.test.d.ts +0 -2
- package/dist/charts/cursor/store.test.d.ts.map +0 -1
- package/dist/charts/kinds/BandStrip.test.d.ts +0 -2
- package/dist/charts/kinds/BandStrip.test.d.ts.map +0 -1
- package/dist/charts/kinds/Bars.test.d.ts +0 -2
- package/dist/charts/kinds/Bars.test.d.ts.map +0 -1
- package/dist/charts/kinds/DualPanel.test.d.ts +0 -2
- package/dist/charts/kinds/DualPanel.test.d.ts.map +0 -1
- package/dist/charts/kinds/MirroredBars.test.d.ts +0 -2
- package/dist/charts/kinds/MirroredBars.test.d.ts.map +0 -1
- package/dist/charts/kinds/MultiLine.test.d.ts +0 -2
- package/dist/charts/kinds/MultiLine.test.d.ts.map +0 -1
- package/dist/charts/kinds/StackedArea.test.d.ts +0 -2
- package/dist/charts/kinds/StackedArea.test.d.ts.map +0 -1
- package/dist/charts/kinds/ZonedLine.test.d.ts +0 -2
- package/dist/charts/kinds/ZonedLine.test.d.ts.map +0 -1
- package/dist/charts/layout/auto-margin.test.d.ts +0 -2
- package/dist/charts/layout/auto-margin.test.d.ts.map +0 -1
- package/dist/charts/primitives/CartesianChart.test.d.ts +0 -2
- package/dist/charts/primitives/CartesianChart.test.d.ts.map +0 -1
- package/dist/charts/primitives/ChartCard.test.d.ts +0 -2
- package/dist/charts/primitives/ChartCard.test.d.ts.map +0 -1
- package/dist/charts/primitives/ChartFrame.test.d.ts +0 -2
- package/dist/charts/primitives/ChartFrame.test.d.ts.map +0 -1
- package/dist/charts/primitives/ChartLegend.test.d.ts +0 -2
- package/dist/charts/primitives/ChartLegend.test.d.ts.map +0 -1
- package/dist/charts/primitives/ChartTooltip.test.d.ts +0 -2
- package/dist/charts/primitives/ChartTooltip.test.d.ts.map +0 -1
- package/dist/charts/primitives/XZoneRects.test.d.ts +0 -2
- package/dist/charts/primitives/XZoneRects.test.d.ts.map +0 -1
- package/dist/charts/series.test.d.ts +0 -2
- package/dist/charts/series.test.d.ts.map +0 -1
- package/dist/charts/utils/domain.test.d.ts +0 -2
- package/dist/charts/utils/domain.test.d.ts.map +0 -1
- package/dist/charts/utils/measure-text.test.d.ts +0 -2
- package/dist/charts/utils/measure-text.test.d.ts.map +0 -1
- package/dist/cli/check-coverage.test.d.ts +0 -2
- package/dist/cli/check-coverage.test.d.ts.map +0 -1
- package/dist/cli/check-theme.test.d.ts +0 -2
- package/dist/cli/check-theme.test.d.ts.map +0 -1
- package/dist/cli/help.test.d.ts +0 -2
- package/dist/cli/help.test.d.ts.map +0 -1
- package/dist/cli/init-sync.test.d.ts +0 -2
- package/dist/cli/init-sync.test.d.ts.map +0 -1
- package/dist/cli/placement-engine.test.d.ts +0 -2
- package/dist/cli/placement-engine.test.d.ts.map +0 -1
- package/dist/cli/shipped-versions.test.d.ts +0 -2
- package/dist/cli/shipped-versions.test.d.ts.map +0 -1
- package/dist/cli/tarball-parity.test.d.ts +0 -2
- package/dist/cli/tarball-parity.test.d.ts.map +0 -1
- package/dist/cli/template-format.test.d.ts +0 -2
- package/dist/cli/template-format.test.d.ts.map +0 -1
- package/dist/cli/template-ledger.test.d.ts +0 -2
- package/dist/cli/template-ledger.test.d.ts.map +0 -1
- package/dist/cli/tokens-css.test.d.ts +0 -2
- package/dist/cli/tokens-css.test.d.ts.map +0 -1
- package/dist/cli/toolchain-wiring.test.d.ts +0 -2
- package/dist/cli/toolchain-wiring.test.d.ts.map +0 -1
- package/dist/cli/waiver-audit.test.d.ts +0 -2
- package/dist/cli/waiver-audit.test.d.ts.map +0 -1
- package/dist/content/article-actions.test.d.ts +0 -2
- package/dist/content/article-actions.test.d.ts.map +0 -1
- package/dist/content/article-model.test.d.ts +0 -2
- package/dist/content/article-model.test.d.ts.map +0 -1
- package/dist/content/block-split.test.d.ts +0 -2
- package/dist/content/block-split.test.d.ts.map +0 -1
- package/dist/content/heading-components.test.d.ts +0 -2
- package/dist/content/heading-components.test.d.ts.map +0 -1
- package/dist/content/markdown.test.d.ts +0 -2
- package/dist/content/markdown.test.d.ts.map +0 -1
- package/dist/content/prose.module.css.test.d.ts +0 -2
- package/dist/content/prose.module.css.test.d.ts.map +0 -1
- package/dist/content/sanitize.test.d.ts +0 -2
- package/dist/content/sanitize.test.d.ts.map +0 -1
- package/dist/content/slug.test.d.ts +0 -2
- package/dist/content/slug.test.d.ts.map +0 -1
- package/dist/controls/actions.test.d.ts +0 -2
- package/dist/controls/actions.test.d.ts.map +0 -1
- package/dist/controls/actions.type-guard.test.d.ts +0 -2
- package/dist/controls/actions.type-guard.test.d.ts.map +0 -1
- package/dist/controls/control-group.test.d.ts +0 -2
- package/dist/controls/control-group.test.d.ts.map +0 -1
- package/dist/controls/controls.router.test.d.ts +0 -2
- package/dist/controls/controls.router.test.d.ts.map +0 -1
- package/dist/controls/filter-set.test.d.ts +0 -2
- package/dist/controls/filter-set.test.d.ts.map +0 -1
- package/dist/controls/peer-boundary.test.d.ts +0 -2
- package/dist/controls/peer-boundary.test.d.ts.map +0 -1
- package/dist/controls/props-contract.test.d.ts +0 -2
- package/dist/controls/props-contract.test.d.ts.map +0 -1
- package/dist/controls/sync-button.test.d.ts +0 -2
- package/dist/controls/sync-button.test.d.ts.map +0 -1
- package/dist/dashboard/query-state.test.d.ts +0 -2
- package/dist/dashboard/query-state.test.d.ts.map +0 -1
- package/dist/dashboard/settings-section.test.d.ts +0 -2
- package/dist/dashboard/settings-section.test.d.ts.map +0 -1
- package/dist/dashboard/stat-card.test.d.ts +0 -2
- package/dist/dashboard/stat-card.test.d.ts.map +0 -1
- package/dist/data/data-table.test.d.ts +0 -2
- package/dist/data/data-table.test.d.ts.map +0 -1
- package/dist/guard/check-source.test.d.ts +0 -2
- package/dist/guard/check-source.test.d.ts.map +0 -1
- package/dist/guard/grace.test.d.ts +0 -20
- package/dist/guard/grace.test.d.ts.map +0 -1
- package/dist/guard/guard-hook.test.d.ts +0 -2
- package/dist/guard/guard-hook.test.d.ts.map +0 -1
- package/dist/provider/index.test.d.ts +0 -2
- package/dist/provider/index.test.d.ts.map +0 -1
- package/dist/provider/lab-theme.test.d.ts +0 -2
- package/dist/provider/lab-theme.test.d.ts.map +0 -1
- package/dist/query/error-message.test.d.ts +0 -2
- package/dist/query/error-message.test.d.ts.map +0 -1
- package/dist/router-tanstack/multi-search-param-store.test.d.ts +0 -2
- package/dist/router-tanstack/multi-search-param-store.test.d.ts.map +0 -1
- package/dist/router-tanstack/nav.test.d.ts +0 -2
- package/dist/router-tanstack/nav.test.d.ts.map +0 -1
- package/dist/router-tanstack/search-param-store.test.d.ts +0 -2
- package/dist/router-tanstack/search-param-store.test.d.ts.map +0 -1
- package/dist/router-tanstack/search-store.router.test.d.ts +0 -2
- package/dist/router-tanstack/search-store.router.test.d.ts.map +0 -1
- package/dist/router-tanstack/search-store.test.d.ts +0 -2
- package/dist/router-tanstack/search-store.test.d.ts.map +0 -1
- package/dist/router-tanstack/use-nav.test.d.ts +0 -2
- package/dist/router-tanstack/use-nav.test.d.ts.map +0 -1
- package/dist/section/section.test.d.ts +0 -2
- package/dist/section/section.test.d.ts.map +0 -1
- package/dist/shell/app-mobile-nav.test.d.ts +0 -2
- package/dist/shell/app-mobile-nav.test.d.ts.map +0 -1
- package/dist/shell/app-sidebar.test.d.ts +0 -2
- package/dist/shell/app-sidebar.test.d.ts.map +0 -1
- package/dist/shell/index.test.d.ts +0 -2
- package/dist/shell/index.test.d.ts.map +0 -1
- package/dist/shell/mobile-nav-model.test.d.ts +0 -2
- package/dist/shell/mobile-nav-model.test.d.ts.map +0 -1
- package/dist/shell/page-bar.test.d.ts +0 -2
- package/dist/shell/page-bar.test.d.ts.map +0 -1
- package/dist/state/fields.test.d.ts +0 -2
- package/dist/state/fields.test.d.ts.map +0 -1
- package/dist/styles.floor.test.d.ts +0 -2
- package/dist/styles.floor.test.d.ts.map +0 -1
- package/dist/theme/border-coverage.test.d.ts +0 -18
- package/dist/theme/border-coverage.test.d.ts.map +0 -1
- package/dist/theme/contrast.test.d.ts +0 -2
- package/dist/theme/contrast.test.d.ts.map +0 -1
- package/dist/theme/ctl-theme.test.d.ts +0 -2
- package/dist/theme/ctl-theme.test.d.ts.map +0 -1
- package/dist/theme/ctl-tier-coverage.test.d.ts +0 -2
- package/dist/theme/ctl-tier-coverage.test.d.ts.map +0 -1
- package/dist/theme/density-option.test.d.ts +0 -2
- package/dist/theme/density-option.test.d.ts.map +0 -1
- package/dist/theme/density-relations.test.d.ts +0 -2
- package/dist/theme/density-relations.test.d.ts.map +0 -1
- package/dist/theme/derive-theme.test.d.ts +0 -2
- package/dist/theme/derive-theme.test.d.ts.map +0 -1
- package/dist/theme/divider-law.test.d.ts +0 -2
- package/dist/theme/divider-law.test.d.ts.map +0 -1
- package/dist/theme/fonts-option.test.d.ts +0 -2
- package/dist/theme/fonts-option.test.d.ts.map +0 -1
- package/dist/theme/icon-slot.test.d.ts +0 -2
- package/dist/theme/icon-slot.test.d.ts.map +0 -1
- package/dist/theme/layout-rhythm-css.test.d.ts +0 -2
- package/dist/theme/layout-rhythm-css.test.d.ts.map +0 -1
- package/dist/theme/radius-option.test.d.ts +0 -2
- package/dist/theme/radius-option.test.d.ts.map +0 -1
- package/dist/theme/radius.test.d.ts +0 -2
- package/dist/theme/radius.test.d.ts.map +0 -1
- package/dist/theme/shadow-surfaces.test.d.ts +0 -26
- package/dist/theme/shadow-surfaces.test.d.ts.map +0 -1
- package/dist/theme/spacing.test.d.ts +0 -2
- package/dist/theme/spacing.test.d.ts.map +0 -1
- package/dist/theme/use-basalt-spacing.test.d.ts +0 -2
- package/dist/theme/use-basalt-spacing.test.d.ts.map +0 -1
- package/dist/theme-lab/derive-controls.test.d.ts +0 -2
- package/dist/theme-lab/derive-controls.test.d.ts.map +0 -1
- package/dist/theme-lab/derive-state.test.d.ts +0 -2
- package/dist/theme-lab/derive-state.test.d.ts.map +0 -1
- package/dist/theme-lab/theme-lab.test.d.ts +0 -2
- package/dist/theme-lab/theme-lab.test.d.ts.map +0 -1
- package/dist/tokens/build-fonts-css.test.d.ts +0 -2
- package/dist/tokens/build-fonts-css.test.d.ts.map +0 -1
- package/dist/tokens/build-radius-css.test.d.ts +0 -2
- package/dist/tokens/build-radius-css.test.d.ts.map +0 -1
- package/dist/tokens/chart-margin.test.d.ts +0 -2
- package/dist/tokens/chart-margin.test.d.ts.map +0 -1
- package/dist/tokens/density.test.d.ts +0 -2
- package/dist/tokens/density.test.d.ts.map +0 -1
- package/dist/tokens/derive-radius.test.d.ts +0 -2
- package/dist/tokens/derive-radius.test.d.ts.map +0 -1
- package/dist/tokens/derive.test.d.ts +0 -2
- package/dist/tokens/derive.test.d.ts.map +0 -1
- package/dist/tokens/palette.test.d.ts +0 -2
- package/dist/tokens/palette.test.d.ts.map +0 -1
- package/dist/tokens/text-scale.test.d.ts +0 -2
- package/dist/tokens/text-scale.test.d.ts.map +0 -1
- package/dist/vite-color-mix.test.d.ts +0 -2
- package/dist/vite-color-mix.test.d.ts.map +0 -1
- package/dist/vite.test.d.ts +0 -2
- package/dist/vite.test.d.ts.map +0 -1
- package/dist/widget-header/delta-badge.test.d.ts +0 -2
- package/dist/widget-header/delta-badge.test.d.ts.map +0 -1
- package/dist/widget-header/no-mantine.test.d.ts +0 -2
- package/dist/widget-header/no-mantine.test.d.ts.map +0 -1
- package/dist/widget-header/widget-header.test.d.ts +0 -2
- package/dist/widget-header/widget-header.test.d.ts.map +0 -1
- package/src/agent/adapter.test.ts +0 -1640
- package/src/agent/ai-sdk-transport.test.ts +0 -658
- package/src/agent/coalesce.test.ts +0 -387
- package/src/agent/foreign.test.ts +0 -51
- package/src/agent/id.test.ts +0 -169
- package/src/agent/merge.test.ts +0 -206
- package/src/agent/part-list.test.tsx +0 -112
- package/src/agent/parts.test.ts +0 -720
- package/src/agent/thread.test.ts +0 -220
- package/src/agent/transport.test.ts +0 -70
- package/src/agent/use-agent-stream.test.tsx +0 -287
- package/src/agent/use-agent-thread-runs.foreign.test.tsx +0 -138
- package/src/agent/use-agent-thread-runs.resume.test.tsx +0 -294
- package/src/agent/use-agent-thread-runs.test.tsx +0 -1120
- package/src/agent/use-agent-thread-runs.wedge.test.tsx +0 -387
- package/src/agent-chat/composer.test.tsx +0 -924
- package/src/agent-chat/relative-time.test.ts +0 -95
- package/src/agent-chat/thread-feed-row.test.tsx +0 -510
- package/src/agent-chat/thread-feed.test.tsx +0 -241
- package/src/agent-chat/thread-message.test.tsx +0 -1285
- package/src/agent-chat/thread-workspace.test.tsx +0 -169
- package/src/agent-chat/tool-chip.test.tsx +0 -139
- package/src/agent-chat/virtualize.type-guard.test.ts +0 -49
- package/src/charts/cursor/resolve.test.ts +0 -151
- package/src/charts/cursor/store.test.ts +0 -64
- package/src/charts/kinds/BandStrip.test.tsx +0 -282
- package/src/charts/kinds/Bars.test.tsx +0 -183
- package/src/charts/kinds/DualPanel.test.tsx +0 -527
- package/src/charts/kinds/MirroredBars.test.tsx +0 -232
- package/src/charts/kinds/MultiLine.test.tsx +0 -218
- package/src/charts/kinds/StackedArea.test.tsx +0 -114
- package/src/charts/kinds/ZonedLine.test.tsx +0 -147
- package/src/charts/layout/auto-margin.test.ts +0 -42
- package/src/charts/primitives/CartesianChart.test.tsx +0 -647
- package/src/charts/primitives/ChartCard.test.tsx +0 -66
- package/src/charts/primitives/ChartFrame.test.tsx +0 -142
- package/src/charts/primitives/ChartLegend.test.tsx +0 -78
- package/src/charts/primitives/ChartTooltip.test.tsx +0 -44
- package/src/charts/primitives/XZoneRects.test.tsx +0 -123
- package/src/charts/series.test.ts +0 -112
- package/src/charts/utils/domain.test.ts +0 -54
- package/src/charts/utils/measure-text.test.ts +0 -36
- package/src/cli/check-coverage.test.ts +0 -297
- package/src/cli/check-theme.test.ts +0 -837
- package/src/cli/help.test.ts +0 -170
- package/src/cli/init-sync.test.ts +0 -343
- package/src/cli/placement-engine.test.ts +0 -298
- package/src/cli/shipped-versions.test.ts +0 -83
- package/src/cli/tarball-parity.test.ts +0 -44
- package/src/cli/template-format.test.ts +0 -64
- package/src/cli/template-ledger.test.ts +0 -219
- package/src/cli/tokens-css.test.ts +0 -249
- package/src/cli/toolchain-wiring.test.ts +0 -1358
- package/src/cli/waiver-audit.test.ts +0 -215
- package/src/content/article-actions.test.ts +0 -78
- package/src/content/article-model.test.ts +0 -119
- package/src/content/block-split.test.ts +0 -75
- package/src/content/heading-components.test.tsx +0 -65
- package/src/content/markdown.test.tsx +0 -603
- package/src/content/prose.module.css.test.ts +0 -39
- package/src/content/sanitize.test.ts +0 -659
- package/src/content/slug.test.ts +0 -62
- package/src/controls/actions.test.tsx +0 -252
- package/src/controls/actions.type-guard.test.ts +0 -63
- package/src/controls/control-group.test.tsx +0 -229
- package/src/controls/controls.router.test.tsx +0 -637
- package/src/controls/filter-set.test.tsx +0 -472
- package/src/controls/peer-boundary.test.ts +0 -85
- package/src/controls/props-contract.test.tsx +0 -106
- package/src/controls/sync-button.test.tsx +0 -183
- package/src/dashboard/query-state.test.tsx +0 -152
- package/src/dashboard/settings-section.test.tsx +0 -56
- package/src/dashboard/stat-card.test.tsx +0 -154
- package/src/data/data-table.test.tsx +0 -434
- package/src/guard/check-source.test.ts +0 -3355
- package/src/guard/grace.test.ts +0 -149
- package/src/guard/guard-hook.test.ts +0 -203
- package/src/provider/index.test.tsx +0 -101
- package/src/provider/lab-theme.test.ts +0 -147
- package/src/query/error-message.test.ts +0 -67
- package/src/router-tanstack/multi-search-param-store.test.ts +0 -124
- package/src/router-tanstack/nav.test.ts +0 -111
- package/src/router-tanstack/search-param-store.test.ts +0 -135
- package/src/router-tanstack/search-store.router.test.tsx +0 -661
- package/src/router-tanstack/search-store.test.ts +0 -418
- package/src/router-tanstack/use-nav.test.tsx +0 -187
- package/src/section/section.test.tsx +0 -204
- package/src/shell/app-mobile-nav.test.tsx +0 -403
- package/src/shell/app-sidebar.test.tsx +0 -509
- package/src/shell/index.test.tsx +0 -428
- package/src/shell/mobile-nav-model.test.ts +0 -517
- package/src/shell/page-bar.test.tsx +0 -316
- package/src/state/fields.test.tsx +0 -258
- package/src/styles.floor.test.ts +0 -36
- package/src/theme/border-coverage.test.ts +0 -272
- package/src/theme/contrast.test.ts +0 -354
- package/src/theme/ctl-theme.test.tsx +0 -275
- package/src/theme/ctl-tier-coverage.test.ts +0 -170
- package/src/theme/density-option.test.ts +0 -96
- package/src/theme/density-relations.test.ts +0 -506
- package/src/theme/derive-theme.test.ts +0 -101
- package/src/theme/divider-law.test.ts +0 -259
- package/src/theme/fonts-option.test.ts +0 -75
- package/src/theme/icon-slot.test.tsx +0 -275
- package/src/theme/layout-rhythm-css.test.ts +0 -72
- package/src/theme/radius-option.test.ts +0 -86
- package/src/theme/radius.test.ts +0 -142
- package/src/theme/shadow-surfaces.test.ts +0 -488
- package/src/theme/spacing.test.ts +0 -495
- package/src/theme/use-basalt-spacing.test.tsx +0 -55
- package/src/theme-lab/derive-controls.test.ts +0 -94
- package/src/theme-lab/derive-state.test.ts +0 -71
- package/src/theme-lab/theme-lab.test.ts +0 -46
- package/src/tokens/build-fonts-css.test.ts +0 -52
- package/src/tokens/build-radius-css.test.ts +0 -25
- package/src/tokens/chart-margin.test.ts +0 -39
- package/src/tokens/density.test.ts +0 -259
- package/src/tokens/derive-radius.test.ts +0 -62
- package/src/tokens/derive.test.ts +0 -30
- package/src/tokens/palette.test.ts +0 -114
- package/src/tokens/text-scale.test.ts +0 -51
- package/src/vite-color-mix.test.ts +0 -46
- package/src/vite.test.ts +0 -423
- package/src/widget-header/delta-badge.test.tsx +0 -60
- package/src/widget-header/no-mantine.test.ts +0 -33
- package/src/widget-header/widget-header.test.tsx +0 -187
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { Group } from '@visx/group'
|
|
2
2
|
import type { PointerEvent, ReactNode } from 'react'
|
|
3
3
|
import { memo, useMemo, useState } from 'react'
|
|
4
|
+
import { assertRequiredProps } from '../../common/validate'
|
|
5
|
+
import type { BasaltProps } from '../../common/props'
|
|
4
6
|
import {
|
|
5
7
|
ChartTooltipFloat,
|
|
6
8
|
TooltipBody,
|
|
@@ -8,6 +10,10 @@ import {
|
|
|
8
10
|
TooltipRow,
|
|
9
11
|
} from '../primitives/ChartTooltip'
|
|
10
12
|
import { ChartFrame } from '../primitives/ChartFrame'
|
|
13
|
+
import { useChartTierMetrics } from '../primitives/chart-tier'
|
|
14
|
+
import type { ChartState } from '../primitives/ChartPending'
|
|
15
|
+
import { maxTextWidth } from '../utils/measure-text'
|
|
16
|
+
import { thinLabels, xLabelPxFor } from '../utils/ticks'
|
|
11
17
|
import { VX, alpha } from '../../tokens'
|
|
12
18
|
|
|
13
19
|
/** A single resolved heatmap cell — the unit the tooltip and hover operate on. */
|
|
@@ -16,7 +22,7 @@ type HeatmapCell = { row: string; col: string; value: number }
|
|
|
16
22
|
/** A hovered cell plus the viewport anchor `ChartTooltipFloat` positions against. */
|
|
17
23
|
type HeatmapTip = HeatmapCell & { anchor: { x: number; y: number } }
|
|
18
24
|
|
|
19
|
-
export type HeatmapProps<T> = {
|
|
25
|
+
export type HeatmapProps<T> = BasaltProps & {
|
|
20
26
|
data: T[]
|
|
21
27
|
/** Fixed height in pixels. Used when neither `aspectRatio` nor `fill` is set. Default 240. */
|
|
22
28
|
height?: number
|
|
@@ -57,6 +63,9 @@ export type HeatmapProps<T> = {
|
|
|
57
63
|
ariaLabel?: string
|
|
58
64
|
/** Forwarded to `ChartFrame` — see `ChartPending`'s JSDoc for the three-state rationale. */
|
|
59
65
|
isPending?: boolean
|
|
66
|
+
/** The three "nothing to draw" states in one prop — pending → error → empty. See
|
|
67
|
+
* `ChartState`; `isPending` stays a supported alias for `state={{ pending: true }}`. */
|
|
68
|
+
state?: ChartState
|
|
60
69
|
}
|
|
61
70
|
|
|
62
71
|
/** Build a first-seen-ordered list of unique keys from data via an accessor. */
|
|
@@ -85,6 +94,10 @@ const LABEL_FONT_FAMILY = 'var(--basalt-font-mono)'
|
|
|
85
94
|
const PAD_LEFT = 44
|
|
86
95
|
const PAD_BOTTOM = 24
|
|
87
96
|
const PAD_TOP = 8
|
|
97
|
+
|
|
98
|
+
/** Line box of one category label at `fontPx` — the vertical room a row label needs, and so the
|
|
99
|
+
* pitch below which the row labels thin (`thinLabels`). Same 1.35em line box `autoMargin` uses. */
|
|
100
|
+
const labelLineHeight = (fontPx: number): number => Math.ceil(fontPx * 1.35)
|
|
88
101
|
// Height of the optional gradient legend strip (+ its label line).
|
|
89
102
|
const LEGEND_H = 8
|
|
90
103
|
const LEGEND_LABEL_H = 16
|
|
@@ -94,14 +107,22 @@ const LEGEND_LABEL_H = 16
|
|
|
94
107
|
* color at an opacity derived from its value; empty cells stay a faint neutral track.
|
|
95
108
|
* Generalizes argo's day-of-week × hour-of-day heatmap. Categorical axes are rendered as
|
|
96
109
|
* plain themed `<text>` (cells are not date-categorical, so there's no shared cursor here) —
|
|
97
|
-
* per-cell hover drives the local tooltip directly.
|
|
110
|
+
* per-cell hover drives the local tooltip directly. Painting them outside the `Axis*` primitives
|
|
111
|
+
* does NOT exempt them from §1's measured law: both runs thin through {@link thinLabels} and the
|
|
112
|
+
* right gutter reserves half the widest column label, so no two painted labels overlap and the
|
|
113
|
+
* last one cannot clip.
|
|
98
114
|
*
|
|
99
115
|
* Composes `ChartFrame` purely for measuring (`height`/`aspectRatio`/`fill`, the same three
|
|
100
116
|
* sizing modes every other kind exposes) — `legend={false}` and an empty `series` opt out of
|
|
101
117
|
* `ChartFrame`'s own derived legend, since Heatmap already ships its own gradient strip.
|
|
102
118
|
*/
|
|
103
119
|
function HeatmapInner<T>(props: HeatmapProps<T>) {
|
|
104
|
-
|
|
120
|
+
// F-ERR-1: name the component and the prop. Without this a missing accessor surfaces
|
|
121
|
+
// from inside visx as `undefined is not a function`, which `BasaltErrorBoundary`
|
|
122
|
+
// swallows into a blank subtree that names nothing.
|
|
123
|
+
assertRequiredProps('Heatmap', props, ['data', 'getRow', 'getCol', 'getValue'])
|
|
124
|
+
const { chartId, height, aspectRatio, fill, ariaLabel, isPending, state, className, style } =
|
|
125
|
+
props
|
|
105
126
|
|
|
106
127
|
return (
|
|
107
128
|
<ChartFrame
|
|
@@ -113,6 +134,9 @@ function HeatmapInner<T>(props: HeatmapProps<T>) {
|
|
|
113
134
|
{...(fill !== undefined && { fill })}
|
|
114
135
|
{...(ariaLabel !== undefined && { ariaLabel })}
|
|
115
136
|
{...(isPending !== undefined && { isPending })}
|
|
137
|
+
{...(state !== undefined && { state })}
|
|
138
|
+
{...(className !== undefined && { className })}
|
|
139
|
+
{...(style !== undefined && { style })}
|
|
116
140
|
>
|
|
117
141
|
{(plot) => <HeatmapPlot {...props} plot={plot} />}
|
|
118
142
|
</ChartFrame>
|
|
@@ -147,6 +171,11 @@ function HeatmapPlot<T>(props: HeatmapPlotProps<T>) {
|
|
|
147
171
|
} = props
|
|
148
172
|
const { width, height } = plot
|
|
149
173
|
|
|
174
|
+
// The row/column labels and the gradient legend's endpoints read like axis ticks, so they take
|
|
175
|
+
// the tier's tick font for the same reason `Axes.tsx` does — a 360px heatmap that painted its
|
|
176
|
+
// categories at the desktop size would be the one chart still ignoring §8.
|
|
177
|
+
const { axisFont } = useChartTierMetrics()
|
|
178
|
+
|
|
150
179
|
const [tip, setTip] = useState<HeatmapTip | null>(null)
|
|
151
180
|
|
|
152
181
|
const rows = useMemo(() => rowsProp ?? firstSeen(data, getRow), [rowsProp, data, getRow])
|
|
@@ -164,13 +193,33 @@ function HeatmapPlot<T>(props: HeatmapPlotProps<T>) {
|
|
|
164
193
|
return { lookup: map, max: m }
|
|
165
194
|
}, [data, getRow, getCol, getValue])
|
|
166
195
|
|
|
196
|
+
const rowLabels = useMemo(() => rows.map(rowLabel), [rows, rowLabel])
|
|
197
|
+
const colLabels = useMemo(() => cols.map(colLabel), [cols, colLabel])
|
|
198
|
+
|
|
167
199
|
const legendH = legend ? LEGEND_H + LEGEND_LABEL_H : 0
|
|
168
|
-
|
|
200
|
+
// The last column label is CENTRED on the last cell, so half of it hangs past the grid — the
|
|
201
|
+
// same reason `autoMargin` reserves half the widest x label on the right. Measured, not a
|
|
202
|
+
// constant: at 390px `19:00` used to print straight off the SVG's own clip edge.
|
|
203
|
+
const padRight = Math.ceil(maxTextWidth(colLabels, axisFont) / 2)
|
|
204
|
+
const gridW = Math.max(0, width - PAD_LEFT - padRight)
|
|
169
205
|
const gridH = Math.max(0, height - PAD_TOP - PAD_BOTTOM - legendH)
|
|
170
206
|
const cellW = cols.length > 0 ? gridW / cols.length : 0
|
|
171
207
|
const cellH = rows.length > 0 ? gridH / rows.length : 0
|
|
172
208
|
const legendGradientId = `${chartId}-heat-legend`
|
|
173
209
|
|
|
210
|
+
// §1's measured law, applied to the one kind that paints its labels as plain `<text>` rather
|
|
211
|
+
// than through the `Axis*` primitives: a label every `ceil(labelPx / cellPitch)` bands, so two
|
|
212
|
+
// painted neighbours can never overlap. Columns thin horizontally by the widest label, rows
|
|
213
|
+
// vertically by the line box.
|
|
214
|
+
const keptCols = useMemo(
|
|
215
|
+
() => thinLabels(colLabels, cellW, xLabelPxFor(colLabels, axisFont)),
|
|
216
|
+
[colLabels, cellW, axisFont],
|
|
217
|
+
)
|
|
218
|
+
const keptRows = useMemo(
|
|
219
|
+
() => thinLabels(rowLabels, cellH, labelLineHeight(axisFont)),
|
|
220
|
+
[rowLabels, cellH, axisFont],
|
|
221
|
+
)
|
|
222
|
+
|
|
174
223
|
const show = (row: string, col: string, value: number, event: PointerEvent<SVGRectElement>) => {
|
|
175
224
|
setTip({ row, col, value, anchor: { x: event.clientX, y: event.clientY } })
|
|
176
225
|
}
|
|
@@ -206,36 +255,40 @@ function HeatmapPlot<T>(props: HeatmapPlotProps<T>) {
|
|
|
206
255
|
|
|
207
256
|
{/* Row labels (left). */}
|
|
208
257
|
<Group left={0} top={PAD_TOP}>
|
|
209
|
-
{rows.map((row, ri) =>
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
258
|
+
{rows.map((row, ri) =>
|
|
259
|
+
keptRows.has(ri) ? (
|
|
260
|
+
<text
|
|
261
|
+
key={row}
|
|
262
|
+
x={PAD_LEFT - 6}
|
|
263
|
+
y={ri * cellH + cellH / 2 + 4}
|
|
264
|
+
textAnchor="end"
|
|
265
|
+
fontSize={axisFont}
|
|
266
|
+
fontFamily={LABEL_FONT_FAMILY}
|
|
267
|
+
fill={VX.faint}
|
|
268
|
+
>
|
|
269
|
+
{rowLabels[ri]}
|
|
270
|
+
</text>
|
|
271
|
+
) : null,
|
|
272
|
+
)}
|
|
222
273
|
</Group>
|
|
223
274
|
|
|
224
275
|
{/* Column labels (bottom). */}
|
|
225
276
|
<Group left={PAD_LEFT} top={PAD_TOP + gridH}>
|
|
226
|
-
{cols.map((col, ci) =>
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
277
|
+
{cols.map((col, ci) =>
|
|
278
|
+
keptCols.has(ci) ? (
|
|
279
|
+
<text
|
|
280
|
+
key={col}
|
|
281
|
+
x={ci * cellW + cellW / 2}
|
|
282
|
+
y={16}
|
|
283
|
+
textAnchor="middle"
|
|
284
|
+
fontSize={axisFont}
|
|
285
|
+
fontFamily={LABEL_FONT_FAMILY}
|
|
286
|
+
fill={VX.faint}
|
|
287
|
+
>
|
|
288
|
+
{colLabels[ci]}
|
|
289
|
+
</text>
|
|
290
|
+
) : null,
|
|
291
|
+
)}
|
|
239
292
|
</Group>
|
|
240
293
|
|
|
241
294
|
{/* Optional gradient legend strip below the grid. */}
|
|
@@ -252,7 +305,7 @@ function HeatmapPlot<T>(props: HeatmapPlotProps<T>) {
|
|
|
252
305
|
x={0}
|
|
253
306
|
y={LEGEND_H + 12}
|
|
254
307
|
textAnchor="start"
|
|
255
|
-
fontSize={
|
|
308
|
+
fontSize={axisFont}
|
|
256
309
|
fontFamily={LABEL_FONT_FAMILY}
|
|
257
310
|
fill={VX.faint}
|
|
258
311
|
>
|
|
@@ -262,7 +315,7 @@ function HeatmapPlot<T>(props: HeatmapPlotProps<T>) {
|
|
|
262
315
|
x={gridW}
|
|
263
316
|
y={LEGEND_H + 12}
|
|
264
317
|
textAnchor="end"
|
|
265
|
-
fontSize={
|
|
318
|
+
fontSize={axisFont}
|
|
266
319
|
fontFamily={LABEL_FONT_FAMILY}
|
|
267
320
|
fill={VX.faint}
|
|
268
321
|
>
|
|
@@ -294,4 +347,8 @@ function HeatmapPlot<T>(props: HeatmapPlotProps<T>) {
|
|
|
294
347
|
* Hand-memoized: React Compiler does not process the shipped dist, so the hot Heatmap kind is
|
|
295
348
|
* wrapped in `React.memo` to retain auto-memoization (parity with ZonedLine / Bars).
|
|
296
349
|
*/
|
|
297
|
-
|
|
350
|
+
const HeatmapMemo = memo(HeatmapInner)
|
|
351
|
+
// Without it every kind reads as `Memo` in React DevTools (audit A16) — a profiler flame
|
|
352
|
+
// graph of nine identically-named nodes names nothing.
|
|
353
|
+
HeatmapMemo.displayName = 'Heatmap'
|
|
354
|
+
export const Heatmap = HeatmapMemo as typeof HeatmapInner
|
|
@@ -2,6 +2,8 @@ import { Group } from '@visx/group'
|
|
|
2
2
|
import { scaleLinear } from '@visx/scale'
|
|
3
3
|
import { memo, useMemo } from 'react'
|
|
4
4
|
import type { ReactNode } from 'react'
|
|
5
|
+
import { assertRequiredProps } from '../../common/validate'
|
|
6
|
+
import type { BasaltProps } from '../../common/props'
|
|
5
7
|
import { VX, alpha } from '../../tokens'
|
|
6
8
|
import type { ChartMargin } from '../../tokens'
|
|
7
9
|
import type { CursorResolution } from '../cursor/resolve'
|
|
@@ -19,6 +21,7 @@ import {
|
|
|
19
21
|
import { Crosshair } from '../primitives/Crosshair'
|
|
20
22
|
import { HatchPattern, hatchFill, hatchSizeFor } from '../primitives/HatchPattern'
|
|
21
23
|
import { HoverOverlay } from '../primitives/HoverOverlay'
|
|
24
|
+
import type { ChartState } from '../primitives/ChartPending'
|
|
22
25
|
import { deriveTooltipRows } from '../series'
|
|
23
26
|
import type { ChartLegendConfig, ChartSeries } from '../series'
|
|
24
27
|
import { fmtAxisDate } from '../utils/format'
|
|
@@ -47,7 +50,7 @@ export type MirroredBarPane = {
|
|
|
47
50
|
format: (v: number) => string
|
|
48
51
|
}
|
|
49
52
|
|
|
50
|
-
export type MirroredBarsProps<T> = {
|
|
53
|
+
export type MirroredBarsProps<T> = BasaltProps & {
|
|
51
54
|
data: readonly T[]
|
|
52
55
|
chartId: string
|
|
53
56
|
/** Extracts the x-domain key — a slot start, hence the `'leading'` cursor default. */
|
|
@@ -92,6 +95,9 @@ export type MirroredBarsProps<T> = {
|
|
|
92
95
|
margin?: Partial<ChartMargin>
|
|
93
96
|
ariaLabel?: string
|
|
94
97
|
isPending?: boolean
|
|
98
|
+
/** The three "nothing to draw" states in one prop — pending → error → empty. See
|
|
99
|
+
* `ChartState`; `isPending` stays a supported alias for `state={{ pending: true }}`. */
|
|
100
|
+
state?: ChartState
|
|
95
101
|
}
|
|
96
102
|
|
|
97
103
|
const DEFAULT_UP_FRACTION = 0.35
|
|
@@ -137,7 +143,12 @@ function assertPaneKey<T>(
|
|
|
137
143
|
* `useBandPlot` choreography instead, which is where the sharing actually belongs.
|
|
138
144
|
*/
|
|
139
145
|
function MirroredBarsInner<T>(props: MirroredBarsProps<T>) {
|
|
140
|
-
|
|
146
|
+
// F-ERR-1: name the component and the prop. Without this a missing accessor surfaces
|
|
147
|
+
// from inside visx as `undefined is not a function`, which `BasaltErrorBoundary`
|
|
148
|
+
// swallows into a blank subtree that names nothing.
|
|
149
|
+
assertRequiredProps('MirroredBars', props, ['data', 'getX', 'series', 'up', 'down'])
|
|
150
|
+
const { series, chartId, height, fill, legend, ariaLabel, isPending, state, className, style } =
|
|
151
|
+
props
|
|
141
152
|
|
|
142
153
|
return (
|
|
143
154
|
<ChartFrame
|
|
@@ -147,6 +158,9 @@ function MirroredBarsInner<T>(props: MirroredBarsProps<T>) {
|
|
|
147
158
|
{...(fill !== undefined && { fill })}
|
|
148
159
|
{...(ariaLabel !== undefined && { ariaLabel })}
|
|
149
160
|
{...(isPending !== undefined && { isPending })}
|
|
161
|
+
{...(state !== undefined && { state })}
|
|
162
|
+
{...(className !== undefined && { className })}
|
|
163
|
+
{...(style !== undefined && { style })}
|
|
150
164
|
legend={resolveLegend(legend)}
|
|
151
165
|
>
|
|
152
166
|
{(plot) => <MirroredBarsPlot {...props} plot={plot} />}
|
|
@@ -488,4 +502,8 @@ function usePaneMax<T>(
|
|
|
488
502
|
* Hand-memoized: React Compiler does not process the shipped dist, so the hot kind is wrapped in
|
|
489
503
|
* `React.memo` to retain the auto-memoization it had as source (parity with `DualPanel`).
|
|
490
504
|
*/
|
|
491
|
-
|
|
505
|
+
const MirroredBarsMemo = memo(MirroredBarsInner)
|
|
506
|
+
// Without it every kind reads as `Memo` in React DevTools (audit A16) — a profiler flame
|
|
507
|
+
// graph of nine identically-named nodes names nothing.
|
|
508
|
+
MirroredBarsMemo.displayName = 'MirroredBars'
|
|
509
|
+
export const MirroredBars = MirroredBarsMemo as typeof MirroredBarsInner
|
|
@@ -1,17 +1,19 @@
|
|
|
1
|
-
import { curveMonotoneX } from '@visx/curve'
|
|
2
1
|
import { LinePath } from '@visx/shape'
|
|
3
2
|
import { memo, useCallback, useMemo } from 'react'
|
|
4
3
|
import type { ReactNode } from 'react'
|
|
4
|
+
import { assertRequiredProps } from '../../common/validate'
|
|
5
|
+
import type { BasaltProps } from '../../common/props'
|
|
5
6
|
import type { CursorResolution } from '../cursor/resolve'
|
|
6
7
|
import type { CartesianTooltipConfig, AxisConfig, PlotContext } from '../primitives/CartesianChart'
|
|
7
8
|
import { CartesianChart } from '../primitives/CartesianChart'
|
|
8
9
|
import type { XZoneSpec } from '../primitives/XZoneRects'
|
|
9
10
|
import type { ZoneSpec } from '../primitives/ZoneRects'
|
|
10
|
-
import {
|
|
11
|
+
import type { ChartState } from '../primitives/ChartPending'
|
|
12
|
+
import { curveFor, definedOn, LINE_OVERLAY_STROKE_WIDTH, toPlotPoint } from '../series'
|
|
11
13
|
import type { ChartLegendConfig, ChartSeries } from '../series'
|
|
12
14
|
import { VX } from '../../tokens'
|
|
13
15
|
|
|
14
|
-
export type MultiLineProps<T> = {
|
|
16
|
+
export type MultiLineProps<T> = BasaltProps & {
|
|
15
17
|
data: T[]
|
|
16
18
|
/** Fixed height in pixels, forwarded to `CartesianChart`. Default 240. */
|
|
17
19
|
height?: number
|
|
@@ -42,6 +44,9 @@ export type MultiLineProps<T> = {
|
|
|
42
44
|
xTickValues?: (keys: readonly string[], xMax: number) => readonly string[]
|
|
43
45
|
/** X tick label formatter. Default `fmtAxisDate` (DD.MM). */
|
|
44
46
|
formatX?: (key: string) => string
|
|
47
|
+
/** Tilt the x tick labels 45° or 90°, or `0` to opt out of the phone tier's auto-rotation —
|
|
48
|
+
* see `CartesianChartProps.xLabelRotate`. */
|
|
49
|
+
xLabelRotate?: 0 | 45 | 90
|
|
45
50
|
/**
|
|
46
51
|
* How a sibling chart's broadcast cursor key resolves against this chart's points. Default
|
|
47
52
|
* `'nearest'`. Pass `'leading'` when `getX` returns a bucket's leading edge (a weekly series
|
|
@@ -60,6 +65,9 @@ export type MultiLineProps<T> = {
|
|
|
60
65
|
ariaLabel?: string
|
|
61
66
|
/** Forwarded to `CartesianChart` — see `ChartPending`'s JSDoc for the three-state rationale. */
|
|
62
67
|
isPending?: boolean
|
|
68
|
+
/** The three "nothing to draw" states in one prop — pending → error → empty. See
|
|
69
|
+
* `ChartState`; `isPending` stays a supported alias for `state={{ pending: true }}`. */
|
|
70
|
+
state?: ChartState
|
|
63
71
|
}
|
|
64
72
|
|
|
65
73
|
const STAR_R = 6
|
|
@@ -76,16 +84,17 @@ function starPath(cx: number, cy: number, r: number): string {
|
|
|
76
84
|
return `M${pts.join('L')}Z`
|
|
77
85
|
}
|
|
78
86
|
|
|
79
|
-
type LinePt<T> = { __d: T; __y: number }
|
|
87
|
+
type LinePt<T> = { __d: T; __y: number | null }
|
|
80
88
|
|
|
81
|
-
/**
|
|
89
|
+
/**
|
|
90
|
+
* Every row, in x order, with `__y: null` where the series reports no value. The null row STAYS in
|
|
91
|
+
* the array: `ChartSeries.getValue` documents null as a line GAP, and dropping the row instead
|
|
92
|
+
* makes `LinePath` join straight across a coverage hole — drawing a measurement that was never
|
|
93
|
+
* taken. `defined` on the consuming shape is what turns it back into a gap. Reused by the lines
|
|
94
|
+
* and the markers.
|
|
95
|
+
*/
|
|
82
96
|
function seriesPoints<T>(series: ChartSeries<T>, data: readonly T[]): LinePt<T>[] {
|
|
83
|
-
|
|
84
|
-
for (const d of data) {
|
|
85
|
-
const v = series.getValue(d)
|
|
86
|
-
if (v !== null && v !== undefined && !Number.isNaN(v)) pts.push({ __d: d, __y: v })
|
|
87
|
-
}
|
|
88
|
-
return pts
|
|
97
|
+
return data.map((d) => ({ __d: d, __y: toPlotPoint(series.getValue(d)) }))
|
|
89
98
|
}
|
|
90
99
|
|
|
91
100
|
/**
|
|
@@ -99,9 +108,14 @@ function seriesPoints<T>(series: ChartSeries<T>, data: readonly T[]): LinePt<T>[
|
|
|
99
108
|
* plotted lines, the legend, and the tooltip rows.
|
|
100
109
|
*
|
|
101
110
|
* X-axis is built from the full `data` array so the calendar is preserved even when a series
|
|
102
|
-
* has nulls; each series line
|
|
111
|
+
* has nulls; each series line BREAKS at a null point, leaving a real gap rather than interpolating
|
|
112
|
+
* across it.
|
|
103
113
|
*/
|
|
104
114
|
function MultiLineInner<T>(props: MultiLineProps<T>) {
|
|
115
|
+
// F-ERR-1: name the component and the prop. Without this a missing accessor surfaces
|
|
116
|
+
// from inside visx as `undefined is not a function`, which `BasaltErrorBoundary`
|
|
117
|
+
// swallows into a blank subtree that names nothing.
|
|
118
|
+
assertRequiredProps('MultiLine', props, ['data', 'getX', 'series'])
|
|
105
119
|
const {
|
|
106
120
|
data,
|
|
107
121
|
chartId,
|
|
@@ -115,6 +129,7 @@ function MultiLineInner<T>(props: MultiLineProps<T>) {
|
|
|
115
129
|
xTicks,
|
|
116
130
|
xTickValues,
|
|
117
131
|
formatX,
|
|
132
|
+
xLabelRotate,
|
|
118
133
|
cursorResolution,
|
|
119
134
|
tooltip,
|
|
120
135
|
markerShape = 'circle',
|
|
@@ -122,6 +137,9 @@ function MultiLineInner<T>(props: MultiLineProps<T>) {
|
|
|
122
137
|
legend,
|
|
123
138
|
ariaLabel,
|
|
124
139
|
isPending,
|
|
140
|
+
state,
|
|
141
|
+
className,
|
|
142
|
+
style,
|
|
125
143
|
} = props
|
|
126
144
|
|
|
127
145
|
// Default line overlays to the redesign's 1.9px stroke (docs/DESIGN-SPEC.md §5) — applied once
|
|
@@ -145,12 +163,16 @@ function MultiLineInner<T>(props: MultiLineProps<T>) {
|
|
|
145
163
|
{...(xTicks !== undefined && { xTicks })}
|
|
146
164
|
{...(xTickValues !== undefined && { xTickValues })}
|
|
147
165
|
{...(formatX !== undefined && { formatX })}
|
|
166
|
+
{...(xLabelRotate !== undefined && { xLabelRotate })}
|
|
148
167
|
{...(cursorResolution !== undefined && { cursorResolution })}
|
|
149
168
|
{...(tooltip !== undefined && { tooltip })}
|
|
150
169
|
{...(height !== undefined && { height })}
|
|
151
170
|
{...(legend !== undefined && { legend })}
|
|
152
171
|
{...(ariaLabel !== undefined && { ariaLabel })}
|
|
153
172
|
{...(isPending !== undefined && { isPending })}
|
|
173
|
+
{...(state !== undefined && { state })}
|
|
174
|
+
{...(className !== undefined && { className })}
|
|
175
|
+
{...(style !== undefined && { style })}
|
|
154
176
|
>
|
|
155
177
|
{(ctx: PlotContext<T>) => <MultiLineMarks getX={getX} markerShape={markerShape} ctx={ctx} />}
|
|
156
178
|
</CartesianChart>
|
|
@@ -209,10 +231,16 @@ function MultiLineMarks<T>({
|
|
|
209
231
|
const op = dimOpacity(s)
|
|
210
232
|
const markers: ReactNode[] = []
|
|
211
233
|
for (const p of pointsBySeries.get(s.key) ?? []) {
|
|
234
|
+
// A null point is an absence: no dot, no marker — the same claim the line's `defined`
|
|
235
|
+
// makes by breaking there.
|
|
236
|
+
if (p.__y === null) continue
|
|
212
237
|
const m = getMarker(p.__d)
|
|
213
238
|
if (m === null) continue
|
|
214
239
|
const cx = xScale(getX(p.__d)) ?? 0
|
|
215
240
|
const cy = scale(p.__y)
|
|
241
|
+
// A non-positive value on a log axis (or any input a scale can't place) maps to NaN —
|
|
242
|
+
// skip the marker rather than paint one at `cy="NaN"`.
|
|
243
|
+
if (!Number.isFinite(cy)) continue
|
|
216
244
|
const color = m.color ?? s.color
|
|
217
245
|
const r = m.r ?? (markerShape === 'star' ? STAR_R : VX.dotR)
|
|
218
246
|
const ring = m.ring ?? true
|
|
@@ -247,20 +275,31 @@ function MultiLineMarks<T>({
|
|
|
247
275
|
return (
|
|
248
276
|
<>
|
|
249
277
|
{visible.map((s) => {
|
|
250
|
-
const
|
|
251
|
-
|
|
278
|
+
const pts = pointsBySeries.get(s.key) ?? []
|
|
279
|
+
// A series that measured nothing (the legend-only `getValue: () => null` idiom) draws no
|
|
280
|
+
// path at all, rather than an empty one.
|
|
281
|
+
if (!pts.some((p) => p.__y !== null)) return null
|
|
252
282
|
const scale = scaleFor(s)
|
|
253
283
|
return (
|
|
254
284
|
<LinePath<LinePt<T>>
|
|
255
285
|
key={`line-${s.key}`}
|
|
256
|
-
data={
|
|
286
|
+
data={pts}
|
|
257
287
|
x={(p) => xScale(getX(p.__d)) ?? 0}
|
|
258
|
-
|
|
288
|
+
// Never reached with a null `__y`: d3's line generator calls the position accessors
|
|
289
|
+
// only for points `defined` accepted. The `NaN` floor is a type-level one, and it can
|
|
290
|
+
// never paint at zero the way a `?? 0` would.
|
|
291
|
+
y={(p) => scale(p.__y ?? NaN)}
|
|
292
|
+
// Two absences, one guard. A null value is a documented GAP (`ChartSeries.getValue`),
|
|
293
|
+
// and a non-positive value on a log axis maps to NaN via `scale(p.__y)` — `defined`
|
|
294
|
+
// breaks the line at both instead of interpolating across the hole (a coverage hole
|
|
295
|
+
// reading as a measured straight line) or emitting a NaN path command, which per SVG
|
|
296
|
+
// error handling blanks the ENTIRE polyline from that point on.
|
|
297
|
+
defined={definedOn(scale)}
|
|
259
298
|
stroke={s.color}
|
|
260
299
|
strokeWidth={s.strokeWidth ?? LINE_OVERLAY_STROKE_WIDTH}
|
|
261
300
|
strokeDasharray={s.dash === 'dashed' ? VX.dashArray : undefined}
|
|
262
301
|
strokeOpacity={dimOpacity(s) * (s.strokeOpacity ?? 1)}
|
|
263
|
-
curve={
|
|
302
|
+
curve={curveFor(s.curve)}
|
|
264
303
|
/>
|
|
265
304
|
)
|
|
266
305
|
})}
|
|
@@ -274,4 +313,8 @@ function MultiLineMarks<T>({
|
|
|
274
313
|
* Hand-memoized: React Compiler does not process the shipped dist, so the hot MultiLine kind is
|
|
275
314
|
* wrapped in `React.memo` to retain the auto-memoization it had as source (parity with ZonedLine).
|
|
276
315
|
*/
|
|
277
|
-
|
|
316
|
+
const MultiLineMemo = memo(MultiLineInner)
|
|
317
|
+
// Without it every kind reads as `Memo` in React DevTools (audit A16) — a profiler flame
|
|
318
|
+
// graph of nine identically-named nodes names nothing.
|
|
319
|
+
MultiLineMemo.displayName = 'MultiLine'
|
|
320
|
+
export const MultiLine = MultiLineMemo as typeof MultiLineInner
|
|
@@ -1,12 +1,16 @@
|
|
|
1
|
-
import { curveMonotoneX } from '@visx/curve'
|
|
2
1
|
import { AreaStack } from '@visx/shape'
|
|
3
2
|
import { memo, useCallback, useMemo } from 'react'
|
|
3
|
+
import { assertRequiredProps } from '../../common/validate'
|
|
4
|
+
import type { BasaltProps } from '../../common/props'
|
|
4
5
|
import type { CursorResolution } from '../cursor/resolve'
|
|
5
6
|
import { CartesianChart } from '../primitives/CartesianChart'
|
|
6
7
|
import type { AxisConfig, PlotContext } from '../primitives/CartesianChart'
|
|
8
|
+
import type { ChartState } from '../primitives/ChartPending'
|
|
9
|
+
import { curveFor } from '../series'
|
|
7
10
|
import type { ChartLegendConfig, ChartSeries } from '../series'
|
|
11
|
+
import { isDev } from '../../utils/is-dev'
|
|
8
12
|
|
|
9
|
-
export type StackedAreaProps<T> = {
|
|
13
|
+
export type StackedAreaProps<T> = BasaltProps & {
|
|
10
14
|
data: T[]
|
|
11
15
|
/** Fixed height in pixels, forwarded to `CartesianChart`. Default 240. */
|
|
12
16
|
height?: number
|
|
@@ -18,8 +22,9 @@ export type StackedAreaProps<T> = {
|
|
|
18
22
|
/** Axis config for ticks/format/grid. `domain` defaults to the summed per-point stack total
|
|
19
23
|
* (padded ×1.1, or `autoMaxFloor` if higher) rather than a per-series max — the seam a stacked
|
|
20
24
|
* chart needs, since the plotted quantity is the cumulative band top, not any one series' own
|
|
21
|
-
* value. Pass a fixed tuple or your own function to override.
|
|
22
|
-
|
|
25
|
+
* value. Pass a fixed tuple or your own function to override. No `scale` — stacking sums bar
|
|
26
|
+
* heights directly and a log axis has no additive zero to sum from. */
|
|
27
|
+
y?: Omit<AxisConfig<T>, 'scale'>
|
|
23
28
|
/** Exact number of x ticks. Default: as many as fit. Ignored when `xTickValues` is set. */
|
|
24
29
|
xTicks?: number
|
|
25
30
|
/** Which domain keys get a tick, from the full key list and the resolved plot width. Takes
|
|
@@ -28,6 +33,9 @@ export type StackedAreaProps<T> = {
|
|
|
28
33
|
xTickValues?: (keys: readonly string[], xMax: number) => readonly string[]
|
|
29
34
|
/** X tick label formatter. Default `fmtAxisDate` (DD.MM). */
|
|
30
35
|
formatX?: (key: string) => string
|
|
36
|
+
/** Tilt the x tick labels 45° or 90°, or `0` to opt out of the phone tier's auto-rotation —
|
|
37
|
+
* see `CartesianChartProps.xLabelRotate`. */
|
|
38
|
+
xLabelRotate?: 0 | 45 | 90
|
|
31
39
|
/**
|
|
32
40
|
* How a sibling chart's broadcast cursor key resolves against this chart's points. Default
|
|
33
41
|
* `'nearest'`. Pass `'leading'` when `getX` returns a bucket's leading edge (a weekly series
|
|
@@ -41,12 +49,32 @@ export type StackedAreaProps<T> = {
|
|
|
41
49
|
ariaLabel?: string
|
|
42
50
|
/** Forwarded to `CartesianChart` — see `ChartPending`'s JSDoc for the three-state rationale. */
|
|
43
51
|
isPending?: boolean
|
|
52
|
+
/** The three "nothing to draw" states in one prop — pending → error → empty. See
|
|
53
|
+
* `ChartState`; `isPending` stays a supported alias for `state={{ pending: true }}`. */
|
|
54
|
+
state?: ChartState
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* A stack is only as dense as its sparsest band. A band's value is only meaningful as part of a
|
|
59
|
+
* cumulative total, so a row where ANY visible band reports `null` has no total — every band gaps
|
|
60
|
+
* across it. Reading the missing band as `0` instead would be a positive claim the quantity was
|
|
61
|
+
* measured at zero, which is exactly the absence-as-data lie `ChartSeries.getValue`'s null
|
|
62
|
+
* contract exists to prevent.
|
|
63
|
+
*/
|
|
64
|
+
function rowIsDense<T>(d: T, bands: readonly ChartSeries<T>[]): boolean {
|
|
65
|
+
return bands.every((s) => s.getValue(d) !== null)
|
|
44
66
|
}
|
|
45
67
|
|
|
46
68
|
/**
|
|
47
69
|
* Multi-series stacked-area chart with an optional derived legend (default on) and legend-hover
|
|
48
70
|
* dimming. Each band's fillOpacity is dimmed when a different key is highlighted via the legend.
|
|
49
71
|
*
|
|
72
|
+
* **A stack is only as dense as its sparsest series.** A row where any VISIBLE band is null is
|
|
73
|
+
* dropped from the stack entirely — the bands break across that x, the crosshair reports no
|
|
74
|
+
* cumulative value there, and the axis domain ignores it. Toggling the sparse band off in the
|
|
75
|
+
* legend closes the gap, because density is measured against the visible set. A chart that needs
|
|
76
|
+
* a null band to read as zero must say so in its own `getValue`.
|
|
77
|
+
*
|
|
50
78
|
* Composes `CartesianChart` (`docs/CHARTS-SPEC.md` §2) — margin, scale, grid, axes, cursor, and
|
|
51
79
|
* tooltip are the primitive's job. This file draws only the `AreaStack` bands.
|
|
52
80
|
*
|
|
@@ -57,6 +85,10 @@ export type StackedAreaProps<T> = {
|
|
|
57
85
|
* to restore the original bottom-to-top stacking order for `AreaStack`'s `keys`.
|
|
58
86
|
*/
|
|
59
87
|
function StackedAreaInner<T>(props: StackedAreaProps<T>) {
|
|
88
|
+
// F-ERR-1: name the component and the prop. Without this a missing accessor surfaces
|
|
89
|
+
// from inside visx as `undefined is not a function`, which `BasaltErrorBoundary`
|
|
90
|
+
// swallows into a blank subtree that names nothing.
|
|
91
|
+
assertRequiredProps('StackedArea', props, ['data', 'getX', 'series'])
|
|
60
92
|
const {
|
|
61
93
|
data,
|
|
62
94
|
chartId,
|
|
@@ -66,13 +98,26 @@ function StackedAreaInner<T>(props: StackedAreaProps<T>) {
|
|
|
66
98
|
xTicks,
|
|
67
99
|
xTickValues,
|
|
68
100
|
formatX,
|
|
101
|
+
xLabelRotate,
|
|
69
102
|
cursorResolution,
|
|
70
103
|
height,
|
|
71
104
|
legend,
|
|
72
105
|
ariaLabel,
|
|
73
106
|
isPending,
|
|
107
|
+
state,
|
|
108
|
+
className,
|
|
109
|
+
style,
|
|
74
110
|
} = props
|
|
75
111
|
|
|
112
|
+
// The stack sums band heights via `getValue` totals directly — a log axis has no additive zero
|
|
113
|
+
// to sum from (`docs/CHARTS-SPEC.md`'s null-gap + log contract, mirrored from `Bars`' own guard).
|
|
114
|
+
if (isDev() && (y as { scale?: string } | undefined)?.scale === 'log') {
|
|
115
|
+
throw new Error(
|
|
116
|
+
'StackedArea: cannot use a log axis (y.scale: "log") — the stack sums band heights, ' +
|
|
117
|
+
'and a log axis has no additive zero to sum from.',
|
|
118
|
+
)
|
|
119
|
+
}
|
|
120
|
+
|
|
76
121
|
// The plotted quantity is the CUMULATIVE stack top, not any one series' value — the built-in
|
|
77
122
|
// 'auto' domain (per-series max) would clip a multi-band stack. Skipped when the caller already
|
|
78
123
|
// supplies a fixed tuple or their own domain function.
|
|
@@ -87,6 +132,8 @@ function StackedAreaInner<T>(props: StackedAreaProps<T>) {
|
|
|
87
132
|
domain: (rows: readonly T[], visible: readonly ChartSeries<T>[]) => {
|
|
88
133
|
let maxTotal = 0
|
|
89
134
|
for (const d of rows) {
|
|
135
|
+
// A sparse row is not drawn, so it cannot set the axis top either.
|
|
136
|
+
if (!rowIsDense(d, visible)) continue
|
|
90
137
|
let total = 0
|
|
91
138
|
for (const s of visible) total += s.getValue(d) ?? 0
|
|
92
139
|
if (total > maxTotal) maxTotal = total
|
|
@@ -100,6 +147,10 @@ function StackedAreaInner<T>(props: StackedAreaProps<T>) {
|
|
|
100
147
|
// tracking — not at the band's own raw value, which sits somewhere inside the fill.
|
|
101
148
|
const stackedCursorValue = useCallback(
|
|
102
149
|
(d: T, s: ChartSeries<T>, visible: readonly ChartSeries<T>[]): number | null => {
|
|
150
|
+
// No total on a sparse row — the bands gap there, so a dot would sit on nothing. The
|
|
151
|
+
// per-band tooltip rows keep skipping their own nulls (`deriveTooltipRows`), so a row the
|
|
152
|
+
// stack cannot draw never contributes a value anywhere.
|
|
153
|
+
if (!rowIsDense(d, visible)) return null
|
|
103
154
|
let total = 0
|
|
104
155
|
// `visible` arrives top-to-bottom (the `series.toReversed()` handed to the primitive);
|
|
105
156
|
// stacking accumulates bottom-up.
|
|
@@ -128,11 +179,15 @@ function StackedAreaInner<T>(props: StackedAreaProps<T>) {
|
|
|
128
179
|
{...(xTicks !== undefined && { xTicks })}
|
|
129
180
|
{...(xTickValues !== undefined && { xTickValues })}
|
|
130
181
|
{...(formatX !== undefined && { formatX })}
|
|
182
|
+
{...(xLabelRotate !== undefined && { xLabelRotate })}
|
|
131
183
|
{...(cursorResolution !== undefined && { cursorResolution })}
|
|
132
184
|
{...(height !== undefined && { height })}
|
|
133
185
|
{...(legend !== undefined && { legend })}
|
|
134
186
|
{...(ariaLabel !== undefined && { ariaLabel })}
|
|
135
187
|
{...(isPending !== undefined && { isPending })}
|
|
188
|
+
{...(state !== undefined && { state })}
|
|
189
|
+
{...(className !== undefined && { className })}
|
|
190
|
+
{...(style !== undefined && { style })}
|
|
136
191
|
>
|
|
137
192
|
{(ctx) => <StackedAreaMarks getX={getX} ctx={ctx} />}
|
|
138
193
|
</CartesianChart>
|
|
@@ -159,6 +214,14 @@ function StackedAreaMarks<T>({ getX, ctx }: { getX: (d: T) => string; ctx: PlotC
|
|
|
159
214
|
// `AreaStack` wants a mutable array; `ctx.data` is readonly. Copy once per data change.
|
|
160
215
|
const rows = useMemo(() => [...ctx.data], [ctx.data])
|
|
161
216
|
|
|
217
|
+
// `AreaStack` draws every band from ONE curve — the bands share their boundaries, so two curves
|
|
218
|
+
// would leave gaps and overlaps between them. `visible` is in `reversedSeries` order (top band
|
|
219
|
+
// first), so this resolves to the TOPMOST VISIBLE band that declares a `curve` — the last such
|
|
220
|
+
// entry in the caller's own `series` array. A band declaring none is skipped rather than read as
|
|
221
|
+
// the monotone default, and a HIDDEN one is never consulted, so a legend toggle can hand the
|
|
222
|
+
// stack to the next declarer down. `series.curve.test.tsx` pins all four halves of that.
|
|
223
|
+
const curve = curveFor(visible.find((s) => s.curve !== undefined)?.curve)
|
|
224
|
+
|
|
162
225
|
return (
|
|
163
226
|
<AreaStack<T, string>
|
|
164
227
|
data={rows}
|
|
@@ -166,8 +229,12 @@ function StackedAreaMarks<T>({ getX, ctx }: { getX: (d: T) => string; ctx: PlotC
|
|
|
166
229
|
x={(d) => xScale(getX(d.data)) ?? 0}
|
|
167
230
|
y0={(d) => yScale(d[0]) ?? 0}
|
|
168
231
|
y1={(d) => yScale(d[1]) ?? 0}
|
|
232
|
+
// d3's stack layout needs a number per cell, so a null still enters the layout as 0 — but
|
|
233
|
+
// `defined` keeps that cell out of every band's PATH, so the zero is never drawn. Without it
|
|
234
|
+
// a missing band reads as a measured zero and the bands above it slide down onto it.
|
|
169
235
|
value={(d, key) => seriesByKey.get(key)?.getValue(d) ?? 0}
|
|
170
|
-
|
|
236
|
+
defined={(d) => rowIsDense(d.data, visible)}
|
|
237
|
+
curve={curve}
|
|
171
238
|
>
|
|
172
239
|
{({ stacks, path }) =>
|
|
173
240
|
stacks.map((stack) => (
|
|
@@ -189,4 +256,8 @@ function StackedAreaMarks<T>({ getX, ctx }: { getX: (d: T) => string; ctx: PlotC
|
|
|
189
256
|
* hot stacked-area kind in `React.memo` to retain the auto-memoization it had as source
|
|
190
257
|
* (parity with ZonedLine / Bars / MultiLine).
|
|
191
258
|
*/
|
|
192
|
-
|
|
259
|
+
const StackedAreaMemo = memo(StackedAreaInner)
|
|
260
|
+
// Without it every kind reads as `Memo` in React DevTools (audit A16) — a profiler flame
|
|
261
|
+
// graph of nine identically-named nodes names nothing.
|
|
262
|
+
StackedAreaMemo.displayName = 'StackedArea'
|
|
263
|
+
export const StackedArea = StackedAreaMemo as typeof StackedAreaInner
|