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
package/MIGRATING.md
CHANGED
|
@@ -32,13 +32,457 @@ at 1.3.0, `./agent-chat` at 1.10.0.
|
|
|
32
32
|
|
|
33
33
|
## Unreleased
|
|
34
34
|
|
|
35
|
-
**Nothing removed
|
|
36
|
-
|
|
37
|
-
|
|
35
|
+
**Nothing removed, and ONE thing changed shape: `inputProps` no longer returns `key`** — a silent
|
|
36
|
+
behaviour change at every field call site, caught by the new `basalt/forms-field-key` and described
|
|
37
|
+
in its own § below. Read that one before upgrading; the rest of the minor is additive, with
|
|
38
|
+
enforcement tightened: five oxlint rules plus one guard
|
|
39
|
+
kind became `error`, and new rule ids shipped at `warn`. The store half of this minor also
|
|
38
40
|
fixed four inference and notification defects consumers hit while porting, plus two ways a fallback
|
|
39
41
|
got pinned into localStorage — see § Stores below. Every level change honours the `theme-allow`
|
|
40
42
|
grammar unchanged; only the severity of an unwaived finding moves.
|
|
41
43
|
|
|
44
|
+
**One behaviour change with a blast radius past this package: `AppShell.Main` is now the
|
|
45
|
+
scrollport, and the WINDOW no longer scrolls inside a `BasaltShell`.** Nothing was removed or
|
|
46
|
+
renamed, but four things a consumer may be doing stop working, and all four have a one-line remedy —
|
|
47
|
+
see § The shell scrollport below.
|
|
48
|
+
|
|
49
|
+
What is new, one line each — nothing here renames or removes anything:
|
|
50
|
+
|
|
51
|
+
- **`scrollParentOf` / `SCROLLPORT_ATTRIBUTE`** (`basalt-ui`) — resolve which box actually scrolls an
|
|
52
|
+
element (`null` = the document). The seam behind the shell scrollport change below.
|
|
53
|
+
- **`PageAside`** (`basalt-ui`) — the right-hand aside REGION a route claims, with the panel filter
|
|
54
|
+
surface in its body and a mobile projection into `PageBar` row 2 (`docs/ASIDE-SPEC.md`).
|
|
55
|
+
- **`PanelRow`** (`basalt-ui/controls`) — the aside's inspector/facet row: label above, control
|
|
56
|
+
below, `end` for a control that rides the label line. Every bound control renders one on the
|
|
57
|
+
`panel` surface.
|
|
58
|
+
- **`SliderControl`** (`basalt-ui/controls`) — a `field.number`-bound track for a weight or a
|
|
59
|
+
threshold. It always renders a `PanelRow`, so unlike the pill filters a `Section` body is a
|
|
60
|
+
legitimate home for it and `basalt/bound-control-outside-home` does not police it.
|
|
61
|
+
- **`MultiSelectFilter.counts` / `.max`** — per-option counts (a mono number plus a proportional
|
|
62
|
+
bar) and the panel facet cut-off before the `Show more` fold. Both optional; omitted is today's
|
|
63
|
+
rendering.
|
|
64
|
+
- **`field.number({ step })`** — the declared grain, republished on the handle. `field.number`
|
|
65
|
+
resolves `1` for an `int: true` field that declared none, so `NumberFilter` and `SliderControl`
|
|
66
|
+
cannot answer it differently.
|
|
67
|
+
- **`basalt/bound-control-outside-home`** — a NEW rule id at `warn` (grace to 1.30.0): a bound
|
|
68
|
+
basalt control written into a `Section` body or a page stack renders as a stray pill.
|
|
69
|
+
`control-outside-home` matches raw Mantine tags only, so this half of law C1 was unguarded. Homes
|
|
70
|
+
are the slot props plus the `FilterSet` / `PageAside` / `PanelRow` subtrees; the escape is
|
|
71
|
+
`theme-allow bound-control-outside-home — <why>`.
|
|
72
|
+
- **The chart phone tier** (`basalt-ui/charts`) — `resolveChartTier` / `chartTierMetrics` /
|
|
73
|
+
`useChartTier` / `useChartTierMetrics`, plus `VX.phoneChartWidth` (480). Below that MEASURED
|
|
74
|
+
container width (never a media query — a chart in a narrow grid cell on a desktop is as narrow as
|
|
75
|
+
one on a phone) a chart drops the legend and tick fonts one type step, tightens the `VX.margin`
|
|
76
|
+
FLOORS to 0.75×, shrinks the crosshair dot, narrows the tooltip 140 → 110, and caps the legend at
|
|
77
|
+
two entries with a `+N more` rollup. **This moves rendering, but only below 480px of measured
|
|
78
|
+
width** — nothing at desktop width changes. Opt back out per chart with an explicit
|
|
79
|
+
`legend.maxRows` / `margin` override. `docs/CHARTS-SPEC.md` §8.
|
|
80
|
+
- **`xLabelRotate` accepts `0`**, and left UNSET now auto-rotates to 45 at the phone tier when the
|
|
81
|
+
measured labels cannot fit three ticks side by side. `0` is the documented opt-out. Also on every
|
|
82
|
+
rotated axis, at every width: the LEFT margin now clears the rotated label's leftward projection
|
|
83
|
+
(`width × cos(angle)`), which previously ran the first label off the plot, and `smartTicks` drops
|
|
84
|
+
the grid tick before an appended final one when the two would overlap. Both are corrections to
|
|
85
|
+
§1's measured-gutter law, so a rotated or a densely-labelled axis will lay out slightly
|
|
86
|
+
differently; an explicit `margin` / `xTicks` / `xTickValues` still wins.
|
|
87
|
+
- **`SeriesStyle.curve`** (`basalt-ui/charts`) — `'monotone' | 'linear' | 'step' | 'stepAfter' |
|
|
88
|
+
'stepBefore'`, plus the `curveFor` mapper and the newly re-exported `curveStep`/`curveStepBefore`.
|
|
89
|
+
Default `'monotone'`, which is what every kind hard-coded, so an omitted `curve` moves nothing.
|
|
90
|
+
Honoured by `MultiLine`, `DualPanel`, `ZonedLine`, `StackedArea` and `BarsLine.curve`. Two of
|
|
91
|
+
those read ONE curve for a whole shape rather than one per series: `ZonedLine` takes the PRIMARY
|
|
92
|
+
series' (its band, area and line are one reading), and `StackedArea` takes the TOPMOST VISIBLE
|
|
93
|
+
band that declares one — the last such entry in your `series` array (`AreaStack`'s bands share
|
|
94
|
+
their boundaries, so two curves would leave gaps between them). A hidden band's curve is ignored
|
|
95
|
+
either way, so a legend toggle can hand a stack to the next declarer down.
|
|
96
|
+
- **Single-series legend suppressed by default** (`basalt-ui/charts`) — since commit `5e0ade1`, a
|
|
97
|
+
chart with exactly one visible series and no `legend` prop renders no legend. Pass `legend={{}}`
|
|
98
|
+
(or any explicit config) to keep it.
|
|
99
|
+
- **`Bars`' baseline is now the axis' domain floor**, not `yScale(0)` — previously a y domain that
|
|
100
|
+
did not reach 0 drew the bar off the bottom of the plot; now it stops at the domain's own floor,
|
|
101
|
+
which also makes a log y-axis usable on `Bars`. A domain that includes 0 is unchanged.
|
|
102
|
+
- **Number formatters** (`basalt-ui/charts`) — `fmtCompact`, `fmtPercent`, `fmtCurrency`, `fmtInt`
|
|
103
|
+
and the `formatters` bundle, all `Intl`-backed with an explicit `locale` defaulting to the
|
|
104
|
+
runtime's. `utils/format.ts` shipped only two DATE formatters, so every call site hand-rolled
|
|
105
|
+
`` `$${v}k` ``. **Every formatter — the two date ones included — now returns an em dash for
|
|
106
|
+
non-finite input** (`NaN`, `±Infinity`, an `Invalid Date`) instead of `Intl`'s own `NaN` / `∞`.
|
|
107
|
+
A collapsed domain therefore stops painting its arithmetic accident as a tick label.
|
|
108
|
+
- **`ChartEmpty` / `ChartError` / `state` / `resolveChartState`** (`basalt-ui/charts`) — the chart
|
|
109
|
+
layer's own three-state placeholder set. `state?: { pending?, error?, empty? }` on
|
|
110
|
+
`CartesianChart` / `ChartFrame` / every kind resolves pending → error → empty, so a consumer no
|
|
111
|
+
longer needs the Mantine-coupled `QueryState` (unreachable from `./charts`) to tell a 500 apart
|
|
112
|
+
from an empty result. **`isPending` still works and is not deprecated** — it is an alias for
|
|
113
|
+
`state={{ pending: true }}`. `ChartError` announces as `role="alert"`; `ChartPending` and
|
|
114
|
+
`ChartEmpty` as `role="status"`, so a screen reader hears the resolution and not only the failure.
|
|
115
|
+
- **`BasaltProps` on every exported chart component** — `className` and `style` now reach the root
|
|
116
|
+
element of every kind, sparkline and primitive; `ChartCard` also takes
|
|
117
|
+
`classNames={{ root, header, body }}`. Additive: a component that ignored `className` now honours
|
|
118
|
+
it, so a stylesheet that previously had no effect starts having one.
|
|
119
|
+
- **`ChartTooltipFloat` server-renders.** It was the one `renderToString` casualty in the package
|
|
120
|
+
(an unconditional `createPortal`); it now emits nothing on the server and is unchanged in the
|
|
121
|
+
browser. Consumers carrying an SSR workaround around a chart tooltip can drop it.
|
|
122
|
+
- **`BREAKPOINTS`** (`basalt-ui/tokens`) — `{ article: 1200 }`. The one `@media` literal in the
|
|
123
|
+
package that was not derived from anything now has a named, testable counterpart; a `@media`
|
|
124
|
+
condition cannot read a custom property, so the literal stays and a test holds the two together.
|
|
125
|
+
- **`theme-lab/boot.ts`** — `applyOverrides`/`loadOverrides`/`readVar` moved into their own
|
|
126
|
+
Mantine-free, SSR-safe module (no-op / empty result with no `document`, instead of throwing).
|
|
127
|
+
`basalt-ui/theme-lab` still resolves all three, unchanged, alongside `ThemeLabControls` and
|
|
128
|
+
`DeriveControls` — nothing renamed or removed, and no new subpath was added.
|
|
129
|
+
- **`basalt/raw-size-literal` / `basalt/no-raw-font-size`** — no longer exempt a consumer's own
|
|
130
|
+
`src/tokens/` directory. The exemption was basalt-internal (the derive engine's own hardcoded
|
|
131
|
+
scale values) and leaked to any package with a same-named directory. Consumers with raw sizes
|
|
132
|
+
there move them to `--vx-*` tokens, or add a `theme-allow` waiver.
|
|
133
|
+
- **`BasaltProvider connectivity` prop** — `Omit<ConnectivityProviderProps, 'children'>`, threaded
|
|
134
|
+
straight through to the auto-mounted `ConnectivityProvider`. Reaches `override` for the first
|
|
135
|
+
time (the only prior route was mounting a second, shadowing `ConnectivityProvider`) — see
|
|
136
|
+
§ BasaltProvider below.
|
|
137
|
+
- **Six new oxlint rule ids, all `warn`** — `basalt/provider-above-router`,
|
|
138
|
+
`basalt/duplicate-notifications-mount`, `basalt/query-dual-import`, `basalt/query-fn-unwrap`,
|
|
139
|
+
`basalt/forms-field-key` (grace to 1.30.0) and `basalt/deprecated-export` (permanently
|
|
140
|
+
advisory). `forms-field-key` is the one that matters most in this minor — it is the only thing
|
|
141
|
+
that reports the `inputProps` call sites below, which a compiler cannot see; see § `inputProps`.
|
|
142
|
+
The first four guard
|
|
143
|
+
four doctrines that shipped stated-but-unguarded under a `not guarded:` banner — the provider/
|
|
144
|
+
router mount order, the `BasaltOverlays` XOR `BasaltNotifications` double-mount, the
|
|
145
|
+
`basalt-ui/query` import seam, and `queryFn` wrapping in `unwrap()`. Each is honest about its
|
|
146
|
+
reach in its own message and its grace entry: all four read ONE file, and the two query rules
|
|
147
|
+
carry a documented text heuristic. Escape with `theme-allow <rule> — <why>` as usual. Nothing
|
|
148
|
+
fails a build: every one is `warn` in the shipped preset.
|
|
149
|
+
- **`basalt/deprecated-export`** — nudges an import or a prop basalt has deprecated but still ships,
|
|
150
|
+
reading the `DEPRECATED_EXPORTS` ledger beside the plugin. Today that is `field` from
|
|
151
|
+
`basalt-ui/forms` (autofixed to `inputProps as field`, so no call site moves) and the three
|
|
152
|
+
flattened `BasaltProvider` connectivity props. Permanently `warn` — a deprecation is a schedule,
|
|
153
|
+
not a defect. **On the `field` row, take the two fixes in order**: that rename lands the new
|
|
154
|
+
`inputProps` shape, which has no `key`, and `basalt/forms-field-key` then reports the same line
|
|
155
|
+
and inserts the `key`. Two `--fix` passes, or one manual edit writing both.
|
|
156
|
+
- **Dev-only duplicate-mount warnings** — `BasaltProvider` now warns when a second instance mounts
|
|
157
|
+
while the first is still mounted; `<BasaltOverlays notifications />` and `<BasaltNotifications />`
|
|
158
|
+
now warn when BOTH are mounted at once (previously prose-only in both cases). Both are
|
|
159
|
+
`console.warn`, dev builds only, no behavior change.
|
|
160
|
+
- **`WidgetGrid` + `WidgetGrid.Item` and `StatGroup`** (`basalt-ui`) — the dashboard column law,
|
|
161
|
+
owned once. `cols` is the DESKTOP count and the only number you state: `WidgetGrid` resolves
|
|
162
|
+
`base 1 → sm min(cols, 2) → lg cols`; `StatGroup` (the KPI row) resolves
|
|
163
|
+
`base 2 → sm min(cols, 3) → lg cols`. `<WidgetGrid.Item span={2}>` widens one cell and is clamped
|
|
164
|
+
to the live count at each breakpoint. `StatGroup divided` swaps the column gap for a hairline rail. **These two are the only
|
|
165
|
+
place `lg` exists in the package** — `sm` remains the only breakpoint a consumer writes
|
|
166
|
+
(`docs/CONTROLS-SPEC.md` §2). Replaces hand-written `SimpleGrid cols={{ base, md }}` /
|
|
167
|
+
`Grid.Col span={{ base: 12, md: 8 }}`; Mantine's responsive `cols` object is deliberately not a
|
|
168
|
+
prop.
|
|
169
|
+
- **`StatCard.query`** — `QueryStateLike`, the same structural subset `QueryState` takes. Supplied,
|
|
170
|
+
the card renders its pending / error / empty branch through `QueryState` at the `'section'` tier
|
|
171
|
+
INSIDE the body, directly under the header, which stays put. Omitted, nothing changes. `value` is
|
|
172
|
+
still yours to format — pass a placeholder while the query is pending.
|
|
173
|
+
- **`WidgetHeaderTitleProps` / `WidgetHeaderMetricProps` / `WidgetHeaderDeltaProps`** (`basalt-ui`)
|
|
174
|
+
— the named `Pick` slices of `WidgetHeaderProps` its composers share, cut along the three rows the
|
|
175
|
+
header paints. `StatCardProps` and `SettingsSectionProps` now compose them instead of re-declaring
|
|
176
|
+
props one at a time; **both gained props as a result** — `SettingsSection`/`DangerZone` now accept
|
|
177
|
+
and FORWARD `icon` and `info`. Nothing was removed from either (pinned by
|
|
178
|
+
`src/dashboard/stat-card-props.test.ts`). `Section` and `ChartCard` still cut their own subsets.
|
|
179
|
+
- **`tier` replaces `variant` on `QueryState` / `LoadingState` / `ErrorState` / `EmptyState`** —
|
|
180
|
+
`tier` is the package's word for "how loud is this" (`WidgetHeader`, `CtlSlot`), and `'section'`
|
|
181
|
+
meant two different things across the two spellings. `variant` is `@deprecated` and still
|
|
182
|
+
honoured; resolution is `tier ?? variant ?? 'page'`, so nothing moves until you change the prop.
|
|
183
|
+
`QueryStateTier` is the new type name; `QueryStateVariant` stays exported as an alias. No removal
|
|
184
|
+
is scheduled — this is a preferred spelling, not a sunset.
|
|
185
|
+
- **`WidgetHeader` and `QueryState` gained slot classes** — `classNames={{ root, title, metric,
|
|
186
|
+
icon }}` on the first, `classNames={{ root }}` on the second (the branch that is live). Additive.
|
|
187
|
+
`Section` now OMITS `classNames` from the `WidgetHeaderProps` it re-publishes, so its slot union
|
|
188
|
+
stays exactly `root | header | body` — a `<Section classNames={{ metric: … }}>` that used to
|
|
189
|
+
type-check (and do nothing) is now a compile error. Reach the header's own slots on a
|
|
190
|
+
`WidgetHeader`.
|
|
191
|
+
- **`Callout` extends `BasaltProps`** — `className`/`style` were already accepted and are now the
|
|
192
|
+
shared members, so `exactOptionalPropertyTypes` consumers can forward an `string | undefined`
|
|
193
|
+
through. No rendering change.
|
|
194
|
+
- **`PageAside` throws on a missing `title`** — it is both the header text and the region's
|
|
195
|
+
`aria-label`, so an omitted one shipped a nameless landmark rather than a crash. Now
|
|
196
|
+
`[basalt] PageAside: prop "title" is required — …`, in every build. `title` was never optional in
|
|
197
|
+
the type; this only reaches untyped JS and runtime-built props objects.
|
|
198
|
+
- **`BasaltDataTable` warns (dev only) when `stickyHeaderOffset` meets `maxHeight`/`minWidth`** —
|
|
199
|
+
the offset has always been DROPPED there (the sticky `<thead>` anchors to the scroll container's
|
|
200
|
+
own top edge, not the window). The behaviour is unchanged; it just says so now.
|
|
201
|
+
- **`query` on `Section`, `BasaltDataTable` and `BasaltVirtualList`** — law C3's uniform container
|
|
202
|
+
contract. Pass a `QueryStateLike` (a TanStack `UseQueryResult` is one) and the container resolves
|
|
203
|
+
the body: pending → its own placeholder (`QueryState`'s section-tier spinner / the table's
|
|
204
|
+
skeleton rows / the list's skeleton rows), error with no data → an `ErrorState` with the query's
|
|
205
|
+
own `refetch` behind Retry, anything else → the content, or the empty branch. **The table and the
|
|
206
|
+
list had NO error branch at all**, so a 500 rendered _No data to display._ / a blank box — the
|
|
207
|
+
false claim `QueryState` exists to delete. Additive: omit `query` and nothing changes.
|
|
208
|
+
`Section` also gains `empty?: QueryEmptyCopy` (copy for that branch, `QueryState`'s own type) and
|
|
209
|
+
`BasaltVirtualList` gains `emptyState?: ReactNode` (which works with or without `query`).
|
|
210
|
+
`isLoading` still works on both containers and is NOT deprecated; passing it beside `query` lets
|
|
211
|
+
`query` win and warns once in dev. The chrome stays drawn through every branch — a table keeps its
|
|
212
|
+
`<thead>`, toolbar and pagination bar, a `Section` keeps its header, chevron and `summary` — which
|
|
213
|
+
is why this is not `QueryState` wrapped around the container. A refetch that fails over rows
|
|
214
|
+
already on screen keeps the rows with no banner; compose `QueryState` AROUND the container for
|
|
215
|
+
that.
|
|
216
|
+
- **`BasaltDataTable.onRowActivate`** — `(row: T) => void`, fired by a click on the row and by Enter
|
|
217
|
+
on a focused one. The row → detail hook that pairs with `PageAside`. The row keeps its native
|
|
218
|
+
`<tr>` semantics and takes `tabIndex=0` + `data-activatable` rather than `role="button"` (a role
|
|
219
|
+
swap costs the column-header announcement that is the reason the data is in a table); the cursor
|
|
220
|
+
and focus ring come from a module class. A click originating inside the selection checkbox does
|
|
221
|
+
not activate.
|
|
222
|
+
- **`BasaltDataTable` row selection** — `enableRowSelection` prepends a checkbox column (header =
|
|
223
|
+
select-all on the page) and arms TanStack's row-selection feature; `rowSelection` /
|
|
224
|
+
`onRowSelectionChange` are the controlled pair over TanStack's own `RowSelectionState` (now
|
|
225
|
+
re-exported from `basalt-ui/data` and `basalt-ui/data/table`), and `getRowId` makes a selection
|
|
226
|
+
survive a re-sort or a refetch (the default id is the row INDEX). `bulkActions` renders a bar
|
|
227
|
+
above the table while ≥1 row is selected — the count, then the actions, through the SAME
|
|
228
|
+
`BarAction[]` vocabulary `PageBar` uses, so the ≤3-inline fold and the mobile kebab are basalt's
|
|
229
|
+
here too. **Its signature is `(rows: T[]) => BarAction[]`, a function and not a bare array**, and
|
|
230
|
+
deliberately: `BarActionItem.onClick` stays `() => void` (one unforked vocabulary across every
|
|
231
|
+
home), so the selected rows reach a handler through the closure you write — and an UNCONTROLLED
|
|
232
|
+
table can offer bulk actions at all, since the selection lives inside it.
|
|
233
|
+
- **`Section.actions` and `BasaltDataTable.actions` accept `BarAction[] | ReactNode`** — law C15.
|
|
234
|
+
Handed typed data, basalt owns the C6 budget and the C7 overflow fold (≤3 inline, the rest behind
|
|
235
|
+
`More`, one kebab below `sm`) exactly as `PageBar` does; handed a node, rendering is byte-for-byte
|
|
236
|
+
what it was. Every entry lands in `secondary` — a `BarAction[]` carries no primary marker, and C6's
|
|
237
|
+
"exactly one primary" stays the page bar's rule. `Section`'s ≤3 dev warning now counts an array
|
|
238
|
+
EXACTLY (`Children.count` read one as a single child). Both slots were `ReactNode` before, so no
|
|
239
|
+
call site moves.
|
|
240
|
+
- **`overlays.confirm` / `overlays.confirmDelete`** (`basalt-ui/commands`) — the two-button dialog
|
|
241
|
+
every consumer was registering as a `defineOverlays` entry with its own button pair, now
|
|
242
|
+
registry-free: `confirm({ title, body?, confirmLabel?, cancelLabel?, danger?, onConfirm,
|
|
243
|
+
onCancel? })` resolves `true`/`false` and fires exactly one callback, whichever exit the user takes
|
|
244
|
+
(cancel, escape, click-outside and the close button all count as `false`). `danger` paints the
|
|
245
|
+
confirm button in the theme's derived destructive family. `confirmDelete({ subject, count?,
|
|
246
|
+
onConfirm })` is the counted one-liner over it ("Delete 3 items?"). Both REJECT with a named
|
|
247
|
+
`[basalt] overlays.confirm: …` error when the `@mantine/modals` peer is absent, or when no
|
|
248
|
+
`ModalsProvider` is live — previously either returned a promise nothing would ever settle, because
|
|
249
|
+
the imperative API is a window event bus with nothing subscribed. `@mantine/modals` stays lazily
|
|
250
|
+
imported, so the peer is still optional. Additive: `defineOverlays` and `overlays.open` are
|
|
251
|
+
unchanged.
|
|
252
|
+
- **`registerModalsProvider()`** (`basalt-ui/commands`) — how a consumer who mounts
|
|
253
|
+
`<ModalsProvider>` THEMSELVES (with `<BasaltOverlays modals={false}>`, or with no `BasaltOverlays`
|
|
254
|
+
at all) tells `overlays.confirm` the layer is up. `<BasaltOverlays>` registers its own provider, so
|
|
255
|
+
the default path needs nothing. Call it from an effect and return its result as the cleanup:
|
|
256
|
+
|
|
257
|
+
```tsx
|
|
258
|
+
useEffect(() => registerModalsProvider(), [])
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
Availability is a COUNTER of live providers, not a flag, so two overlapping mounts (a route swap
|
|
262
|
+
mounting the next shell before unmounting the last) never report "no layer" while one is serving.
|
|
263
|
+
There is no way to detect the provider from outside React — its context is only readable through
|
|
264
|
+
`useModals()`, and `confirm` is an imperative call with no component to read it from — so the
|
|
265
|
+
registration is explicit and unregistered is indistinguishable from absent.
|
|
266
|
+
|
|
267
|
+
- **`notifyUndo` / `notifyUndoable`** (`basalt-ui/notifications`) — an undo window on top of the
|
|
268
|
+
existing toast machinery: `notifyUndo({ message, onUndo, window = 6000, onExpire })` shows a toast
|
|
269
|
+
carrying an `Undo` button and returns `{ id, dismiss() }`. The affordance and the grace period are
|
|
270
|
+
ONE number (`autoClose === window`), and exactly one of `onUndo` / `onExpire` runs, exactly once —
|
|
271
|
+
`onExpire` is where the optimistic mutation COMMITS. `dismiss()` settles the window immediately
|
|
272
|
+
(running `onExpire`), so a dismissed toast can never strand an uncommitted change.
|
|
273
|
+
`notifyUndoable(mutate, undo, opts)` is the same thing spelled for the optimistic shape. No new
|
|
274
|
+
store — the toast is recorded to the notification history like any other.
|
|
275
|
+
- **`NotifyOptions.historyMessage`** — what the persisted history records when `message` is a
|
|
276
|
+
composed ReactNode the store cannot stringify (`String(<Group/>)` is `[object Object]`). Defaults
|
|
277
|
+
to today's `String(message)`, so nothing moves unless you pass it. `notifyUndo` uses it.
|
|
278
|
+
- **`missingLayer`** (`basalt-ui`) — a message builder beside `requiredProp`/`oneOf`/`duplicateMount`
|
|
279
|
+
for "this call needs a layer that is not mounted or not installed". Additive.
|
|
280
|
+
- **`emit`'s payload now narrows per kind** (`basalt-ui/notifications`) — `NotificationSpec<P>` and
|
|
281
|
+
`NotificationAction<P>` are generic, `P` inferred from `toMessage`/`action.run`'s parameter, the
|
|
282
|
+
same mechanism `Overlay<P>` uses for `render`. Annotate the payload shape and `emit('kind', …)`
|
|
283
|
+
requires it, a wrong shape is a tsc error. A kind that annotates neither function keeps today's
|
|
284
|
+
`payload?: unknown` — additive, no existing `defineNotifications` call needs a change.
|
|
285
|
+
- **The form layer** (`basalt-ui/forms`) — `./forms` was an adapter with no layout, no submit
|
|
286
|
+
lifecycle, no array helper and no disabled propagation (audit B #5). Seven new exports, all
|
|
287
|
+
additive; `useBasaltForm`, `FormErrorSummary` and `useFormDraft`'s existing signature are
|
|
288
|
+
untouched. `inputProps` is the one exception, and it is not additive — see § `inputProps` no
|
|
289
|
+
longer returns `key` below.
|
|
290
|
+
- **`FormSection` / `FormRow` / `FormGroup` / `FormActions`** — the layout. `FormRow` IS law C1's
|
|
291
|
+
third home, the form row: label left / control right, label above below `sm`, the swap in CSS
|
|
292
|
+
(law C9). It does NOT replace `SettingsRow` — that stays the settings-page variant, and both
|
|
293
|
+
keep Mantine's `md` tier rather than mounting a `CtlSlot`. `FormActions` takes the same
|
|
294
|
+
`BarAction[] | ReactNode` union law C15 gave `Section.actions`.
|
|
295
|
+
- **`useFormSubmit(form, handler, options?)`** — `{ submit, isSubmitting, submitError, reset }`.
|
|
296
|
+
Catches the handler's throw and decodes it through `toErrorMessage` (override with `mapError`),
|
|
297
|
+
routes a thrown `{ fieldErrors }` envelope onto the fields via `form.setErrors`, and focuses the
|
|
298
|
+
first errored field on BOTH failure paths. `isSubmitting` is Mantine's own `form.submitting`,
|
|
299
|
+
not a second flag beside it.
|
|
300
|
+
- **`options.validateAsync`** — the async validation rule `useBasaltForm` has no room for:
|
|
301
|
+
`schemaResolver(schema, { sync: true })` is still hard-coded, so `validate()`/`isValid()` stay
|
|
302
|
+
synchronous, and the async rule runs at submit time after the schema and before the handler.
|
|
303
|
+
- **`FormStateProvider` / `useFormState`** — `{ disabled, submitting }`. The layout primitives
|
|
304
|
+
read it and disable their control region through a native `<fieldset disabled>`, so nothing has
|
|
305
|
+
to be threaded to each input and no child is cloned. Nesting ORs; it cannot re-enable.
|
|
306
|
+
- **`useFieldArray(form, path)`** — `{ items, append, remove, move, key }` over
|
|
307
|
+
`insertListItem`/`removeListItem`/`reorderListItem` + `form.key`. `key(index)` is POSITIONAL
|
|
308
|
+
(Mantine's list actions do not rotate the form key generation) — a user-reorderable list still
|
|
309
|
+
wants an id on the item.
|
|
310
|
+
- **`useFormDraft(form, { autosave })`** — `true`, or `{ debounceMs }`. The hook now owns its own
|
|
311
|
+
`form.watch` subscription, replacing the documented `saveDraftRef` + `onValuesChange` dance. It
|
|
312
|
+
is OFF by default and READ ONCE at mount (the watch set is a hook count), so every existing call
|
|
313
|
+
site behaves exactly as before. `DEFAULT_AUTOSAVE_DEBOUNCE_MS` is exported.
|
|
314
|
+
- **Still subpath-only.** The root barrel re-exports none of this, so a consumer without
|
|
315
|
+
`@mantine/form` is unaffected by importing `basalt-ui`.
|
|
316
|
+
- **Mobile "More" sheet rows now 40px with the sidebar's own insets** — `--vx-space-mobile-nav-row-
|
|
317
|
+
height` 44 → 40 (WCAG 2.5.5 AA touch floor, not the AAA figure the bar's own `mobileNavBarHeight`
|
|
318
|
+
still holds to). The rows themselves no longer force a bespoke touch padding over the theme's
|
|
319
|
+
`NavLink` styling; they now render with the SAME `--vx-space-row-inset-y`/`-x` padding and
|
|
320
|
+
`VX.text.md` the desktop sidebar row does. A nested (child) row gains the sidebar's own child
|
|
321
|
+
indent — a 1px `--vx-divider` left guide. Purely visual; no prop, export or behaviour changed.
|
|
322
|
+
- **`NotificationCenter` defaults to `width: '100%'`, not a hardcoded `320`** — it now sizes to its
|
|
323
|
+
host instead of assuming it always sits inside its own 320px popover. `NotificationBell` fixes the
|
|
324
|
+
320px width at the `Popover` itself (`<Popover width={320}>`) instead, so nothing changes for that
|
|
325
|
+
call path; a consumer mounting `NotificationCenter` directly (a Drawer, an inline card) now gets a
|
|
326
|
+
component that shrinks to its container rather than overflowing it. `style` still merges over the
|
|
327
|
+
default, so `style={{ width: 280 }}` still wins.
|
|
328
|
+
|
|
329
|
+
### `inputProps` no longer returns `key` — pair it with the new `fieldKey`
|
|
330
|
+
|
|
331
|
+
**This is the one thing in the minor that needs a code change at every call site, and the compiler
|
|
332
|
+
will not tell you about a single one of them.** It is a one-line-per-field edit:
|
|
333
|
+
|
|
334
|
+
```tsx
|
|
335
|
+
/* before (1.27) */ <TextInput {...inputProps(form, 'email')} />
|
|
336
|
+
/* after */ <TextInput key={fieldKey(form, 'email')} {...inputProps(form, 'email')} />
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
**Exactly what changed.** In 1.27 `inputProps(form, path)` returned `form.getInputProps(path)` **and
|
|
340
|
+
`key`** in one object, so a single spread covered both. It now returns `form.getInputProps(path)`
|
|
341
|
+
and nothing else; `fieldKey(form, path)` is the other half, written as a real JSX `key` attribute.
|
|
342
|
+
The bundle was basalt's own invention, and React 19 logs `A props object containing a "key" prop is
|
|
343
|
+
being spread into JSX` on every render of it — three fields, three warnings per page.
|
|
344
|
+
`key={form.key(path)} {...form.getInputProps(path)}` is Mantine's own documented idiom; `fieldKey` +
|
|
345
|
+
`inputProps` is that idiom with basalt's names.
|
|
346
|
+
|
|
347
|
+
**What breaks if you only upgrade and do nothing.** Nothing type-checks differently, nothing throws
|
|
348
|
+
and no warning is logged — the 1.27 call site is still a valid spread of a valid object. The element
|
|
349
|
+
simply has no `key` any more, so React reuses the DOM node and an uncontrolled input keeps its old
|
|
350
|
+
text through `form.reset()`, `form.setValues()` and a removed list row. That is the entire failure
|
|
351
|
+
mode: a form that stops resetting, with no signal anywhere.
|
|
352
|
+
|
|
353
|
+
**What catches it: `basalt/forms-field-key`**, new in this minor at `warn` (grace to 1.30.0). It
|
|
354
|
+
reports every `{...inputProps(…)}` spread whose element carries no sibling `key`, and it
|
|
355
|
+
**autofixes** — inserting `key={fieldKey(<same args>)}` and adding `fieldKey` to the existing
|
|
356
|
+
`basalt-ui/forms` import. Run `oxlint --fix` over the app and read the diff; the escape hatch for an
|
|
357
|
+
element genuinely remounted by its parent is `theme-allow forms-field-key — <why>`.
|
|
358
|
+
|
|
359
|
+
**The deprecated `field` alias did NOT follow `inputProps` here.** It is no longer
|
|
360
|
+
`export const field = inputProps`: it keeps the 1.27 return shape, `key` included, so
|
|
361
|
+
`{...field(form, 'x')}` behaves in 1.28.0 byte for byte as it did in 1.27 — including the React 19
|
|
362
|
+
key-spread warning. An alias would have changed what every existing call site DOES without changing
|
|
363
|
+
whether it compiles, and a deprecation is a schedule, not a behaviour change. `forms-field-key`
|
|
364
|
+
reports the `field(` spread too, with its own message pointing here; the alias itself is removed in
|
|
365
|
+
`1.29.0`.
|
|
366
|
+
|
|
367
|
+
### `BasaltDataTable` — the root is a `<div>`, not a Fragment
|
|
368
|
+
|
|
369
|
+
**One structural change, no prop change.** The component returned a Fragment, so the header row, the
|
|
370
|
+
table (or its scroll container) and the pagination bar were DIRECT CHILDREN of whatever the caller
|
|
371
|
+
rendered it into. It now always renders a wrapper:
|
|
372
|
+
|
|
373
|
+
```html
|
|
374
|
+
<div class="{classNames.root} {className}" style="{style}">
|
|
375
|
+
…header row… …table / Table.ScrollContainer… …pagination bar…
|
|
376
|
+
</div>
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
A `className` needs a root to live on (`common/props.ts`), and a Fragment has none — so the wrapper
|
|
380
|
+
is what `className`, `style` and `classNames.root` all resolve against. It is unconditional: a table
|
|
381
|
+
with no title, no toolbar and no pagination still renders it.
|
|
382
|
+
|
|
383
|
+
**What breaks:** any CSS or test selector written against the OLD flat structure. A
|
|
384
|
+
`.page-grid > table`, a `:first-child` rule aimed at the table, an `:nth-child` counting the header
|
|
385
|
+
row and the pagination bar as siblings of your own content, or a flex/grid parent that laid those
|
|
386
|
+
three boxes out itself — all now see one child. Target the wrapper instead, and give it the layout:
|
|
387
|
+
|
|
388
|
+
```css
|
|
389
|
+
/* before */ .page-grid > table { … }
|
|
390
|
+
/* after */ .page-grid > div > table { … } /* or: <BasaltDataTable classNames={{ root: 'my-table' }} /> */
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
Pinned by `src/data/data-table.test.tsx` ("the root is one div carrying classNames.root, wrapping
|
|
394
|
+
the table and the pagination bar"), so it cannot revert silently.
|
|
395
|
+
|
|
396
|
+
### BasaltProvider — a `connectivity` object replaces three flattened props
|
|
397
|
+
|
|
398
|
+
`sseUrl` / `healthUrl` / `healthIntervalMs` on `BasaltProvider` are now `@deprecated` aliases for
|
|
399
|
+
the corresponding fields on the new `connectivity` prop — **removed in 1.29.0**. `connectivity`
|
|
400
|
+
wins WHOLESALE once supplied, not per-key: passing `connectivity` at all makes basalt ignore the
|
|
401
|
+
three deprecated props entirely, even ones `connectivity` itself leaves unset. Supplying both logs a
|
|
402
|
+
dev-only warning. Move every deprecated field to `connectivity` in one pass, not one field at a time.
|
|
403
|
+
|
|
404
|
+
| Removed / deprecated | Replacement |
|
|
405
|
+
| ----------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
|
|
406
|
+
| `<BasaltProvider sseUrl={…} />` | `<BasaltProvider connectivity={{ sseUrl: … }} />` — `@deprecated`, removed 1.29.0 |
|
|
407
|
+
| `<BasaltProvider healthUrl={…} />` | `<BasaltProvider connectivity={{ healthUrl: … }} />` — `@deprecated`, removed 1.29.0 |
|
|
408
|
+
| `<BasaltProvider healthIntervalMs={…} />` | `<BasaltProvider connectivity={{ healthIntervalMs: … }} />` — `@deprecated`, removed 1.29.0 |
|
|
409
|
+
| (unreachable before this minor) | `<BasaltProvider connectivity={{ override: {…} }} />` — simulate a signal for testing/demo, no second `ConnectivityProvider` needed |
|
|
410
|
+
|
|
411
|
+
**`cssVariablesResolver` can no longer reach `BasaltProvider` through the passthrough
|
|
412
|
+
`MantineProviderProps` rest** — it was silently spreadable and would override basalt's own resolver
|
|
413
|
+
(the one thing the provider exists to install). `Omit`ted from the accepted prop type; pass any
|
|
414
|
+
palette customization through `createBasaltTheme(overrides, { derive, fonts, radius, density })`
|
|
415
|
+
instead.
|
|
416
|
+
|
|
417
|
+
### `basalt-ui/connectivity` — `queryOnline` narrowed to `boolean`
|
|
418
|
+
|
|
419
|
+
`ConnectivitySnapshot['details'].queryOnline` and `ConnectivityOverride.queryOnline` drop the
|
|
420
|
+
`| null` arm. The JSDoc used to claim null meant "QueryClient not mounted", but `onlineManager` is a
|
|
421
|
+
module-level singleton read with no such check — the only null this field ever carried was the
|
|
422
|
+
pre-hydration SSR snapshot, which now reports an optimistic `true` (matching `browserOnline`'s own
|
|
423
|
+
SSR default) instead. Code branching on `queryOnline === null` was already dead; delete it.
|
|
424
|
+
|
|
425
|
+
### `basalt-ui/state` — eight internal symbols dropped from the barrel
|
|
426
|
+
|
|
427
|
+
| Removed / renamed | Replacement | Note |
|
|
428
|
+
| ---------------------------------------------------------------------------------------------------------------- | ----------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
429
|
+
| `createStoreCore`, `resolveFieldCodec` (`basalt-ui/state`) | none | Both were `@internal` — the seam `createSearchStore` is built on, not a consumer API — and were never meant to be a public contract. No replacement needed. |
|
|
430
|
+
| `FieldCodec`, `StoreEntry`, `StoreCoreOptions`, `StoreCore`, `FieldUse`, `FieldWrite` (types, `basalt-ui/state`) | none | Also `@internal` — the supporting types behind `createStoreCore`/`resolveFieldCodec`, dropped alongside the two functions for the same reason. No replacement needed. |
|
|
431
|
+
|
|
432
|
+
### `basalt-ui/forms` — `field` renamed to `inputProps`
|
|
433
|
+
|
|
434
|
+
Two unrelated exports shared the name `field`: the forms adapter's `getInputProps`+`key` bundler and
|
|
435
|
+
the `field.enum/multi/range/number/boolean/string` store-field builder in `basalt-ui/state` and
|
|
436
|
+
`basalt-ui/router-tanstack`. A page combining a form and a filter store had to alias one on import.
|
|
437
|
+
|
|
438
|
+
| Removed / renamed | Replacement | Note |
|
|
439
|
+
| --------------------------- | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
440
|
+
| `field` (`basalt-ui/forms`) | `inputProps` | Same signature — `inputProps(form, path)`. `field` still resolves from `basalt-ui/forms` as a `@deprecated` alias, so nothing breaks; the alias goes away the next time the forms surface changes, and that removal ships as a plain `feat:`, never a major. **Since the Unreleased minor the two are no longer the same function**: `inputProps` dropped `key` from its return and `field` did not — see § `inputProps` no longer returns `key`. |
|
|
441
|
+
|
|
442
|
+
The `field.*` store builder (`basalt-ui/state`, `basalt-ui/router-tanstack`) is untouched.
|
|
443
|
+
|
|
444
|
+
### Shell — region seams, and what moved with them
|
|
445
|
+
|
|
446
|
+
**Every `AppShell` region now ends in a real, themed 1px `--vx-divider` line on its Main-facing
|
|
447
|
+
edge, with no opt-out** (`docs/DESIGN-SPEC.md` §5 "Region seams", §8 inversion #12): sidebar|main
|
|
448
|
+
(full height, under `layout="alt"` it owns the top-left corner), header|main (main column only),
|
|
449
|
+
main|aside (full height, absent when the aside is unclaimed), main|mobile-nav (below `sm`). Mantine
|
|
450
|
+
draws all four itself through `[data-with-border]`; the colour is one theme var,
|
|
451
|
+
`AppShell.extend({ vars: () => ({ root: { '--app-shell-border-color': 'var(--vx-divider)' } }) })`.
|
|
452
|
+
The aside's shell-form header also carries its own `border-bottom: 1px solid var(--vx-divider)`, so
|
|
453
|
+
the top belt's seam closes across the panel instead of dead-ending at the aside column.
|
|
454
|
+
**Delete any hand-drawn twin**: a `border-left` on your own aside-shaped panel, a `border-bottom`
|
|
455
|
+
under `PageBar` via `className`, a `withBorder` or a `--app-shell-border-color` override on your own
|
|
456
|
+
`AppShell` sections — the theme only pins the COLOUR; `withBorder` still adds or removes the edge
|
|
457
|
+
per section (Mantine gates the border CSS on `[data-with-border]`), so a leftover `withBorder={false}`
|
|
458
|
+
still suppresses the seam and must be deleted to get it, and a leftover `withBorder={true}` is
|
|
459
|
+
redundant (Mantine's own default).
|
|
460
|
+
|
|
461
|
+
- **`--vx-divider` moved.** Light is now `rgba(<derived ink>, 0.09)` (was
|
|
462
|
+
`color-mix(in srgb, #e5e5e5 65%, transparent)`) — visibly darker on light, tracks a non-default
|
|
463
|
+
`neutral`/`lightLevel` where the old hex did not, and never flips polarity at `lightLevel <= -3`
|
|
464
|
+
the way the fixed hex did. Dark moved too: `color-mix(in srgb, #ffffff 6%, transparent)` →
|
|
465
|
+
`rgba(255, 255, 255, 0.08)`.
|
|
466
|
+
- **The header's horizontal inset moved from `md` to `sm`**, so the breadcrumb's left edge and the
|
|
467
|
+
global actions' right edge land on the card column's edges. The sidebar brand row and the aside's
|
|
468
|
+
header now sit at the SAME `appShellHeaderHeight` band, so their centrelines meet the header's
|
|
469
|
+
across the seams. `SPACE_STEP.sidebarBrandInsetTop` / `--vx-space-sidebar-brand-inset-top` are
|
|
470
|
+
deleted with no replacement — the row IS the band now, not an inset inside it.
|
|
471
|
+
`PageAside`'s title renders the head-font `--vx-text-md`/550/ink title treatment, not the old mono
|
|
472
|
+
micro-label.
|
|
473
|
+
- **[S2] `PageBar` row 2 below `sm`** is two declared lines — the tabs, then the pill row — instead
|
|
474
|
+
of one overflowing `nowrap` line. `--basalt-page-bar-h` grows to match, and the `className` JSDoc
|
|
475
|
+
no longer suggests drawing a hairline under the bar.
|
|
476
|
+
- **[S3] `DeltaBadge.polarity` and `deltaPolarity`** on `WidgetHeader`/`StatCard`/`ChartCard` —
|
|
477
|
+
`'up-good'` (default, today's tone), `'up-bad'`, `'neutral'`. And `WidgetHeader tier="group"` — a
|
|
478
|
+
`Section` mounted inside `PageAside` now resolves it automatically and renders a mono micro-label
|
|
479
|
+
`h3` with a zero-gap row body; outside an aside nothing changes.
|
|
480
|
+
- **[S4] `AxisConfig.scale: 'log'`** on `CartesianChart` — 1-2-5 mantissa ticks, `autoMinCeil`
|
|
481
|
+
ignored on a log axis. Honoured by every kind whose domain isn't anchored at zero (`MultiLine`,
|
|
482
|
+
`ZonedLine`, un-stacked `Bars`); `StackedArea` and stacked `Bars` install a domain function with a
|
|
483
|
+
hard `0` floor and their marks anchor at the baseline, so a log scale on either yields `NaN`
|
|
484
|
+
geometry — don't opt in there. Additive; omitted stays linear.
|
|
485
|
+
|
|
42
486
|
### Stores — the `custom` flag, patched writes, lazy fallbacks, derived windows
|
|
43
487
|
|
|
44
488
|
**Additive, except one type that got narrower on purpose.** `field.range({ presets, fallback })`
|
|
@@ -262,7 +706,7 @@ renders in a tiered slot, and keying the exemption on a single owner made the ve
|
|
|
262
706
|
attribute came later in the file.
|
|
263
707
|
|
|
264
708
|
**`basalt/control-outside-home` and `raw-selection-control` did NOT promote. They are re-dated to
|
|
265
|
-
1.
|
|
709
|
+
1.30.0, and the reason is a measurement rather than caution:** the wave-7 consumer run left 9 warns
|
|
266
710
|
in argo, and every one is a control inside a modal/form module whose `<Modal>` is rendered by the
|
|
267
711
|
PARENT route — law C1's cross-file case, which is advisory by declaration because no scan of one
|
|
268
712
|
file can see it. Both lanes now exempt a file whose BASENAME matches
|
|
@@ -286,6 +730,155 @@ half is deliberately NOT exempted the same way — a local `StatCard` beside an
|
|
|
286
730
|
`import { StatCard as Base }` kept the name AND a piece of the original, which is the fork shape this
|
|
287
731
|
rule most wants to see.
|
|
288
732
|
|
|
733
|
+
### `basalt-ui/data` — a typed facet id, and a required `getItemKey`
|
|
734
|
+
|
|
735
|
+
**`BasaltDataTable`: a mistyped `facets[].columnId` used to render no pill, silently — `if
|
|
736
|
+
(!column) return null`.** It now throws in dev, naming the id and every known column id
|
|
737
|
+
(`facet columnId "…" matches no column`); production still degrades to no pill for that one facet.
|
|
738
|
+
`DataTableFacet` also gained a type parameter — `DataTableFacet<T = unknown>` — so `columnId` is
|
|
739
|
+
typed off the row shape wherever TanStack's `accessor`/manual `id` inference allows it
|
|
740
|
+
(`Extract<keyof T, string> | (string & {})`); the default keeps a bare `DataTableFacet[]`
|
|
741
|
+
compiling unchanged. `BasaltDataTableProps.facets` is now `DataTableFacet<T>[]`, and
|
|
742
|
+
`initialColumnPinning` moved from TanStack's own `ColumnPinningState` to a new, `T`-derived
|
|
743
|
+
`DataTableColumnPinning<T>` (structurally assignable to `ColumnPinningState`, so no cast is
|
|
744
|
+
needed at either end). Both are additive for existing call sites — an id that was already a real
|
|
745
|
+
column keeps compiling and rendering exactly as before.
|
|
746
|
+
|
|
747
|
+
**`BasaltVirtualList.getItemKey` is now required.** The index fallback hid stale rows across a
|
|
748
|
+
mutation: an insert/delete shifts every index below it, so the OLD item kept rendering at each
|
|
749
|
+
shifted index until an unrelated re-render happened to catch it up — in the one component whose
|
|
750
|
+
job is a long mutable list. Pass a real per-item key (`(item) => item.id`); there is no
|
|
751
|
+
replacement for the index fallback.
|
|
752
|
+
|
|
753
|
+
**`BasaltVirtualList` gained a ref.** `ref?: Ref<BasaltVirtualListHandle>` exposes
|
|
754
|
+
`scrollToIndex`/`scrollToOffset`/`scrollToEnd` (delegating to the internal
|
|
755
|
+
`@tanstack/react-virtual` instance) plus `getVirtualizer()` as the full escape hatch — mirrors
|
|
756
|
+
`./data/table`'s `useReactTable` re-export as the table's own. Additive; omitting `ref` changes
|
|
757
|
+
nothing.
|
|
758
|
+
|
|
759
|
+
### `basalt-ui/commands` — `BasaltOverlays` no longer WRAPS your app in `ModalsProvider`
|
|
760
|
+
|
|
761
|
+
**Same props, same imperative API, one structural change: every layer — `ModalsProvider`
|
|
762
|
+
included — now renders as a SIBLING of `children` instead of an ancestor.** The old shape put the
|
|
763
|
+
whole app under a `React.lazy` Suspense boundary (`<Suspense fallback={<>{app}</>}>
|
|
764
|
+
<LazyModalsProvider>{app}</LazyModalsProvider></Suspense>`), and `React.lazy` suspends on its first
|
|
765
|
+
render even when the module is already warm. Two consequences, both real: the app's FIRST COMMIT was
|
|
766
|
+
deferred past a microtask — long enough for TanStack Router's async `loadMatches` to `setState` onto
|
|
767
|
+
a not-yet-mounted fiber ("Can't perform a React state update on a component that hasn't mounted
|
|
768
|
+
yet", once per full page load) — and the app tree mounted TWICE, once inside the fallback and once
|
|
769
|
+
resolved, so every effect in the app ran twice on boot.
|
|
770
|
+
|
|
771
|
+
Nothing to change for the overlay APIs. `modals.open` / `modals.openConfirmModal` (and so basalt's
|
|
772
|
+
own `overlays.open` / `overlays.close`) go through `@mantine/modals`' window CustomEvent bus, which
|
|
773
|
+
`ModalsProvider` subscribes to — being inside it was never a requirement, and the provider renders
|
|
774
|
+
its own managed `Modal` regardless of where it sits.
|
|
775
|
+
|
|
776
|
+
**The one thing a sibling cannot serve is React CONTEXT**: `useModals()` from `@mantine/modals`
|
|
777
|
+
called inside your app now throws its "was called outside of context" error. If you use it (or
|
|
778
|
+
`openContextModal`, which needs the provider's `modals` map that `BasaltOverlays` never passed
|
|
779
|
+
anyway), mount your own provider and turn basalt's off — two providers would both answer the event
|
|
780
|
+
bus and open every modal twice:
|
|
781
|
+
|
|
782
|
+
```tsx
|
|
783
|
+
<BasaltOverlays modals={false}>
|
|
784
|
+
<ModalsProvider modals={CONTEXT_MODALS}>
|
|
785
|
+
<App />
|
|
786
|
+
</ModalsProvider>
|
|
787
|
+
</BasaltOverlays>
|
|
788
|
+
```
|
|
789
|
+
|
|
790
|
+
### `basalt-ui/controls` — the mobile `Filters (n)` sheet renders panel rows, not its own list
|
|
791
|
+
|
|
792
|
+
**The sheet's `SheetOptionList` (44px rows, a hairline between them, one per option) is gone.**
|
|
793
|
+
`useFilterSurface() === 'sheet'` now resolves to the SAME `PanelRow`/`PanelChoice`/facet-list body
|
|
794
|
+
`'panel'` already renders (`docs/CONTROLS-SPEC.md` §3: "sheet = panel rows inside a Drawer") — label
|
|
795
|
+
above, full-width control below, folding past `PANEL_TRACK_MAX` (3, a `Select`) or `max` (a
|
|
796
|
+
`MultiSelectFilter`'s `Show N more`) the same way the aside already did. A set with many options no
|
|
797
|
+
longer grows the sheet to a full column of option rows. `RangeFilter`'s sheet form is the panel's one
|
|
798
|
+
`Select` (presets plus a `Custom range…` row revealing the injected picker) instead of a
|
|
799
|
+
`SheetOptionList` with the picker behind a separate disclosure row.
|
|
800
|
+
|
|
801
|
+
Also fixed in the same pass: a `fullWidth` `SegmentedControl` (`PanelChoice`'s ≤3-option form, and
|
|
802
|
+
`ViewTabs`) now splits its options EVENLY — Mantine's own `.control` carries no `min-width`
|
|
803
|
+
override, so the initial `auto` floored each option at its content width and a `fullWidth` track
|
|
804
|
+
split unevenly; a long label now ellipsizes inside its equal share instead of forcing the column
|
|
805
|
+
wide. The active segment's fill is a second ink-mix step
|
|
806
|
+
(`color-mix(in srgb, var(--vx-ink) 12%, var(--vx-surface-panel))`), not a flat `--vx-surface-panel`,
|
|
807
|
+
so it stays visible against its own track when the whole control sits on a panel-coloured surface (a
|
|
808
|
+
`PanelRow`), where a flat panel fill read as barely-there next to the 6%-tinted track around it.
|
|
809
|
+
|
|
810
|
+
| Removed | Replacement | Note |
|
|
811
|
+
| ---------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
812
|
+
| `SheetOptionList`, `SheetField`, `SheetDisclosure` (`basalt-ui/controls`) | `PanelRow` / `PanelChoice` (already exported) | Were never part of the public `./controls` barrel — internal to `filter-sheet.tsx` — so this only breaks a consumer test that imported them directly out of `basalt-ui/controls/filter-sheet` or hooked a `role="radio"` `<fieldset>` DOM shape inside the sheet (now a `PanelChoice` `SegmentedControl`, `role="radiogroup"`, or a `Select`). |
|
|
813
|
+
| `SheetRow`, `sheetRowClassNames` (`basalt-ui/controls`) | none | Also internal-only. `ToggleFilter`'s sheet form is now a `PanelRow` whose `Switch` rides the label line, the same shape the panel surface always used. |
|
|
814
|
+
| `.sheetOption` / `.sheetList` / `.sheetField` / `.sheetRow` / `.sheetDisclosureBody` / `.sheetLabel` (`controls.module.css`) | `panel-row.module.css`'s `.row`/`.head`/`.control`/`.label` | CSS-module classes were never a public contract; named for a consumer that vendored a copy of the sheet's old CSS. |
|
|
815
|
+
|
|
816
|
+
### The shell scrollport — Main scrolls, not the window
|
|
817
|
+
|
|
818
|
+
`BasaltShell` dropped Mantine's `layout="alt"` (the header now spans the full viewport width, above
|
|
819
|
+
the sidebar and the aside, instead of being inset beside the sidebar) and gave `AppShell.Main` a
|
|
820
|
+
bounded height with `overflow: auto`. Main is therefore THE scrolling element: the document's
|
|
821
|
+
`scrollHeight` equals the viewport height, the browser scrollbar sits on Main's own right edge
|
|
822
|
+
(inside the aside, where the content is) instead of at the far edge of the window, and
|
|
823
|
+
`window.scrollY` is pinned at 0.
|
|
824
|
+
|
|
825
|
+
Main carries two handles: `data-basalt-scrollport` (basalt's own, and what `scrollParentOf` looks
|
|
826
|
+
for) and `data-scroll-restoration-id="basalt-main"` (the attribute `@tanstack/router-core`'s scroll
|
|
827
|
+
restoration reads, so a router-driven app restores this element rather than the window).
|
|
828
|
+
|
|
829
|
+
What to change in a consumer:
|
|
830
|
+
|
|
831
|
+
| If your app… | Do this |
|
|
832
|
+
| ------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
833
|
+
| reads `window.scrollY` / listens for `scroll` on `window` | `const port = scrollParentOf(el)` and read `port.scrollTop` / listen on `port` — `null` still means the window, so shell-less code is unchanged |
|
|
834
|
+
| scrolls with `window.scrollTo` / `document.scrollingElement` | target `document.querySelector('[data-basalt-scrollport]')` first, with the document as the fallback |
|
|
835
|
+
| uses window-based scroll restoration | point it at `[data-scroll-restoration-id="basalt-main"]`; TanStack Router picks it up with no config |
|
|
836
|
+
| overrides `--vx-space-sticky-header-clearance` | the token NO LONGER includes the app-shell header height — it is `anchors.stackMd` (12px at level 0), pure breathing room, because BOTH the header and the page-bar band are regions outside the scrollport |
|
|
837
|
+
| passes `BasaltDataTable stickyHeaderOffset` inside a shell | drop it entirely. Nothing overhangs the scrollport any more, so a sticky table head wants `top: 0`, which is the default |
|
|
838
|
+
| computes a viewport-filling body from `--basalt-page-bar-h` | inside a shell that is just `100%` now — the band is outside Main rather than scrolling with it. The var is still published |
|
|
839
|
+
| passes `mobileNav.getScrollElement` only to reach the page scroller | you can drop it — the default resolves the scrollport now |
|
|
840
|
+
|
|
841
|
+
Three rendering changes ride along, all visible without any code change:
|
|
842
|
+
|
|
843
|
+
- **The brand moved out of the sidebar and into the header.** The header spans the full viewport
|
|
844
|
+
width now, so the sidebar's `appShellHeaderHeight` brand row painted as a SECOND 48px band under
|
|
845
|
+
the header seam. It is the header's leading zone instead — `--app-shell-navbar-offset` wide, so it
|
|
846
|
+
still tracks the rail collapse and still ends on the sidebar\|main seam — and the sidebar column
|
|
847
|
+
starts at `SidebarSearch`. `brand`, `brand.menu` and the collapse toggle are unchanged; only the
|
|
848
|
+
markup's home moved. Two consequences for a consumer mounting `AppSidebar` DIRECTLY (rather than
|
|
849
|
+
through `BasaltShell`, which is the supported path): it no longer paints a brand row, and its
|
|
850
|
+
`onToggleCollapse` prop is no longer read there — `BasaltShell` feeds it to the header instead.
|
|
851
|
+
- **`PageBar` row 2 is a shell-owned BAND**, not a row in the page: it portals into an outlet
|
|
852
|
+
`BasaltShell` renders between the header and the scrollport, exactly as row 1 portals into the
|
|
853
|
+
header. It spans Main's width, carries `--vx-surface-bg` and one `--vx-divider` hairline, and is a
|
|
854
|
+
zero-height, seam-less box on a route with no `PageBar`. It is no longer sticky and no longer
|
|
855
|
+
depends on where you wrote `<PageBar>` — nested in a `Stack` or written as Main's direct child now
|
|
856
|
+
produce identical geometry. Its padding-block tightened from `--vx-space-stack-sm` to
|
|
857
|
+
`--vx-space-stack-xs`, so the bar is 8px shorter.
|
|
858
|
+
- **`BasaltDataTable` contains itself horizontally by default.** A table with neither `maxHeight`
|
|
859
|
+
nor `minWidth` used to render a bare `<table>`, which sizes to its own min-content — a five-column
|
|
860
|
+
table measured 448px inside a 390px viewport and dragged the whole page sideways. Every table now
|
|
861
|
+
renders inside `Table.ScrollContainer type="native"` (`minWidth: 0` when you set none), so a wide
|
|
862
|
+
table scrolls inside its own card. `stickyHeader` with neither prop cannot take that container —
|
|
863
|
+
an `overflow-x` box computes `overflow-y` to `auto` and becomes the header's scrollport, and with
|
|
864
|
+
no height cap it has no scroll range, so the header would go inert — so it takes a wrapper whose
|
|
865
|
+
overflow is **measured** instead: while the table fits its container the wrapper declares no
|
|
866
|
+
overflow at all and the page-sticky header sticks exactly as before; once the table is wider the
|
|
867
|
+
wrapper flips to `overflow-x: auto`, the columns stay reachable, and the header is inert at that
|
|
868
|
+
width. The flip is a live `ResizeObserver` reading in both directions, so the wrapper goes back to
|
|
869
|
+
bare when the space returns (the window widened, the sidebar collapsed, the aside closed), and it
|
|
870
|
+
publishes `data-contained="true|false"`. The dev warning on that shape now states the trade rather
|
|
871
|
+
than a defect and points at `maxHeight` for a table that must both scroll and stick. Pinning takes
|
|
872
|
+
the same wrapper: the `overflow-x: auto` `Box` a pinned, uncapped, sticky table used to get is
|
|
873
|
+
gone, because it was the inert-header shape it was meant to avoid. **The TOOLBAR was the other
|
|
874
|
+
half of the same defect and is fixed with it**: the toolbar `Group` is the header row's flex item
|
|
875
|
+
(`CtlSlot` between them is `display: contents`) and carried `flex: 0 0 auto`, so a 220px search
|
|
876
|
+
beside a 230px facet pill row was an unshrinkable 461px box in a 302px column — `AppShell.Main`
|
|
877
|
+
measured `scrollWidth` 505 against `clientWidth` 390 at 390x844. It is now `flex: 0 1 auto` with
|
|
878
|
+
`min-width: 0`, and the search's `w={220}` became a flex BASIS (`flex: 0 1 220px`, floored at
|
|
879
|
+
`12ch`, capped at `100%`). The field still resolves to 220px wherever 220 fits and still never
|
|
880
|
+
grows with the table; below that the search and the pills wrap onto their own lines.
|
|
881
|
+
|
|
289
882
|
## 1.26.0 — the control tier, the page bar and the store
|
|
290
883
|
|
|
291
884
|
**One export removed and two deprecated — see § Stores below; two shell PROPS removed — see
|
|
@@ -305,7 +898,7 @@ happened to the nine rows below.
|
|
|
305
898
|
(`shadow-basalt-export`). Both ledgers now hold only the wave-6 control guards listed under
|
|
306
899
|
§ Guards — six plugin rules and two guard kinds, each `{ since: '1.26.0', promote: '1.27.0' }` —
|
|
307
900
|
which the C16 gate forced to promote or be deleted at 1.27.0. Five rules and one kind promoted there;
|
|
308
|
-
the C1 pair was re-dated to 1.
|
|
901
|
+
the C1 pair was re-dated to 1.30.0 against a measurement (see `## Unreleased` above). A theme-allow escape written against
|
|
309
902
|
any of these still works unchanged; only the SEVERITY of an unwaived finding moves from `warn` to
|
|
310
903
|
`error`.
|
|
311
904
|
|
|
@@ -616,21 +1209,21 @@ A consumer that uses `DateRangePicker` installs `@mantine/dates` and imports
|
|
|
616
1209
|
|
|
617
1210
|
**Nothing removed. Eight new oxlint rules and two new guard kinds. `Ships` below is the level as of
|
|
618
1211
|
THIS minor** — eight land `error`, and the C1 pair (`control-outside-home` and its text lane) is the
|
|
619
|
-
only grace left, re-dated to 1.
|
|
1212
|
+
only grace left, re-dated to 1.30.0 on a measurement (see § Guards — the promotions).\*\* Every one honours `theme-allow <id> — <why>` on the
|
|
620
1213
|
node and `theme-allow-file <id> — <why>` on the file, the same grammar as the rest.
|
|
621
1214
|
|
|
622
|
-
| Rule / kind | Fires on
|
|
623
|
-
| ------------------------------------ |
|
|
624
|
-
| `basalt/hand-rolled-filter` | A raw Mantine `Select`/`SegmentedControl`/… handed to a TIERED home slot (`actions`/`filters`/`tabs`/`sync`/`filtersEnd` on `PageBar`/`Section`/`WidgetHeader`/`ChartCard`/`StatCard`/`BasaltDataTable`/`SettingsSection`/`FilterSet`)
|
|
625
|
-
| `basalt/page-bar-budget` | A second `PageBar` in the SAME returned tree, >4 `actions.secondary`, >3 `Section` actions, a second filled `Button`/`ActionIcon` in one slot (outside an overlay)
|
|
626
|
-
| `basalt/control-outside-home` | The same raw control with no home at all — exempt under a settings row / overlay / composer, in an `@mantine/form` file, in a file that DEFINES a basalt control, or in a file basenamed `*-{modal,drawer,popover,panel,form}.tsx`
|
|
627
|
-
| `basalt/control-size-literal` | `size`/`w`/`fullWidth`/`visibleFrom`/`hiddenFrom` on anything inside a home slot (the slot sets the tier)
|
|
628
|
-
| `basalt/in-body-page-title` | `<Title order={1\|2}>` outside prose/overlay context and outside a `content/` path
|
|
629
|
-
| `basalt/responsive-twin` | The same control mounted twice, one `visibleFrom="X"` and one `hiddenFrom="X"`
|
|
630
|
-
| `basalt/search-literal-link` | A `search:` object literal in a `linkOptions()` inside `defineNav()`/`navGroup()`
|
|
631
|
-
| `basalt/use-search-from-literal` | `useSearch({ from: '<route>' })`
|
|
632
|
-
| `in-body-page-title` (guard kind) | The text lane of the same law — SAME id, so one annotation waives both lanes
|
|
633
|
-
| `raw-selection-control` (guard kind) | The text lane of `control-outside-home`, approximated by a 12-line host-tag window, plus the same overlay-basename exemption
|
|
1215
|
+
| Rule / kind | Fires on | Ships |
|
|
1216
|
+
| ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------- |
|
|
1217
|
+
| `basalt/hand-rolled-filter` | A raw Mantine `Select`/`SegmentedControl`/… handed to a TIERED home slot (`actions`/`filters`/`tabs`/`sync`/`filtersEnd` on `PageBar`/`Section`/`WidgetHeader`/`ChartCard`/`StatCard`/`BasaltDataTable`/`SettingsSection`/`FilterSet`) | error |
|
|
1218
|
+
| `basalt/page-bar-budget` | A second `PageBar` in the SAME returned tree, >4 `actions.secondary`, >3 `Section` actions, a second filled `Button`/`ActionIcon` in one slot (outside an overlay) | error |
|
|
1219
|
+
| `basalt/control-outside-home` | The same raw control with no home at all — exempt under a settings row / overlay / composer, in an `@mantine/form` file, in a file that DEFINES a basalt control (and imports no `basalt-ui`), or in a file basenamed `*-{modal,drawer,popover,panel,form}.tsx` / `<Subject>{Modal,Drawer,Popover,Panel,Form}.tsx` | warn → 1.30.0 |
|
|
1220
|
+
| `basalt/control-size-literal` | `size`/`w`/`fullWidth`/`visibleFrom`/`hiddenFrom` on anything inside a home slot (the slot sets the tier) | **error** |
|
|
1221
|
+
| `basalt/in-body-page-title` | `<Title order={1\|2}>` outside prose/overlay context and outside a `content/` path | **error** |
|
|
1222
|
+
| `basalt/responsive-twin` | The same control mounted twice, one `visibleFrom="X"` and one `hiddenFrom="X"` | **error** |
|
|
1223
|
+
| `basalt/search-literal-link` | A `search:` object literal in a `linkOptions()` inside `defineNav()`/`navGroup()` | **error** |
|
|
1224
|
+
| `basalt/use-search-from-literal` | `useSearch({ from: '<route>' })` | **error** |
|
|
1225
|
+
| `in-body-page-title` (guard kind) | The text lane of the same law — SAME id, so one annotation waives both lanes | **error** |
|
|
1226
|
+
| `raw-selection-control` (guard kind) | The text lane of `control-outside-home`, approximated by a 12-line host-tag window, plus the same overlay-basename exemption | warn → 1.30.0 |
|
|
634
1227
|
|
|
635
1228
|
**A `SettingsRow`'s `control` is not a tiered slot, so nothing in this table fires inside one.**
|
|
636
1229
|
It is law C1's third home — the form row — and a form keeps Mantine's `md` tier
|
|
@@ -1488,8 +2081,8 @@ deleting an entry forces the level flip in the same commit.
|
|
|
1488
2081
|
| `basalt/responsive-twin` | 1.26.0 as `warn` | **1.27.0** |
|
|
1489
2082
|
| `basalt/search-literal-link` | 1.26.0 as `warn` | **1.27.0** |
|
|
1490
2083
|
| `basalt/use-search-from-literal` | 1.26.0 as `warn` | **1.27.0** |
|
|
1491
|
-
| `basalt/control-outside-home` | 1.26.0 as `warn` | still `warn`, `promote: '1.
|
|
1492
|
-
| `raw-selection-control` (guard kind) | 1.26.0 as `warn` | still `warn`, `promote: '1.
|
|
2084
|
+
| `basalt/control-outside-home` | 1.26.0 as `warn` | still `warn`, `promote: '1.30.0'` — re-dated on 9 measured cross-file overlay warns in argo |
|
|
2085
|
+
| `raw-selection-control` (guard kind) | 1.26.0 as `warn` | still `warn`, `promote: '1.30.0'` — the text lane of the row above |
|
|
1493
2086
|
|
|
1494
2087
|
`card-with-border`, `inline-display`, `raw-html-layout`, `raw-form-control`, `raw-font-family` and
|
|
1495
2088
|
the other original guard kinds have been `error` since before 1.2.0 — they never had a grace minor.
|