basalt-ui 1.40.1 → 1.40.2

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 CHANGED
@@ -1,3 +1,10 @@
1
+ ## [1.40.2](https://github.com/jkrumm/basalt-ui/compare/v1.40.1...v1.40.2) (2026-10-05)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * sidebar footer rows sit on the nav row's height and 1px pitch ([bbd5c66](https://github.com/jkrumm/basalt-ui/commit/bbd5c66a223af61888df28cca837b89ef95181b1))
7
+
1
8
  ## [1.40.1](https://github.com/jkrumm/basalt-ui/compare/v1.40.0...v1.40.1) (2026-10-05)
2
9
 
3
10
 
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 | 1.32.0 | 1.32.1 | 1.33.0 | 1.34.0 | 1.34.1 | 1.35.0 | 1.36.0 | 1.36.1 | 1.37.0 | 1.37.1 | 1.38.0 | 1.38.1 | 1.39.0 | 1.40.0 | 1.40.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) | `CONTAINER_GRID_BREAKPOINTS`; `raw-breakpoint` trusts it (§ 1.33.0) | `CONTAINER_KEYS` (§ 1.34.0) | — | — | — | — | — | — | — | | `appShellInset` 20 → 16 (§ 1.38.1) | — | — | — | — |
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`) | — | `useBreakpoint` removed (§ 1.34.0) | — | — | `useCoarsePointer()` (§ `useCoarsePointer()`) | — | — | — | — | | content gutter 16, block 8 from `sm` (§ 1.38.1) | — | — | — | — |
74
- | **controls** (`./controls`) | `NumberFilter`, `field.number` (§ Controls) | sheet renders panel rows; `PanelRow`, `SliderControl` (§ `basalt-ui/controls`) | — | — | — | — | — | — | — | `NumberFilter clearable`; `createSearchStore` `resets` (§ State and controls) | — | — | — | `FormSection`/`FormRow`/`FormGroup`/`FormActions` move here (§ The form layout moves) | — | — | — | — | — | — | — | — | — |
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) | — | — | — | — | the layout + `useForm`/`schemaResolver` deprecated, removed 1.37.0 (§ The form layout moves) | — | — | — | — | — | — | — | — | — |
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) | — | — | — | `unknown-vx-token` → `error`; the token factories throw (§ 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 | 1.34.0 | 1.34.1 | 1.35.0 | 1.36.0 | 1.36.1 | 1.37.0 | 1.37.1 | 1.38.0 | 1.38.1 | 1.39.0 | 1.40.0 | 1.40.1 | 1.40.2 | 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) | `CONTAINER_KEYS` (§ 1.34.0) | — | — | — | — | — | — | — | | `appShellInset` 20 → 16 (§ 1.38.1) | — | — | — | — | — |
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`) | — | `useBreakpoint` removed (§ 1.34.0) | — | — | `useCoarsePointer()` (§ `useCoarsePointer()`) | — | — | — | — | | content gutter 16, block 8 from `sm` (§ 1.38.1) | — | — | — | — | — |
74
+ | **controls** (`./controls`) | `NumberFilter`, `field.number` (§ Controls) | sheet renders panel rows; `PanelRow`, `SliderControl` (§ `basalt-ui/controls`) | — | — | — | — | — | — | — | `NumberFilter clearable`; `createSearchStore` `resets` (§ State and controls) | — | — | — | `FormSection`/`FormRow`/`FormGroup`/`FormActions` move here (§ The form layout moves) | — | — | — | — | — | — | — | — | — | — |
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) | — | — | — | — | the layout + `useForm`/`schemaResolver` deprecated, removed 1.37.0 (§ The form layout moves) | — | — | — | — | — | — | — | — | — | — |
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) | — | — | — | `unknown-vx-token` → `error`; the token factories throw (§ Guards) | — | — | — | — | — | — | — | — | — | — |
81
81
 
82
82
  ---
83
83
 
@@ -86,6 +86,10 @@ 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.40.2
90
+
91
+ _Nothing to migrate in this release._
92
+
89
93
  ## 1.40.1
90
94
 
91
95
  _Nothing to migrate in this release._
@@ -205,9 +205,8 @@
205
205
  * bottom-placed block (a `kind: 'progress'` block defaults to `'bottom'`) stacked FLUSH on the
206
206
  * settings and account rows and on the scroll region above, which is the "cramped" footer.
207
207
  *
208
- * `region-gap` (12) above the cluster, `stack-sm` (8) between its parts — deliberately tighter
209
- * than the nav's `section-gap` (16): the footer is ONE pinned cluster whose rows belong together,
210
- * not a list of peer sections.
208
+ * `region-gap` (12) above the cluster, `stack-sm` (8) between BLOCKS, and the settings/account rows
209
+ * on the nav's own 1px pitch (see `.footerLinks + *` below): the footer rows are one list with the nav.
211
210
  */
212
211
  .footer {
213
212
  flex-shrink: 0;
@@ -223,6 +222,12 @@
223
222
  margin-top: var(--vx-space-stack-sm);
224
223
  }
225
224
 
