basalt-ui 1.32.0 → 1.33.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/CHANGELOG.md +50 -0
- package/MIGRATING.md +228 -20
- package/agent/rules/basalt-mantine.md +2 -2
- package/agent/rules/basalt-state.md +2 -2
- package/agent/rules/basalt-tokens.md +1 -1
- package/configs/oxlint-plugin.js +160 -89
- package/configs/oxlint-plugin.test.ts +273 -10
- package/configs/oxlint.json +2 -2
- package/dist/agent/coalesce.d.ts.map +1 -1
- package/dist/agent/coalesce.js +1 -2
- package/dist/agent/merge.d.ts.map +1 -1
- package/dist/agent/merge.js +1 -2
- package/dist/agent-chat/relative-time.d.ts +9 -0
- package/dist/agent-chat/relative-time.d.ts.map +1 -1
- package/dist/agent-chat/relative-time.js +1 -2
- package/dist/agent-chat/thread-message.d.ts.map +1 -1
- package/dist/agent-chat/thread-message.js +1 -2
- package/dist/charts/kinds/BandStrip.d.ts.map +1 -1
- package/dist/charts/kinds/BandStrip.js +3 -3
- package/dist/charts/kinds/Bars.d.ts.map +1 -1
- package/dist/charts/kinds/Bars.js +1 -2
- package/dist/charts/kinds/StackedArea.d.ts.map +1 -1
- package/dist/charts/kinds/StackedArea.js +1 -2
- package/dist/charts/primitives/legend-disclosure.d.ts.map +1 -1
- package/dist/cli/audit-allows.d.ts +1 -1
- package/dist/cli/audit-allows.d.ts.map +1 -1
- package/dist/cli/audit-allows.js +4 -4
- package/dist/cli/check-theme.d.ts.map +1 -1
- package/dist/cli/check-theme.js +1 -2
- package/dist/cli/config.d.ts +197 -0
- package/dist/cli/config.d.ts.map +1 -0
- package/dist/cli/config.js +20 -0
- package/dist/cli/doctor.js +1 -1
- package/dist/cli/guard-hook.d.ts.map +1 -1
- package/dist/cli/guard-hook.js +2 -8
- package/dist/cli/index.d.ts +2 -196
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +1 -18
- 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.map +1 -1
- package/dist/commands/define-overlays.js +1 -2
- package/dist/common/index.d.ts +0 -1
- package/dist/common/index.d.ts.map +1 -1
- package/dist/common/index.js +0 -2
- package/dist/common/validate.d.ts +2 -2
- package/dist/common/validate.d.ts.map +1 -1
- package/dist/common/validate.js +2 -3
- package/dist/content/article-card.d.ts.map +1 -1
- package/dist/content/article-card.js +4 -1
- package/dist/controls/enum-filter.d.ts.map +1 -1
- package/dist/controls/enum-filter.js +3 -13
- package/dist/controls/filter-pill.d.ts +8 -0
- package/dist/controls/filter-pill.d.ts.map +1 -1
- package/dist/controls/filter-pill.js +15 -0
- package/dist/controls/multi-select-filter.d.ts.map +1 -1
- package/dist/controls/multi-select-filter.js +3 -13
- package/dist/controls/number-filter.d.ts +3 -0
- package/dist/controls/number-filter.d.ts.map +1 -1
- package/dist/controls/number-filter.js +12 -4
- package/dist/controls/range-filter.d.ts.map +1 -1
- package/dist/controls/range-filter.js +1 -2
- package/dist/data/data-table.d.ts +9 -2
- package/dist/data/data-table.d.ts.map +1 -1
- package/dist/data/data-table.js +2 -3
- package/dist/forms/form-layout.d.ts +6 -1
- package/dist/forms/form-layout.d.ts.map +1 -1
- package/dist/forms/form-layout.module.css +3 -0
- package/dist/guard/index.d.ts +18 -4
- package/dist/guard/index.d.ts.map +1 -1
- package/dist/guard/index.js +67 -31
- package/dist/guard/types.d.ts +3 -3
- package/dist/guard/types.d.ts.map +1 -1
- package/dist/guard/vx-names.d.ts +3 -0
- package/dist/guard/vx-names.d.ts.map +1 -0
- package/dist/guard/vx-names.js +257 -0
- package/dist/notifications/mount-guard.d.ts.map +1 -1
- package/dist/notifications/mount-guard.js +1 -2
- package/dist/provider/index.d.ts.map +1 -1
- package/dist/provider/index.js +2 -3
- package/dist/provider/lab-theme.d.ts +5 -4
- package/dist/provider/lab-theme.d.ts.map +1 -1
- package/dist/provider/lab-theme.js +1 -3
- package/dist/router-tanstack/search-store.d.ts +18 -0
- package/dist/router-tanstack/search-store.d.ts.map +1 -1
- package/dist/router-tanstack/search-store.js +33 -1
- package/dist/shell/mobile-nav-model.d.ts.map +1 -1
- package/dist/shell/mobile-nav-model.js +3 -4
- package/dist/shell/page-bar.d.ts +24 -0
- package/dist/shell/page-bar.d.ts.map +1 -1
- package/dist/shell/page-bar.js +1 -2
- package/dist/surfaces.d.ts +1 -1
- package/dist/surfaces.d.ts.map +1 -1
- package/dist/surfaces.js +2 -0
- package/dist/tokens/index.d.ts +2 -0
- package/dist/tokens/index.d.ts.map +1 -1
- package/dist/tokens/index.js +10 -0
- package/dist/tokens/size-classes.d.ts +13 -0
- package/dist/tokens/size-classes.d.ts.map +1 -1
- package/dist/tokens/size-classes.js +8 -0
- package/llms.txt +2 -2
- package/package.json +1 -1
- package/src/agent/coalesce.ts +1 -2
- package/src/agent/merge.ts +1 -2
- package/src/agent-chat/relative-time.ts +1 -2
- package/src/agent-chat/thread-message.tsx +2 -3
- package/src/charts/kinds/BandStrip.tsx +7 -3
- package/src/charts/kinds/Bars.tsx +1 -2
- package/src/charts/kinds/StackedArea.tsx +4 -2
- package/src/charts/primitives/legend-disclosure.tsx +1 -0
- package/src/cli/audit-allows.ts +10 -9
- package/src/cli/check-theme.ts +1 -2
- package/src/cli/config.ts +209 -0
- package/src/cli/doctor.ts +2 -2
- package/src/cli/guard-hook.ts +2 -8
- package/src/cli/index.ts +2 -206
- package/src/commands/define-commands.ts +2 -2
- package/src/commands/define-overlays.ts +1 -2
- package/src/common/index.ts +0 -1
- package/src/common/validate.ts +4 -5
- package/src/content/article-card.tsx +1 -0
- package/src/controls/enum-filter.tsx +3 -13
- package/src/controls/filter-pill.tsx +20 -0
- package/src/controls/multi-select-filter.tsx +3 -13
- package/src/controls/number-filter.tsx +24 -3
- package/src/controls/range-filter.tsx +1 -2
- package/src/data/data-table.tsx +11 -5
- package/src/forms/form-layout.module.css +3 -0
- package/src/forms/form-layout.tsx +6 -1
- package/src/guard/index.ts +151 -62
- package/src/guard/types.ts +3 -2
- package/src/guard/vx-names.ts +257 -0
- package/src/notifications/mount-guard.ts +1 -2
- package/src/provider/index.tsx +2 -3
- package/src/provider/lab-theme.ts +28 -21
- package/src/router-tanstack/search-store.ts +73 -1
- package/src/shell/mobile-nav-model.ts +3 -5
- package/src/shell/page-bar.tsx +25 -4
- package/src/surfaces.ts +2 -0
- package/src/tokens/index.ts +10 -0
- package/src/tokens/size-classes.ts +14 -0
- package/dist/common/is-dev.d.ts +0 -3
- package/dist/common/is-dev.d.ts.map +0 -1
- package/dist/common/is-dev.js +0 -6
- package/src/common/is-dev.ts +0 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,53 @@
|
|
|
1
|
+
# [1.33.0](https://github.com/jkrumm/basalt-ui/compare/v1.32.1...v1.33.0) (2026-10-01)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* audit-allows asks oxlint about dual-lane and mixed waivers ([9e0a3d5](https://github.com/jkrumm/basalt-ui/commit/9e0a3d5a43cd9e27625801dd28c3360975f155ed))
|
|
7
|
+
* audit-allows probes bare line-scope waivers through oxlint ([b5d53f9](https://github.com/jkrumm/basalt-ui/commit/b5d53f9c8e3ac1712e455dd0fd7310d88358104f))
|
|
8
|
+
* break the audit-allows → index → check-theme → audit-allows cycle ([98d746c](https://github.com/jkrumm/basalt-ui/commit/98d746cd13e36b7cbf5fa809e120c91cd9d23c53))
|
|
9
|
+
* count only real declaration positions as a local --vx declaration ([4b5b723](https://github.com/jkrumm/basalt-ui/commit/4b5b723c994c6f6c2b01612f5a303649881f3cc2))
|
|
10
|
+
* gate the lab store on the dotted NODE_ENV form, record the fold matrix ([7d336b5](https://github.com/jkrumm/basalt-ui/commit/7d336b5209aa7be846ba11faa935e31e5aa8f795))
|
|
11
|
+
* gen-vx-names reads CSS declarations in ts/tsx and says what QUOTED admits ([238cdb9](https://github.com/jkrumm/basalt-ui/commit/238cdb9fb887b6b703e61c684d0c657d3a9a6a5c))
|
|
12
|
+
* harden the provider-only budget's build, dist and externals handling ([8a20d0f](https://github.com/jkrumm/basalt-ui/commit/8a20d0f49784e496b7db9634a2ac83f97c01903d))
|
|
13
|
+
* judge a resets write against the URL at navigate time, not the render ([74a6dc7](https://github.com/jkrumm/basalt-ui/commit/74a6dc762965e470525e9aabe14e9f5e0972b07b))
|
|
14
|
+
* judge only the vx names basalt claims — removed names and bare roots ([bf15dab](https://github.com/jkrumm/basalt-ui/commit/bf15dab0704858022ec2c157b74e8183dda71586))
|
|
15
|
+
* keep the page when clear() leaves a field where it was ([2a6b40f](https://github.com/jkrumm/basalt-ui/commit/2a6b40faebb38011b2203b10382411c97fb6d551))
|
|
16
|
+
* keep the page when Reset all moves no field ([c12d01a](https://github.com/jkrumm/basalt-ui/commit/c12d01ae7fa998f569369b3fb347bc941c56cf6c))
|
|
17
|
+
* print a failed provider-only build as a budget row, not a stack ([66361ef](https://github.com/jkrumm/basalt-ui/commit/66361ef1a41019b6f096e33ffc0d13d28913e639))
|
|
18
|
+
* resolve the CONTAINER_GRID_BREAKPOINTS trust through the scope manager ([26f664b](https://github.com/jkrumm/basalt-ui/commit/26f664b6c5af662ce89f09ff1d839fd8fc34830e))
|
|
19
|
+
* see a --vx reference a formatter wrapped across lines ([ba469b1](https://github.com/jkrumm/basalt-ui/commit/ba469b12cc7513d90fbc5171e570cfacc83312bf))
|
|
20
|
+
* stop NumberFilter's Clear from committing the draft on its way ([04e3156](https://github.com/jkrumm/basalt-ui/commit/04e315682571ad9cca24cadd451accce0a312134))
|
|
21
|
+
* trust CONTAINER_GRID_BREAKPOINTS read off a namespace import ([cc15f76](https://github.com/jkrumm/basalt-ui/commit/cc15f760fbcafa041404b750f1e588c712108745))
|
|
22
|
+
* word the bare-waiver oxlint verdict by what it waives, not a fake id ([3b5e3b2](https://github.com/jkrumm/basalt-ui/commit/3b5e3b2757b0ff7b875dc1a337f4a8137e8c4bc3))
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
### Features
|
|
26
|
+
|
|
27
|
+
* add clearable to NumberFilter for parity with SelectFilter ([a46d805](https://github.com/jkrumm/basalt-ui/commit/a46d805f97c1b60b93017ade2f6edb5a293fd302))
|
|
28
|
+
* add resets to createSearchStore for sibling params like page ([e809fd7](https://github.com/jkrumm/basalt-ui/commit/e809fd78e0b397f1ea52bb860b68bda5353c4943))
|
|
29
|
+
* promote the C1 and breakpoint twin pairs to error ([d49a5e2](https://github.com/jkrumm/basalt-ui/commit/d49a5e22b4f678f82f2377485f15ce6bc65c1be6))
|
|
30
|
+
* report removed and misspelled --vx-* names as unknown-vx-token ([6405f1a](https://github.com/jkrumm/basalt-ui/commit/6405f1af265cb7659026c1806bead121a22253f6))
|
|
31
|
+
* ship CONTAINER_GRID_BREAKPOINTS and let raw-breakpoint trust it ([4e3addb](https://github.com/jkrumm/basalt-ui/commit/4e3addbf50d1d358d8037389ad679d434ba00d98))
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
### Performance Improvements
|
|
35
|
+
|
|
36
|
+
* budget the provider-only first paint in check-budgets ([d36bed2](https://github.com/jkrumm/basalt-ui/commit/d36bed2c9c898490fddde0de126a36541ee25860))
|
|
37
|
+
* fold every dev-only gate out of production bundles ([25f94b7](https://github.com/jkrumm/basalt-ui/commit/25f94b79e81b045c05fe5eefb9479edebe195c43))
|
|
38
|
+
* keep the theme lab's store out of production first paint ([4e7512b](https://github.com/jkrumm/basalt-ui/commit/4e7512b41846e54fbb3d196ec157435c03b1c582))
|
|
39
|
+
|
|
40
|
+
## [1.32.1](https://github.com/jkrumm/basalt-ui/compare/v1.32.0...v1.32.1) (2026-09-30)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
### Bug Fixes
|
|
44
|
+
|
|
45
|
+
* align guard lanes on FormRow/FormGroup, drop basalt-main ([17e673d](https://github.com/jkrumm/basalt-ui/commit/17e673d421c3e2f93be01c2b8d24e10e56d5b71c))
|
|
46
|
+
* bottom-align FormGroup's row direction so a trailing button isn't stretched ([e5ca2ab](https://github.com/jkrumm/basalt-ui/commit/e5ca2ab5e433e4e3ef15f505913c672b4912f0e9))
|
|
47
|
+
* export the size- and container-class tables from basalt-ui/tokens ([14fb784](https://github.com/jkrumm/basalt-ui/commit/14fb784586c3348a3647280e74ea905b2df0091b))
|
|
48
|
+
* point every § Unreleased reference at the section the release names ([bc17710](https://github.com/jkrumm/basalt-ui/commit/bc1771001048f2883607d6917e6f94cc397865be))
|
|
49
|
+
* resolve consts before unwrapping raw-breakpoint conditionals ([4f9cc79](https://github.com/jkrumm/basalt-ui/commit/4f9cc7912ae0805eb5e574f8ed8a8f9c068e0ddf))
|
|
50
|
+
|
|
1
51
|
# [1.32.0](https://github.com/jkrumm/basalt-ui/compare/v1.31.0...v1.32.0) (2026-09-30)
|
|
2
52
|
|
|
3
53
|
|
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 | 1.31.0
|
|
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` (§
|
|
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 (§
|
|
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 (§
|
|
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 | 1.32.0 | 1.32.1 | 1.33.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` (§ 1.31.0) | — | `SIZE_CLASSES`/`CONTAINER_CLASSES` actually exported (§ Fixes) | `CONTAINER_GRID_BREAKPOINTS`; `raw-breakpoint` trusts it (§ 1.33.0) | — |
|
|
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 (§ 1.31.0) | — | `ResponsiveChartHeight` `sm` → key (§ Container recipes) | — | — |
|
|
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 (§ 1.31.0) | `useBreakpoint` removal → 1.33.0; `useSizeClass` is shell-only (§ 1.32.0) | shell-less `shell/` gutter, `AppShell` breakpoints, `useSizeClass` for overlays (§§ Shell-less, `useSizeClass`) | — | — |
|
|
74
|
+
| **controls** (`./controls`) | `NumberFilter`, `field.number` (§ Controls) | sheet renders panel rows; `PanelRow`, `SliderControl` (§ `basalt-ui/controls`) | — | — | — | — | — | — | — | `NumberFilter clearable`; `createSearchStore` `resets` (§ State and controls) | — |
|
|
75
|
+
| **forms** (`./forms`) | — | `field` → `inputProps`, **`inputProps` drops `key`**, the layout tier (§ `inputProps`) | `field` DELETED — and the `--fix` recipe no longer works (§ Consolidation) | — | — | — | — | — | `FormGroup` row no longer stretches (§ Fixes) | — | — |
|
|
76
|
+
| **data** (`./data/table`) | — | root is a `<div>`, row selection, `getItemKey` required (§ `basalt-ui/data`) | `./data` + `./query` + `./connectivity` dropped (§ Consolidation) | — | — | — | — | — | `renderCard` documented (§ `renderCard`) | — | — |
|
|
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) | — | — | — | `raw-breakpoint`: the container-grid answer, `error` at 1.33.0 (§ 1.32.0) | `FormRow`/`FormGroup` homes in both lanes; `basalt-main` dropped (§ Fixes) | C1 + breakpoint pairs → `error`; `unknown-vx-token` `warn` (§ Guards) | — |
|
|
81
81
|
|
|
82
82
|
---
|
|
83
83
|
|
|
@@ -86,6 +86,215 @@ 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.33.0 — the 1.33.0 minor
|
|
90
|
+
|
|
91
|
+
### `CONTAINER_GRID_BREAKPOINTS` — the `Grid type="container"` map ships
|
|
92
|
+
|
|
93
|
+
`basalt-ui/tokens` exports the five-key map the 1.32.0 recipe had every consumer hand-write
|
|
94
|
+
(`xs` compact 240px · `sm` regular 480px · `md`/`lg`/`xl` wide 800px), derived from
|
|
95
|
+
`CONTAINER_CLASSES`. `basalt/raw-breakpoint` trusts it by name: before, it read an IMPORTED map as
|
|
96
|
+
unresolvable and flagged every `Grid.Col` span under it, so each route file declared its own
|
|
97
|
+
same-file literal (argo: five identical copies).
|
|
98
|
+
|
|
99
|
+
```tsx
|
|
100
|
+
import { CONTAINER_GRID_BREAKPOINTS } from 'basalt-ui/tokens'
|
|
101
|
+
;<Grid type="container" breakpoints={CONTAINER_GRID_BREAKPOINTS}>
|
|
102
|
+
<Grid.Col span={{ base: 12, md: 4 }}>…</Grid.Col>
|
|
103
|
+
</Grid>
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
| Delete | Replace with |
|
|
107
|
+
| ------------------------------------------------------------------------------------ | -------------------------------------------- |
|
|
108
|
+
| a same-file `const GRID_BREAKPOINTS = { xs: …, sm: …, md: …, lg: …, xl: … }` literal | `breakpoints={CONTAINER_GRID_BREAKPOINTS}` |
|
|
109
|
+
| a shared map you export yourself (flagged when imported) | the shipped one, or keep a same-file literal |
|
|
110
|
+
|
|
111
|
+
The trust is provenance-gated: the import must name `CONTAINER_GRID_BREAKPOINTS` from
|
|
112
|
+
`basalt-ui/tokens` (an alias `{ CONTAINER_GRID_BREAKPOINTS as bp }`, a namespace member
|
|
113
|
+
`tokens.CONTAINER_GRID_BREAKPOINTS` on `import * as tokens`, and a same-file `const bp = …` of
|
|
114
|
+
either all count; a parameter or inner `const` that shadows the name does not). A map of your own
|
|
115
|
+
that deviates from it — a 1200px `xl`, say — stays a same-file literal. `SimpleGrid type="container"` is unchanged: its keys
|
|
116
|
+
are CSS lengths, so ``[`${CONTAINER_CLASSES.regular}px`]`` stays the form.
|
|
117
|
+
|
|
118
|
+
### State and controls — `resets: ['page']`, `NumberFilter clearable`
|
|
119
|
+
|
|
120
|
+
Additive; nothing to change unless you carry one of the two workarounds below.
|
|
121
|
+
|
|
122
|
+
**`createSearchStore({ …, resets: ['page'] })`** drops the named sibling params — ones the store does
|
|
123
|
+
NOT own — in the same navigate as every URL-lane write that moves a value (setter, `clear()`,
|
|
124
|
+
`useReset()`); a `url: false` field makes no navigate and keeps the page. The route's own `validateSearch` resolves the default (`page` → 1). An explicit
|
|
125
|
+
`set(v, { patch: { page } })` still wins; naming a param the store owns throws at definition.
|
|
126
|
+
Store-wide by design: every filter of a list narrows the same list, sort included.
|
|
127
|
+
|
|
128
|
+
```ts
|
|
129
|
+
// before — an effect per page, which also snapped Back/Forward onto page 1
|
|
130
|
+
useEffect(() => { if (filtersChanged && search.page !== 1) navigate({ search: (p) => ({ ...p, page: 1 }) }) }, [filterKey])
|
|
131
|
+
|
|
132
|
+
// after — the store owns it; Back restores filter AND page, because they were one write
|
|
133
|
+
export const b2Filters = createSearchStore({ key: 'b2-filters', fields: { … }, resets: ['page'] })
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
**`NumberFilter clearable`** — parity with `SelectFilter`/`EnumFilter`: a `Clear` in the popover that
|
|
137
|
+
writes the fallback back, in both the `options` and the stepper form. "No filter" is the FALLBACK,
|
|
138
|
+
not a row: with `clearable`, drop an `{ value: 0, label: 'Any …' }` option — the pill reads the
|
|
139
|
+
filter's `label` while no preset matches.
|
|
140
|
+
|
|
141
|
+
### Guards — four ids promote to `error`
|
|
142
|
+
|
|
143
|
+
The last two twin pairs leave grace together, one law per pair and one promotion for both lanes:
|
|
144
|
+
|
|
145
|
+
| Law | oxlint rule (JSX) | `check-theme` kind (text/CSS) | In grace since |
|
|
146
|
+
| --------------------- | ----------------------------- | ----------------------------- | -------------- |
|
|
147
|
+
| C1 — a control's home | `basalt/control-outside-home` | `raw-selection-control` | 1.26.0 |
|
|
148
|
+
| the breakpoint law | `basalt/raw-breakpoint` | `raw-media-query` | 1.31.0 |
|
|
149
|
+
|
|
150
|
+
Measured before flipping, 2026-10-01: all nine consumers on 1.32.1 — argo, rb, image-gen,
|
|
151
|
+
image-share, email-gateway, linewatch, rollhook, obsidian, weatherorb — at 0 for all four ids.
|
|
152
|
+
basalt's own tree and the playground are at 0 too, after two reasoned waivers in the package
|
|
153
|
+
(`legend-disclosure.tsx` clamps a fixed panel with `window.innerWidth`, a position rather than a
|
|
154
|
+
breakpoint; `ArticleGrid`'s `cols` is documented per viewport `lg`, so moving it to container keys
|
|
155
|
+
would re-flow every consumer's grid and ships opt-in instead).
|
|
156
|
+
|
|
157
|
+
If one fires after upgrading, it is code written since the measurement: the remedies are unchanged
|
|
158
|
+
(§ 1.31.0 for C1's homes, § 1.32.0 `basalt/raw-breakpoint` for the container recipe), or a
|
|
159
|
+
`theme-allow <id> — <why>`. `basalt.severity` still turns a kind down per repo; the shipped oxlint
|
|
160
|
+
preset's level can be overridden in your own `.oxlintrc.json`.
|
|
161
|
+
|
|
162
|
+
### `unknown-vx-token` — a removed `--vx-*` name is a finding (`warn`, `error` at 1.34.0)
|
|
163
|
+
|
|
164
|
+
A `var(--vx-*)` naming a token basalt does not emit resolves to its fallback — or to nothing — with
|
|
165
|
+
no error from tsc, oxlint or the browser. obsidian lost its 44px touch floor that way, to
|
|
166
|
+
`var(--vx-space-touch-target)`. `check-theme` now reports it, in every scanned file type. It ships
|
|
167
|
+
`warn` for this minor and promotes at 1.34.0. Measured at ship time: all nine consumers at 0.
|
|
168
|
+
|
|
169
|
+
| Removed name | Replacement |
|
|
170
|
+
| --------------------------------------------- | --------------------------------------------------------- |
|
|
171
|
+
| `--vx-space-touch-target` | `--vx-hit` |
|
|
172
|
+
| `--vx-space-touch-control-height` | `--vx-hit` |
|
|
173
|
+
| `--vx-space-app-header-mobile-actions-height` | `--vx-space-sticky-header-clearance` |
|
|
174
|
+
| `--vx-space-sticky-header-clearance-mobile` | `--vx-space-sticky-header-clearance` |
|
|
175
|
+
| `--vx-space-sidebar-brand-inset-top` | none — the brand row is the header band (§ 1.30.0 Chrome) |
|
|
176
|
+
|
|
177
|
+
- **Judged: a removed name** (the table) **and a bare family root nothing emits** —
|
|
178
|
+
`var(--vx-surface)`, `var(--vx-space)`, `var(--vx-status)`: basalt only writes `<root>-<key>`,
|
|
179
|
+
and so does `groupTokens`. The live set is exactly `basalt-ui/tokens.css` plus three
|
|
180
|
+
component-scoped names (`--vx-hit-gap`, `--vx-space-icon-size`, `--vx-keyboard-inset`).
|
|
181
|
+
- **Not judged: any other unknown name**, even under a basalt prefix. `groupTokens('surface', …)`
|
|
182
|
+
emits `--vx-surface-<key>` from a file a per-file scan cannot see, so `--vx-surface-2` could be
|
|
183
|
+
your group or a typo, and the guard does not guess. Check such a name against
|
|
184
|
+
`basalt-ui/tokens.css` yourself. Your `defineSeries`/`groupTokens` series (argo's `--vx-lp-*`,
|
|
185
|
+
rb's `--vx-confidence-*`), a computed name (`var(--vx-fill-${hue})`) and a name the same file
|
|
186
|
+
declares are never reported.
|
|
187
|
+
|
|
188
|
+
## 1.32.1 — the 1.32.0 recipe resolves, and the gaps consumers hit upgrading to it
|
|
189
|
+
|
|
190
|
+
A patch: no new API beyond restoring what 1.31.0/1.32.0 already documented. Eight consumers
|
|
191
|
+
upgraded to 1.32.0; this section is what they had to find out by reading source.
|
|
192
|
+
|
|
193
|
+
### Fixes you can now delete a workaround for
|
|
194
|
+
|
|
195
|
+
| What | Delete |
|
|
196
|
+
| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- |
|
|
197
|
+
| **`SIZE_CLASSES`, `CONTAINER_CLASSES`, `resolveContainerClass`, `ContainerClass` are exported from `basalt-ui/tokens`.** The 1.31.0/1.32.0 sections, the `raw-breakpoint` message and the `BasaltDataTable` JSDoc all named that import; it did not resolve. A test now fails the build when a fenced import in this file names a symbol its subpath does not export. | the local `container-classes.ts` mirror or the literal `'480px'`/`800` — import them |
|
|
198
|
+
| **`FormRow` / `FormGroup` are control homes in `check-theme` too.** The oxlint plugin already treated them as homes; the text lane's `raw-selection-control` did not, so a correctly migrated form row warned (and would have errored at 1.33.0). A parity test now pins both lanes' home lists to one set. | every `theme-allow raw-selection-control — … FormRow/FormGroup …` waiver (grep `WORKAROUND: homed in a FormRow`) |
|
|
199
|
+
| **`basalt-main` is no longer an accepted `@container` name.** Nothing ever declared it, so a query against it never matched. Declare your own container (`container: <name> / inline-size` on the element) or use `basalt-grid` on the parent. | `@container basalt-main …` — rewrite against a container you declare |
|
|
200
|
+
| **The `raw-media-query` message no longer over-claims.** Only `basalt-card` and unnamed `@container` queries are judged against the 0/240/480/800 table; any other declared name is accepted at any width. Same behaviour, honest text. | — |
|
|
201
|
+
| **`raw-breakpoint` exempts a `tests?/` directory** (e.g. a `tests/setup/dom.ts` `matchMedia` polyfill), not only `*.test.*`/`__tests__`. The message now says `cols={{ base: 3 }}` is just `cols={3}`, and a `(hover: none)` read gets a pointer-tier hint. | the polyfill's `theme-allow raw-breakpoint` |
|
|
202
|
+
| **`FormGroup direction="row"` no longer stretches a trailing button** (`align-items: flex-end`). | a `style={{ alignSelf: … }}` on the button |
|
|
203
|
+
|
|
204
|
+
**This patch also TIGHTENS two checks — expect NEW warnings after upgrading, still `warn` until
|
|
205
|
+
1.33.0:** `raw-breakpoint` now sees a responsive object inside a conditional, logical or
|
|
206
|
+
const-resolved prop value (`span={wide ? { base: 12, md: 4 } : 12}` used to slip through), and
|
|
207
|
+
`raw-media-query` rejects `@container basalt-main`. (The `FormRow`/`FormGroup` change only removes
|
|
208
|
+
warnings.)
|
|
209
|
+
|
|
210
|
+
**After any guard narrows, audit your waivers:** `basalt-ui check-theme --audit-allows` lists every
|
|
211
|
+
`theme-allow` and whether it still suppresses anything. Dead ones (rb carried three
|
|
212
|
+
`in-body-page-title`, linewatch one `bound-control-outside-home`) go. Before 1.33.0 the audit also
|
|
213
|
+
called an `in-body-page-title` waiver dead when only the oxlint lane still needed it — if deleting
|
|
214
|
+
one makes `oxlint` fail, restore it.
|
|
215
|
+
|
|
216
|
+
**Scope — the breakpoint law is Mantine/CSS-scoped.** `raw-breakpoint` is an oxlint rule over JSX
|
|
217
|
+
and `raw-media-query` a `check-theme` kind over `.css`. A tokens-only (Tailwind) consumer has only
|
|
218
|
+
the `check-theme` lane; nothing here asks it to adopt `type="container"` grids.
|
|
219
|
+
|
|
220
|
+
### Container recipes 1.32.0 left implicit
|
|
221
|
+
|
|
222
|
+
**Swap two children at a container width in ONE query** — narrow default, flip both sides inside
|
|
223
|
+
one `min-width` rule. A `max-width: 799.9px` / `min-width: 800px` pair leaves a sub-pixel band where
|
|
224
|
+
both or neither render.
|
|
225
|
+
|
|
226
|
+
```css
|
|
227
|
+
.root {
|
|
228
|
+
container: basalt-grid / inline-size;
|
|
229
|
+
}
|
|
230
|
+
.wide {
|
|
231
|
+
display: none;
|
|
232
|
+
}
|
|
233
|
+
@container basalt-grid (min-width: 800px) {
|
|
234
|
+
.narrow {
|
|
235
|
+
display: none;
|
|
236
|
+
}
|
|
237
|
+
.wide {
|
|
238
|
+
display: block;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
**A plain Mantine `Table` (not `BasaltDataTable`)** has no column fold or card projection; the
|
|
244
|
+
sanctioned remedy is the same CSS module — declare the container on the wrapper and hide columns or
|
|
245
|
+
swap to a list inside a `min-width` query. `BasaltDataTable` needs the optional
|
|
246
|
+
`@tanstack/react-table` peer; don't add it only to get the fold.
|
|
247
|
+
|
|
248
|
+
**Layouts that need a step above `wide` (800px).** There is no fifth class; one ships when two named
|
|
249
|
+
consumers need the same width. Until then, verified against the 1.32.0 plugin:
|
|
250
|
+
|
|
251
|
+
| Where | Off-class width (e.g. `1200px`) |
|
|
252
|
+
| ------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
253
|
+
| `SimpleGrid type="container"` px key — `cols={{ base: 1, '1200px': 5 }}` | passes: `raw-breakpoint` does not judge px keys, only theme names (`sm`) |
|
|
254
|
+
| `Grid type="container"` `breakpoints` map value — `xl: '1200px'` | passes: the map's values are not judged |
|
|
255
|
+
| `@container basalt-card` or unnamed, in CSS | flagged — `theme-allow raw-media-query — <why this layout needs 1200px>` |
|
|
256
|
+
| `@container <your-own-name>` or `basalt-grid`, in CSS | passes — the name is unjudged, so write no waiver (`--audit-allows` reports one dead); a minor that starts judging `basalt-grid` will say so here |
|
|
257
|
+
|
|
258
|
+
Either way, write the reason next to the width: it is the evidence the fifth class is waiting on.
|
|
259
|
+
|
|
260
|
+
**`ResponsiveChartHeight` `sm` (768px) → which key.** `wide` (800) is 32px later and keeps the old
|
|
261
|
+
step's meaning ("tablet or wider"); `regular` (480) opens 288px earlier. Pick by which side of the old
|
|
262
|
+
width the height was for.
|
|
263
|
+
|
|
264
|
+
### `BasaltDataTable` `renderCard` (1.32.0, undocumented here until now)
|
|
265
|
+
|
|
266
|
+
The law lives in the prop's JSDoc (`src/data/data-table.tsx`, shipped in `dist/data/table.d.ts`).
|
|
267
|
+
The points consumers tripped on:
|
|
268
|
+
|
|
269
|
+
- Swaps at the table's OWN width `< CONTAINER_CLASSES.regular` (480px), not the viewport.
|
|
270
|
+
- Card order is the table's processed order — sort, filter, page. For a domain order, pass
|
|
271
|
+
`initialSorting` or sort `data`; there is no second sort.
|
|
272
|
+
- `minWidth` disables the COLUMN fold (it declares a horizontal floor) and is ignored by the card
|
|
273
|
+
list. `stickyHeader` alone keeps the fold; pair it with `maxHeight` to stick at every width.
|
|
274
|
+
- Activation is click or **Enter** — not Space (the browser's page scroll on a focused non-button).
|
|
275
|
+
|
|
276
|
+
### Shell-less apps and the 1.31.0 breakpoint move
|
|
277
|
+
|
|
278
|
+
1.31.0 moved `sm` from 48em to **52.5em** (840px). What its checklist missed:
|
|
279
|
+
|
|
280
|
+
- **Re-key your own literals:** grep `.css` for `47.99375em` / `48em` → `52.49375em` / `52.5em`.
|
|
281
|
+
- **A shell-less app's gutter / sticky-bar CSS belongs under your own `shell/` directory** at
|
|
282
|
+
52.5em: any `shell/`-pathed CSS may write a width `@media` at a `SIZE_CLASSES` boundary; anywhere
|
|
283
|
+
else it is `raw-media-query`.
|
|
284
|
+
- **A consumer-owned Mantine `AppShell`** resolves `navbar.breakpoint` / `aside.breakpoint` through
|
|
285
|
+
`theme.breakpoints`, so `breakpoint: 'sm'` collapses at 840px now, not 768px.
|
|
286
|
+
- **In the `medium` class the sidebar defaults to the rail**, and the rail hides a `kind: 'custom'`
|
|
287
|
+
block entirely (a list block keeps a dot only with both `icon` and `count`). Anything a
|
|
288
|
+
`medium`-width user needs must not live only in a custom block.
|
|
289
|
+
- **`PageBar` without a shell:** see the shell-less example in its JSDoc — `title` leads the one
|
|
290
|
+
sticky bar, and `classNames.root` is where the gutter bleed goes.
|
|
291
|
+
|
|
292
|
+
### `useSizeClass()` outside the shell — two sanctioned uses
|
|
293
|
+
|
|
294
|
+
Layout stays a container decision; an overlay's form (`Drawer` side, sheet vs dialog) and content
|
|
295
|
+
paired with a `ViewTabs` option `only: 'sm-down'` may read it. Law and wording:
|
|
296
|
+
`agent/rules/basalt-mantine.md` (a shipped rule, placed by `basalt-ui sync`).
|
|
297
|
+
|
|
89
298
|
## 1.32.0 — `basalt/raw-breakpoint` gets its answer
|
|
90
299
|
|
|
91
300
|
### The C1 pair (`control-outside-home` / `raw-selection-control`) — `error` at 1.33.0, the last extension
|
|
@@ -105,7 +314,7 @@ minor with a documented answer). A `theme-allow raw-breakpoint — <reason>` wai
|
|
|
105
314
|
|
|
106
315
|
**Its CSS twin, the `raw-media-query` guard kind** (`basalt-ui check-theme`), enforces the same law
|
|
107
316
|
in `.css`: a width `@media` outside `shell/**`, an `@container` name other than `basalt-card` /
|
|
108
|
-
`basalt-form` / `basalt-
|
|
317
|
+
`basalt-form` / `basalt-grid` (`basalt-main` was listed here too; dropped in 1.32.1, nothing declared it) or at a width off a `CONTAINER_CLASSES` boundary, and
|
|
109
318
|
a pointer query other than `coarse`/`fine`. Same `warn`, and it moved with the rule — **`error` at
|
|
110
319
|
1.33.0** (was 1.32.0). `theme-allow raw-media-query — <reason>` waives one line.
|
|
111
320
|
|
|
@@ -138,11 +347,10 @@ source, which is what the rule's exemption is built on:
|
|
|
138
347
|
<Grid><Grid.Col span={{ base: 12, lg: 4 }}>…</Grid.Col></Grid>
|
|
139
348
|
|
|
140
349
|
// after — the grid's own width
|
|
141
|
-
import { CONTAINER_CLASSES as C } from 'basalt-ui/tokens'
|
|
350
|
+
import { CONTAINER_CLASSES as C, CONTAINER_GRID_BREAKPOINTS } from 'basalt-ui/tokens'
|
|
142
351
|
<SimpleGrid type="container" cols={{ base: 1, [`${C.regular}px`]: 3 }}>…</SimpleGrid>
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
<Grid type="container" breakpoints={containerBreakpoints}>
|
|
352
|
+
// the shipped map (§ 1.33.0); on 1.32.x, a same-file literal of the same five keys
|
|
353
|
+
<Grid type="container" breakpoints={CONTAINER_GRID_BREAKPOINTS}>
|
|
146
354
|
<Grid.Col span={{ base: 12, md: 4 }}>…</Grid.Col>
|
|
147
355
|
</Grid>
|
|
148
356
|
```
|
|
@@ -406,7 +614,7 @@ exactly the case it was restored for. Measured: a 7-entry legend in a 92–150px
|
|
|
406
614
|
entries at `maxRows` 3, 6 **and** 99, with five series drawn in colours nothing named.
|
|
407
615
|
|
|
408
616
|
The fit now resolves an ABSENT cap only. When a caller states a number on a `fill` band, the legend
|
|
409
|
-
takes the ENTRIES it asked for (`maxRows` counts entries, not rows — see §
|
|
617
|
+
takes the ENTRIES it asked for (`maxRows` counts entries, not rows — see § 1.30.1) and
|
|
410
618
|
**`VX.minPlotHeight` stops being a floor** — the plot yields the height instead. Both things that used to trim the number are framework DEFAULTS (the tier's cap,
|
|
411
619
|
and a floor about the plot); the stated number is the only intent in the room.
|
|
412
620
|
|
|
@@ -571,7 +779,7 @@ children is invisible to every rule. Grep for `SimpleGrid` before concluding the
|
|
|
571
779
|
### Charts — a responsive `height`, and the legend escape 1.30.0 promised
|
|
572
780
|
|
|
573
781
|
Both of these landed in 1.30.0 with no row here, and both were only partly reachable. **Read this
|
|
574
|
-
section against 1.30.1, not 1.30.0** — the §
|
|
782
|
+
section against 1.30.1, not 1.30.0** — the § 1.30.1 entries above are what makes them usable.
|
|
575
783
|
|
|
576
784
|
- **`height` accepts `{ base, sm?, md?, lg? }`** as well as a plain number, resolved against the
|
|
577
785
|
chart's MEASURED container width (the same width the tier reads), not the viewport. In 1.30.0 the
|
|
@@ -583,7 +791,7 @@ section against 1.30.1, not 1.30.0** — the § Unreleased entries above are wha
|
|
|
583
791
|
measured box, so a 380px inspector panel on a 1440px desktop IS "a phone" and its two-row default
|
|
584
792
|
rolled a six-series legend up to `+4 more` with no way to say no. `margin` and `xLabelRotate`
|
|
585
793
|
always had that escape; the legend did not. Under `fill` a measured cap still applies on top — see
|
|
586
|
-
§
|
|
794
|
+
§ 1.30.1 for what that actually costs, because "can still roll up FURTHER" understated it.
|
|
587
795
|
|
|
588
796
|
### Toolchain — the shipped lefthook preset's `check-theme`, and what it does NOT fix
|
|
589
797
|
|
|
@@ -97,8 +97,8 @@ Depth-tier law (which token for which surface, why static, why the ring is inset
|
|
|
97
97
|
clears the iOS zoom threshold via an `!important` floor (`sub-16-input-font` flags a smaller one).
|
|
98
98
|
- **Charts measure themselves** — pass `height`/`aspectRatio`/`fill` only; never `useElementSize`
|
|
99
99
|
in a chart file (Mantine is banned there), never raw `@visx/responsive` outside `charts/**`.
|
|
100
|
-
- **A page's
|
|
101
|
-
|
|
100
|
+
- **A page's layout keys on its container, not the viewport** (`type="container"` grids, `CONTAINER_CLASSES`).
|
|
101
|
+
`useSizeClass()`: shell chrome, overlay form, `ViewTabs only: 'sm-down'` partners. Recipes: `MIGRATING.md`.
|
|
102
102
|
|
|
103
103
|
## Scroll regions
|
|
104
104
|
|
|
@@ -76,8 +76,8 @@ export const analytics = createSearchStore({
|
|
|
76
76
|
hand-count either.
|
|
77
77
|
- **A reset UNSETS.** `useReset()`/`field.clear()` DELETE the persisted key, never write
|
|
78
78
|
`fallback` (which would pin a thunk fallback as a value nobody chose).
|
|
79
|
-
- **`set(next, { patch })`** merges
|
|
80
|
-
|
|
79
|
+
- **`set(next, { patch })`** merges params the store does NOT own into the same navigate; store-level
|
|
80
|
+
`resets: ['page']` does it on every URL-lane write (never a `useEffect`: it snaps Back/Forward).
|
|
81
81
|
|
|
82
82
|
## Nav links carry the store BY REFERENCE
|
|
83
83
|
|
|
@@ -9,7 +9,7 @@ paths:
|
|
|
9
9
|
|
|
10
10
|
<!-- basalt:coverage -->
|
|
11
11
|
<!-- GENERATED from src/surfaces.ts — `bun scripts/check-coverage.ts --write`. Do not hand-edit. -->
|
|
12
|
-
<!-- backed by: guard kinds — css-raw-surface, inline-font-size, off-identity-accent, off-system-surface-var, raw-color-fn, raw-font-family, raw-hex, raw-radius, raw-surface, surface-shadow-override, theme-allow-unscoped · oxlint rules — basalt/no-raw-font-size, basalt/raw-size-literal, basalt/token-layer-boundary -->
|
|
12
|
+
<!-- backed by: guard kinds — css-raw-surface, inline-font-size, off-identity-accent, off-system-surface-var, raw-color-fn, raw-font-family, raw-hex, raw-radius, raw-surface, surface-shadow-override, theme-allow-unscoped, unknown-vx-token · oxlint rules — basalt/no-raw-font-size, basalt/raw-size-literal, basalt/token-layer-boundary -->
|
|
13
13
|
<!-- not guarded: — -->
|
|
14
14
|
<!-- /basalt:coverage -->
|
|
15
15
|
|