basalt-ui 1.23.0 → 1.24.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.
Files changed (81) hide show
  1. package/AGENTS.md +31 -17
  2. package/CHANGELOG.md +23 -0
  3. package/MIGRATING.md +222 -6
  4. package/README.md +159 -49
  5. package/agent/rules/basalt-app.md +8 -2
  6. package/agent/rules/basalt-charts.md +38 -2
  7. package/agent/rules/basalt-content.md +3 -3
  8. package/agent/rules/basalt-data.md +45 -13
  9. package/agent/rules/basalt-mantine.md +4 -4
  10. package/agent/rules/basalt-query.md +57 -0
  11. package/agent/rules/basalt-tokens.md +18 -5
  12. package/agent/skills/basalt-app/SKILL.md +32 -12
  13. package/agent/skills/basalt-charts/SKILL.md +4 -2
  14. package/agent/templates/CLAUDE-block.md.tpl +3 -2
  15. package/dist/charts/kinds/BandStrip.d.ts +20 -6
  16. package/dist/charts/kinds/BandStrip.d.ts.map +1 -1
  17. package/dist/charts/kinds/BandStrip.js +59 -6
  18. package/dist/charts/kinds/MirroredBars.d.ts +4 -2
  19. package/dist/charts/kinds/MirroredBars.d.ts.map +1 -1
  20. package/dist/charts/kinds/MirroredBars.js +13 -0
  21. package/dist/cli/index.d.ts +4 -2
  22. package/dist/cli/index.d.ts.map +1 -1
  23. package/dist/cli/index.js +269 -27
  24. package/dist/dashboard/empty-state.d.ts +6 -2
  25. package/dist/dashboard/empty-state.d.ts.map +1 -1
  26. package/dist/dashboard/empty-state.js +1 -1
  27. package/dist/dashboard/index.d.ts +1 -0
  28. package/dist/dashboard/index.d.ts.map +1 -1
  29. package/dist/dashboard/index.js +8 -0
  30. package/dist/dashboard/query-state.d.ts +96 -0
  31. package/dist/dashboard/query-state.d.ts.map +1 -0
  32. package/dist/dashboard/query-state.js +123 -0
  33. package/dist/dashboard/query-state.test.d.ts +2 -0
  34. package/dist/dashboard/query-state.test.d.ts.map +1 -0
  35. package/dist/data/data-table.d.ts +61 -4
  36. package/dist/data/data-table.d.ts.map +1 -1
  37. package/dist/data/data-table.js +41 -4
  38. package/dist/data/data-table.test.d.ts +2 -0
  39. package/dist/data/data-table.test.d.ts.map +1 -0
  40. package/dist/data/table.d.ts +1 -1
  41. package/dist/data/table.d.ts.map +1 -1
  42. package/dist/guard/index.d.ts.map +1 -1
  43. package/dist/guard/index.js +50 -9
  44. package/dist/index.d.ts +1 -1
  45. package/dist/index.d.ts.map +1 -1
  46. package/dist/index.js +7 -1
  47. package/dist/query/error-message.d.ts +41 -0
  48. package/dist/query/error-message.d.ts.map +1 -0
  49. package/dist/query/error-message.js +30 -0
  50. package/dist/query/error-message.test.d.ts +2 -0
  51. package/dist/query/error-message.test.d.ts.map +1 -0
  52. package/dist/query/index.d.ts +1 -19
  53. package/dist/query/index.d.ts.map +1 -1
  54. package/dist/query/index.js +2 -14
  55. package/dist/surfaces.d.ts +1 -1
  56. package/dist/surfaces.js +1 -1
  57. package/llms.txt +3 -3
  58. package/package.json +1 -1
  59. package/src/charts/kinds/BandStrip.test.tsx +87 -5
  60. package/src/charts/kinds/BandStrip.tsx +105 -12
  61. package/src/charts/kinds/MirroredBars.test.tsx +39 -0
  62. package/src/charts/kinds/MirroredBars.tsx +38 -2
  63. package/src/cli/check-theme.test.ts +34 -0
  64. package/src/cli/help.test.ts +74 -1
  65. package/src/cli/index.ts +496 -41
  66. package/src/cli/tokens-css.test.ts +129 -0
  67. package/src/cli/toolchain-wiring.test.ts +146 -0
  68. package/src/dashboard/empty-state.tsx +9 -3
  69. package/src/dashboard/index.ts +11 -0
  70. package/src/dashboard/query-state.test.tsx +152 -0
  71. package/src/dashboard/query-state.tsx +272 -0
  72. package/src/data/data-table.test.tsx +158 -0
  73. package/src/data/data-table.tsx +123 -5
  74. package/src/data/table.ts +6 -1
  75. package/src/guard/check-source.test.ts +214 -0
  76. package/src/guard/index.ts +169 -15
  77. package/src/index.ts +9 -0
  78. package/src/query/error-message.test.ts +67 -0
  79. package/src/query/error-message.ts +70 -0
  80. package/src/query/index.ts +2 -34
  81. package/src/surfaces.ts +1 -1
@@ -76,6 +76,63 @@ const { data } = useSuspenseQuery(resourceQueries.summary())
76
76
  router's `ensureQueryData` (see basalt-router.md).
77
77
  - Wrap pages or panels in `<Suspense fallback={…}>` at the route level.
78
78
 