225
+ /* Footer rows ARE a list like the nav's (`Stack gap={1}`): the settings rows and the account row
226
+ * sit on the nav's 1px pitch, not the cluster gap that separates blocks from rows. */
227
+ .footer > .footerLinks + * {
228
+ margin-top: 1px;
229
+ }
230
+
226
231
  /*
227
232
  * Footer settings row — IDENTICAL geometry to a nav row (padding 6px 10px, radius 6, gap 10,
228
233
  * 15px): muted text + faint icon at rest, ink-6% tint + ink on hover, exactly like an inactive
@@ -237,6 +242,9 @@
237
242
  padding: var(--vx-space-row-inset-y) var(--vx-space-row-inset-x);
238
243
  border-radius: var(--vx-radius-ctrl);
239
244
  font-size: var(--vx-text-md);
245
+ /* The nav row's line-height, so a footer row is exactly as tall as a nav row (Mantine's `Text`
246
+ * would otherwise bring its own 1.55 and add ~3px). */
247
+ line-height: var(--vx-space-row-line-height);
240
248
  color: var(--vx-muted);
241
249
  }
242
250
 
@@ -272,6 +280,7 @@
272
280
  .footerText {
273
281
  flex: 1;
274
282
  text-align: left;
283
+ line-height: var(--vx-space-row-line-height);
275
284
  }
276
285
 
277
286
  /*
@@ -296,6 +305,7 @@
296
305
  flex: 1;
297
306
  min-width: 0;
298
307
  text-align: left;
308
+ line-height: var(--vx-space-row-line-height);
299
309
  }
300
310
 
301
311
  /*
@@ -584,6 +594,7 @@
584
594
  .footerLinks {
585
595
  display: flex;
586
596
  flex-direction: column;
597
+ gap: 1px;
587
598
  }
588
599
 
589
600
  /* Fixed 18px icon column for a flat footer row — an icon-less row keeps the label aligned with
package/llms.txt CHANGED
@@ -1,4 +1,4 @@
1
- # basalt-ui v1.40.1
1
+ # basalt-ui v1.40.2
2
2
  # Opinionated framework for Mantine-based React apps — theme, app shell, visx charts, toolchain presets
3
3
  #
4
4
  # basalt-ui is an opinionated framework for Mantine-based React apps.
@@ -19,7 +19,7 @@
19
19
  # ./tokens.css subpath. Guide: docs/FRAMEWORK-FREE.md in the repo.
20
20
 
21
21
  Package: basalt-ui
22
- Version: 1.40.1
22
+ Version: 1.40.2
23
23
 
24
24
  ## basalt-ui
25
25
  Import: import { ... } from 'basalt-ui'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "basalt-ui",
3
- "version": "1.40.1",
3
+ "version": "1.40.2",
4
4
  "description": "Opinionated framework for Mantine-based React apps — theme, app shell, visx charts, toolchain presets",
5
5
  "keywords": [
6
6
  "charts",
@@ -205,9 +205,8 @@
205
205
  * bottom-placed block (a `kind: 'progress'` block defaults to `'bottom'`) stacked FLUSH on the
206
206
  * settings and account rows and on the scroll region above, which is the "cramped" footer.
207
207
  *
208
- * `region-gap` (12) above the cluster, `stack-sm` (8) between its parts — deliberately tighter
209
- * than the nav's `section-gap` (16): the footer is ONE pinned cluster whose rows belong together,
210
- * not a list of peer sections.
208
+ * `region-gap` (12) above the cluster, `stack-sm` (8) between BLOCKS, and the settings/account rows
209
+ * on the nav's own 1px pitch (see `.footerLinks + *` below): the footer rows are one list with the nav.
211
210
  */
212
211
  .footer {
213
212
  flex-shrink: 0;
@@ -223,6 +222,12 @@
223
222
  margin-top: var(--vx-space-stack-sm);
224
223
  }
225
224
 
225
+ /* Footer rows ARE a list like the nav's (`Stack gap={1}`): the settings rows and the account row
226
+ * sit on the nav's 1px pitch, not the cluster gap that separates blocks from rows. */
227
+ .footer > .footerLinks + * {
228
+ margin-top: 1px;
229
+ }
230
+
226
231
  /*
227
232
  * Footer settings row — IDENTICAL geometry to a nav row (padding 6px 10px, radius 6, gap 10,
228
233
  * 15px): muted text + faint icon at rest, ink-6% tint + ink on hover, exactly like an inactive
@@ -237,6 +242,9 @@
237
242
  padding: var(--vx-space-row-inset-y) var(--vx-space-row-inset-x);
238
243
  border-radius: var(--vx-radius-ctrl);
239
244
  font-size: var(--vx-text-md);
245
+ /* The nav row's line-height, so a footer row is exactly as tall as a nav row (Mantine's `Text`
246
+ * would otherwise bring its own 1.55 and add ~3px). */
247
+ line-height: var(--vx-space-row-line-height);
240
248
  color: var(--vx-muted);
241
249
  }
242
250
 
@@ -272,6 +280,7 @@
272
280
  .footerText {
273
281
  flex: 1;
274
282
  text-align: left;
283
+ line-height: var(--vx-space-row-line-height);
275
284
  }
276
285
 
277
286
  /*
@@ -296,6 +305,7 @@
296
305
  flex: 1;
297
306
  min-width: 0;
298
307
  text-align: left;
308
+ line-height: var(--vx-space-row-line-height);
299
309
  }
300
310
 
301
311
  /*
@@ -584,6 +594,7 @@
584
594
  .footerLinks {
585
595
  display: flex;
586
596
  flex-direction: column;
597
+ gap: 1px;
587
598
  }
588
599
 
589
600
  /* Fixed 18px icon column for a flat footer row — an icon-less row keeps the label aligned with