basalt-ui 1.30.2 → 1.31.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 +1 -1
- package/CHANGELOG.md +31 -0
- package/MIGRATING.md +172 -12
- package/agent/rules/basalt-controls.md +19 -19
- package/agent/rules/basalt-mantine.md +1 -1
- package/configs/oxlint-plugin.js +254 -4
- package/configs/oxlint-plugin.test.ts +145 -2
- package/configs/oxlint.json +2 -1
- package/dist/agent-chat/composer.d.ts.map +1 -1
- package/dist/agent-chat/composer.js +41 -43
- package/dist/agent-chat/thread-workspace.d.ts +2 -2
- package/dist/agent-chat/thread-workspace.d.ts.map +1 -1
- package/dist/agent-chat/thread-workspace.js +3 -4
- package/dist/agent-chat/use-keyboard-inset.d.ts +2 -0
- package/dist/agent-chat/use-keyboard-inset.d.ts.map +1 -0
- package/dist/agent-chat/use-keyboard-inset.js +34 -0
- package/dist/charts/cursor/touch-pin.d.ts +45 -0
- package/dist/charts/cursor/touch-pin.d.ts.map +1 -0
- package/dist/charts/cursor/touch-pin.js +79 -0
- package/dist/charts/hooks/use-discrete-cursor.d.ts +66 -0
- package/dist/charts/hooks/use-discrete-cursor.d.ts.map +1 -0
- package/dist/charts/hooks/use-discrete-cursor.js +198 -0
- package/dist/charts/hooks/use-hysteresis.d.ts +18 -0
- package/dist/charts/hooks/use-hysteresis.d.ts.map +1 -0
- package/dist/charts/hooks/use-hysteresis.js +12 -0
- package/dist/charts/hooks/useBandPlot.d.ts +7 -0
- package/dist/charts/hooks/useBandPlot.d.ts.map +1 -1
- package/dist/charts/hooks/useBandPlot.js +62 -18
- package/dist/charts/hooks/useChartCursor.d.ts +40 -11
- package/dist/charts/hooks/useChartCursor.d.ts.map +1 -1
- package/dist/charts/hooks/useChartCursor.js +102 -11
- package/dist/charts/index.d.ts +0 -1
- package/dist/charts/index.d.ts.map +1 -1
- package/dist/charts/index.js +0 -10
- package/dist/charts/kinds/BandStrip.d.ts.map +1 -1
- package/dist/charts/kinds/BandStrip.js +54 -41
- package/dist/charts/kinds/Donut.d.ts +9 -3
- package/dist/charts/kinds/Donut.d.ts.map +1 -1
- package/dist/charts/kinds/Donut.js +110 -48
- package/dist/charts/kinds/DualPanel.d.ts.map +1 -1
- package/dist/charts/kinds/DualPanel.js +145 -131
- package/dist/charts/kinds/Heatmap.d.ts +7 -0
- package/dist/charts/kinds/Heatmap.d.ts.map +1 -1
- package/dist/charts/kinds/Heatmap.js +37 -16
- package/dist/charts/kinds/MirroredBars.d.ts.map +1 -1
- package/dist/charts/kinds/MirroredBars.js +83 -68
- package/dist/charts/kinds/donut-layout.d.ts +47 -0
- package/dist/charts/kinds/donut-layout.d.ts.map +1 -0
- package/dist/charts/kinds/donut-layout.js +52 -0
- package/dist/charts/layout/auto-margin.d.ts +7 -2
- package/dist/charts/layout/auto-margin.d.ts.map +1 -1
- package/dist/charts/layout/auto-margin.js +12 -3
- package/dist/charts/layout/end-labels.d.ts +64 -0
- package/dist/charts/layout/end-labels.d.ts.map +1 -0
- package/dist/charts/layout/end-labels.js +76 -0
- package/dist/charts/primitives/Axes.d.ts +32 -4
- package/dist/charts/primitives/Axes.d.ts.map +1 -1
- package/dist/charts/primitives/Axes.js +62 -16
- package/dist/charts/primitives/CartesianChart.d.ts +7 -6
- package/dist/charts/primitives/CartesianChart.d.ts.map +1 -1
- package/dist/charts/primitives/CartesianChart.js +271 -125
- package/dist/charts/primitives/ChartCard.d.ts +0 -14
- package/dist/charts/primitives/ChartCard.d.ts.map +1 -1
- package/dist/charts/primitives/ChartCard.js +74 -21
- package/dist/charts/primitives/ChartFrame.d.ts +28 -22
- package/dist/charts/primitives/ChartFrame.d.ts.map +1 -1
- package/dist/charts/primitives/ChartFrame.js +133 -34
- package/dist/charts/primitives/ChartLegend.d.ts +19 -15
- package/dist/charts/primitives/ChartLegend.d.ts.map +1 -1
- package/dist/charts/primitives/ChartLegend.js +212 -71
- package/dist/charts/primitives/ChartTooltip.d.ts.map +1 -1
- package/dist/charts/primitives/ChartTooltip.js +4 -3
- package/dist/charts/primitives/Crosshair.js +2 -2
- package/dist/charts/primitives/HoverOverlay.d.ts +6 -1
- package/dist/charts/primitives/HoverOverlay.d.ts.map +1 -1
- package/dist/charts/primitives/HoverOverlay.js +37 -26
- package/dist/charts/primitives/HoverOverlay.module.css +13 -0
- package/dist/charts/primitives/HoverOverlay.module.css.d.ts +8 -0
- package/dist/charts/primitives/chart-card-context.d.ts +29 -0
- package/dist/charts/primitives/chart-card-context.d.ts.map +1 -0
- package/dist/charts/primitives/chart-card-context.js +13 -0
- package/dist/charts/primitives/chart-frame-layout.d.ts +93 -113
- package/dist/charts/primitives/chart-frame-layout.d.ts.map +1 -1
- package/dist/charts/primitives/chart-frame-layout.js +76 -29
- package/dist/charts/primitives/chart-layout.d.ts +112 -0
- package/dist/charts/primitives/chart-layout.d.ts.map +1 -0
- package/dist/charts/primitives/chart-layout.js +175 -0
- package/dist/charts/primitives/chart-tier.d.ts +13 -11
- package/dist/charts/primitives/chart-tier.d.ts.map +1 -1
- package/dist/charts/primitives/chart-tier.js +42 -13
- package/dist/charts/series.d.ts +4 -1
- package/dist/charts/series.d.ts.map +1 -1
- package/dist/charts/utils/ticks.d.ts +27 -8
- package/dist/charts/utils/ticks.d.ts.map +1 -1
- package/dist/charts/utils/ticks.js +35 -11
- package/dist/common/errors.d.ts +11 -1
- package/dist/common/errors.d.ts.map +1 -1
- package/dist/common/errors.js +16 -2
- package/dist/common/hit-floor.d.ts +10 -0
- package/dist/common/hit-floor.d.ts.map +1 -0
- package/dist/common/hit-floor.js +6 -0
- package/dist/{shell → common}/isomorphic-layout-effect.d.ts +4 -3
- package/dist/common/isomorphic-layout-effect.d.ts.map +1 -0
- package/dist/common/use-measured-widths.d.ts +37 -0
- package/dist/common/use-measured-widths.d.ts.map +1 -0
- package/dist/common/use-measured-widths.js +51 -0
- package/dist/common/use-media-query.d.ts +6 -0
- package/dist/common/use-media-query.d.ts.map +1 -0
- package/dist/common/use-media-query.js +40 -0
- package/dist/common/validate.d.ts +9 -0
- package/dist/common/validate.d.ts.map +1 -1
- package/dist/common/validate.js +9 -4
- package/dist/content/article-layout.d.ts +4 -2
- package/dist/content/article-layout.d.ts.map +1 -1
- package/dist/content/article-layout.js +43 -3
- package/dist/content/article-layout.module.css +45 -4
- package/dist/content/article-layout.module.css.d.ts +3 -0
- package/dist/content/code-block.d.ts.map +1 -1
- package/dist/content/code-block.js +40 -2
- package/dist/content/code-block.module.css +32 -2
- package/dist/content/prose.module.css +13 -8
- package/dist/controls/actions.d.ts +29 -6
- package/dist/controls/actions.d.ts.map +1 -1
- package/dist/controls/actions.js +158 -27
- package/dist/controls/actions.module.css +14 -1
- package/dist/controls/actions.module.css.d.ts +1 -0
- package/dist/controls/controls.module.css +8 -31
- package/dist/controls/enum-filter.js +2 -2
- package/dist/controls/filter-context.d.ts +10 -0
- package/dist/controls/filter-context.d.ts.map +1 -1
- package/dist/controls/filter-context.js +2 -0
- package/dist/controls/filter-pill.d.ts.map +1 -1
- package/dist/controls/filter-pill.js +1 -0
- package/dist/controls/index.d.ts +1 -1
- package/dist/controls/index.d.ts.map +1 -1
- package/dist/controls/index.js +0 -2
- package/dist/controls/multi-select-filter.js +2 -2
- package/dist/controls/sync-button.module.css +1 -1
- package/dist/dashboard/section.d.ts.map +1 -1
- package/dist/dashboard/section.js +1 -0
- package/dist/dashboard/section.module.css +1 -26
- package/dist/dashboard/stat-card.d.ts +1 -1
- package/dist/dashboard/stat-card.d.ts.map +1 -1
- package/dist/dashboard/stat-card.js +4 -1
- package/dist/dashboard/stat-card.module.css +6 -9
- package/dist/dashboard/stat-group.module.css +16 -4
- package/dist/dashboard/widget-grid.d.ts.map +1 -1
- package/dist/dashboard/widget-header.d.ts +14 -4
- package/dist/dashboard/widget-header.d.ts.map +1 -1
- package/dist/dashboard/widget-header.js +23 -6
- package/dist/dashboard/widget-header.module.css +145 -133
- package/dist/dashboard/widget-header.module.css.d.ts +2 -0
- package/dist/data/data-table.d.ts +23 -0
- package/dist/data/data-table.d.ts.map +1 -1
- package/dist/data/data-table.js +339 -141
- package/dist/data/data-table.module.css +94 -0
- package/dist/data/data-table.module.css.d.ts +11 -0
- package/dist/data/virtual-list.d.ts.map +1 -1
- package/dist/data/virtual-list.js +10 -0
- package/dist/forms/form-layout.d.ts.map +1 -1
- package/dist/forms/form-layout.js +3 -3
- package/dist/forms/form-layout.module.css +30 -5
- package/dist/forms/form-layout.module.css.d.ts +1 -0
- package/dist/guard/index.d.ts +8 -2
- package/dist/guard/index.d.ts.map +1 -1
- package/dist/guard/index.js +67 -2
- package/dist/guard/types.d.ts +3 -3
- package/dist/guard/types.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/provider/index.d.ts +20 -1
- package/dist/provider/index.d.ts.map +1 -1
- package/dist/provider/index.js +22 -2
- package/dist/shell/app-brand.d.ts.map +1 -1
- package/dist/shell/app-brand.js +1 -0
- package/dist/shell/app-brand.module.css +2 -2
- package/dist/shell/app-header.module.css +18 -8
- package/dist/shell/app-main.module.css +54 -3
- package/dist/shell/app-main.module.css.d.ts +1 -0
- package/dist/shell/app-mobile-nav.module.css +16 -4
- package/dist/shell/app-sidebar.module.css +4 -6
- package/dist/shell/index.d.ts +12 -0
- package/dist/shell/index.d.ts.map +1 -1
- package/dist/shell/index.js +57 -16
- package/dist/shell/mobile-nav-model.d.ts +1 -1
- package/dist/shell/page-aside.d.ts +22 -3
- package/dist/shell/page-aside.d.ts.map +1 -1
- package/dist/shell/page-aside.js +27 -13
- package/dist/shell/page-bar.d.ts.map +1 -1
- package/dist/shell/page-bar.js +10 -5
- package/dist/shell/page-bar.module.css +10 -34
- package/dist/shell/use-breakpoint.d.ts +3 -4
- package/dist/shell/use-breakpoint.d.ts.map +1 -1
- package/dist/shell/use-breakpoint.js +3 -25
- package/dist/shell/use-size-class.d.ts +6 -0
- package/dist/shell/use-size-class.d.ts.map +1 -0
- package/dist/shell/use-size-class.js +19 -0
- package/dist/state/persisted-or-local.d.ts +4 -1
- package/dist/state/persisted-or-local.d.ts.map +1 -1
- package/dist/state/persisted-or-local.js +4 -3
- package/dist/state/persisted.d.ts +10 -0
- package/dist/state/persisted.d.ts.map +1 -1
- package/dist/state/persisted.js +44 -14
- package/dist/styles.css +41 -0
- package/dist/surfaces.d.ts +4 -4
- package/dist/surfaces.d.ts.map +1 -1
- package/dist/surfaces.js +11 -3
- package/dist/theme/controls.module.css +7 -0
- package/dist/theme/ctl-theme.d.ts +1 -0
- package/dist/theme/ctl-theme.d.ts.map +1 -1
- package/dist/theme/ctl-theme.js +12 -4
- package/dist/theme/floating.module.css +36 -0
- package/dist/theme/floating.module.css.d.ts +3 -0
- package/dist/theme/index.d.ts +2 -2
- package/dist/theme/index.d.ts.map +1 -1
- package/dist/theme/index.js +34 -5
- package/dist/theme/nav-link.module.css +7 -0
- package/dist/tokens/index.d.ts +7 -16
- package/dist/tokens/index.d.ts.map +1 -1
- package/dist/tokens/index.js +23 -28
- package/dist/tokens/palette.d.ts +5 -27
- package/dist/tokens/palette.d.ts.map +1 -1
- package/dist/tokens/palette.js +8 -30
- package/dist/tokens/size-classes.d.ts +40 -0
- package/dist/tokens/size-classes.d.ts.map +1 -0
- package/dist/tokens/size-classes.js +29 -0
- package/dist/tokens.css +8 -4
- package/llms.txt +3 -3
- package/package.json +17 -17
- package/src/agent-chat/composer.tsx +74 -47
- package/src/agent-chat/thread-workspace.tsx +8 -11
- package/src/agent-chat/use-keyboard-inset.ts +68 -0
- package/src/charts/cursor/touch-pin.ts +138 -0
- package/src/charts/hooks/use-discrete-cursor.ts +335 -0
- package/src/charts/hooks/use-hysteresis.ts +26 -0
- package/src/charts/hooks/useBandPlot.ts +90 -27
- package/src/charts/hooks/useChartCursor.ts +211 -26
- package/src/charts/index.ts +0 -8
- package/src/charts/kinds/BandStrip.tsx +11 -1
- package/src/charts/kinds/Donut.tsx +153 -62
- package/src/charts/kinds/DualPanel.tsx +19 -4
- package/src/charts/kinds/Heatmap.tsx +61 -22
- package/src/charts/kinds/MirroredBars.tsx +15 -3
- package/src/charts/kinds/donut-layout.ts +82 -0
- package/src/charts/layout/auto-margin.ts +24 -5
- package/src/charts/layout/end-labels.ts +135 -0
- package/src/charts/primitives/Axes.tsx +112 -21
- package/src/charts/primitives/CartesianChart.tsx +282 -68
- package/src/charts/primitives/ChartCard.tsx +141 -48
- package/src/charts/primitives/ChartFrame.tsx +243 -60
- package/src/charts/primitives/ChartLegend.tsx +257 -73
- package/src/charts/primitives/ChartTooltip.tsx +8 -3
- package/src/charts/primitives/Crosshair.tsx +2 -2
- package/src/charts/primitives/HoverOverlay.module.css +13 -0
- package/src/charts/primitives/HoverOverlay.module.css.d.ts +8 -0
- package/src/charts/primitives/HoverOverlay.tsx +15 -4
- package/src/charts/primitives/chart-card-context.ts +37 -0
- package/src/charts/primitives/chart-frame-layout.ts +214 -177
- package/src/charts/primitives/chart-layout.ts +318 -0
- package/src/charts/primitives/chart-tier.tsx +66 -21
- package/src/charts/series.ts +4 -1
- package/src/charts/utils/ticks.ts +95 -19
- package/src/common/errors.ts +25 -1
- package/src/common/hit-floor.ts +9 -0
- package/src/{shell → common}/isomorphic-layout-effect.ts +4 -3
- package/src/common/use-measured-widths.ts +88 -0
- package/src/common/use-media-query.ts +56 -0
- package/src/common/validate.ts +17 -4
- package/src/content/article-layout.module.css +45 -4
- package/src/content/article-layout.module.css.d.ts +3 -0
- package/src/content/article-layout.tsx +60 -5
- package/src/content/code-block.module.css +32 -2
- package/src/content/code-block.tsx +47 -3
- package/src/content/prose.module.css +13 -8
- package/src/controls/actions.module.css +14 -1
- package/src/controls/actions.module.css.d.ts +1 -0
- package/src/controls/actions.tsx +223 -75
- package/src/controls/controls.module.css +8 -31
- package/src/controls/enum-filter.tsx +2 -2
- package/src/controls/filter-context.tsx +11 -0
- package/src/controls/filter-pill.tsx +1 -0
- package/src/controls/index.ts +0 -1
- package/src/controls/multi-select-filter.tsx +2 -2
- package/src/controls/sync-button.module.css +1 -1
- package/src/dashboard/section.module.css +1 -26
- package/src/dashboard/section.tsx +1 -0
- package/src/dashboard/stat-card.module.css +6 -9
- package/src/dashboard/stat-card.tsx +6 -3
- package/src/dashboard/stat-group.module.css +16 -4
- package/src/dashboard/widget-grid.tsx +7 -6
- package/src/dashboard/widget-header.module.css +145 -133
- package/src/dashboard/widget-header.module.css.d.ts +2 -0
- package/src/dashboard/widget-header.tsx +45 -11
- package/src/data/data-table.module.css +94 -0
- package/src/data/data-table.module.css.d.ts +11 -0
- package/src/data/data-table.tsx +503 -164
- package/src/data/virtual-list.tsx +31 -0
- package/src/forms/form-layout.module.css +30 -5
- package/src/forms/form-layout.module.css.d.ts +1 -0
- package/src/forms/form-layout.tsx +12 -10
- package/src/guard/index.ts +183 -3
- package/src/guard/types.ts +3 -2
- package/src/index.ts +2 -0
- package/src/provider/index.tsx +53 -1
- package/src/shell/app-brand.module.css +2 -2
- package/src/shell/app-brand.tsx +1 -0
- package/src/shell/app-header.module.css +18 -8
- package/src/shell/app-main.module.css +54 -3
- package/src/shell/app-main.module.css.d.ts +1 -0
- package/src/shell/app-mobile-nav.module.css +16 -4
- package/src/shell/app-sidebar.module.css +4 -6
- package/src/shell/index.tsx +200 -129
- package/src/shell/mobile-nav-model.ts +1 -1
- package/src/shell/page-aside.tsx +70 -21
- package/src/shell/page-bar.module.css +10 -34
- package/src/shell/page-bar.tsx +10 -5
- package/src/shell/use-breakpoint.ts +9 -45
- package/src/shell/use-size-class.ts +31 -0
- package/src/state/persisted-or-local.ts +10 -4
- package/src/state/persisted.ts +76 -17
- package/src/styles.css +41 -0
- package/src/surfaces.ts +9 -1
- package/src/theme/controls.module.css +7 -0
- package/src/theme/ctl-theme.tsx +15 -3
- package/src/theme/floating.module.css +36 -0
- package/src/theme/floating.module.css.d.ts +3 -0
- package/src/theme/index.ts +46 -8
- package/src/theme/nav-link.module.css +7 -0
- package/src/tokens/index.ts +20 -30
- package/src/tokens/palette.ts +6 -28
- package/src/tokens/size-classes.ts +46 -0
- package/dist/shell/isomorphic-layout-effect.d.ts.map +0 -1
- /package/dist/{shell → common}/isomorphic-layout-effect.js +0 -0
package/AGENTS.md
CHANGED
|
@@ -8,7 +8,7 @@ Toolchain: Bun runtime, oxlint + oxfmt, conventional commits (empty scope), `mas
|
|
|
8
8
|
|
|
9
9
|
| Subpath | Layer | Purpose |
|
|
10
10
|
| --------------------------- | --------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
11
|
-
| `basalt-ui` | mantine-coupled | BasaltProvider, createBasaltTheme, BasaltShell + sidebar/mobile-nav/breadcrumbs, PageBar, PageAside, useBreakpoint, NavCountBadge, ThemeToggle, ThreadWorkspace + thread-chat components, WidgetHeader, dashboard composites (DeltaBadge, StatCard with threshold tone, EmptyState, QueryState/LoadingState/ErrorState, SettingsSection/SettingsRow/DangerZone), ConnectivityProvider/useConnectivity/ConnectivityIndicator (auto-mounted, C1: absorbed from the dropped ./connectivity), createBasaltQueryClient/unwrap/BasaltQueryDevtools (C1: absorbed from the dropped ./query), BasaltDevDock (C5: lazy Router/Query devtools + theme lab in one dock)
|
|
11
|
+
| `basalt-ui` | mantine-coupled | BasaltProvider, createBasaltTheme, BasaltShell + sidebar/mobile-nav/breadcrumbs, PageBar, PageAside, useSizeClass (useBreakpoint on notice), NavCountBadge, ThemeToggle, ThreadWorkspace + thread-chat components, WidgetHeader, dashboard composites (DeltaBadge, StatCard with threshold tone, EmptyState, QueryState/LoadingState/ErrorState, SettingsSection/SettingsRow/DangerZone), ConnectivityProvider/useConnectivity/ConnectivityIndicator (auto-mounted, C1: absorbed from the dropped ./connectivity), createBasaltQueryClient/unwrap/BasaltQueryDevtools (C1: absorbed from the dropped ./query), BasaltDevDock (C5: lazy Router/Query devtools + theme lab in one dock) |
|
|
12
12
|
| `basalt-ui/charts` | headless | CartesianChart + visx chart primitives, kinds, sparklines, hooks, and token re-exports (Mantine-free) |
|
|
13
13
|
| `basalt-ui/tokens` | headless | VX token refs, buildPaletteCss, defineSeries, seriesTokens, groupTokens, alpha (Mantine-free) |
|
|
14
14
|
| `basalt-ui/theme-lab` | mantine-coupled | ThemeLabControls, applyOverrides, COLOR_GROUPS — a low-level inspector for the non-derived structural tokens; identity/color tuning lives in DeriveControls |
|
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,34 @@
|
|
|
1
|
+
# [1.31.0](https://github.com/jkrumm/basalt-ui/compare/v1.30.2...v1.31.0) (2026-09-28)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* card and legend correctness — hysteresis, dots fit, slot ownership ([890658f](https://github.com/jkrumm/basalt-ui/commit/890658fc6ac5d2ffac1e04b79f6ec8d33f73e583))
|
|
7
|
+
* close responsive-guard gaps and dedupe measured-fold/hit-floor internals ([d37d9c2](https://github.com/jkrumm/basalt-ui/commit/d37d9c29151a65ffc83a9cce9344e602b223bfce))
|
|
8
|
+
* economise chart axis space with a shared y-placement ladder ([05562c7](https://github.com/jkrumm/basalt-ui/commit/05562c748bff5b6f2bf62b020e6d112463e615d1))
|
|
9
|
+
* give the plot its space — inside-y floor, wrap law, height clamp ([16e3e18](https://github.com/jkrumm/basalt-ui/commit/16e3e189c62170151d72014000140726c94a2204))
|
|
10
|
+
* keep a committed chart pin through a cancelled second press ([53e0264](https://github.com/jkrumm/basalt-ui/commit/53e0264343ffd2c06fe666bc916d6159c28ab16d))
|
|
11
|
+
* make chart touch presses provisional and dismiss on scroll ([c0ee0ae](https://github.com/jkrumm/basalt-ui/commit/c0ee0ae17cb6ecaf91183107b26c7f35a026b83f))
|
|
12
|
+
* resolve the pre-release review findings ([a33b6dd](https://github.com/jkrumm/basalt-ui/commit/a33b6ddd58519912698f3dc5b7a6a2c7ff5adf92))
|
|
13
|
+
* thin rotated x labels by projected width, default charts to regular ([105b12d](https://github.com/jkrumm/basalt-ui/commit/105b12d36900846212c7cf91eb6361fe4a554ae5))
|
|
14
|
+
* touch floors, filter hit gap, form-row container width, composer padding ([a12f230](https://github.com/jkrumm/basalt-ui/commit/a12f230963270a8785070b6711768204548fe02d))
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
### Features
|
|
18
|
+
|
|
19
|
+
* adopt the pointer-tier hit area, gate hover reveals, sheet the modal ([3a63850](https://github.com/jkrumm/basalt-ui/commit/3a63850b489190927d221eaea62d67dd1a8d1f62))
|
|
20
|
+
* drop the dead chart-tier API and consolidate media-query hooks ([b255dcf](https://github.com/jkrumm/basalt-ui/commit/b255dcf5d408b34bec76a4b6a9e5da712e27fa52))
|
|
21
|
+
* fit chart legends by measured width, fold donut and label line ends ([5f0c5bd](https://github.com/jkrumm/basalt-ui/commit/5f0c5bd16cd3abd0b7772da991321ceaff8a1477))
|
|
22
|
+
* fold chart-card headers by height, not width alone ([9d7fc88](https://github.com/jkrumm/basalt-ui/commit/9d7fc889c5981b08db8bd47908a6598c94a55999))
|
|
23
|
+
* fold DataTable columns, warn short rows, sheet the TOC, pin composer keys ([f3bd775](https://github.com/jkrumm/basalt-ui/commit/f3bd775a57411bcb42a0ff49cfc3ae3a80d5a162))
|
|
24
|
+
* fold short-card chart legends to dots, ship the raw-breakpoint guards ([2557d9d](https://github.com/jkrumm/basalt-ui/commit/2557d9dc88438cbb88e0b7a90c572c69dd79c827))
|
|
25
|
+
* key card chrome on the card's own width ([aa407b8](https://github.com/jkrumm/basalt-ui/commit/aa407b866a0d9b343ce5b48f2b3c8f2b60341888))
|
|
26
|
+
* pin chart tooltips on tap, add keyboard parity to donut and heatmap ([a9cc50a](https://github.com/jkrumm/basalt-ui/commit/a9cc50aa6dd0626e3d312eba068cf95bbf50817b))
|
|
27
|
+
* resolve chart layout from the container class, height from width ([ae9632c](https://github.com/jkrumm/basalt-ui/commit/ae9632c010f58c02f49659cec1343bb8c1e23540))
|
|
28
|
+
* size-class shell docking, measured page-bar fold and toast bottom inset ([1fd619d](https://github.com/jkrumm/basalt-ui/commit/1fd619db7f58d81b60b20832b6353968b957c905))
|
|
29
|
+
* spend compact-width axes on the plot, not the gutters ([b0d5b49](https://github.com/jkrumm/basalt-ui/commit/b0d5b49f442a471f1a53b2fb57c90144efb66095))
|
|
30
|
+
* three-axis responsive foundations and --vx-hit ([6609ec1](https://github.com/jkrumm/basalt-ui/commit/6609ec1d62d189184dd512c12334963fb8fe0b84))
|
|
31
|
+
|
|
1
32
|
## [1.30.2](https://github.com/jkrumm/basalt-ui/compare/v1.30.1...v1.30.2) (2026-09-09)
|
|
2
33
|
|
|
3
34
|
|
package/MIGRATING.md
CHANGED
|
@@ -66,18 +66,18 @@ There is one row per SURFACE, not per export, and a surface earns a row once any
|
|
|
66
66
|
shipped lefthook preset both changed in 1.30.0 with no row that owned them — which is how a
|
|
67
67
|
consumer read this index, found nothing, and diffed a KPI row that had silently gone 4-up → 2-up.
|
|
68
68
|
|
|
69
|
-
| Surface | 1.27.0 | 1.28.0 | 1.29.0 | 1.30.0 | 1.30.1 | 1.30.2 | Unreleased |
|
|
70
|
-
| ----------------------------- | ------------------------------------------------------------ | -------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | --------------------------------------------------------------------- | ------ | ---------- |
|
|
71
|
-
| **tokens** (`./tokens`) | — | `--vx-divider` → `rgba()` on both schemes (§ Shell) | `--vx-space-touch-target` added (§ Additions) | eight spacing numbers (§ Chrome) | — | — | — |
|
|
72
|
-
| **charts** (`./charts`) | — | phone tier, `curve`, formatters, `state`, log axis (§ preamble) | `ChartState.empty: string`, `AxisBottomNumeric` (§ Additions) | responsive `height`, `legend.maxRows` (§ Charts) | `height` reaches the kinds; `maxRows` beats the `fill` fit (§ Charts) | — | — |
|
|
73
|
-
| **shell** (`.`) | — | scrollport, region seams, **the brand left the sidebar** (§§ scrollport, brand, Shell) | `PageTitle`, `BasaltDevDock`, `useBreakpoint` (§ Additions) | More popover, aside pill, the responsive gutter, `useBasaltSpacing` (§ Chrome) | — | — | — |
|
|
74
|
-
| **controls** (`./controls`) | `NumberFilter`, `field.number` (§ Controls) | sheet renders panel rows; `PanelRow`, `SliderControl` (§ `basalt-ui/controls`) | — | — | — | — | — |
|
|
75
|
-
| **forms** (`./forms`) | — | `field` → `inputProps`, **`inputProps` drops `key`**, the layout tier (§ `inputProps`) | `field` DELETED — and the `--fix` recipe no longer works (§ Consolidation) | — | — | — | — |
|
|
76
|
-
| **data** (`./data/table`) | — | root is a `<div>`, row selection, `getItemKey` required (§ `basalt-ui/data`) | `./data` + `./query` + `./connectivity` dropped (§ Consolidation) | — | — | — | — |
|
|
77
|
-
| **dashboard** (`.`) | `StatCard`: `unit`, `breakdown`, delta format (§ `StatCard`) | `StatGroup`, `WidgetGrid`, query-aware `StatCard` — additive | — | **the column law keys on the CONTAINER; `cols={4}` is 2-up at `sm`** (§ Dashboard) | — | — | — |
|
|
78
|
-
| **toolchain** (`./configs/*`) | — | — | the shipped lefthook preset's `check-theme` BROKE — the CLI resolver stopped ascending (§ CLI) | the preset's default bin, and the `root:` recipe (§ Toolchain) | — | — | — |
|
|
79
|
-
| **CLI** (`basalt-ui`) | — | — | **resolver stops relocating; `doctor` loses 6 of 10 checks** (§ CLI) | — | — | — | — |
|
|
80
|
-
| **guards** | five rules → `error` (§ Guards) | six new ids at `warn` (§ preamble) | `query-dual-import` retired in 1.29.1 (§ Guards) | four rules → `error` (§ Guards) | — | — | — |
|
|
69
|
+
| Surface | 1.27.0 | 1.28.0 | 1.29.0 | 1.30.0 | 1.30.1 | 1.30.2 | 1.31.0 | Unreleased |
|
|
70
|
+
| ----------------------------- | ------------------------------------------------------------ | -------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | --------------------------------------------------------------------- | ------ | --------------------------------------------------------------------------------------------------------- | ---------- |
|
|
71
|
+
| **tokens** (`./tokens`) | — | `--vx-divider` → `rgba()` on both schemes (§ Shell) | `--vx-space-touch-target` added (§ Additions) | eight spacing numbers (§ Chrome) | — | — | `--vx-hit` replaces the touch vars; `SIZE_CLASSES` (§ Unreleased) | — |
|
|
72
|
+
| **charts** (`./charts`) | — | phone tier, `curve`, formatters, `state`, log axis (§ preamble) | `ChartState.empty: string`, `AxisBottomNumeric` (§ Additions) | responsive `height`, `legend.maxRows` (§ Charts) | `height` reaches the kinds; `maxRows` beats the `fill` fit (§ Charts) | — | container-class tier + `height` keys (§ Unreleased) | — |
|
|
73
|
+
| **shell** (`.`) | — | scrollport, region seams, **the brand left the sidebar** (§§ scrollport, brand, Shell) | `PageTitle`, `BasaltDevDock`, `useBreakpoint` (§ Additions) | More popover, aside pill, the responsive gutter, `useBasaltSpacing` (§ Chrome) | — | — | `theme.breakpoints` derived, `useSizeClass`, `data-basalt-host`, `useBreakpoint` on notice (§ Unreleased) | — |
|
|
74
|
+
| **controls** (`./controls`) | `NumberFilter`, `field.number` (§ Controls) | sheet renders panel rows; `PanelRow`, `SliderControl` (§ `basalt-ui/controls`) | — | — | — | — | — | — |
|
|
75
|
+
| **forms** (`./forms`) | — | `field` → `inputProps`, **`inputProps` drops `key`**, the layout tier (§ `inputProps`) | `field` DELETED — and the `--fix` recipe no longer works (§ Consolidation) | — | — | — | — | — |
|
|
76
|
+
| **data** (`./data/table`) | — | root is a `<div>`, row selection, `getItemKey` required (§ `basalt-ui/data`) | `./data` + `./query` + `./connectivity` dropped (§ Consolidation) | — | — | — | — | — |
|
|
77
|
+
| **dashboard** (`.`) | `StatCard`: `unit`, `breakdown`, delta format (§ `StatCard`) | `StatGroup`, `WidgetGrid`, query-aware `StatCard` — additive | — | **the column law keys on the CONTAINER; `cols={4}` is 2-up at `sm`** (§ Dashboard) | — | — | — | — |
|
|
78
|
+
| **toolchain** (`./configs/*`) | — | — | the shipped lefthook preset's `check-theme` BROKE — the CLI resolver stopped ascending (§ CLI) | the preset's default bin, and the `root:` recipe (§ Toolchain) | — | — | — | — |
|
|
79
|
+
| **CLI** (`basalt-ui`) | — | — | **resolver stops relocating; `doctor` loses 6 of 10 checks** (§ CLI) | — | — | — | — | — |
|
|
80
|
+
| **guards** | five rules → `error` (§ Guards) | six new ids at `warn` (§ preamble) | `query-dual-import` retired in 1.29.1 (§ Guards) | four rules → `error` (§ Guards) | — | — | — | — |
|
|
81
81
|
|
|
82
82
|
---
|
|
83
83
|
|
|
@@ -86,6 +86,166 @@ consumer read this index, found nothing, and diffed a KPI row that had silently
|
|
|
86
86
|
_Nothing yet. Author the next section under this heading as `## Unreleased — <title>`; the
|
|
87
87
|
release renames it and opens a new one here._
|
|
88
88
|
|
|
89
|
+
## 1.31.0 — size classes and the pointer tier
|
|
90
|
+
|
|
91
|
+
`theme.breakpoints` is now derived from `SIZE_CLASSES` (compact < 840, medium 840–1199, expanded
|
|
92
|
+
≥ 1200) and **no longer overridable** — `createBasaltTheme` drops a `breakpoints` override and types
|
|
93
|
+
it out. Mapping: `xs` = `sm` = 52.5em (medium opens), `md` = `lg` = `xl` = 75em (expanded opens) — the
|
|
94
|
+
keys collapse. So `xs` moves 36em → 52.5em, `sm` 48em → 52.5em (an iPad portrait is now bottom-bar chrome), `md`
|
|
95
|
+
62em → 75em, `lg` stays 75em and `xl` 88em → 75em. Check every `visibleFrom`/`hiddenFrom`/`useBreakpoint`
|
|
96
|
+
on those keys: `xs` no longer differs from `sm`, and `md`/`lg`/`xl` now switch at the same width.
|
|
97
|
+
|
|
98
|
+
| Removed | Replacement |
|
|
99
|
+
| --------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
100
|
+
| `VX.spaceTouchTarget`, `--vx-space-touch-target` | `VX.hit`, `--vx-hit` (24px on fine pointers, 44px under `(pointer: coarse)`) |
|
|
101
|
+
| `VX.space.touchControlHeight`, `--vx-space-touch-control-height` | `VX.hit`; density-exempt, so it no longer tracks the knob |
|
|
102
|
+
| `DESKTOP_SECONDARY_MAX` (`./controls`) | none — `PageBar` row 1 folds secondary actions by its measured width (icon-only, then into `More`); removed with no grace window because nothing but the row's own count read it |
|
|
103
|
+
| `resolveChartTier`, `chartTierMetrics`, `useChartTier`, `useChartTierMetrics`, `ChartTier`, `ChartTierMetrics` (`./charts`) | none — removed, no grace: zero consumers. Chart chrome sizes follow the measured container class internally; there is no public tier API to read it from |
|
|
104
|
+
| `VX.phoneChartWidth` | `CONTAINER_CLASSES.regular` (`basalt-ui/tokens`) — removed, no grace: zero consumers, and the constant no longer drove any resolution |
|
|
105
|
+
| `ResponsiveChartHeight.sm/md/lg` | `regular` / `wide` — removed, no grace: zero consumers |
|
|
106
|
+
| `legend.mode` (every kind's `ChartLegendConfig`, `ChartFrameLegend`) | none — the resolver's own 'dots'/'chips' pick is the law; a speculative escape hatch with zero consumers that could silently re-open the plot-eating legend the wave-11 chain removed |
|
|
107
|
+
| `BasaltProvider host` | none — `<html data-basalt-host>` is now always auto-detected (`pwa`/`web`); re-add when a Capacitor/Tauri consumer is named |
|
|
108
|
+
|
|
109
|
+
| Changed | Notes |
|
|
110
|
+
| ------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
111
|
+
| Themed `Modal` is a bottom sheet below the `medium` size class; `./content` hover-reveal affordances are visible on touch | Opt out of the sheet by overriding `classNames.inner`/`content`/`body`. A consumer `attributes` (Switch/Checkbox/Radio) or `closeButtonProps` (Modal) replaces the shipped `data-basalt-hit` shallowly — re-add `'data-basalt-hit': true` where needed. |
|
|
112
|
+
|
|
113
|
+
`--vx-space-mobile-nav-row-height` is 44px (was 40). A hit overlay is `[data-basalt-hit]` in
|
|
114
|
+
`styles.css`; the home controls' overlays now key on `(pointer: coarse)` instead of width.
|
|
115
|
+
|
|
116
|
+
**A touch press on a chart is now PROVISIONAL, not pinned on contact** (behaviour change; `useChartCursor`'s exported `ChartCursor<T>` type gains a required `onPointerUp` field and widens `onPointerLeave` to take the pointer event — source-compatible for the normal `{...cursor}`/JSX-prop usage every shipped kind and consumer chart uses, but a manual `cursor.onPointerLeave()` call with no argument now throws). `pointerdown` still resolves and shows immediately; `pointerup` for that pointer commits the pin; a `pointercancel`/`pointerleave` before commit (the browser taking the gesture as a scroll) clears the readout instead of leaving it pinned. A pinned tooltip is now also dismissed by a `document` scroll and by Escape from anywhere in the document, not just an overlay that holds focus. A bespoke chart wired directly to `HoverOverlay` (the five declared non-`CartesianChart` shapes, or a consumer's own) needs to pass through the hook's new `onPointerUp`/`onUp` the same way it already passes `onDown`/`onMove`.
|
|
117
|
+
|
|
118
|
+
**Chart axes economise space at `compact`/`micro` container width** (behaviour change, no API change).
|
|
119
|
+
Y labels draw inside the plot over the grid, on a solid background chip (wave 8: was a thin surface
|
|
120
|
+
halo stroke, which still let the digits visually blend into a bar's fill — a bar/band chart's first
|
|
121
|
+
and last ticks sit directly over drawn ink with no clear region the way a line/area chart's do) and
|
|
122
|
+
the left gutter drops to its floor; `micro` drops the y axis and keeps two x terminals; terminal x
|
|
123
|
+
labels anchor inward; multi-word x labels wrap before they rotate (rotate only past 2x what fits). A
|
|
124
|
+
tick within one line-height of the plot's top edge flips its label below the tick line instead of
|
|
125
|
+
above it, so it no longer clips against the chart's own SVG viewBox (wave 8). At every width y labels
|
|
126
|
+
over 4 chars compact (`12.5k`, `1.2M`) and the y tick count is one per ~44px of plot height (min 2).
|
|
127
|
+
Opt out with explicit props: `margin.left` (keeps y labels outside), `y.format`, `y.ticks`,
|
|
128
|
+
`xLabelRotate`.
|
|
129
|
+
|
|
130
|
+
**`useSizeClass()` (`.`) is added** — `'compact' | 'medium' | 'expanded'`, `useSyncExternalStore`
|
|
131
|
+
over one `MediaQueryList` per boundary. Its server snapshot is the new `<BasaltProvider
|
|
132
|
+
sizeClassHint>` (default `'compact'`). `PageAside` and `ThreadWorkspace` now read it: the first
|
|
133
|
+
server/hydration frame is `compact` unless a hint says otherwise, so an SSR app that used to get the
|
|
134
|
+
desktop `PageAside` projection first should pass `sizeClassHint`. `ThreadWorkspace`'s narrow layout
|
|
135
|
+
follows the compact class (< 840px, was < `sm` 48em).
|
|
136
|
+
|
|
137
|
+
**`<html data-basalt-host="web|pwa">`** is set by `BasaltProvider` (`pwa` when
|
|
138
|
+
`(display-mode: standalone)` matches, else `web` — always auto-detected; the `host="native"` force
|
|
139
|
+
had zero consumers and is removed). The shell's safe-area padding keys on a non-`web` host instead
|
|
140
|
+
of a raw `display-mode` query.
|
|
141
|
+
|
|
142
|
+
**`PageAside`'s `defaultFolded` default now depends on whether the aside can dock.** Where an open
|
|
143
|
+
aside would push main (`expanded`, main keeps its floor width) it starts open; everywhere else it
|
|
144
|
+
would overlay main, so it starts folded on the rail. An explicit choice — a persisted or toggled fold —
|
|
145
|
+
always wins. Opt out with `defaultFolded={false}` (open everywhere) or `defaultFolded` (folded
|
|
146
|
+
everywhere).
|
|
147
|
+
|
|
148
|
+
**The navbar defaults to the rail in the `medium` class** while nothing is persisted under
|
|
149
|
+
`storageKey`. Opt out with a controlled `collapsed` prop; a persisted `false` (the user opened it
|
|
150
|
+
once) pins it open.
|
|
151
|
+
|
|
152
|
+
**On notice — `useBreakpoint` (removed next minor).** `@deprecated`, still works. Replace
|
|
153
|
+
`useBreakpoint('sm')` with `useSizeClass() !== 'compact'`, and `useBreakpoint('lg')` with
|
|
154
|
+
`useSizeClass() === 'expanded'`. A `max`-edge or non-shell width read is a container concern: use
|
|
155
|
+
`@container` in CSS.
|
|
156
|
+
|
|
157
|
+
**Card chrome keys on the card's own width, not the viewport.** `ChartCard`, `StatCard` and `Section`
|
|
158
|
+
are now `container: basalt-card / inline-size` (`container-type: inline-size` — layout and inline-size
|
|
159
|
+
containment). That has two consequences: a card needs a **definite inline size** (a block child, a
|
|
160
|
+
grid `1fr` track or an explicit width — it can no longer shrink-to-fit inside a flex row or an `auto`
|
|
161
|
+
grid track, where it would collapse to 0), and it becomes the containing block for `position: fixed`
|
|
162
|
+
and absolute descendants. What moved onto the card's width (`CONTAINER_CLASSES`: micro < 240,
|
|
163
|
+
compact 240–479, regular 480–799, wide ≥ 800):
|
|
164
|
+
|
|
165
|
+
- **Under 480px, or under 280px of the card's own HEIGHT regardless of width (wave 8), `subtitle`
|
|
166
|
+
folds into the info glyph** and the visible line is hidden. A card with a `subtitle` and no `info`
|
|
167
|
+
now renders a `More information` button (hidden past both floors); with both, the one glyph's
|
|
168
|
+
bubble reads `info`, then `subtitle`. A test asserting the subtitle is visible in a narrow OR short
|
|
169
|
+
card, or that no `More information` button exists without `info`, needs updating. The height half
|
|
170
|
+
is JS-measured (`ChartCard` only, via a `data-basalt-card-short` attribute it sets from its own
|
|
171
|
+
rendered height) rather than a `@container` size query — `container-type: size` collapses an
|
|
172
|
+
auto-height card to 0, so there is no CSS-only way to query a card's own height without an
|
|
173
|
+
explicit size. `StatCard`/`Section` do not (yet) set the attribute, so only `ChartCard` folds by
|
|
174
|
+
height today.
|
|
175
|
+
- **From 480px (was 800px in 1.30.x — wave 8), `value` + `delta` sit on the title row**, before
|
|
176
|
+
`actions`, instead of on their own row. The KPI value never ellipsizes any more: it shrinks with
|
|
177
|
+
the card (`cqi`, `kpi` → 16px) and breaks a pathological string rather than clipping it. A short
|
|
178
|
+
`ChartCard` (see above) also shrinks the value to the `lg` step and trims the header's own top
|
|
179
|
+
inset, so a short-but-wide chart card's header stays at or under a fifth of the card's height.
|
|
180
|
+
- **`StatCard` `sparklinePlacement="right"` collapses to the stacked layout** when the card is under
|
|
181
|
+
480px wide (it keyed to the viewport's `sm` before). Two-up cards on a
|
|
182
|
+
desktop that kept the sparkline beside the value now stack when the card itself is narrow.
|
|
183
|
+
- **`StatGroup` is one column under 260px** of its own width, with no leading rail hairline.
|
|
184
|
+
- `ChartCard` is a flex column (`display: flex`, body `flex: 1 1 auto`): in a stretched grid row the
|
|
185
|
+
spare height goes to the body.
|
|
186
|
+
- **The chart tier is the measured container class** (`micro`/`compact` < 480px keep the old phone
|
|
187
|
+
metrics; `regular`/`wide` the desktop ones). **Hard removal, no grace window: `resolveChartTier`,
|
|
188
|
+
`chartTierMetrics`, `useChartTier`, `useChartTierMetrics`, `ChartTier`, `ChartTierMetrics` and
|
|
189
|
+
`VX.phoneChartWidth`.** Zero consumers, so these ship straight to removed rather than carrying a
|
|
190
|
+
deprecated forwarder for one more minor — there is no replacement export; chart chrome sizes
|
|
191
|
+
follow the measured container class internally, with no public tier API to read it from.
|
|
192
|
+
`ChartTierMetrics.legendMaxRows` (the field a stated `legend.maxRows` could never actually reach,
|
|
193
|
+
since the tier no longer caps a legend) goes with the type; state a cap with `legend.maxRows`
|
|
194
|
+
directly where one is wanted. **Before the first measurement the class follows the viewport**
|
|
195
|
+
(`<BasaltProvider sizeClassHint>`, default `compact`), so an unmeasured first frame is
|
|
196
|
+
phone-shaped unless a hint says otherwise. With no `BasaltProvider` at all (a charts-only
|
|
197
|
+
consumer) it is `regular`, never phone chrome.
|
|
198
|
+
- **`ResponsiveChartHeight` keys are `base` / `regular` / `wide`** (from 480 / 800px of the frame's
|
|
199
|
+
measured width). **Hard removal, no grace window: the `sm`/`md`/`lg` aliases.** Zero consumers, so
|
|
200
|
+
the old keys are gone outright rather than warning for a minor first — `sm` was `regular` (768 →
|
|
201
|
+
480px), `md`/`lg` were `wide` (992/1200 → 800px, one step). A `height={{ sm: … }}` object now
|
|
202
|
+
fails `tsc` on the unknown key; rename to `regular`/`wide` and re-check any object that relied on
|
|
203
|
+
the old widths. **On notice (adopt-or-delete): the whole object form.** Nothing under
|
|
204
|
+
`~/SourceRoot` uses `{ base, regular, wide }` over a plain number — the derived height law
|
|
205
|
+
(`ChartFrame` with no `height`, next bullet) already covers the common case a per-step height
|
|
206
|
+
existed for. A future minor may drop it for a plain number plus an explicit override, unless a
|
|
207
|
+
consumer names a need for it first.
|
|
208
|
+
- **`ChartFrame` with no `height` derives one** from its measured width (≈0.62 / 0.5 / 0.4 × width by
|
|
209
|
+
class, clamped 160–420, and to 0.45 × viewport height on a coarse pointer) instead of 240. A
|
|
210
|
+
numeric `height` is an override and warns once in dev when it leaves the plot under
|
|
211
|
+
`VX.minPlotHeight`. Inside a `ChartCard` the height is a minimum: the frame grows into a taller
|
|
212
|
+
card body.
|
|
213
|
+
- **The legend fits by measured width, and `legend.maxRows` is `@deprecated`** (dev-warns once,
|
|
214
|
+
removed in 1.32.0; an explicit value still wins this release, as an entry count). Overflow folds
|
|
215
|
+
into an **`All N`** chip (was `+N more` / `Show less`) that opens every entry, toggles included, in
|
|
216
|
+
a popover on a fine pointer and a bottom sheet on a coarse one — it never grows the band. A legend
|
|
217
|
+
never rolls up fewer than 2 entries and left-aligns (was centred) with a 6px row gap. Inside a
|
|
218
|
+
`ChartCard` with a header the legend now renders in the header slot instead of under the plot; a
|
|
219
|
+
frame under 240px (micro) draws no legend. The phone tier no longer caps a legend at two entries
|
|
220
|
+
by default.
|
|
221
|
+
- **Hard removal, no grace window: `legend.mode`.** A speculative escape hatch back to labels for a
|
|
222
|
+
chart in a short card, added with zero consumers — the resolver's own `'dots'`/`'chips'` pick is
|
|
223
|
+
now the only law, with no override.
|
|
224
|
+
- **Selectors and text matching the old rollup move.** Anything matching `+N more` / `Show less`
|
|
225
|
+
(tests, e2e selectors, screenshots' text) now matches the `All N` chip and the disclosure it opens
|
|
226
|
+
(`role="dialog"`, name `Legend`, `data-basalt-legend-disclosure`); there is no in-place expand.
|
|
227
|
+
- **Standalone `ChartLegend` no longer applies a tier entry cap.** It renders every entry unless
|
|
228
|
+
`maxRows` is passed; only `ChartFrame` derives a cap (from the measured fit).
|
|
229
|
+
|
|
230
|
+
**`BasaltDataTable` folds low-priority columns instead of only scrolling, once the table no
|
|
231
|
+
longer fits its wrapper (behaviour change, no API change beyond the new `meta.priority`).** The
|
|
232
|
+
same measured fit `stickyHeader` already used (`useMeasuredContainment`) now also drives an
|
|
233
|
+
analytic fold: the lowest-priority data columns move into a per-row disclosure (a chevron toggle
|
|
234
|
+
in a new leading cell, revealing the folded columns as label/value pairs directly under the row)
|
|
235
|
+
until the rest fit, rather than forcing `Table.ScrollContainer` into horizontal scroll. **With no
|
|
236
|
+
`meta.priority` set anywhere — every existing `<BasaltDataTable data columns />` — the LAST
|
|
237
|
+
declared column folds first**, so a table that already fit its container renders exactly as
|
|
238
|
+
before; only a table that would otherwise have scrolled changes. Order it explicitly via
|
|
239
|
+
`meta.priority` on a column (a higher number folds before a lower one). Never engages beside an
|
|
240
|
+
explicit `maxHeight`/`minWidth` (a declared scroll box), and never folds the selection column.
|
|
241
|
+
|
|
242
|
+
**`Composer` pins itself above the on-screen keyboard, and its root is now a wrapper (behaviour
|
|
243
|
+
change, no API change).** `className`, `style` and `classNames.root` land on an outer wrapper that
|
|
244
|
+
also holds a keyboard-inset spacer (`--vx-keyboard-inset`, 0px when no keyboard is open), and the
|
|
245
|
+
input row plus actions sit in an inner stack. Padding, margin, border and background on the root
|
|
246
|
+
behave as before; a flex/`gap` override on the root no longer reaches the input row. Style the row
|
|
247
|
+
through `classNames.actions` or wrap the Composer instead.
|
|
248
|
+
|
|
89
249
|
## 1.30.2 — the `legendWins` collapse, and two things `ChartFrame` never said out loud
|
|
90
250
|
|
|
91
251
|
**A patch. Nothing is added, renamed or removed.** One rendering regression 1.30.1 shipped is
|
|
@@ -23,24 +23,24 @@ size tier and one persistence binding, and basalt owns all three. The API is in
|
|
|
23
23
|
|
|
24
24
|
## The laws
|
|
25
25
|
|
|
26
|
-
| # | Law
|
|
27
|
-
| --- |
|
|
28
|
-
| C1 | A control lives in exactly ONE of three homes — the page bar, a section/widget header, or a form row — entered only through a slot prop.
|
|
29
|
-
| C2 | A basalt filter or tab has no `value`/`onChange`; it takes `field` and owns both the URL write and the localStorage mirror.
|
|
30
|
-
| C3 | Tab and filter state never lives in `useState` — it derives from a store field on the URL lane or the local lane.
|
|
31
|
-
| C4 | Every field declares its lanes once, at definition, and resolves URL ⊳ localStorage ⊳ fallback uniformly for every field kind.
|
|
32
|
-
| C5 | The HOME sets the size tier; an element inside a home slot carries no `size`, `w`, `fullWidth`, `visibleFrom` or `hiddenFrom`.
|
|
33
|
-
| C6 | A page has one `PageBar`; its `actions` hold ≤5 entries and exactly one `primary`; a `Section` holds ≤3.
|
|
34
|
-
| C7 | A home never scrolls horizontally and never wraps — overflow folds into a `More` menu or a `Filters (n)` sheet, computed by basalt from typed data.
|
|
35
|
-
| C8 | Every section, card or table title is a `WidgetHeader`; the page title is the breadcrumb (or `PageBar.title` with no shell). An in-body h1/h2 is an error.
|
|
36
|
-
| C9 | A responsive swap belongs to the control — rendering the same control twice under `visibleFrom`/`hiddenFrom` is an error.
|
|
37
|
-
| C10 | A nav link carrying a store field passes `store.linkSearch` by reference; a `search:` literal in a nav definition, or a literal `useSearch({ from })`, is an error.
|
|
38
|
-
| C11 | Every table or list inside a section states its count in its header.
|
|
39
|
-
| C12 | Refresh/sync has ONE shape, `SyncButton`, whose `scope` picks the home (`global` → the shell header, `page` → `PageBar.sync`).
|
|
40
|
-
| C13 | Sidebar blocks are declared data (`SidebarBlock[]`), never `ReactNode` slots, so rail and More-sheet projection stay basalt's.
|
|
41
|
-
| C14 | An empty home renders nothing, so no route pays for a reserved row.
|
|
42
|
-
| C15 | Every touch target inside a home clears
|
|
43
|
-
| C16 | A new guard lands `warn` with a dated `promote` version, and the build fails once the package version reaches it while the rule is still `warn`.
|
|
26
|
+
| # | Law |
|
|
27
|
+
| --- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
28
|
+
| C1 | A control lives in exactly ONE of three homes — the page bar, a section/widget header, or a form row — entered only through a slot prop. |
|
|
29
|
+
| C2 | A basalt filter or tab has no `value`/`onChange`; it takes `field` and owns both the URL write and the localStorage mirror. |
|
|
30
|
+
| C3 | Tab and filter state never lives in `useState` — it derives from a store field on the URL lane or the local lane. |
|
|
31
|
+
| C4 | Every field declares its lanes once, at definition, and resolves URL ⊳ localStorage ⊳ fallback uniformly for every field kind. |
|
|
32
|
+
| C5 | The HOME sets the size tier; an element inside a home slot carries no `size`, `w`, `fullWidth`, `visibleFrom` or `hiddenFrom`. |
|
|
33
|
+
| C6 | A page has one `PageBar`; its `actions` hold ≤5 entries and exactly one `primary`; a `Section` holds ≤3. |
|
|
34
|
+
| C7 | A home never scrolls horizontally and never wraps — overflow folds into a `More` menu or a `Filters (n)` sheet, computed by basalt from typed data. |
|
|
35
|
+
| C8 | Every section, card or table title is a `WidgetHeader`; the page title is the breadcrumb (or `PageBar.title` with no shell). An in-body h1/h2 is an error. |
|
|
36
|
+
| C9 | A responsive swap belongs to the control — rendering the same control twice under `visibleFrom`/`hiddenFrom` is an error. |
|
|
37
|
+
| C10 | A nav link carrying a store field passes `store.linkSearch` by reference; a `search:` literal in a nav definition, or a literal `useSearch({ from })`, is an error. |
|
|
38
|
+
| C11 | Every table or list inside a section states its count in its header. |
|
|
39
|
+
| C12 | Refresh/sync has ONE shape, `SyncButton`, whose `scope` picks the home (`global` → the shell header, `page` → `PageBar.sync`). |
|
|
40
|
+
| C13 | Sidebar blocks are declared data (`SidebarBlock[]`), never `ReactNode` slots, so rail and More-sheet projection stay basalt's. |
|
|
41
|
+
| C14 | An empty home renders nothing, so no route pays for a reserved row. |
|
|
42
|
+
| C15 | Every touch target inside a home clears `--vx-hit` (44px under a coarse pointer). The mobile `Filters (n)` sheet draws no row of its own — it renders the same `PanelRow` the aside's panel surface does. |
|
|
43
|
+
| C16 | A new guard lands `warn` with a dated `promote` version, and the build fails once the package version reaches it while the rule is still `warn`. |
|
|
44
44
|
|
|
45
45
|
A green lint run is not evidence the advisory laws the generated header above lists hold.
|
|
46
46
|
|
|
@@ -70,7 +70,7 @@ A green lint run is not evidence the advisory laws the generated header above li
|
|
|
70
70
|
| `controlHeightTag` | count-tag `Badge` | inline chip, table cell |
|
|
71
71
|
| `controlHeightWidget` | `--ai-size-icon` (explicit `size="icon"`, ActionIcon only) | sidebar search actions — no home defaults to it |
|
|
72
72
|
| `controlHeightCtl` | `size="ctl"` | `PageBar`, `Section`, table toolbar, sidebar blocks |
|
|
73
|
-
| `
|
|
73
|
+
| `--vx-hit` | hit area, 44px under `(pointer: coarse)` | every home |
|
|
74
74
|
| `controlHeight` | `size="md"` | forms — unchanged |
|
|
75
75
|
|
|
76
76
|
A home sizes its **slot**, never its body: a raw `Button` in `PageBar.actions` is already the right
|
|
@@ -8,7 +8,7 @@ paths:
|
|
|
8
8
|
|
|
9
9
|
<!-- basalt:coverage -->
|
|
10
10
|
<!-- GENERATED from src/surfaces.ts — `bun scripts/check-coverage.ts --write`. Do not hand-edit. -->
|
|
11
|
-
<!-- backed by: guard kinds — card-with-border, hidden-inline-style, in-body-page-title, inline-display, inline-spacing, mantine-shade-index, raw-form-control, raw-html-layout, raw-motion-value, raw-spacing, sub-16-input-font · oxlint rules — basalt/card-inset, basalt/deprecated-export, basalt/hand-rolled-shell, basalt/in-body-page-title, basalt/no-import-meta-env, basalt/page-bar-budget, basalt/provider-above-router, basalt/raw-scroll-container, basalt/shadow-basalt-export -->
|
|
11
|
+
<!-- backed by: guard kinds — card-with-border, hidden-inline-style, in-body-page-title, inline-display, inline-spacing, mantine-shade-index, raw-form-control, raw-html-layout, raw-media-query, raw-motion-value, raw-spacing, sub-16-input-font · oxlint rules — basalt/card-inset, basalt/deprecated-export, basalt/hand-rolled-shell, basalt/in-body-page-title, basalt/no-import-meta-env, basalt/page-bar-budget, basalt/provider-above-router, basalt/raw-breakpoint, basalt/raw-scroll-container, basalt/shadow-basalt-export -->
|
|
12
12
|
<!-- not guarded: no second cssVariablesResolver — don't hand-build createTheme or re-add the resolver basalt already installs -->
|
|
13
13
|
<!-- /basalt:coverage -->
|
|
14
14
|
|