79
+ ## Rendering a query — use `QueryState`, don't write the switch
80
+
81
+ ```tsx
82
+ import { QueryState } from 'basalt-ui' // NOT basalt-ui/query — it renders Mantine
83
+
84
+ function Library() {
85
+ const q = useQuery(imageQueries.list())
86
+ return (
87
+ <QueryState
88
+ query={q}
89
+ variant="page" // or "section" for a panel inside a page
90
+ errorTitle="Could not load images"
91
+ empty={{ title: 'No images yet', description: 'Upload one to get started.' }}
92
+ isEmpty={(d) => d.items.length === 0}
93
+ >
94
+ {(data) => <ImageGrid items={data.items} />}
95
+ </QueryState>
96
+ )
97
+ }
98
+ ```
99
+
100
+ **Rendering only the empty branch is the bug this retires.** A consumer's library showed
101
+ `No images` on a **500**, and a share detail showed `Share not found` on a dropped connection —
102
+ "nothing here" is what an app renders when nobody wrote the other three branches. One import
103
+ replaced 204 hand-rolled lines across 10 call sites there.
104
+
105
+ Precedence, in evaluation order:
106
+
107
+ | Condition | Renders |
108
+ | ----------------------------------- | ------------------------------------------------------------------------- |
109
+ | `isError`, no `data` | `ErrorState` — `errorTitle` / `errorFallback` / `errorAction`, with Retry |
110
+ | no `data`, `fetchStatus === 'idle'` | the `empty` copy (nothing, if `empty` is omitted) |
111
+ | no `data` | `loading`, else `LoadingState` |
112
+ | `data`, `isEmpty(data)` | the `empty` copy |
113
+ | `data` | `children` — a node, or `(data) => node` |
114
+ | `data` **and** `isError` | a fixed _Showing cached data_ banner above `children` |
115
+
116
+ `errorTitle` / `errorFallback` / `errorAction` reach the no-data error branch only; the stale-data
117
+ banner carries its own copy. `empty` is `{ title, description?, icon?, action? }` — `description`
118
+ is optional, so a compact panel needs no invented second sentence.
119
+
120
+ **`useQuery`, not `useSuspenseQuery`.** A suspense read never hands you an undefined `data` or an
121
+ error branch — it throws to the nearest boundary — so `QueryState` has nothing to decide there.
122
+ Suspense + an error boundary and `QueryState` are the two ways to render a query; pick one per read.
123
+
124
+ `LoadingState` and `ErrorState` ship beside it as the escape hatch for a page that must place its
125
+ branches in different DOM positions.
126
+
127
+ **`query` is a structural subset, checked at runtime.** It needs `{ data, isError, error,
128
+ fetchStatus, refetch }` — a TanStack `UseQueryResult` satisfies it, and a hand-composed object is
129
+ legal. Because the subset gives up the compiler's help, a missing `isError` **throws** naming the
130
+ field rather than rendering a false claim about the data.
131
+
132
+ Decoding an unknown error into copy is `toErrorMessage(err, fallback?)` from `basalt-ui/query`,
133
+ with `errorStatus(err)` for the status; `toErrorMessage` folds the status into the fallback when the
134
+ body decodes to nothing readable, so an opaque envelope never renders as `{}`.
135
+
79
136
  ## Mutations
80
137
 
81
138
  ```ts
@@ -10,7 +10,8 @@ paths:
10
10
  # Basalt Tokens — Color, Spacing, Radius, Type
11
11
 
12
12
  basalt-ui ships one color/type/spacing/radius identity shared by the Mantine chrome and the visx
13
- charts. The **identity is modern zinc** (see `docs/DESIGN-SPEC.md` in the basalt-ui repo) —
13
+ charts. The **identity is modern zinc** (long form: <https://github.com/jkrumm/basalt-ui/blob/master/docs/DESIGN-SPEC.md>, which does not ship in the
14
+ package) —
14
15
  **cool-neutral zinc surfaces**
15
16
  (Tailwind zinc family) on both light and dark, low-contrast panel lift on a slightly darker page,
16
17
  depth via a whisper shadow + 1px ring (`shadow-card` on panels, `shadow-raised` on interactive
@@ -21,8 +22,7 @@ lines, focus ring) it is `#0077bd` light / `#8ec5ff` dark; as a FILLED SURFACE i
21
22
  `#0077bd` in BOTH schemes with a WHITE label (`--vx-accent-fill`, never `--vx-accent`). Neutrals do ~90% of the
22
23
  surface (60/30/10, pushed toward 90/10); the accent only points — primary CTA, focus, links, small
23
24
  status pops — never floods. (Blueprint/Basalt zinc-charcoal are the historical hue-tuning
24
- ancestors; `docs/DESIGN-SPEC.md` in the basalt-ui repo supersedes both — see its "Doctrine
25
- inversions" section.) This
25
+ ancestors; DESIGN-SPEC supersedes both — see its "Doctrine inversions" section.) This
26
26
  rule is the operational checklist; it is enforced mechanically by **`basalt-ui check-theme`**
27
27
  (wire it into `lint`: `oxlint . && basalt-ui check-theme`; `init` seeds that as `lint:basalt`). A
28
28
  violation fails the build. Escape hatch: a scoped `theme-allow <rule-id> — <reason>` comment
@@ -120,13 +120,26 @@ the guard with that one occurrence neutralized, so the verdict comes from the sc
120
120
  parsing the waiver's text:
121
121
 
122
122
  ```text
123
+ theme-allow annotations (3):
123
124
  src/shell/x.tsx:42 suppresses raw-surface@43
124
125
  src/theme/y.ts:18 SUPPRESSES NOTHING — dead, delete it
125
- src/charts/z.tsx:7 scoped to hand-rolled-plot — not a check-theme kind, so this audit cannot judge it
126
+ src/charts/z.tsx:7 suppresses hand-rolled-plot@8 (oxlint)
127
+
128
+ basalt.exemptRules entries (1):
126
129
  raw-hex: "site.webmanifest" suppresses findings in public/site.webmanifest — <the recorded reason>
130
+
131
+ 3 live, 1 dead, 0 unjudgeable, 0 unaccountable (reported as theme-allow-unscoped by a normal run).
132
+ Scope: the N file(s) check-theme scans — everything under basalt.roots (…), plus each root's
133
+ sibling index.html and public/ tree, plus anything named in basalt.include (none). …
127
134
  ```
