basalt-ui 1.31.0 → 1.32.1
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 +34 -0
- package/MIGRATING.md +212 -20
- package/agent/rules/basalt-mantine.md +4 -4
- package/configs/oxlint-plugin.js +240 -59
- package/configs/oxlint-plugin.test.ts +329 -1
- package/dist/charts/kinds/BandStrip.d.ts.map +1 -1
- package/dist/charts/kinds/BandStrip.js +18 -66
- package/dist/charts/kinds/DualPanel.d.ts.map +1 -1
- package/dist/charts/kinds/DualPanel.js +5 -26
- package/dist/charts/kinds/MirroredBars.d.ts.map +1 -1
- package/dist/charts/kinds/MirroredBars.js +10 -68
- package/dist/charts/kinds/band-chrome.d.ts +31 -0
- package/dist/charts/kinds/band-chrome.d.ts.map +1 -0
- package/dist/charts/kinds/band-chrome.js +71 -0
- package/dist/charts/primitives/CartesianChart.d.ts.map +1 -1
- package/dist/charts/primitives/CartesianChart.js +49 -76
- package/dist/charts/primitives/ChartCard.d.ts.map +1 -1
- package/dist/charts/primitives/ChartCard.js +5 -23
- package/dist/charts/primitives/ChartFrame.d.ts.map +1 -1
- package/dist/charts/primitives/ChartFrame.js +23 -40
- package/dist/charts/primitives/ChartLegend.d.ts.map +1 -1
- package/dist/charts/primitives/ChartLegend.js +5 -133
- package/dist/charts/primitives/ChartTooltip.d.ts +5 -0
- package/dist/charts/primitives/ChartTooltip.d.ts.map +1 -1
- package/dist/charts/primitives/ChartTooltip.js +16 -1
- package/dist/charts/primitives/HoverOverlay.d.ts +24 -9
- package/dist/charts/primitives/HoverOverlay.d.ts.map +1 -1
- package/dist/charts/primitives/HoverOverlay.js +17 -1
- package/dist/charts/primitives/chart-card-context.d.ts +17 -13
- package/dist/charts/primitives/chart-card-context.d.ts.map +1 -1
- package/dist/charts/primitives/chart-card-context.js +10 -5
- package/dist/charts/primitives/chart-frame-layout.d.ts.map +1 -1
- package/dist/charts/primitives/chart-frame-layout.js +25 -31
- package/dist/charts/primitives/legend-disclosure.d.ts +27 -0
- package/dist/charts/primitives/legend-disclosure.d.ts.map +1 -0
- package/dist/charts/primitives/legend-disclosure.js +153 -0
- package/dist/controls/controls.module.css +5 -0
- package/dist/controls/sync-button.module.css +1 -0
- package/dist/dashboard/stat-group.module.css +19 -64
- package/dist/dashboard/widget-grid.module.css +11 -38
- package/dist/data/data-table-state.d.ts +83 -0
- package/dist/data/data-table-state.d.ts.map +1 -0
- package/dist/data/data-table-state.js +139 -0
- package/dist/data/data-table.d.ts +40 -2
- package/dist/data/data-table.d.ts.map +1 -1
- package/dist/data/data-table.js +179 -277
- 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 +6 -13
- package/dist/guard/index.d.ts +2 -2
- package/dist/guard/index.d.ts.map +1 -1
- package/dist/guard/index.js +10 -14
- package/dist/notifications/center.d.ts.map +1 -1
- package/dist/provider/index.d.ts.map +1 -1
- package/dist/provider/index.js +12 -10
- package/dist/shell/aside-docking.d.ts +31 -0
- package/dist/shell/aside-docking.d.ts.map +1 -0
- package/dist/shell/aside-docking.js +19 -0
- package/dist/shell/index.d.ts +0 -11
- package/dist/shell/index.d.ts.map +1 -1
- package/dist/shell/index.js +13 -14
- package/dist/shell/page-bar.d.ts +24 -0
- package/dist/shell/page-bar.d.ts.map +1 -1
- package/dist/shell/use-breakpoint.d.ts +1 -1
- package/dist/theme/floating.module.css +1 -0
- package/dist/theme-lab/derive-controls.d.ts.map +1 -1
- package/dist/tokens/index.d.ts +2 -0
- package/dist/tokens/index.d.ts.map +1 -1
- package/dist/tokens/index.js +4 -0
- package/llms.txt +2 -2
- package/package.json +2 -1
- package/src/charts/kinds/BandStrip.tsx +18 -64
- package/src/charts/kinds/DualPanel.tsx +4 -24
- package/src/charts/kinds/MirroredBars.tsx +12 -66
- package/src/charts/kinds/band-chrome.tsx +91 -0
- package/src/charts/primitives/CartesianChart.tsx +79 -122
- package/src/charts/primitives/ChartCard.tsx +5 -27
- package/src/charts/primitives/ChartFrame.tsx +37 -76
- package/src/charts/primitives/ChartLegend.tsx +7 -154
- package/src/charts/primitives/ChartTooltip.tsx +16 -0
- package/src/charts/primitives/HoverOverlay.tsx +52 -21
- package/src/charts/primitives/chart-card-context.ts +25 -16
- package/src/charts/primitives/chart-frame-layout.ts +44 -56
- package/src/charts/primitives/legend-disclosure.tsx +177 -0
- package/src/controls/controls.module.css +5 -0
- package/src/controls/sync-button.module.css +1 -0
- package/src/dashboard/stat-group.module.css +19 -64
- package/src/dashboard/widget-grid.module.css +11 -38
- package/src/data/data-table-state.ts +218 -0
- package/src/data/data-table.tsx +134 -218
- package/src/forms/form-layout.module.css +6 -13
- package/src/forms/form-layout.tsx +6 -1
- package/src/guard/index.ts +38 -34
- package/src/notifications/center.tsx +3 -0
- package/src/provider/index.tsx +18 -17
- package/src/shell/aside-docking.ts +54 -0
- package/src/shell/index.tsx +15 -37
- package/src/shell/page-bar.tsx +24 -0
- package/src/shell/use-breakpoint.ts +2 -2
- package/src/theme/floating.module.css +1 -0
- package/src/theme-lab/derive-controls.tsx +2 -0
- package/src/tokens/index.ts +5 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,37 @@
|
|
|
1
|
+
## [1.32.1](https://github.com/jkrumm/basalt-ui/compare/v1.32.0...v1.32.1) (2026-09-30)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* align guard lanes on FormRow/FormGroup, drop basalt-main ([17e673d](https://github.com/jkrumm/basalt-ui/commit/17e673d421c3e2f93be01c2b8d24e10e56d5b71c))
|
|
7
|
+
* bottom-align FormGroup's row direction so a trailing button isn't stretched ([e5ca2ab](https://github.com/jkrumm/basalt-ui/commit/e5ca2ab5e433e4e3ef15f505913c672b4912f0e9))
|
|
8
|
+
* export the size- and container-class tables from basalt-ui/tokens ([14fb784](https://github.com/jkrumm/basalt-ui/commit/14fb784586c3348a3647280e74ea905b2df0091b))
|
|
9
|
+
* point every § Unreleased reference at the section the release names ([bc17710](https://github.com/jkrumm/basalt-ui/commit/bc1771001048f2883607d6917e6f94cc397865be))
|
|
10
|
+
* resolve consts before unwrapping raw-breakpoint conditionals ([4f9cc79](https://github.com/jkrumm/basalt-ui/commit/4f9cc7912ae0805eb5e574f8ed8a8f9c068e0ddf))
|
|
11
|
+
|
|
12
|
+
# [1.32.0](https://github.com/jkrumm/basalt-ui/compare/v1.31.0...v1.32.0) (2026-09-30)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
### Bug Fixes
|
|
16
|
+
|
|
17
|
+
* build BasaltDataTable cards only in card mode, guard the routed-prop lookup ([4024e83](https://github.com/jkrumm/basalt-ui/commit/4024e8333c83cb4808507929f47246209e67a00a))
|
|
18
|
+
* exempt a container Grid only when its breakpoints map resolves ([d6d9bda](https://github.com/jkrumm/basalt-ui/commit/d6d9bdaa7eb693a01166d121fdc5bb95002bb09d))
|
|
19
|
+
* honour maxHeight in BasaltDataTable's card projection ([3b59a2f](https://github.com/jkrumm/basalt-ui/commit/3b59a2f5304969e0dcadfa77b1ff375fd0f1d048))
|
|
20
|
+
* key StatGroup and WidgetGrid on the container-class law ([db6e130](https://github.com/jkrumm/basalt-ui/commit/db6e130d050d562926fce63e7f1a5e3d0aeb45f8))
|
|
21
|
+
* move raw-media-query's promotion to 1.33.0 with its AST twin ([ac2641c](https://github.com/jkrumm/basalt-ui/commit/ac2641c4ac1fcb42b2381758ae9a2b20809ce630))
|
|
22
|
+
* move useBreakpoint's removal to 1.33.0 and correct its replacement ([a2c356b](https://github.com/jkrumm/basalt-ui/commit/a2c356bd1979960b8b9fc26eb8341cc84d3e88ee))
|
|
23
|
+
* narrow the container-grid exemption to the props Mantine routes ([d547022](https://github.com/jkrumm/basalt-ui/commit/d5470226008984fba39849062c0ee0abbac178cc))
|
|
24
|
+
* prune ignored dirs during the doc-drift repo walk instead of after it ([a4647dc](https://github.com/jkrumm/basalt-ui/commit/a4647dcd380f74f7ac73989fa6857d2041d16a23))
|
|
25
|
+
* read only width clauses when judging a shell/ media query ([3f14b7f](https://github.com/jkrumm/basalt-ui/commit/3f14b7f342c64c9f2b7b1b04887930f37f695f01))
|
|
26
|
+
* say legend.maxRows changed unit in its deprecation warning ([29ad3a5](https://github.com/jkrumm/basalt-ui/commit/29ad3a5183648a0edc71250b22a996fa818edfb8))
|
|
27
|
+
* stop warning legend-slot contention on a same-commit owner hand-off ([af18cfa](https://github.com/jkrumm/basalt-ui/commit/af18cfad7c3d9747a7cc6c0a117db34bbb8cd531))
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
### Features
|
|
31
|
+
|
|
32
|
+
* give basalt/raw-breakpoint a reachable container-grid answer ([2bf4a22](https://github.com/jkrumm/basalt-ui/commit/2bf4a2256fff9b08adcd6c3716b92993b4fdb40a))
|
|
33
|
+
* project BasaltDataTable rows as cards on the table's own width ([f201b2a](https://github.com/jkrumm/basalt-ui/commit/f201b2ac81726fc47b2adb5660fd42ce2c881b3e))
|
|
34
|
+
|
|
1
35
|
# [1.31.0](https://github.com/jkrumm/basalt-ui/compare/v1.30.2...v1.31.0) (2026-09-28)
|
|
2
36
|
|
|
3
37
|
|
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 | 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) | — |
|
|
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`) | — | — | — | — | — | — | — | — |
|
|
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) | — |
|
|
81
81
|
|
|
82
82
|
---
|
|
83
83
|
|
|
@@ -86,6 +86,196 @@ 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.32.1 — the 1.32.0 recipe resolves, and the gaps consumers hit upgrading to it
|
|
90
|
+
|
|
91
|
+
A patch: no new API beyond restoring what 1.31.0/1.32.0 already documented. Eight consumers
|
|
92
|
+
upgraded to 1.32.0; this section is what they had to find out by reading source.
|
|
93
|
+
|
|
94
|
+
### Fixes you can now delete a workaround for
|
|
95
|
+
|
|
96
|
+
| What | Delete |
|
|
97
|
+
| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- |
|
|
98
|
+
| **`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 |
|
|
99
|
+
| **`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`) |
|
|
100
|
+
| **`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 |
|
|
101
|
+
| **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. | — |
|
|
102
|
+
| **`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` |
|
|
103
|
+
| **`FormGroup direction="row"` no longer stretches a trailing button** (`align-items: flex-end`). | a `style={{ alignSelf: … }}` on the button |
|
|
104
|
+
|
|
105
|
+
**This patch also TIGHTENS two checks — expect NEW warnings after upgrading, still `warn` until
|
|
106
|
+
1.33.0:** `raw-breakpoint` now sees a responsive object inside a conditional, logical or
|
|
107
|
+
const-resolved prop value (`span={wide ? { base: 12, md: 4 } : 12}` used to slip through), and
|
|
108
|
+
`raw-media-query` rejects `@container basalt-main`. (The `FormRow`/`FormGroup` change only removes
|
|
109
|
+
warnings.)
|
|
110
|
+
|
|
111
|
+
**After any guard narrows, audit your waivers:** `basalt-ui check-theme --audit-allows` lists every
|
|
112
|
+
`theme-allow` and whether it still suppresses anything. Dead ones (rb carried five
|
|
113
|
+
`in-body-page-title`, linewatch one `bound-control-outside-home`) go.
|
|
114
|
+
|
|
115
|
+
**Scope — the breakpoint law is Mantine/CSS-scoped.** `raw-breakpoint` is an oxlint rule over JSX
|
|
116
|
+
and `raw-media-query` a `check-theme` kind over `.css`. A tokens-only (Tailwind) consumer has only
|
|
117
|
+
the `check-theme` lane; nothing here asks it to adopt `type="container"` grids.
|
|
118
|
+
|
|
119
|
+
### Container recipes 1.32.0 left implicit
|
|
120
|
+
|
|
121
|
+
**Swap two children at a container width in ONE query** — narrow default, flip both sides inside
|
|
122
|
+
one `min-width` rule. A `max-width: 799.9px` / `min-width: 800px` pair leaves a sub-pixel band where
|
|
123
|
+
both or neither render.
|
|
124
|
+
|
|
125
|
+
```css
|
|
126
|
+
.root {
|
|
127
|
+
container: basalt-grid / inline-size;
|
|
128
|
+
}
|
|
129
|
+
.wide {
|
|
130
|
+
display: none;
|
|
131
|
+
}
|
|
132
|
+
@container basalt-grid (min-width: 800px) {
|
|
133
|
+
.narrow {
|
|
134
|
+
display: none;
|
|
135
|
+
}
|
|
136
|
+
.wide {
|
|
137
|
+
display: block;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
**A plain Mantine `Table` (not `BasaltDataTable`)** has no column fold or card projection; the
|
|
143
|
+
sanctioned remedy is the same CSS module — declare the container on the wrapper and hide columns or
|
|
144
|
+
swap to a list inside a `min-width` query. `BasaltDataTable` needs the optional
|
|
145
|
+
`@tanstack/react-table` peer; don't add it only to get the fold.
|
|
146
|
+
|
|
147
|
+
**Layouts that need a step above `wide` (800px).** There is no fifth class; one ships when two named
|
|
148
|
+
consumers need the same width. Until then, verified against the 1.32.0 plugin:
|
|
149
|
+
|
|
150
|
+
| Where | Off-class width (e.g. `1200px`) |
|
|
151
|
+
| ------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------- |
|
|
152
|
+
| `SimpleGrid type="container"` px key — `cols={{ base: 1, '1200px': 5 }}` | passes: `raw-breakpoint` does not judge px keys, only theme names (`sm`) |
|
|
153
|
+
| `Grid type="container"` `breakpoints` map value — `xl: '1200px'` | passes: the map's values are not judged |
|
|
154
|
+
| `@container basalt-card` or unnamed, in CSS | flagged — `theme-allow raw-media-query — <why this layout needs 1200px>` |
|
|
155
|
+
| `@container <your-own-name>` or `basalt-grid`, in CSS | passes today; a later minor may judge `basalt-grid` — prefer a reasoned `theme-allow` over relying on the unjudged name |
|
|
156
|
+
|
|
157
|
+
Either way, write the reason next to the width: it is the evidence the fifth class is waiting on.
|
|
158
|
+
|
|
159
|
+
**`ResponsiveChartHeight` `sm` (768px) → which key.** `wide` (800) is 32px later and keeps the old
|
|
160
|
+
step's meaning ("tablet or wider"); `regular` (480) opens 288px earlier. Pick by which side of the old
|
|
161
|
+
width the height was for.
|
|
162
|
+
|
|
163
|
+
### `BasaltDataTable` `renderCard` (1.32.0, undocumented here until now)
|
|
164
|
+
|
|
165
|
+
The law lives in the prop's JSDoc (`src/data/data-table.tsx`, shipped in `dist/data/table.d.ts`).
|
|
166
|
+
The points consumers tripped on:
|
|
167
|
+
|
|
168
|
+
- Swaps at the table's OWN width `< CONTAINER_CLASSES.regular` (480px), not the viewport.
|
|
169
|
+
- Card order is the table's processed order — sort, filter, page. For a domain order, pass
|
|
170
|
+
`initialSorting` or sort `data`; there is no second sort.
|
|
171
|
+
- `minWidth` disables the COLUMN fold (it declares a horizontal floor) and is ignored by the card
|
|
172
|
+
list. `stickyHeader` alone keeps the fold; pair it with `maxHeight` to stick at every width.
|
|
173
|
+
- Activation is click or **Enter** — not Space (the browser's page scroll on a focused non-button).
|
|
174
|
+
|
|
175
|
+
### Shell-less apps and the 1.31.0 breakpoint move
|
|
176
|
+
|
|
177
|
+
1.31.0 moved `sm` from 48em to **52.5em** (840px). What its checklist missed:
|
|
178
|
+
|
|
179
|
+
- **Re-key your own literals:** grep `.css` for `47.99375em` / `48em` → `52.49375em` / `52.5em`.
|
|
180
|
+
- **A shell-less app's gutter / sticky-bar CSS belongs under your own `shell/` directory** at
|
|
181
|
+
52.5em: any `shell/`-pathed CSS may write a width `@media` at a `SIZE_CLASSES` boundary; anywhere
|
|
182
|
+
else it is `raw-media-query`.
|
|
183
|
+
- **A consumer-owned Mantine `AppShell`** resolves `navbar.breakpoint` / `aside.breakpoint` through
|
|
184
|
+
`theme.breakpoints`, so `breakpoint: 'sm'` collapses at 840px now, not 768px.
|
|
185
|
+
- **In the `medium` class the sidebar defaults to the rail**, and the rail hides a `kind: 'custom'`
|
|
186
|
+
block entirely (a list block keeps a dot only with both `icon` and `count`). Anything a
|
|
187
|
+
`medium`-width user needs must not live only in a custom block.
|
|
188
|
+
- **`PageBar` without a shell:** see the shell-less example in its JSDoc — `title` leads the one
|
|
189
|
+
sticky bar, and `classNames.root` is where the gutter bleed goes.
|
|
190
|
+
|
|
191
|
+
### `useSizeClass()` outside the shell — two sanctioned uses
|
|
192
|
+
|
|
193
|
+
Layout stays a container decision; an overlay's form (`Drawer` side, sheet vs dialog) and content
|
|
194
|
+
paired with a `ViewTabs` option `only: 'sm-down'` may read it. Law and wording:
|
|
195
|
+
`agent/rules/basalt-mantine.md` (a shipped rule, placed by `basalt-ui sync`).
|
|
196
|
+
|
|
197
|
+
## 1.32.0 — `basalt/raw-breakpoint` gets its answer
|
|
198
|
+
|
|
199
|
+
### The C1 pair (`control-outside-home` / `raw-selection-control`) — `error` at 1.33.0, the last extension
|
|
200
|
+
|
|
201
|
+
Re-measured 2026-09-30: basalt's own tree 0, the fleet ~33 (image-gen 11, rb 7, image-share 6,
|
|
202
|
+
weatherorb 5, email-gateway 4, argo 2). Clear them on 1.32.0 while they still warn — the remedies
|
|
203
|
+
are unchanged (§ 1.31.0 below: a `PageBar` home, `basalt-ui/forms` rows, bound `FieldHandle`s, or a
|
|
204
|
+
reasoned `theme-allow`). 1.33.0 promotes all four ids — this pair plus `raw-breakpoint` and
|
|
205
|
+
`raw-media-query` — together.
|
|
206
|
+
|
|
207
|
+
### `basalt/raw-breakpoint`
|
|
208
|
+
|
|
209
|
+
1.31.0 shipped this rule (`warn`) with a message that said "reach for a container query" and named
|
|
210
|
+
no primitive, and this file never mentioned it. It flags four shapes; each has a concrete target
|
|
211
|
+
now. **Severity: `warn`, promotes to `error` at 1.33.0** (moved from 1.32.0 — this is the first
|
|
212
|
+
minor with a documented answer). A `theme-allow raw-breakpoint — <reason>` waives one occurrence.
|
|
213
|
+
|
|
214
|
+
**Its CSS twin, the `raw-media-query` guard kind** (`basalt-ui check-theme`), enforces the same law
|
|
215
|
+
in `.css`: a width `@media` outside `shell/**`, an `@container` name other than `basalt-card` /
|
|
216
|
+
`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
|
|
217
|
+
a pointer query other than `coarse`/`fine`. Same `warn`, and it moved with the rule — **`error` at
|
|
218
|
+
1.33.0** (was 1.32.0). `theme-allow raw-media-query — <reason>` waives one line.
|
|
219
|
+
|
|
220
|
+
**The law.** `useSizeClass()` is for **shell chrome**. A page swapping its OWN layout — a column
|
|
221
|
+
count, a table for a card list, a row for a stack — is a **container** decision, keyed on
|
|
222
|
+
`CONTAINER_CLASSES` (`basalt-ui/tokens`: compact 240 · regular 480 · wide 800), not the viewport.
|
|
223
|
+
The primitive is Mantine 9's own `type="container"` grid. Verified against `@mantine/core` 9.3
|
|
224
|
+
source, which is what the rule's exemption is built on:
|
|
225
|
+
|
|
226
|
+
- `SimpleGrid type="container"` wraps itself in a `container: simple-grid / inline-size` div (no
|
|
227
|
+
ancestor needed) and writes **each key verbatim** into `@container simple-grid (min-width: <key>)`.
|
|
228
|
+
Keys are CSS lengths — `'480px'`, not `480` (unitless is invalid) and not `sm` (never resolved
|
|
229
|
+
through `theme.breakpoints`; emits a dead query). The rule flags `sm`-style keys there.
|
|
230
|
+
- `Grid type="container"` only goes container **when it also gets a `breakpoints` map**; without
|
|
231
|
+
one it silently renders viewport media queries (flagged). The map is typed
|
|
232
|
+
`Record<MantineSize, string>` — all five `xs`–`xl`, no custom names — and `Grid.Col` keys resolve
|
|
233
|
+
through it, so `sm` there means whatever width the map gives it (exempt).
|
|
234
|
+
|
|
235
|
+
| Shape (what it flags) | Replace with |
|
|
236
|
+
| ----------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
237
|
+
| responsive object on a Mantine prop — `SimpleGrid cols={{ base, sm }}` | `SimpleGrid type="container"` with px keys (below) |
|
|
238
|
+
| `Grid.Col span={{ base, lg }}` | `Grid type="container"` + a `breakpoints` map onto container widths; spans keyed through it |
|
|
239
|
+
| `Flex direction={{ base: 'column', sm: 'row' }}` | the container `SimpleGrid` (equal columns); a plain `Group` (wraps by default) for intrinsic-width items; or a CSS module: `container: basalt-grid / inline-size` on the parent, `@container basalt-grid (min-width: 480px)` on the child |
|
|
240
|
+
| `visibleFrom`/`hiddenFrom` outside a shell home or a control's C9 swap | the same container rule, `display` toggled in the CSS module — or drop the swap |
|
|
241
|
+
| `useMediaQuery`/`useMatches`/`useViewportSize` (`@mantine/*`), `window.matchMedia`/`innerWidth` | shell chrome: `useSizeClass()`; a page's layout: one of the above |
|
|
242
|
+
|
|
243
|
+
```tsx
|
|
244
|
+
// before — viewport breakpoints
|
|
245
|
+
<SimpleGrid cols={{ base: 1, sm: 3 }}>…</SimpleGrid>
|
|
246
|
+
<Grid><Grid.Col span={{ base: 12, lg: 4 }}>…</Grid.Col></Grid>
|
|
247
|
+
|
|
248
|
+
// after — the grid's own width
|
|
249
|
+
import { CONTAINER_CLASSES as C } from 'basalt-ui/tokens'
|
|
250
|
+
<SimpleGrid type="container" cols={{ base: 1, [`${C.regular}px`]: 3 }}>…</SimpleGrid>
|
|
251
|
+
const px = (n: number) => `${n}px`
|
|
252
|
+
const containerBreakpoints = { xs: px(C.compact), sm: px(C.regular), md: px(C.wide), lg: px(C.wide), xl: px(C.wide) }
|
|
253
|
+
<Grid type="container" breakpoints={containerBreakpoints}>
|
|
254
|
+
<Grid.Col span={{ base: 12, md: 4 }}>…</Grid.Col>
|
|
255
|
+
</Grid>
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
Pick the container key by the grid's own width, not by the viewport key it replaces: a grid inside a
|
|
259
|
+
page with an aside or a sidebar is narrower than the viewport, which is the point.
|
|
260
|
+
|
|
261
|
+
### `StatGroup` / `WidgetGrid` — `sm` opens at 800px, container name `basalt-grid`
|
|
262
|
+
|
|
263
|
+
Both grids now key on the container-class law basalt ships: the `sm` column count opens at the
|
|
264
|
+
`wide` class (**800px** of the grid's own width, was 768); the full `cols` count still opens at
|
|
265
|
+
1200px. A grid 768–799px wide now renders its base count (StatGroup 2, WidgetGrid 1). The
|
|
266
|
+
container they declare is renamed `basalt-stat-group`/`basalt-widget-grid` → **`basalt-grid`** — only
|
|
267
|
+
a consumer rule written against the old names needs editing. The `@supports not (container-type)`
|
|
268
|
+
viewport fallbacks (these two and `FormRow`'s) are gone: every browser that parses basalt's
|
|
269
|
+
`color-mix()` also parses `@container`.
|
|
270
|
+
|
|
271
|
+
### `useBreakpoint` — removal moved to 1.33.0, and the 1.31.0 replacement line was half wrong
|
|
272
|
+
|
|
273
|
+
`useBreakpoint('sm')` → `useSizeClass() !== 'compact'` holds for **shell chrome only**. A page
|
|
274
|
+
swapping its own layout on it (argo's table ↔ card list) is a container decision — see above. Note
|
|
275
|
+
that `useSizeClass()` answers `'compact'` on the first frame (the server snapshot,
|
|
276
|
+
`<BasaltProvider sizeClassHint>`) where `useBreakpoint` returned `undefined`, so an
|
|
277
|
+
`isLg === true` guard written for that `undefined` can go.
|
|
278
|
+
|
|
89
279
|
## 1.31.0 — size classes and the pointer tier
|
|
90
280
|
|
|
91
281
|
`theme.breakpoints` is now derived from `SIZE_CLASSES` (compact < 840, medium 840–1199, expanded
|
|
@@ -93,7 +283,9 @@ release renames it and opens a new one here._
|
|
|
93
283
|
it out. Mapping: `xs` = `sm` = 52.5em (medium opens), `md` = `lg` = `xl` = 75em (expanded opens) — the
|
|
94
284
|
keys collapse. So `xs` moves 36em → 52.5em, `sm` 48em → 52.5em (an iPad portrait is now bottom-bar chrome), `md`
|
|
95
285
|
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.
|
|
286
|
+
on those keys: `xs` no longer differs from `sm`, and `md`/`lg`/`xl` now switch at the same width. Outside a
|
|
287
|
+
shell home those props are `basalt/raw-breakpoint` findings — move them to a container grid rather
|
|
288
|
+
than re-keying them (see that section above).
|
|
97
289
|
|
|
98
290
|
| Removed | Replacement |
|
|
99
291
|
| --------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
@@ -149,10 +341,10 @@ everywhere).
|
|
|
149
341
|
`storageKey`. Opt out with a controlled `collapsed` prop; a persisted `false` (the user opened it
|
|
150
342
|
once) pins it open.
|
|
151
343
|
|
|
152
|
-
**On notice — `useBreakpoint` (
|
|
153
|
-
`useBreakpoint('sm')` with `useSizeClass() !== 'compact'
|
|
154
|
-
`useSizeClass() === 'expanded'`. A
|
|
155
|
-
|
|
344
|
+
**On notice — `useBreakpoint` (removal moved to 1.33.0).** `@deprecated`, still works. For shell
|
|
345
|
+
chrome, replace `useBreakpoint('sm')` with `useSizeClass() !== 'compact'` and `useBreakpoint('lg')`
|
|
346
|
+
with `useSizeClass() === 'expanded'`. A page's own layout swap is a container decision, not a
|
|
347
|
+
`useSizeClass()` one — corrected after release; see the `basalt/raw-breakpoint` section above.
|
|
156
348
|
|
|
157
349
|
**Card chrome keys on the card's own width, not the viewport.** `ChartCard`, `StatCard` and `Section`
|
|
158
350
|
are now `container: basalt-card / inline-size` (`container-type: inline-size` — layout and inline-size
|
|
@@ -322,7 +514,7 @@ exactly the case it was restored for. Measured: a 7-entry legend in a 92–150px
|
|
|
322
514
|
entries at `maxRows` 3, 6 **and** 99, with five series drawn in colours nothing named.
|
|
323
515
|
|
|
324
516
|
The fit now resolves an ABSENT cap only. When a caller states a number on a `fill` band, the legend
|
|
325
|
-
takes the ENTRIES it asked for (`maxRows` counts entries, not rows — see §
|
|
517
|
+
takes the ENTRIES it asked for (`maxRows` counts entries, not rows — see § 1.30.1) and
|
|
326
518
|
**`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,
|
|
327
519
|
and a floor about the plot); the stated number is the only intent in the room.
|
|
328
520
|
|
|
@@ -487,7 +679,7 @@ children is invisible to every rule. Grep for `SimpleGrid` before concluding the
|
|
|
487
679
|
### Charts — a responsive `height`, and the legend escape 1.30.0 promised
|
|
488
680
|
|
|
489
681
|
Both of these landed in 1.30.0 with no row here, and both were only partly reachable. **Read this
|
|
490
|
-
section against 1.30.1, not 1.30.0** — the §
|
|
682
|
+
section against 1.30.1, not 1.30.0** — the § 1.30.1 entries above are what makes them usable.
|
|
491
683
|
|
|
492
684
|
- **`height` accepts `{ base, sm?, md?, lg? }`** as well as a plain number, resolved against the
|
|
493
685
|
chart's MEASURED container width (the same width the tier reads), not the viewport. In 1.30.0 the
|
|
@@ -499,7 +691,7 @@ section against 1.30.1, not 1.30.0** — the § Unreleased entries above are wha
|
|
|
499
691
|
measured box, so a 380px inspector panel on a 1440px desktop IS "a phone" and its two-row default
|
|
500
692
|
rolled a six-series legend up to `+4 more` with no way to say no. `margin` and `xLabelRotate`
|
|
501
693
|
always had that escape; the legend did not. Under `fill` a measured cap still applies on top — see
|
|
502
|
-
§
|
|
694
|
+
§ 1.30.1 for what that actually costs, because "can still roll up FURTHER" understated it.
|
|
503
695
|
|
|
504
696
|
### Toolchain — the shipped lefthook preset's `check-theme`, and what it does NOT fix
|
|
505
697
|
|
|
@@ -48,8 +48,7 @@ single mount (`basalt/hand-rolled-shell` fires on `AppShell.*` parts or a `Burge
|
|
|
48
48
|
does not render it). The sub-components are exported for a genuinely divergent layout; prefer the
|
|
49
49
|
shell, which already wires collapse persistence, the mobile breakpoint and the breadcrumb.
|
|
50
50
|
|
|
51
|
-
|
|
52
|
-
projection:
|
|
51
|
+
Extension points are **declared data, not `ReactNode` slots**, so basalt owns the mobile projection:
|
|
53
52
|
|
|
54
53
|
| Prop | Shape | What basalt then owns |
|
|
55
54
|
| ------------------- | ------------------------------------ | -------------------------------------------------------------------------------------- |
|
|
@@ -98,6 +97,8 @@ Depth-tier law (which token for which surface, why static, why the ring is inset
|
|
|
98
97
|
clears the iOS zoom threshold via an `!important` floor (`sub-16-input-font` flags a smaller one).
|
|
99
98
|
- **Charts measure themselves** — pass `height`/`aspectRatio`/`fill` only; never `useElementSize`
|
|
100
99
|
in a chart file (Mantine is banned there), never raw `@visx/responsive` outside `charts/**`.
|
|
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`.
|
|
101
102
|
|
|
102
103
|
## Scroll regions
|
|
103
104
|
|
|
@@ -105,8 +106,7 @@ Depth-tier law (which token for which surface, why static, why the ring is inset
|
|
|
105
106
|
it draws its own bar inside its root, so the bar floats instead of reflowing the column
|
|
106
107
|
(`AppSidebar`'s nav is the reference: `type="hover"`, `scrollbars="y"`). Raw `overflow: auto` stays
|
|
107
108
|
correct only where a library owns the node (`BasaltStickToBottom`, `BasaltVirtualList`) and for a
|
|
108
|
-
table body (`Table.ScrollContainer type="native"` — a `ScrollArea` viewport
|
|
109
|
-
`<thead>`'s positioning context).
|
|
109
|
+
table body (`Table.ScrollContainer type="native"` — a `ScrollArea` viewport breaks a sticky `<thead>`).
|
|
110
110
|
|
|
111
111
|
## Interaction feedback and motion
|
|
112
112
|
|