basalt-ui 1.27.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 +59 -0
- package/MIGRATING.md +613 -20
- package/README.md +33 -3
- package/agent/rules/basalt-batteries.md +25 -10
- package/agent/rules/basalt-controls.md +56 -31
- package/agent/rules/basalt-mantine.md +17 -6
- package/agent/rules/basalt-tokens.md +1 -1
- package/configs/oxlint-plugin.js +1056 -28
- package/configs/oxlint-plugin.test.ts +1066 -0
- package/configs/oxlint.json +7 -0
- 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 +3 -2
- package/dist/controls/enum-filter.d.ts.map +1 -1
- package/dist/controls/enum-filter.js +28 -13
- package/dist/controls/filter-context.d.ts +8 -4
- 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 +2 -0
- package/dist/controls/index.d.ts.map +1 -1
- package/dist/controls/index.js +4 -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 +122 -20
- package/dist/controls/number-filter.d.ts +7 -5
- package/dist/controls/number-filter.d.ts.map +1 -1
- package/dist/controls/number-filter.js +40 -11
- 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 +2 -1
- package/dist/controls/range-filter.d.ts.map +1 -1
- package/dist/controls/range-filter.js +57 -35
- 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 +25 -10
- 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 +28 -11
- 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 +7 -1
- 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 +44 -38
- package/dist/dashboard/stat-card.d.ts.map +1 -1
- package/dist/dashboard/stat-card.js +55 -42
- package/dist/dashboard/stat-card.module.css +46 -31
- package/dist/dashboard/stat-card.module.css.d.ts +1 -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 +384 -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.map +1 -1
- package/dist/guard/index.js +26 -6
- 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/search-store.d.ts.map +1 -1
- package/dist/router-tanstack/search-store.js +1 -1
- 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 +23 -3
- package/dist/state/fields.d.ts.map +1 -1
- package/dist/state/fields.js +13 -2
- 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.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 +42 -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 +69 -4
- package/dist/widget-header/widget-header.d.ts.map +1 -1
- package/dist/widget-header/widget-header.js +42 -27
- package/dist/widget-header/widget-header.module.css +72 -7
- 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 +32 -16
- package/src/controls/filter-context.tsx +14 -6
- 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 +7 -0
- package/src/controls/multi-select-filter.tsx +177 -27
- package/src/controls/number-filter.tsx +61 -23
- 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 +76 -39
- package/src/controls/search-filter.tsx +30 -12
- 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 +36 -16
- 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 +13 -1
- package/src/dashboard/query-state.tsx +154 -84
- package/src/dashboard/settings-section.tsx +87 -31
- package/src/dashboard/stat-card.module.css +46 -31
- package/src/dashboard/stat-card.module.css.d.ts +1 -0
- package/src/dashboard/stat-card.tsx +185 -127
- 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 +919 -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 +73 -18
- package/src/index.ts +74 -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 +1 -0
- package/src/router-tanstack/search-store.ts +3 -10
- 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 +43 -10
- package/src/state/persisted-or-local.ts +50 -0
- package/src/state.ts +0 -9
- package/src/surfaces.ts +42 -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 +72 -7
- package/src/widget-header/widget-header.tsx +150 -71
- 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/range-filter.type-guard.test.d.ts +0 -2
- package/dist/controls/range-filter.type-guard.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/state/persisted.test.d.ts +0 -2
- package/dist/state/persisted.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 -1053
- 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 -137
- package/src/controls/range-filter.type-guard.test.tsx +0 -122
- 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 -385
- package/src/data/data-table.test.tsx +0 -434
- package/src/guard/check-source.test.ts +0 -3388
- package/src/guard/grace.test.ts +0 -158
- 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 -882
- package/src/router-tanstack/search-store.test.ts +0 -578
- 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 -512
- package/src/state/persisted.test.ts +0 -91
- 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
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Duplicate-Notifications-mount guard (F15) — a shared module-level counter, not a per-caller ref,
|
|
3
|
+
* because the whole point is detecting a SECOND, unrelated caller: `<BasaltOverlays notifications />`
|
|
4
|
+
* (`commands/overlays-mount.tsx`) and `<BasaltNotifications />` (`./overlay.tsx`) both render
|
|
5
|
+
* Mantine's `<Notifications />` and neither can see the other mount. `overlays-mount.tsx`'s own
|
|
6
|
+
* JSDoc has warned against combining them since it shipped ("do NOT mount both … (double-mount of
|
|
7
|
+
* `<Notifications />`)") with nothing enforcing it — this is that enforcement, finally.
|
|
8
|
+
*
|
|
9
|
+
* Lives here (`./notifications`), not `./commands`, so `commands` is the one importing a shared util
|
|
10
|
+
* rather than the reverse — `./notifications` never depends on `./commands`. Zero `@mantine/*`
|
|
11
|
+
* import, so pulling it into `commands` does not eagerly load `@mantine/notifications`.
|
|
12
|
+
*
|
|
13
|
+
* Not exported from the `./notifications` public barrel (`index.ts`) — internal wiring only, same
|
|
14
|
+
* as `provider/lab-theme.ts`.
|
|
15
|
+
*/
|
|
16
|
+
import { useEffect } from 'react'
|
|
17
|
+
import { isDev } from '../utils/is-dev'
|
|
18
|
+
|
|
19
|
+
let mountedNotificationsCount = 0
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Call from any component that renders a `<Notifications />` overlay. Warns in dev when a second
|
|
23
|
+
* caller is mounted at the same time. Not a false positive under React 18 StrictMode's double-invoke
|
|
24
|
+
* (that mounts/unmounts the SAME instance in sequence, so the count returns to 0 before a genuine
|
|
25
|
+
* second instance could exist).
|
|
26
|
+
*/
|
|
27
|
+
export function useNotificationsMountGuard(): void {
|
|
28
|
+
useEffect(() => {
|
|
29
|
+
mountedNotificationsCount++
|
|
30
|
+
if (mountedNotificationsCount > 1 && isDev()) {
|
|
31
|
+
console.warn(
|
|
32
|
+
'[basalt] more than one Notifications overlay is mounted at once — mount ONE of ' +
|
|
33
|
+
'<BasaltOverlays notifications /> or <BasaltNotifications />, never both (they both ' +
|
|
34
|
+
"render Mantine's <Notifications />, so toasts would double-fire).",
|
|
35
|
+
)
|
|
36
|
+
}
|
|
37
|
+
return () => {
|
|
38
|
+
mountedNotificationsCount--
|
|
39
|
+
}
|
|
40
|
+
}, [])
|
|
41
|
+
}
|
|
@@ -7,7 +7,8 @@
|
|
|
7
7
|
* 2. dedupKey window — module-level Map prevents duplicate keys within 1500ms
|
|
8
8
|
*
|
|
9
9
|
* For loading→success/error transitions use notifyPromise — it calls notifications.update
|
|
10
|
-
* (never show()) so the loading state is replaced correctly.
|
|
10
|
+
* (never show()) so the loading state is replaced correctly. For an optimistic mutation with a
|
|
11
|
+
* grace period use notifyUndo — one number is both the Undo affordance and the commit delay.
|
|
11
12
|
*
|
|
12
13
|
* @example
|
|
13
14
|
* notify({ intent: 'success', message: 'Saved' })
|
|
@@ -15,6 +16,7 @@
|
|
|
15
16
|
* notifyPromise(apiCall(), { loading: 'Saving…', success: 'Saved', error: 'Failed' })
|
|
16
17
|
*/
|
|
17
18
|
import type { ReactNode } from 'react'
|
|
19
|
+
import { Button, Group, Text } from '@mantine/core'
|
|
18
20
|
import { notifications } from '@mantine/notifications'
|
|
19
21
|
import { add } from './store'
|
|
20
22
|
import type { NotificationIntent, NotificationActionRef } from './store'
|
|
@@ -85,6 +87,12 @@ export type NotifyOptions = {
|
|
|
85
87
|
* only when calling `notify()` for an action registered in the notifications registry.
|
|
86
88
|
*/
|
|
87
89
|
action?: NotificationActionRef
|
|
90
|
+
/**
|
|
91
|
+
* What the persisted history records instead of `String(message)`. Only needed when `message` is
|
|
92
|
+
* a composed ReactNode the store cannot stringify — `String(<Group/>)` is `[object Object]`.
|
|
93
|
+
* `notifyUndo` passes its plain text here because its toast body carries the Undo button.
|
|
94
|
+
*/
|
|
95
|
+
historyMessage?: string
|
|
88
96
|
}
|
|
89
97
|
|
|
90
98
|
// ── notify ────────────────────────────────────────────────────────────────────
|
|
@@ -98,7 +106,17 @@ export type NotifyOptions = {
|
|
|
98
106
|
* const id = notify({ intent: 'error', message: <b>Failed</b>, autoClose: false })
|
|
99
107
|
*/
|
|
100
108
|
export function notify(opts: NotifyOptions): string {
|
|
101
|
-
const {
|
|
109
|
+
const {
|
|
110
|
+
intent = 'info',
|
|
111
|
+
message,
|
|
112
|
+
title,
|
|
113
|
+
icon,
|
|
114
|
+
autoClose,
|
|
115
|
+
id,
|
|
116
|
+
dedupKey,
|
|
117
|
+
action,
|
|
118
|
+
historyMessage,
|
|
119
|
+
} = opts
|
|
102
120
|
|
|
103
121
|
// Two-layer dedup: dedupKey window guard
|
|
104
122
|
if (dedupKey !== undefined && isDuplicateKey(dedupKey)) return id ?? nextId()
|
|
@@ -123,7 +141,7 @@ export function notify(opts: NotifyOptions): string {
|
|
|
123
141
|
id: resolvedId,
|
|
124
142
|
intent,
|
|
125
143
|
...(title !== undefined && { title: String(title) }),
|
|
126
|
-
message: String(message),
|
|
144
|
+
message: historyMessage ?? String(message),
|
|
127
145
|
createdAt: Date.now(),
|
|
128
146
|
...(action !== undefined && { action }),
|
|
129
147
|
})
|
|
@@ -186,6 +204,107 @@ export function notifyInfo(
|
|
|
186
204
|
return notify({ ...opts, intent: 'info', message })
|
|
187
205
|
}
|
|
188
206
|
|
|
207
|
+
// ── notifyUndo ────────────────────────────────────────────────────────────────
|
|
208
|
+
|
|
209
|
+
/** Default undo window (ms) — the toast's autoClose and the grace period are the same number. */
|
|
210
|
+
const UNDO_WINDOW_MS = 6000
|
|
211
|
+
|
|
212
|
+
export type NotifyUndoOptions = {
|
|
213
|
+
/** The toast text, left of the Undo button. Also what the history records. */
|
|
214
|
+
message: ReactNode
|
|
215
|
+
/** Revert the optimistic change. Runs once, on click; `onExpire` then never runs. */
|
|
216
|
+
onUndo: () => void
|
|
217
|
+
/** How long the Undo button stays offered, in ms. Also the toast's autoClose. Default: 6000. */
|
|
218
|
+
window?: number
|
|
219
|
+
/**
|
|
220
|
+
* The window elapsed with no undo — the place to COMMIT the optimistic mutation. Runs at most
|
|
221
|
+
* once, and never after `onUndo`.
|
|
222
|
+
*/
|
|
223
|
+
onExpire?: () => void
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
export type NotifyUndoHandle = {
|
|
227
|
+
/** The toast id — the same id in Mantine and in the notification history. */
|
|
228
|
+
id: string
|
|
229
|
+
/**
|
|
230
|
+
* Close the toast early and settle the window NOW: `onExpire` runs (unless undo already did), so
|
|
231
|
+
* a dismissed toast can never strand an uncommitted mutation. Idempotent.
|
|
232
|
+
*/
|
|
233
|
+
dismiss: () => void
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Show a toast offering an Undo for `window` ms, then commit.
|
|
238
|
+
*
|
|
239
|
+
* The affordance and the grace period are ONE number: `autoClose === window`, so the button is on
|
|
240
|
+
* screen for exactly as long as undoing still does something. Exactly one of `onUndo` / `onExpire`
|
|
241
|
+
* runs, exactly once — clicking Undo cancels the timer, and letting it elapse (or calling
|
|
242
|
+
* `dismiss()`) commits.
|
|
243
|
+
*
|
|
244
|
+
* Built on `notify`, so the toast is recorded to the notification history like any other.
|
|
245
|
+
*
|
|
246
|
+
* @example
|
|
247
|
+
* // Optimistic delete: the row is already gone from the UI; commit when the window closes.
|
|
248
|
+
* setRows((rows) => rows.filter((r) => r.id !== id))
|
|
249
|
+
* notifyUndo({
|
|
250
|
+
* message: 'Item deleted',
|
|
251
|
+
* onUndo: () => setRows(before),
|
|
252
|
+
* onExpire: () => api.delete(id),
|
|
253
|
+
* })
|
|
254
|
+
*/
|
|
255
|
+
export function notifyUndo(opts: NotifyUndoOptions): NotifyUndoHandle {
|
|
256
|
+
const { message, onUndo, window: undoWindow = UNDO_WINDOW_MS, onExpire } = opts
|
|
257
|
+
const id = nextId()
|
|
258
|
+
|
|
259
|
+
let settled = false
|
|
260
|
+
let timer: ReturnType<typeof setTimeout> | undefined
|
|
261
|
+
|
|
262
|
+
const settle = (undone: boolean): void => {
|
|
263
|
+
if (settled) return
|
|
264
|
+
settled = true
|
|
265
|
+
if (timer !== undefined) clearTimeout(timer)
|
|
266
|
+
notifications.hide(id)
|
|
267
|
+
if (undone) onUndo()
|
|
268
|
+
else onExpire?.()
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
timer = setTimeout(() => settle(false), undoWindow)
|
|
272
|
+
|
|
273
|
+
notify({
|
|
274
|
+
intent: 'info',
|
|
275
|
+
id,
|
|
276
|
+
autoClose: undoWindow,
|
|
277
|
+
historyMessage: String(message),
|
|
278
|
+
message: (
|
|
279
|
+
<Group justify="space-between" wrap="nowrap" gap="sm">
|
|
280
|
+
<Text span size="sm">
|
|
281
|
+
{message}
|
|
282
|
+
</Text>
|
|
283
|
+
<Button variant="subtle" size="compact-xs" onClick={() => settle(true)}>
|
|
284
|
+
Undo
|
|
285
|
+
</Button>
|
|
286
|
+
</Group>
|
|
287
|
+
),
|
|
288
|
+
})
|
|
289
|
+
|
|
290
|
+
return { id, dismiss: () => settle(false) }
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
* `notifyUndo` for the common optimistic shape: the UI already changed, `undo` puts it back, and
|
|
295
|
+
* `mutate` is what actually commits when the window closes.
|
|
296
|
+
*
|
|
297
|
+
* @example
|
|
298
|
+
* notifyUndoable(() => api.delete(id), () => setRows(before), { message: 'Item deleted' })
|
|
299
|
+
*/
|
|
300
|
+
export function notifyUndoable(
|
|
301
|
+
mutate: () => void,
|
|
302
|
+
undo: () => void,
|
|
303
|
+
opts: Omit<NotifyUndoOptions, 'onUndo' | 'onExpire'>,
|
|
304
|
+
): NotifyUndoHandle {
|
|
305
|
+
return notifyUndo({ ...opts, onUndo: undo, onExpire: mutate })
|
|
306
|
+
}
|
|
307
|
+
|
|
189
308
|
// ── notifyPromise ─────────────────────────────────────────────────────────────
|
|
190
309
|
|
|
191
310
|
export type NotifyPromiseMessages = {
|
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
* )
|
|
30
30
|
*/
|
|
31
31
|
import { Notifications } from '@mantine/notifications'
|
|
32
|
+
import { useNotificationsMountGuard } from './mount-guard'
|
|
32
33
|
|
|
33
34
|
export type BasaltNotificationsProps = {
|
|
34
35
|
/** Toast position. Default: 'bottom-right'. */
|
|
@@ -60,5 +61,6 @@ export function BasaltNotifications({
|
|
|
60
61
|
autoClose = 4000,
|
|
61
62
|
limit = 5,
|
|
62
63
|
}: BasaltNotificationsProps) {
|
|
64
|
+
useNotificationsMountGuard()
|
|
63
65
|
return <Notifications position={position} autoClose={autoClose} limit={limit} />
|
|
64
66
|
}
|
|
@@ -21,6 +21,13 @@ import { useSyncExternalStore } from 'react'
|
|
|
21
21
|
|
|
22
22
|
// ── Types ─────────────────────────────────────────────────────────────────────
|
|
23
23
|
|
|
24
|
+
/**
|
|
25
|
+
* Mantine's own notification vocabulary — kept as its own type rather than aliased to
|
|
26
|
+
* `common/props.ts`'s `Tone` (`'good' | 'warn' | 'bad'`) because `@mantine/notifications` and
|
|
27
|
+
* `INTENT_COLOR`/`INTENT_ROLE` key off exactly these four strings. Roughly:
|
|
28
|
+
* `success` ~ `Tone.good`, `error`/`warning` ~ `Tone.bad`/`Tone.warn`, `info` has no `Tone`
|
|
29
|
+
* equivalent (`ToneWithNeutral`'s `'neutral'` is the nearest fit).
|
|
30
|
+
*/
|
|
24
31
|
export type NotificationIntent = 'success' | 'error' | 'warning' | 'info'
|
|
25
32
|
|
|
26
33
|
/**
|
package/src/provider/index.tsx
CHANGED
|
@@ -21,12 +21,14 @@ import { Component, useEffect, useMemo } from 'react'
|
|
|
21
21
|
import type { ErrorInfo, ReactNode } from 'react'
|
|
22
22
|
import { VxThemeProvider } from '../charts/theme'
|
|
23
23
|
import { ConnectivityProvider } from '../connectivity'
|
|
24
|
+
import type { ConnectivityProviderProps } from '../connectivity'
|
|
24
25
|
import { cssVariablesResolver } from '../theme'
|
|
25
26
|
import { useLabTheme } from './lab-theme'
|
|
26
27
|
import { buildDensityCss, buildFontsCss, buildPaletteCss, buildRadiusCss } from '../tokens'
|
|
27
28
|
import type { BuildPaletteOpts } from '../tokens'
|
|
28
29
|
import { isDefaultDeriveConfig } from '../tokens/derive'
|
|
29
30
|
import { buildPaletteData } from '../tokens/palette'
|
|
31
|
+
import { isDev } from '../utils/is-dev'
|
|
30
32
|
|
|
31
33
|
/**
|
|
32
34
|
* Where an error surfaced — drives consumer routing (a render error vs a global rejection differ).
|
|
@@ -91,18 +93,35 @@ export type BasaltProviderProps = {
|
|
|
91
93
|
* prop; its nonce mechanism is `getStyleNonce: () => string`, which flows through `...rest`.
|
|
92
94
|
*/
|
|
93
95
|
nonce?: string
|
|
94
|
-
/**
|
|
96
|
+
/**
|
|
97
|
+
* Options threaded through to the auto-mounted `ConnectivityProvider` (everything except
|
|
98
|
+
* `children`) — `sseUrl`, `healthUrl`, `healthIntervalMs`, and `override` (previously
|
|
99
|
+
* unreachable through `BasaltProvider`: the only way to reach it was a second, shadowing
|
|
100
|
+
* `ConnectivityProvider`). Takes precedence over the deprecated flattened props below when both
|
|
101
|
+
* are set.
|
|
102
|
+
*/
|
|
103
|
+
connectivity?: Omit<ConnectivityProviderProps, 'children'>
|
|
104
|
+
/**
|
|
105
|
+
* @deprecated Use `connectivity={{ sseUrl }}` instead. Still honoured when `connectivity` is
|
|
106
|
+
* unset or omits `sseUrl`; removed in 1.29.0.
|
|
107
|
+
*/
|
|
95
108
|
sseUrl?: string
|
|
96
|
-
/**
|
|
109
|
+
/**
|
|
110
|
+
* @deprecated Use `connectivity={{ healthUrl }}` instead. Still honoured when `connectivity` is
|
|
111
|
+
* unset or omits `healthUrl`; removed in 1.29.0.
|
|
112
|
+
*/
|
|
97
113
|
healthUrl?: string
|
|
98
|
-
/**
|
|
114
|
+
/**
|
|
115
|
+
* @deprecated Use `connectivity={{ healthIntervalMs }}` instead. Still honoured when
|
|
116
|
+
* `connectivity` is unset or omits `healthIntervalMs`; removed in 1.29.0.
|
|
117
|
+
*/
|
|
99
118
|
healthIntervalMs?: number
|
|
100
|
-
} & Omit<MantineProviderProps, 'children' | 'theme' | 'defaultColorScheme'>
|
|
119
|
+
} & Omit<MantineProviderProps, 'children' | 'theme' | 'defaultColorScheme' | 'cssVariablesResolver'>
|
|
101
120
|
|
|
102
121
|
// ── Default error handler ─────────────────────────────────────────────────────────────────────────
|
|
103
122
|
|
|
104
123
|
function defaultOnError(error: unknown, ctx: BasaltErrorContext): void {
|
|
105
|
-
if (
|
|
124
|
+
if (isDev()) {
|
|
106
125
|
// eslint-disable-next-line no-console -- intentional dev-only diagnostic when no onError is supplied
|
|
107
126
|
console.error('[BasaltProvider] unhandled error', ctx.kind, error)
|
|
108
127
|
}
|
|
@@ -255,6 +274,68 @@ function BasaltBridge({
|
|
|
255
274
|
)
|
|
256
275
|
}
|
|
257
276
|
|
|
277
|
+
// ── Duplicate-mount guard (F14) ───────────────────────────────────────────────────────────────────
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* Module-level (deliberately NOT a per-instance ref, unlike `fence-block.tsx`'s warn-once gate) —
|
|
281
|
+
* the whole point is detecting a SECOND, unrelated `BasaltProvider` mounted anywhere else in the
|
|
282
|
+
* tree, which a per-instance gate could never see. Nested/duplicate providers double-mount
|
|
283
|
+
* `MantineProvider`, the palette `<style>` and `ConnectivityProvider`'s signal listeners — real
|
|
284
|
+
* misuse, not a false positive from React 18 StrictMode's double-invoke (that mounts/unmounts the
|
|
285
|
+
* SAME instance in sequence, so the count returns to 0 before a second instance could ever exist).
|
|
286
|
+
*/
|
|
287
|
+
let mountedProviderCount = 0
|
|
288
|
+
|
|
289
|
+
function useDuplicateProviderGuard(): void {
|
|
290
|
+
useEffect(() => {
|
|
291
|
+
mountedProviderCount++
|
|
292
|
+
if (mountedProviderCount > 1 && isDev()) {
|
|
293
|
+
console.warn(
|
|
294
|
+
'[basalt] BasaltProvider: more than one instance is mounted at once — nested/duplicate ' +
|
|
295
|
+
'BasaltProviders double-mount MantineProvider, the palette <style> and ' +
|
|
296
|
+
'ConnectivityProvider. Mount exactly one, at the app root.',
|
|
297
|
+
)
|
|
298
|
+
}
|
|
299
|
+
return () => {
|
|
300
|
+
mountedProviderCount--
|
|
301
|
+
}
|
|
302
|
+
}, [])
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* Resolves the `connectivity` object against the three deprecated flattened props: `connectivity`
|
|
307
|
+
* wins WHOLESALE when provided, not per-key — a partial `connectivity={{ sseUrl }}` no longer picks
|
|
308
|
+
* up a stray `healthUrl` left on the old prop, which was surprising for a mid-migration consumer who
|
|
309
|
+
* expected the new prop to fully replace the old ones once set. Warns once, dev builds only, when
|
|
310
|
+
* both are actually supplied. Exported as a pure function (same rationale as `composeInjectedCss`
|
|
311
|
+
* above) so `provider/index.test.ts` can assert the precedence without rendering a tree.
|
|
312
|
+
*/
|
|
313
|
+
export function resolveConnectivityProps(props: {
|
|
314
|
+
connectivity: Omit<ConnectivityProviderProps, 'children'> | undefined
|
|
315
|
+
sseUrl: string | undefined
|
|
316
|
+
healthUrl: string | undefined
|
|
317
|
+
healthIntervalMs: number | undefined
|
|
318
|
+
}): Omit<ConnectivityProviderProps, 'children'> {
|
|
319
|
+
if (props.connectivity !== undefined) {
|
|
320
|
+
const hasDeprecated =
|
|
321
|
+
props.sseUrl !== undefined ||
|
|
322
|
+
props.healthUrl !== undefined ||
|
|
323
|
+
props.healthIntervalMs !== undefined
|
|
324
|
+
if (hasDeprecated && isDev()) {
|
|
325
|
+
console.warn(
|
|
326
|
+
'[basalt] BasaltProvider: `connectivity` and one of `sseUrl`/`healthUrl`/`healthIntervalMs` ' +
|
|
327
|
+
'were both supplied — `connectivity` wins wholesale and the deprecated props are ignored.',
|
|
328
|
+
)
|
|
329
|
+
}
|
|
330
|
+
return props.connectivity
|
|
331
|
+
}
|
|
332
|
+
return {
|
|
333
|
+
...(props.sseUrl !== undefined ? { sseUrl: props.sseUrl } : {}),
|
|
334
|
+
...(props.healthUrl !== undefined ? { healthUrl: props.healthUrl } : {}),
|
|
335
|
+
...(props.healthIntervalMs !== undefined ? { healthIntervalMs: props.healthIntervalMs } : {}),
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
|
|
258
339
|
// ── Public provider ───────────────────────────────────────────────────────────────────────────────
|
|
259
340
|
|
|
260
341
|
export function BasaltProvider({
|
|
@@ -265,11 +346,13 @@ export function BasaltProvider({
|
|
|
265
346
|
defaultColorScheme = 'dark',
|
|
266
347
|
onError,
|
|
267
348
|
nonce,
|
|
349
|
+
connectivity,
|
|
268
350
|
sseUrl,
|
|
269
351
|
healthUrl,
|
|
270
352
|
healthIntervalMs,
|
|
271
353
|
...rest
|
|
272
354
|
}: BasaltProviderProps) {
|
|
355
|
+
useDuplicateProviderGuard()
|
|
273
356
|
const errorHandler = onError ?? defaultOnError
|
|
274
357
|
|
|
275
358
|
// `createBasaltTheme(theme)` — plus, when the theme lab's "Apply" switch is on, the delta of its
|
|
@@ -278,12 +361,23 @@ export function BasaltProvider({
|
|
|
278
361
|
// Basalt base and nothing else. See `./lab-theme.ts`.
|
|
279
362
|
const resolvedTheme = useLabTheme(theme)
|
|
280
363
|
|
|
364
|
+
const resolvedConnectivity = resolveConnectivityProps({
|
|
365
|
+
connectivity,
|
|
366
|
+
sseUrl,
|
|
367
|
+
healthUrl,
|
|
368
|
+
healthIntervalMs,
|
|
369
|
+
})
|
|
370
|
+
|
|
281
371
|
return (
|
|
372
|
+
// `...rest` spreads FIRST so a consumer's `MantineProviderProps` can never shadow the three
|
|
373
|
+
// values that follow it — `cssVariablesResolver` in particular is the resolver the package
|
|
374
|
+
// exists to install (F24); `theme`/`defaultColorScheme` are excluded from `rest`'s type too,
|
|
375
|
+
// this is belt-and-braces against a widened rest at the call site.
|
|
282
376
|
<MantineProvider
|
|
377
|
+
{...rest}
|
|
283
378
|
theme={resolvedTheme}
|
|
284
379
|
cssVariablesResolver={cssVariablesResolver}
|
|
285
380
|
defaultColorScheme={defaultColorScheme}
|
|
286
|
-
{...rest}
|
|
287
381
|
>
|
|
288
382
|
<BasaltErrorBoundary onError={errorHandler}>
|
|
289
383
|
<BasaltBridge
|
|
@@ -292,13 +386,7 @@ export function BasaltProvider({
|
|
|
292
386
|
nonce={nonce}
|
|
293
387
|
onError={errorHandler}
|
|
294
388
|
>
|
|
295
|
-
<ConnectivityProvider
|
|
296
|
-
{...(sseUrl !== undefined ? { sseUrl } : {})}
|
|
297
|
-
{...(healthUrl !== undefined ? { healthUrl } : {})}
|
|
298
|
-
{...(healthIntervalMs !== undefined ? { healthIntervalMs } : {})}
|
|
299
|
-
>
|
|
300
|
-
{children}
|
|
301
|
-
</ConnectivityProvider>
|
|
389
|
+
<ConnectivityProvider {...resolvedConnectivity}>{children}</ConnectivityProvider>
|
|
302
390
|
</BasaltBridge>
|
|
303
391
|
</BasaltErrorBoundary>
|
|
304
392
|
</MantineProvider>
|
|
@@ -44,6 +44,7 @@ import { useMemo } from 'react'
|
|
|
44
44
|
import { useDeriveControlsState, toDeriveOverride } from '../theme-lab/derive-state'
|
|
45
45
|
import type { DeriveOverride } from '../theme-lab/derive-state'
|
|
46
46
|
import { baseTheme, createBasaltTheme } from '../theme'
|
|
47
|
+
import { isDev } from '../utils/is-dev'
|
|
47
48
|
|
|
48
49
|
type Plain = Record<string, unknown>
|
|
49
50
|
|
|
@@ -135,7 +136,7 @@ export function applyLabOverride(
|
|
|
135
136
|
* through a dev server (`bun run dev`), so that is the right side of the trade — but if you ever
|
|
136
137
|
* preview the playground via `vite build && vite preview`, the sliders will be inert there.
|
|
137
138
|
*/
|
|
138
|
-
const LAB_ENABLED =
|
|
139
|
+
const LAB_ENABLED = isDev()
|
|
139
140
|
|
|
140
141
|
/**
|
|
141
142
|
* Dev build: subscribed to the lab store.
|
package/src/query/devtools.tsx
CHANGED
|
@@ -10,6 +10,7 @@ import type { ReactQueryDevtools } from '@tanstack/react-query-devtools'
|
|
|
10
10
|
const LazyDevtools = lazy(() =>
|
|
11
11
|
import('@tanstack/react-query-devtools').then((m) => ({ default: m.ReactQueryDevtools })),
|
|
12
12
|
)
|
|
13
|
+
Object.assign(LazyDevtools, { displayName: 'LazyDevtools' })
|
|
13
14
|
|
|
14
15
|
/**
|
|
15
16
|
* Lazy, production-excluded wrapper for ReactQueryDevtools. Safe to import unconditionally —
|
|
@@ -30,16 +30,9 @@
|
|
|
30
30
|
* Headless — no Mantine, no JSX. Same tier as `useBasaltNav` and `useRouterBreadcrumbs`.
|
|
31
31
|
*/
|
|
32
32
|
import { useNavigate, useSearch } from '@tanstack/react-router'
|
|
33
|
-
import { createStoreCore } from '../state'
|
|
34
|
-
import type {
|
|
35
|
-
|
|
36
|
-
FieldHandle,
|
|
37
|
-
FieldSetOptions,
|
|
38
|
-
FieldWrite,
|
|
39
|
-
SearchValues,
|
|
40
|
-
StoreEntry,
|
|
41
|
-
StoredValues,
|
|
42
|
-
} from '../state'
|
|
33
|
+
import { createStoreCore } from '../state/fields'
|
|
34
|
+
import type { FieldWrite, StoreEntry } from '../state/fields'
|
|
35
|
+
import type { AnyField, FieldHandle, FieldSetOptions, SearchValues, StoredValues } from '../state'
|
|
43
36
|
|
|
44
37
|
// ── Types ──────────────────────────────────────────────────────────────────
|
|
45
38
|
|
|
@@ -113,26 +113,31 @@ export function useNav<
|
|
|
113
113
|
// chain: the widened `AnyNavLink['search']` is `unknown`, which `LinkComponentProps` rejects.
|
|
114
114
|
// The consumer gets zero casts, which is the point.
|
|
115
115
|
//
|
|
116
|
-
// `activeOptions: { exact: true }` is what makes `resolveState` above
|
|
117
|
-
// active, and it is not a preference — a `Link` computes its own
|
|
118
|
-
// `activeOptions.exact: false`, i.e. prefix) and spreads
|
|
119
|
-
// 'aria-current': 'page' }` LAST, after `activeProps` and after
|
|
120
|
-
// (`@tanstack/react-router/dist/esm/link.js` — `...isActive &&
|
|
121
|
-
// final entry of the returned object). So `aria-current` cannot
|
|
122
|
-
// the only lever is `isActive` itself. Left at its default, the
|
|
123
|
-
// fuzzy match this resolver exists to replace, and at
|
|
124
|
-
// and the child anchor carried `aria-current="page"`
|
|
125
|
-
// of them an ancestor — verified in Chrome, and the
|
|
126
|
-
// measured as no fix at all.
|
|
116
|
+
// `activeOptions: { exact: true, includeSearch: true }` is what makes `resolveState` above
|
|
117
|
+
// the ONLY authority on active, and it is not a preference — a `Link` computes its own
|
|
118
|
+
// `isActive` (default `activeOptions.exact: false`, i.e. prefix) and spreads
|
|
119
|
+
// `{ 'data-status': 'active', 'aria-current': 'page' }` LAST, after `activeProps` and after
|
|
120
|
+
// every caller prop (`@tanstack/react-router/dist/esm/link.js` — `...isActive &&
|
|
121
|
+
// STATIC_ACTIVE_PROPS` is the final entry of the returned object). So `aria-current` cannot
|
|
122
|
+
// be overridden from outside; the only lever is `isActive` itself. Left at its default, the
|
|
123
|
+
// router re-derived the exact fuzzy match this resolver exists to replace, and at
|
|
124
|
+
// `/dashboard/sessions` BOTH the parent and the child anchor carried `aria-current="page"`
|
|
125
|
+
// even with basalt's own model marking one of them an ancestor — verified in Chrome, and the
|
|
126
|
+
// reason the first attempt at this fix measured as no fix at all. `includeSearch` already
|
|
127
|
+
// defaults to `true` upstream; naming it here is belt-and-braces so a future default change
|
|
128
|
+
// cannot silently reopen the gap.
|
|
127
129
|
//
|
|
128
130
|
// Exact here does NOT narrow basalt's own law. `resolveState` still matches fuzzily and still
|
|
129
131
|
// lights an item whose exact route is never visited; that item is simply named by the
|
|
130
132
|
// `aria-current` `app-sidebar.tsx` stamps itself, which survives because the router's spread
|
|
131
|
-
// is conditional on ITS `isActive` being true.
|
|
133
|
+
// is conditional on ITS `isActive` being true. The CSS side no longer treats `aria-current`
|
|
134
|
+
// as a style hook either (`theme/nav-link.module.css`, `shell/app-sidebar.module.css`), so
|
|
135
|
+
// `use-nav`'s single `data-active` winner is the one visual authority even if the router's
|
|
136
|
+
// own `isActive` ever disagreed.
|
|
132
137
|
const Anchor: NavAnchor = (props) =>
|
|
133
138
|
createElement(Link as ElementType, {
|
|
134
139
|
...item.link,
|
|
135
|
-
activeOptions: { exact: true },
|
|
140
|
+
activeOptions: { exact: true, includeSearch: true },
|
|
136
141
|
...props,
|
|
137
142
|
})
|
|
138
143
|
|
package/src/section/index.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { Section, type SectionProps } from './section'
|
|
1
|
+
export { Section, type SectionProps, type SectionSlot } from './section'
|
|
@@ -22,6 +22,17 @@
|
|
|
22
22
|
gap: var(--vx-space-stack-md, 0.75rem);
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
+
/*
|
|
26
|
+
* `group` tier (an aside/inspector Section): zero gap between children. `PanelRow`s already own
|
|
27
|
+
* their own vertical rhythm — `--vx-space-row-inset-y` (6px) plus the `.row + .row` hairline — so
|
|
28
|
+
* stacking the 12px `stack-md` gap ON TOP made a one-line row's pitch 55px with the hairline sitting
|
|
29
|
+
* 33/22 off-centre in it. At gap 0 the pitch is 43px and the rule is centred (Trellis ≈29, Quiver
|
|
30
|
+
* ≈33, the sidebar's own rows 33) — no negative margins, the gap simply isn't there to fight.
|
|
31
|
+
*/
|
|
32
|
+
.root[data-tier='group'] .body {
|
|
33
|
+
gap: 0;
|
|
34
|
+
}
|
|
35
|
+
|
|
25
36
|
/*
|
|
26
37
|
* `summary` — the always-visible row under the header. No border, no background (the Section owns
|
|
27
38
|
* neither); it is a plain flow row, so a consumer's `Group` of stats or one line of `Text` lands
|