128
135
 
129
- It closes with a `live / dead / outside reach / unaccountable` tally and **exits 1 on a dead
136
+ **Two sections, not one list** — annotations first, then `basalt.exemptRules`, each with its own
137
+ count. A plugin-rule annotation is judged too (since 1.22.0, by re-running oxlint over one
138
+ neutralized sibling file), so `unjudgeable` now means only "names no rule at all" or "oxlint could
139
+ not be run here" — never "not a check-theme kind". The scope line is part of the report: `0 dead`
140
+ is not `0 dead anywhere`.
141
+
142
+ It closes with a `live / dead / unjudgeable / unaccountable` tally and **exits 1 on a dead
130
143
  waiver**, so it wires into CI. A waiver that stopped covering anything is not harmless: it silently
131
144
  covers the next real finding on that line. Basalt's own source had one; it is deleted.
132
145
 
@@ -6,18 +6,26 @@ when_to_use: User is adding basalt-ui to a new or existing app, asks how to set
6
6
 
7
7
  `/basalt-app` scaffolds a basalt-ui consumer and keeps its shipped doctrine fresh. It wraps the two
8
8
  CLI subcommands — `basalt-ui init` (first run) and `basalt-ui sync` (refresh) — and explains the
9
- wiring they don't do for you (provider, shell, vite). All of it via `bunx basalt-ui` (Bun runtime).
9
+ wiring they don't do for you (provider, shell, vite). Bun runtime.
10
10
 
11
11
  ## One package, one command, one version
12
12
 
13
13
  Everything ships in the `basalt-ui` npm package — components, toolchain presets, rules, skills,
14
14
  templates. Becoming a consumer is exactly two steps:
15
15
 
16
- ```
16
+ ```bash
17
17
  bun add basalt-ui
18
- bunx basalt-ui init
18
+ bunx basalt-ui init # `init` is the ONE command that legitimately predates the install
19
+ ./node_modules/.bin/basalt-ui --version # every command after it: the LOCAL bin
19
20
  ```
20
21
 
22
+ **After `init`, never `bunx`.** `bunx` does not re-resolve a package it has cached, so it can run
23
+ a months-old CLI against a freshly-pinned install and report a green gate you did not configure —
24
+ which is exactly how one consumer filed a P0 against a 1.20.0 cache while believing it was on
25
+ 1.22.0. Use `./node_modules/.bin/basalt-ui` (or a `package.json` script, which `bun run` resolves
26
+ from the same place). `basalt-ui --version` / `-v` prints one bare line and exits 0; that is the
27
+ check, and it costs nothing to run first.
28
+
21
29
  There is no plugin and no marketplace. `init`/`sync` place every file with one of two modes, and
22
30
  which mode a file gets answers a single question — **does Claude read it?**
23
31
 
@@ -130,7 +138,7 @@ The consumer series file (`<first basalt.root>/lib/series.ts` by default — so
130
138
  a plain app, `apps/web/src/lib/series.ts` on a monorepo; override via `basalt.seriesModulePath`) is
131
139
  the single guard-exempt palette source — see `/basalt-charts`.
132
140
 
133
- ## Refresh: `bunx basalt-ui sync`
141
+ ## Refresh: `basalt-ui sync`
134
142
 
135
143
  `sync` re-applies shipped doctrine after a basalt-ui upgrade, three-way against
136
144
  `.basalt/manifest.json`:
@@ -141,6 +149,13 @@ the single guard-exempt palette source — see `/basalt-charts`.
141
149
  - `sync --check` makes no changes and exits non-zero on drift — wire it as a CI freshness gate so a
142
150
  consumer can't silently fall behind the shipped rules.
143
151
 
152
+ **Run it anywhere in the repo.** `sync`, `check-theme` and `doctor` share one resolver:
153
+ `BASALT_CWD` → the cwd → declared workspace packages → a two-level descend → an **ascend** to the
154
+ nearest ancestor carrying a basalt project, bounded by the repo root. Both directions announce the
155
+ relocation in one sentence. From a sub-package `sync` now refreshes the parent install rather than
156
+ refusing — but it still **exits 1 rather than scaffolding a second consumer** where the resolved
157
+ project has no `.basalt/manifest.json`. Creating an install stays `basalt-ui init`'s decision.
158
+
144
159
  Seeds (`DESIGN.md`, the toolchain files, the scaffolds) are never reconciled or drift-reported —
145
160
  they are yours. The managed files (rules, skills, the CLAUDE block) are framework-owned and meant
146
161
  to be overwritten; the sync diff is where you review a doctrine change before committing it.
@@ -158,14 +173,15 @@ both.
158
173
  ## Checklist
159
174
 
160
175
  - Ran `bun add basalt-ui && bunx basalt-ui init` — rules, skills, CLAUDE block, DESIGN.md all
161
- present from the one package.
176
+ present from the one package. Every command after it runs the local bin, not `bunx`.
162
177
  - `BasaltProvider` wraps the app; `createBasaltTheme` used for theme deltas; `basalt-ui/styles.css`
163
178
  imported.
164
179
  - `basaltViteConfig` adopted; `oxlint . && basalt-ui check-theme` is the lint command.
165
- - `basaltAppPlugin` composed into `plugins` (see the vite.config.ts snippet above); icon files
166
- (`favicon.ico`, `favicon.svg`, `favicon-96x96.png`, `apple-touch-icon.png`,
167
- `web-app-manifest-192x192.png`, `web-app-manifest-512x512.png`) generated and placed under
168
- `public/` — `basalt-ui doctor` warns if any are missing.
180
+ - `basaltAppPlugin` composed into `plugins` (see the vite.config.ts snippet above); either the six
181
+ default icon files (`favicon.ico`, `favicon.svg`, `favicon-96x96.png`, `apple-touch-icon.png`,
182
+ `web-app-manifest-192x192.png`, `web-app-manifest-512x512.png`) under `public/`, or an `icons`
183
+ array naming the ones you actually have. `doctor` reads the option out of your vite config, so an
184
+ app that names one SVG is not told to generate five PNGs it does not want.
169
185
  - `site.webmanifest` is emitted by `basaltAppPlugin` — no manual manifest file needed unless
170
186
  `manifest: false` was passed.
171
187
  - A thin `DESIGN.md` (deltas) + the thirteen `basalt-*` rules + the managed CLAUDE block are present.
@@ -179,14 +195,18 @@ both.
179
195
  - `init`, `sync`, and `check-theme` are all **real**. `sync` reconciles via a sha256 three-way diff
180
196
  (`--check` is a CI drift gate, `--force` overwrites local edits); `check-theme` is the palette
181
197
  guard; `doctor` checks resolution, version, guard scan, oxlint preset, spacing-scale drift and
182
- cross-package `ai` major parity. All via `bunx basalt-ui …`.
183
- - **Not a React app?** `bunx basalt-ui tokens:css --out src/tokens.css` emits the `--vx-*` layer with
198
+ cross-package `ai` major parity. All via the local bin. An unrecognized flag exits 1 naming it
199
+ (`doctor --json` used to run doctor and exit 0), and an unknown command says so above the usage
200
+ block.
201
+ - **Not a React app?** `bunx basalt-ui tokens:css --out src/tokens.css` (no install to resolve, so
202
+ `bunx` is right here) emits the `--vx-*` layer with
184
203
  no package in your dependency tree, `--selector-class dark` for the Tailwind `<html class="dark">`
185
204
  convention, and `fonts:css` emits the shipped `--basalt-font-*` stacks. Both carry the two-line
186
205
  `@generated basalt-ui` header the guard skips on — that header verbatim, and then only the LINES
187
206
  that are basalt custom properties, selectors, `}` or self-closing comments, so the marker pasted
188
207
  into a `.tsx` suppresses nothing and a declaration added to such a file is still reported — and
189
- both take `--check` as a CI drift gate. See `docs/FRAMEWORK-FREE.md` in the basalt-ui repo.
208
+ both take `--check` as a CI drift gate — which compares everything but the header's provenance
209
+ line, so a basalt-ui version bump alone never forces a no-op commit. See <https://github.com/jkrumm/basalt-ui/blob/master/docs/FRAMEWORK-FREE.md> (not in the package).
190
210
  - The framework ships **no** icon or notification dep — pass icons as `ReactNode` and wire toasts
191
211
  yourself (e.g. `ThemeLabControls`' `copyIcon` / `onCopy`).
192
212
  - The framework DOES ship `motion` (motion.dev, formerly framer-motion) as a bundled dependency —
@@ -7,8 +7,10 @@ when_to_use: User wants to add a chart, restyle an existing one structurally, in
7
7
  `/basalt-charts` is the how-to for the chart system. `/basalt-design` owns the aesthetic law
8
8
  (palette, restraint, the theme-lab loop) and the DESIGN.md precedence — read it for "what color /
9
9
  how should this look". This skill answers "how do I wire it" with basalt-ui's `./charts` and
10
- `./tokens` surfaces. `docs/CHARTS-SPEC.md` is the ground truth for the chart-primitive contract
11
- everything below assumes — composing `CartesianChart` (single-plot) or `ChartFrame` directly
10
+ `./tokens` surfaces. `.claude/rules/basalt-charts.md` — which you have — is the chart-primitive
11
+ contract everything below assumes (the repo's `docs/CHARTS-SPEC.md` is the long form and is not in
12
+ the package:
13
+ <https://github.com/jkrumm/basalt-ui/blob/master/docs/CHARTS-SPEC.md>) — composing `CartesianChart` (single-plot) or `ChartFrame` directly
12
14
  (multi-pane/radial/matrix) is mandatory, mechanically enforced (see "Respect the boundary" below).
13
15
 
14
16
  ## The decision: kind vs bespoke (Rule of Three)
@@ -12,8 +12,9 @@ Colors come from the three-tier `--vx-*` token system — read `VX.*` / a `defin
12
12
  never a raw hex/`rgb()`/`hsl()`. Charts are visx via `basalt-ui/charts`: every single-plot chart
13
13
  composes `CartesianChart` (owns margins, scales, axes, grid, cursor, tooltip — draw only marks);
14
14
  legends/tooltip rows are DERIVED from `series`, never hand-authored (`basalt/hand-rolled-plot` +
15
- `basalt/chart-legend-literal` enforce both); `DualPanel`/`Donut`/`Heatmap` are the declared
16
- exceptions. Add a kind on the third repeat, don't loosen the primitives. `basalt-ui/charts` and
15
+ `basalt/chart-legend-literal` enforce both); `DualPanel`/`BandStrip`/`MirroredBars` declare
16
+ themselves exceptions, and `Donut`/`Heatmap` render no plot-assembly element so the rule never
17
+ fires on them. Add a kind on the third repeat, don't loosen the primitives. `basalt-ui/charts` and
17
18
  `basalt-ui/tokens` are Mantine-free internally (a framework invariant, not something your own app
18
19
  code must follow) — never import `@visx/*` outside a `charts/` directory (oxlint-enforced).
19
20
  Toolchain is oxlint + oxfmt (no ESLint/Biome/Prettier) and `basalt-ui check-theme` guards the
@@ -7,16 +7,29 @@ import type { ChartLegendConfig, SeriesStyle } from '../series.js';
7
7
  * numeric value to plot — `formatValue` reads the datum directly.
8
8
  */
9
9
  export type BandStripSeries<T> = SeriesStyle & {
10
- /** The derived tooltip row's value for a band in this state. Omit for a state whose NAME is the
11
- * whole reading ("Not measured"), which then renders as a label with an empty value. */
12
- formatValue?: (d: T) => string;
10
+ /**
11
+ * The derived tooltip row's value for a band in this state.
12
+ *
13
+ * Return `null` for a datum in this state whose reading is ABSENT — the row renders
14
+ * {@link NO_READING} instead, which is the escape `ChartSeries.getValue` has and this shape did
15
+ * not: with no value accessor, an absent reading had to come back as `''` and render as a label
16
+ * with an empty value, indistinguishable from a state whose name is the whole reading.
17
+ *
18
+ * Omit the function entirely for a state whose NAME *is* the whole reading ("Not measured").
19
+ */
20
+ formatValue?: (d: T) => string | null;
13
21
  };
14
22
  /** One drawn band — which state it is in, and the three ways a state can be qualified. */
15
23
  export type BandSpan = {
16
24
  /**
17
25
  * Series key naming this band's state: the tie to its legend entry, its fill, and its derived
18
- * tooltip row. A key not present in `series` draws nothing — the loud failure is deliberate,
19
- * since the alternative is a mark no legend entry accounts for.
26
+ * tooltip row.
27
+ *
28
+ * A key not present in `series` is a bug TypeScript cannot catch (this is a `string`), and it
29
+ * used to draw NOTHING — which on a strip whose vocabulary is measured/not-measured is
30
+ * indistinguishable from a real coverage gap, so a typo silently asserted "not measured". It now
31
+ * throws in development and draws an explicit unknown band in production; see
32
+ * {@link unknownStateError} for why the two differ.
20
33
  */
21
34
  state: string;
22
35
  /**
@@ -79,7 +92,8 @@ export type BandStripProps<T> = {
79
92
  legend?: ChartLegendConfig | false;
80
93
  /** Colour of the absence hatch. Names a `series` entry, so absence is legended like any other
81
94
  * state — a hatched band is the one mark a reader cannot decode from an axis. Default
82
- * `VX.neutral`, unnamed. */
95
+ * `VX.neutral`, unnamed. A key naming no `series` entry throws (a PROP, so a typo can only be a
96
+ * wiring error) rather than falling back to the unnamed default. */
83
97
  absentState?: string;
84
98
  /** Per-side overrides of the measured margins — applied last. */
85
99
  margin?: Partial<ChartMargin>;
@@ -1 +1 @@
1
- {"version":3,"file":"BandStrip.d.ts","sourceRoot":"","sources":["../../../src/charts/kinds/BandStrip.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAC/C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AAEzD,OAAO,KAAK,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AAYvE,OAAO,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AAG/D;;;GAGG;AACH,MAAM,MAAM,eAAe,CAAC,CAAC,IAAI,WAAW,GAAG;IAC7C;4FACwF;IACxF,WAAW,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,CAAA;CAC/B,CAAA;AAED,0FAA0F;AAC1F,MAAM,MAAM,QAAQ,GAAG;IACrB;;;;OAIG;IACH,KAAK,EAAE,MAAM,CAAA;IACb;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAA;IACb;;;;;;OAMG;IACH,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB;;;;OAIG;IACH,MAAM,CAAC,EAAE;QACP,iFAAiF;QACjF,KAAK,CAAC,EAAE,MAAM,CAAA;QACd,uEAAuE;QACvE,KAAK,CAAC,EAAE,MAAM,CAAA;KACf,CAAA;CACF,CAAA;AAED,MAAM,MAAM,cAAc,CAAC,CAAC,IAAI;IAC9B,IAAI,EAAE,SAAS,CAAC,EAAE,CAAA;IAClB,gEAAgE;IAChE,OAAO,EAAE,MAAM,CAAA;IACf;yFACqF;IACrF,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,CAAA;IACtB;sCACkC;IAClC,MAAM,EAAE,SAAS,eAAe,CAAC,CAAC,CAAC,EAAE,CAAA;IACrC,oCAAoC;IACpC,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,QAAQ,CAAA;IAC3B;kEAC8D;IAC9D,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,+EAA+E;IAC/E,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,6DAA6D;IAC7D,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAA;IACjC,mDAAmD;IACnD,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,SAAS,EAAE,MAAM,KAAK,SAAS,MAAM,EAAE,CAAA;IAC/E,4EAA4E;IAC5E,IAAI,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAA;IAClB;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,gBAAgB,CAAA;IACnC,OAAO,CAAC,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAAG,KAAK,CAAA;IACtC,MAAM,CAAC,EAAE,iBAAiB,GAAG,KAAK,CAAA;IAClC;;gCAE4B;IAC5B,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,iEAAiE;IACjE,MAAM,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,CAAA;IAC7B;iDAC6C;IAC7C,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,8DAA8D;IAC9D,SAAS,CAAC,EAAE,OAAO,CAAA;CACpB,CAAA;AAID;;;;;;;;;;;;;GAaG;AACH,iBAAS,cAAc,CAAC,CAAC,EAAE,KAAK,EAAE,cAAc,CAAC,CAAC,CAAC,+BAgBlD;AAuND;;;GAGG;AACH,eAAO,MAAM,SAAS,EAA2B,OAAO,cAAc,CAAA"}
1
+ {"version":3,"file":"BandStrip.d.ts","sourceRoot":"","sources":["../../../src/charts/kinds/BandStrip.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAC/C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AAEzD,OAAO,KAAK,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AAYvE,OAAO,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AAG/D;;;GAGG;AACH,MAAM,MAAM,eAAe,CAAC,CAAC,IAAI,WAAW,GAAG;IAC7C;;;;;;;;;OASG;IACH,WAAW,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,GAAG,IAAI,CAAA;CACtC,CAAA;AAED,0FAA0F;AAC1F,MAAM,MAAM,QAAQ,GAAG;IACrB;;;;;;;;;OASG;IACH,KAAK,EAAE,MAAM,CAAA;IACb;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAA;IACb;;;;;;OAMG;IACH,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB;;;;OAIG;IACH,MAAM,CAAC,EAAE;QACP,iFAAiF;QACjF,KAAK,CAAC,EAAE,MAAM,CAAA;QACd,uEAAuE;QACvE,KAAK,CAAC,EAAE,MAAM,CAAA;KACf,CAAA;CACF,CAAA;AAED,MAAM,MAAM,cAAc,CAAC,CAAC,IAAI;IAC9B,IAAI,EAAE,SAAS,CAAC,EAAE,CAAA;IAClB,gEAAgE;IAChE,OAAO,EAAE,MAAM,CAAA;IACf;yFACqF;IACrF,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,CAAA;IACtB;sCACkC;IAClC,MAAM,EAAE,SAAS,eAAe,CAAC,CAAC,CAAC,EAAE,CAAA;IACrC,oCAAoC;IACpC,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,QAAQ,CAAA;IAC3B;kEAC8D;IAC9D,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,+EAA+E;IAC/E,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,6DAA6D;IAC7D,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAA;IACjC,mDAAmD;IACnD,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,SAAS,EAAE,MAAM,KAAK,SAAS,MAAM,EAAE,CAAA;IAC/E,4EAA4E;IAC5E,IAAI,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAA;IAClB;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,gBAAgB,CAAA;IACnC,OAAO,CAAC,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAAG,KAAK,CAAA;IACtC,MAAM,CAAC,EAAE,iBAAiB,GAAG,KAAK,CAAA;IAClC;;;wEAGoE;IACpE,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,iEAAiE;IACjE,MAAM,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,CAAA;IAC7B;iDAC6C;IAC7C,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,8DAA8D;IAC9D,SAAS,CAAC,EAAE,OAAO,CAAA;CACpB,CAAA;AAkDD;;;;;;;;;;;;;GAaG;AACH,iBAAS,cAAc,CAAC,CAAC,EAAE,KAAK,EAAE,cAAc,CAAC,CAAC,CAAC,+BAgBlD;AAwPD;;;GAGG;AACH,eAAO,MAAM,SAAS,EAA2B,OAAO,cAAc,CAAA"}
@@ -16,6 +16,25 @@ import { HatchPattern, hatchFill, hatchSizeFor } from "../primitives/HatchPatter
16
16
  import { HoverOverlay } from "../primitives/HoverOverlay.js";
17
17
  import { fmtAxisDate } from "../utils/format.js";
18
18
  const DEFAULT_MARKER_INSET = 6;
19
+ const NO_READING = "\u2014";
20
+ const UNKNOWN_MARK = {
21
+ fill: alpha(VX.neutral, 0.2),
22
+ stroke: VX.neutral,
23
+ strokeWidth: 1,
24
+ strokeDasharray: "3 2"
25
+ };
26
+ function isDev() {
27
+ return process.env["NODE_ENV"] !== "production";
28
+ }
29
+ function unknownStateError(what, key, known) {
30
+ return new Error(
31
+ `BandStrip: ${what} "${key}" names no \`series\` entry (known: ${[...known].join(", ")}) \u2014 so it has no legend entry, no colour and no tooltip row. Add the state to \`series\`, or map the datum onto one that is there.`
32
+ );
33
+ }
34
+ function formatBandValue(style, datum) {
35
+ if (style.formatValue === void 0) return "";
36
+ return style.formatValue(datum) ?? NO_READING;
37
+ }
19
38
  function BandStripInner(props) {
20
39
  const { series, chartId, height, fill, legend, ariaLabel, isPending } = props;
21
40
  return /* @__PURE__ */ jsx(
@@ -66,19 +85,44 @@ function BandStripPlot(props) {
66
85
  const { bands, margin, plotWidth, scale, cursor, point, crosshairX, step, bandWidth } = band;
67
86
  const stripHeight = Math.max(plot.height - margin.top - margin.bottom, 1);
68
87
  const hatchId = `${chartId}-band-absent`;
88
+ if (absentState !== void 0 && !styleByKey.has(absentState)) {
89
+ throw unknownStateError("absentState", absentState, styleByKey.keys());
90
+ }
69
91
  const absentColor = (absentState === void 0 ? void 0 : styleByKey.get(absentState)?.color) ?? VX.neutral;
70
92
  const rects = useMemo(() => {
71
93
  const out = [];
72
94
  bands.forEach((d, i) => {
73
95
  const span = getBand(d);
74
96
  const style = styleByKey.get(span.state);
75
- if (style === void 0 || hidden.has(span.state)) return;
97
+ const x = i * step;
98
+ if (style === void 0) {
99
+ if (isDev()) throw unknownStateError("BandSpan.state", span.state, styleByKey.keys());
100
+ out.push(
101
+ /* @__PURE__ */ jsx(
102
+ "rect",
103
+ {
104
+ ...UNKNOWN_MARK,
105
+ x,
106
+ y: 0,
107
+ width: bandWidth,
108
+ height: stripHeight,
109
+ rx: 1,
110
+ pointerEvents: "none"
111
+ },
112
+ getX(d)
113
+ )
114
+ );
115
+ return;
116
+ }
117
+ if (hidden.has(span.state)) return;
76
118
  const absent = clampFraction(span.absentFraction);
77
119
  const measuredWidth = bandWidth * (1 - absent);
78
120
  const hatchWidth = bandWidth - measuredWidth;
79
- const x = i * step;
80
121
  const markerKey = span.marker?.state ?? span.state;
81
122
  const markerColor = styleByKey.get(markerKey)?.color;
123
+ if (span.marker !== void 0 && markerColor === void 0 && isDev()) {
124
+ throw unknownStateError("BandSpan.marker.state", markerKey, styleByKey.keys());
125
+ }
82
126
  const inset = span.marker?.inset ?? DEFAULT_MARKER_INSET;
83
127
  out.push(
84
128
  /* @__PURE__ */ jsxs("g", { children: [
@@ -106,15 +150,15 @@ function BandStripPlot(props) {
106
150
  pointerEvents: "none"
107
151
  }
108
152
  ),
109
- span.marker !== void 0 && markerColor !== void 0 && measuredWidth > 0 && /* @__PURE__ */ jsx(
153
+ span.marker !== void 0 && measuredWidth > 0 && /* @__PURE__ */ jsx(
110
154
  "rect",
111
155
  {
156
+ ...markerColor === void 0 ? UNKNOWN_MARK : { fill: markerColor },
112
157
  x,
113
158
  y: inset,
114
159
  width: measuredWidth,
115
160
  height: Math.max(stripHeight - 2 * inset, 2),
116
161
  rx: 1,
117
- fill: markerColor,
118
162
  pointerEvents: "none"
119
163
  }
120
164
  )
@@ -203,11 +247,20 @@ function clampFraction(value) {
203
247
  }
204
248
  function deriveBandRow(span, styleByKey, hidden, datum) {
205
249
  const style = styleByKey.get(span.state);
206
- if (style === void 0 || style.tooltip === false || hidden.has(span.state)) return null;
250
+ if (style === void 0) {
251
+ return {
252
+ color: VX.neutral,
253
+ label: "Unknown state",
254
+ value: span.state,
255
+ shape: "bar",
256
+ dashed: true
257
+ };
258
+ }
259
+ if (style.tooltip === false || hidden.has(span.state)) return null;
207
260
  return {
208
261
  color: style.color,
209
262
  label: style.label,
210
- value: style.formatValue?.(datum) ?? "",
263
+ value: formatBandValue(style, datum),
211
264
  shape: style.mark === "line" ? "line" : "bar",
212
265
  dashed: style.dash === "dashed"
213
266
  };
@@ -4,7 +4,8 @@ import type { BandFold, BandTooltipConfig } from '../hooks/useBandPlot.js';
4
4
  import type { ChartLegendConfig, ChartSeries } from '../series.js';
5
5
  /** One of the two panes. Each resolves its own domain — that is the whole point of the kind. */
6
6
  export type MirroredBarPane = {
7
- /** Key of the `series` entry this pane draws: its colour, its legend entry, its tooltip row. */
7
+ /** Key of the `series` entry this pane draws: its colour, its legend entry, its tooltip row.
8
+ * A key naming no entry throws — see {@link assertPaneKey}. */
8
9
  key: string;
9
10
  /**
10
11
  * The pane's upper bound. `'auto'` (default) is its own visible maximum; a number pins it.
@@ -63,7 +64,8 @@ export type MirroredBarsProps<T> = {
63
64
  cursorResolution?: CursorResolution;
64
65
  tooltip?: BandTooltipConfig<T> | false;
65
66
  legend?: ChartLegendConfig | false;
66
- /** Series key whose colour the absence hatch is drawn in. Default `VX.neutral`. */
67
+ /** Series key whose colour the absence hatch is drawn in. Default `VX.neutral`. A key naming no
68
+ * `series` entry throws rather than falling back to the unnamed default. */
67
69
  absentState?: string;
68
70
  margin?: Partial<ChartMargin>;
69
71
  ariaLabel?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"MirroredBars.d.ts","sourceRoot":"","sources":["../../../src/charts/kinds/MirroredBars.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAC/C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AAEzD,OAAO,KAAK,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AAcvE,OAAO,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AAG/D,gGAAgG;AAChG,MAAM,MAAM,eAAe,GAAG;IAC5B,gGAAgG;IAChG,GAAG,EAAE,MAAM,CAAA;IACX;;;;;;;OAOG;IACH,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACrB;sBACkB;IAClB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,sDAAsD;IACtD,KAAK,CAAC,EAAE,MAAM,CAAA;IACd;oFACgF;IAChF,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAA;CAC9B,CAAA;AAED,MAAM,MAAM,iBAAiB,CAAC,CAAC,IAAI;IACjC,IAAI,EAAE,SAAS,CAAC,EAAE,CAAA;IAClB,OAAO,EAAE,MAAM,CAAA;IACf,sFAAsF;IACtF,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,CAAA;IACtB;;;;;OAKG;IACH,MAAM,EAAE,SAAS,WAAW,CAAC,CAAC,CAAC,EAAE,CAAA;IACjC,yCAAyC;IACzC,EAAE,EAAE,eAAe,CAAA;IACnB,yCAAyC;IACzC,IAAI,EAAE,eAAe,CAAA;IACrB;8FAC0F;IAC1F,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,CAAA;IACpC;kCAC8B;IAC9B,aAAa,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,CAAA;IAChC,kEAAkE;IAClE,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAA;IACjC,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,SAAS,EAAE,MAAM,KAAK,SAAS,MAAM,EAAE,CAAA;IAC/E,IAAI,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAA;IAClB,mEAAmE;IACnE,gBAAgB,CAAC,EAAE,gBAAgB,CAAA;IACnC,OAAO,CAAC,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAAG,KAAK,CAAA;IACtC,MAAM,CAAC,EAAE,iBAAiB,GAAG,KAAK,CAAA;IAClC,mFAAmF;IACnF,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,CAAA;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,SAAS,CAAC,EAAE,OAAO,CAAA;CACpB,CAAA;AAKD;;;;;;;;;;;;;GAaG;AACH,iBAAS,iBAAiB,CAAC,CAAC,EAAE,KAAK,EAAE,iBAAiB,CAAC,CAAC,CAAC,+BAgBxD;AAmUD;;;GAGG;AACH,eAAO,MAAM,YAAY,EAA8B,OAAO,iBAAiB,CAAA"}
1
+ {"version":3,"file":"MirroredBars.d.ts","sourceRoot":"","sources":["../../../src/charts/kinds/MirroredBars.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAC/C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AAEzD,OAAO,KAAK,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AAcvE,OAAO,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AAG/D,gGAAgG;AAChG,MAAM,MAAM,eAAe,GAAG;IAC5B;mEAC+D;IAC/D,GAAG,EAAE,MAAM,CAAA;IACX;;;;;;;OAOG;IACH,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACrB;sBACkB;IAClB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,sDAAsD;IACtD,KAAK,CAAC,EAAE,MAAM,CAAA;IACd;oFACgF;IAChF,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAA;CAC9B,CAAA;AAED,MAAM,MAAM,iBAAiB,CAAC,CAAC,IAAI;IACjC,IAAI,EAAE,SAAS,CAAC,EAAE,CAAA;IAClB,OAAO,EAAE,MAAM,CAAA;IACf,sFAAsF;IACtF,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,CAAA;IACtB;;;;;OAKG;IACH,MAAM,EAAE,SAAS,WAAW,CAAC,CAAC,CAAC,EAAE,CAAA;IACjC,yCAAyC;IACzC,EAAE,EAAE,eAAe,CAAA;IACnB,yCAAyC;IACzC,IAAI,EAAE,eAAe,CAAA;IACrB;8FAC0F;IAC1F,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,CAAA;IACpC;kCAC8B;IAC9B,aAAa,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,CAAA;IAChC,kEAAkE;IAClE,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAA;IACjC,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,SAAS,EAAE,MAAM,KAAK,SAAS,MAAM,EAAE,CAAA;IAC/E,IAAI,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAA;IAClB,mEAAmE;IACnE,gBAAgB,CAAC,EAAE,gBAAgB,CAAA;IACnC,OAAO,CAAC,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAAG,KAAK,CAAA;IACtC,MAAM,CAAC,EAAE,iBAAiB,GAAG,KAAK,CAAA;IAClC;gFAC4E;IAC5E,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,CAAA;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,SAAS,CAAC,EAAE,OAAO,CAAA;CACpB,CAAA;AA8BD;;;;;;;;;;;;;GAaG;AACH,iBAAS,iBAAiB,CAAC,CAAC,EAAE,KAAK,EAAE,iBAAiB,CAAC,CAAC,CAAC,+BAgBxD;AA4UD;;;GAGG;AACH,eAAO,MAAM,YAAY,EAA8B,OAAO,iBAAiB,CAAA"}
@@ -20,6 +20,12 @@ import { deriveTooltipRows } from "../series.js";
20
20
  import { fmtAxisDate } from "../utils/format.js";
21
21
  const DEFAULT_UP_FRACTION = 0.35;
22
22
  const DEFAULT_PANE_TICKS = 3;
23
+ function assertPaneKey(side, key, resolved, series) {
24
+ if (resolved !== void 0) return;
25
+ throw new Error(
26
+ `MirroredBars: ${side}.key "${key}" names no \`series\` entry (known: ${series.map((s) => s.key).join(", ")}) \u2014 the pane would silently vanish, which reads as a measured zero. Add the series, or point the pane at one that exists.`
27
+ );
28
+ }
23
29
  function MirroredBarsInner(props) {
24
30
  const { series, chartId, height, fill, legend, ariaLabel, isPending } = props;
25
31
  return /* @__PURE__ */ jsx(
@@ -61,6 +67,8 @@ function MirroredBarsPlot(props) {
61
67
  const seriesByKey = useMemo(() => new Map(series.map((s) => [s.key, s])), [series]);
62
68
  const upSeries = seriesByKey.get(up.key);
63
69
  const downSeries = seriesByKey.get(down.key);
70
+ assertPaneKey("up", up.key, upSeries, series);
71
+ assertPaneKey("down", down.key, downSeries, series);
64
72
  const upVisible = upSeries !== void 0 && !hidden.has(up.key);
65
73
  const downVisible = downSeries !== void 0 && !hidden.has(down.key);
66
74
  const upMax = usePaneMax(data, upSeries, up, upVisible);
@@ -112,6 +120,11 @@ function MirroredBarsPlot(props) {
112
120
  [upMax, upHeight]
113
121
  );
114
122
  const hatchId = `${chartId}-mirrored-absent`;
123
+ if (absentState !== void 0 && !seriesByKey.has(absentState)) {
124
+ throw new Error(
125
+ `MirroredBars: absentState "${absentState}" names no \`series\` entry (known: ${series.map((s) => s.key).join(", ")}) \u2014 the hatch would fall back to an unnamed neutral, and a hatched bar is the one mark a reader cannot decode from either axis.`
126
+ );
127
+ }
115
128
  const absentColor = (absentState === void 0 ? void 0 : seriesByKey.get(absentState)?.color) ?? VX.neutral;
116
129
  const drawnUp = upVisible ? upSeries : void 0;
117
130
  const drawnDown = downVisible ? downSeries : void 0;
@@ -454,8 +454,10 @@ type DoctorResult = {
454
454
  * demonstrably not the installed package — see the check).
455
455
  * 5. The running CLI's own version matches the installed basalt-ui (catches a stale
456
456
  * `bunx basalt-ui` npm fetch; best-effort, skipped if node_modules is absent).
457
- * 9. `basaltAppPlugin`'s (basalt-ui/vite) default icon filenames exist under public/ (only when
458
- * a public/ dir exists at all — skipped otherwise).
457
+ * 9. The icon files `basaltAppPlugin` (basalt-ui/vite) references exist under the app package's
458
+ * public/ — the package found via `basalt.roots`, not just cwd, so a root-invoked run still
459
+ * reaches it. Never silently omitted: no plugin call anywhere is a pass that says so, a
460
+ * plugin call with no public/ beside it is a SKIPPED.
459
461
  * 10 (second half). A declared `basalt.aiMajorSkewReason` when the ai majors currently AGREE — the
460
462
  * exemption is stale and can be deleted; an exemption nobody revisits is how a real, later
461
463
  * skew slips through unnoticed.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}