basalt-ui 2.3.0 → 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,21 @@
1
+ # [2.4.0](https://github.com/jkrumm/basalt-ui/compare/v2.3.0...v2.4.0) (2026-10-14)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * guard band edge rules in one place and share the tooltip row builders ([75a386b](https://github.com/jkrumm/basalt-ui/commit/75a386b677518e24fc7b13ab7c49c3469c1aaa9d))
7
+ * let the managed pre-commit pass when every staged file is lint-ignored ([dbaa6bc](https://github.com/jkrumm/basalt-ui/commit/dbaa6bce1ea0eefbecee0666ea94c656f81d5b18))
8
+
9
+
10
+ ### Features
11
+
12
+ * connect a series across null rows ([3c14ed1](https://github.com/jkrumm/basalt-ui/commit/3c14ed18583710c9b742cd5fa0139c75c06beb4d))
13
+ * cursor dots for marks-drawn series and edge rules on bands ([27bb5b2](https://github.com/jkrumm/basalt-ui/commit/27bb5b228e6212f9e86737aa7868ed375fd66cda))
14
+ * dashed tooltip swatches for reference and dashed series ([5938eb8](https://github.com/jkrumm/basalt-ui/commit/5938eb859fb571a527394b157ab47614406b5444))
15
+ * let a store field take a fallback derived at the call site ([3c12371](https://github.com/jkrumm/basalt-ui/commit/3c12371536a73b45418b1f75ff3479fa4012bd23))
16
+ * reference lines name themselves in the legend ([b49ae5b](https://github.com/jkrumm/basalt-ui/commit/b49ae5bb0317aa99f02e33bcb72f5f493351ddd9))
17
+ * tooltipFormat on the DualPanel bar and top specs ([bde88fe](https://github.com/jkrumm/basalt-ui/commit/bde88fe59de3cdc931a94ed52a696cec3987ab86))
18
+
1
19
  # [2.3.0](https://github.com/jkrumm/basalt-ui/compare/v2.2.0...v2.3.0) (2026-10-14)
2
20
 
3
21
 
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 | 1.40.2 | 1.40.3 | 1.41.0 | 2.0.0 | 2.0.1 | 2.0.2 | 2.0.3 | 2.0.4 | 2.0.5 | 2.1.0 | 2.2.0 | 2.3.0 | Unreleased |
70
- | ----------------------------- | ------------------------------------------------------------ | -------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | --------------------------------------------------------------------- | ------ | ----------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------- | ---------------------------------- | ------ | ------ | -------------------------------------------------------------------------------------------- | ------ | ------ | ------ | ------ | ------ | ----------------------------------------------- | ------ | ------ | ------ | ------ | ------------------------------------------------------------ | ---------- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
71
- | **tokens** (`./tokens`) | — | `--vx-divider` → `rgba()` on both schemes (§ Shell) | `--vx-space-touch-target` added (§ Additions) | eight spacing numbers (§ Chrome) | — | — | `--vx-hit` replaces the touch vars; `SIZE_CLASSES` (§ 1.31.0) | — | `SIZE_CLASSES`/`CONTAINER_CLASSES` actually exported (§ Fixes) | `CONTAINER_GRID_BREAKPOINTS`; `raw-breakpoint` trusts it (§ 1.33.0) | `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) | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | the managed block moves `CLAUDE.md` → `AGENTS.md` (§ 1.41.0) | — | — | — | — | — | — | — | — | — | — |
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 | 1.40.3 | 1.41.0 | 2.0.0 | 2.0.1 | 2.0.2 | 2.0.3 | 2.0.4 | 2.0.5 | 2.1.0 | 2.2.0 | 2.3.0 | 2.4.0 | Unreleased |
70
+ | ----------------------------- | ------------------------------------------------------------ | -------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | --------------------------------------------------------------------- | ------ | ----------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------- | ---------------------------------- | ------ | ------ | -------------------------------------------------------------------------------------------- | ------ | ------ | ------ | ------ | ------ | ----------------------------------------------- | ------ | ------ | ------ | ------ | ------------------------------------------------------------ | ---------- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
71
+ | **tokens** (`./tokens`) | — | `--vx-divider` → `rgba()` on both schemes (§ Shell) | `--vx-space-touch-target` added (§ Additions) | eight spacing numbers (§ Chrome) | — | — | `--vx-hit` replaces the touch vars; `SIZE_CLASSES` (§ 1.31.0) | — | `SIZE_CLASSES`/`CONTAINER_CLASSES` actually exported (§ Fixes) | `CONTAINER_GRID_BREAKPOINTS`; `raw-breakpoint` trusts it (§ 1.33.0) | `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) | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | the managed block moves `CLAUDE.md` → `AGENTS.md` (§ 1.41.0) | — | — | — | — | — | — | — | — | — | — | — |
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
 
@@ -992,6 +992,51 @@ optional, subpath-required peers.
992
992
  _Nothing yet. Author the next section under this heading as `## Unreleased — <title>`; the
993
993
  release renames it and opens a new one here._
994
994
 
995
+ ## 2.4.0 — chart gaps and legends, local-store fallbacks, the pre-commit hook
996
+
997
+ All additive; no call site changes. Named consumers are argo `apps/dashboard/src/features/…`.
998
+
999
+ - `createLocalStore` fields take `use({ fallback })`: a call-site default (e.g. a prop-derived
1000
+ leader) that applies only while the field is unset and is never persisted, so a reset returns to
1001
+ it. Replace a store rebuilt per prop with it. `createSearchStore` fields do not take it yet.
1002
+ - The managed lefthook oxlint step passes `--no-error-on-unmatched-pattern`, so a commit whose
1003
+ staged files are all in `ignorePatterns` no longer fails; a real lint error still does. Picked up
1004
+ through the extended preset.
1005
+
1006
+ - `ChartTooltipRow` takes `swatch: 'solid' | 'dashed'`. A series with `dash: 'dashed'` now lists a
1007
+ dashed swatch in its own tooltip row on `CartesianChart`, `Lines`, `Bars` and `DualPanel` (it was
1008
+ solid while the legend and the line were dashed), and a `tooltip.rows` entry sets it itself. A
1009
+ `color` per point needs no new option: `tooltip.rows(d)` already receives the datum, so the row's
1010
+ `color` can be a function of it (garmin-health `recovery-trend-chart.tsx`, its `Zone` row). argo:
1011
+ `garmin-health/charts/stress-chart.tsx` (the dashed `Overnight` line).
1012
+ - `RefLine.legend: { label, mark? }` gives a reference line its own legend entry (the line's color,
1013
+ dashed as `dashed`, role `reference`; a toggle hides the line, keyed by its index in `refLines`; series keys starting `__ref-` are reserved and throw in dev), so a threshold needs no always-`null`
1014
+ series. argo `strength-tracker/charts/weekly-volume-chart.tsx`: delete `LANDMARK_LEGEND` and put
1015
+ `legend: { label: 'MEV' }` on the three `refLines`.
1016
+ - `DualPanelBar.tooltipFormat` and `DualPanelProps.top.tooltipFormat` format the tooltip rows while
1017
+ `format` keeps the axis ticks (default: `format`; `formatValue` still wins per row). argo
1018
+ `strength-tracker/charts/momentum-chart.tsx`: drop the separate `formatValue` copy of the axis format.
1019
+ - `ChartSeries.cursorValue: (d) => number | null` gives a series drawn from your own `marks` a cursor
1020
+ dot: the y at each datum, shown while the cursor is on that x, in the series color. Pass a series
1021
+ with `getValue: () => null` (no tooltip row) and the mark stays yours. argo
1022
+ `astro-window/charts/sky-panorama.tsx` (the sun track).
1023
+ - `ZoneSpec.edge` (`side: 'top' | 'bottom' | 'both'`) and `XZoneSpec.edge` (`'start' | 'end' | 'both'`)
1024
+ draw a rule along the band's boundary, with `color`, `dashed` and `width`. A bound at the plot edge
1025
+ (infinite, outside the domain, or an omitted x bound) draws none. argo
1026
+ `astro-window/charts/night-timeline-chart.tsx`: the shooting-window `rect` + two `ruleX` become one
1027
+ `xZones` entry with `edge: { side: 'both', color: VX.accent, width: 2 }`.
1028
+ - `ChartSeries.gaps: 'break' | 'connect'` (`Lines`; default `'break'`, today's behaviour). `'connect'`
1029
+ draws the line, and its `area`, through the series' non-null points only, so a series that is null
1030
+ on most shared x values is one continuous line instead of dots and stubs. Markers stay on real
1031
+ points; the cursor and tooltip read the value at the hovered x (no value, no row). argo
1032
+ `strength-tracker/charts/relative-progression-chart.tsx` and `one-rm-trend-chart.tsx`: set
1033
+ `gaps: 'connect'` on each lift's series.
1034
+ - Not added: a per-datum `fill` for the engine's `rect`. `@tanstack/charts` 1.1.0 types `RectOptions.fill`
1035
+ as a `string`; its `color` channel resolves through the chart's own color scale, which `marks` cannot
1036
+ reach. Keep one `rect` per fill bucket (argo `astro-window/charts/sky-panorama.tsx`, skyglow).
1037
+ - The night-timeline lines can use `chartCurve(s.curve ?? 'monotone')` from 2.3.0 unchanged; nothing
1038
+ is missing there.
1039
+
995
1040
  ## 2.3.0 — optional-safe chart props, `chartCurve`, zone-coloured area
996
1041
 
997
1042
  - Every optional prop of `ChartState`, `ChartSeries`, `AxisConfig`, the tooltip config and the chart
@@ -24,7 +24,7 @@ State a control reads or writes is a field on a store; the URL wins over localSt
24
24
  - Option labels come from `.labels()` at definition, never a control prop. [type createSearchStore]
25
25
  - Route `validateSearch` is `store.validateSearch`; a wider search shape spreads `...store.validateSearch(raw)`. [type createSearchStore]
26
26
  - Read with `store.useValues()` or take the value as a prop; never `useSearch({ from: '<literal>' })`. [basalt/use-search-from-literal]
27
- - A handle's `use()` returns `[value, setValue]`; the setter owns the navigate and the persist. [type field]
27
+ - A handle's `use()` returns `[value, setValue]`; the setter owns the navigate and the persist; on a `createLocalStore` field a prop-derived default is `use({ fallback })` (unset only, never persisted; search stores lack it), never a store rebuilt per prop. [type field]
28
28
  - Count active filters and reset them with the store's `useActiveCount()` and `useReset()`; a reset unsets, it does not write the fallback. [type createSearchStore]
29
29
  - A color scheme is `useMantineColorScheme()`, never a store or `localStorage['theme']`. [check-theme localstorage-theme]
30
30
  - A preference that must survive navigation but is not URL-worthy uses `createPersistedState`, called once at module scope. [type createPersistedState]
@@ -37,9 +37,12 @@
37
37
  pre-commit:
38
38
  parallel: true
39
39
  commands:
40
+ # `--no-error-on-unmatched-pattern`: oxlint exits 1 ("No files found to lint") when EVERY staged
41
+ # file is excluded by `ignorePatterns` (a consumer's `scripts/`), failing a commit that touches
42
+ # only ignored files. A real error in a non-ignored staged file still fails.
40
43
  oxlint:
41
44
  glob: '*.{ts,tsx,js,jsx}'
42
- run: bunx oxlint {staged_files}
45
+ run: bunx oxlint --no-error-on-unmatched-pattern {staged_files}
43
46
  # `css` is load-bearing, not tidiness: oxfmt formats stylesheets, so without it a CSS-only
44
47
  # commit passes the hook and then fails the same check in CI. `oxlint` above deliberately
45
48
  # stops at JS — it has nothing to say about CSS.
@@ -1 +1 @@
1
- {"version":3,"file":"CartesianChart.d.ts","sourceRoot":"","sources":["../../src/charts/CartesianChart.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAiB,YAAY,EAAa,MAAM,OAAO,CAAA;AAGnE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAA;AAKpD,OAAO,KAAK,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAEvE,6DAA6D;AAC7D,MAAM,MAAM,WAAW,GAAG;IACxB,6BAA6B;IAC7B,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,yDAAyD;IACzD,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,sDAAsD;IACtD,KAAK,CAAC,EAAE,SAAS,GAAG,YAAY,CAAA;CACjC,CAAA;AAgCD,kGAAkG;AAClG,MAAM,MAAM,YAAY,GAAG;IACzB,gDAAgD;IAChD,OAAO,EAAE,MAAM,CAAA;IACf,8CAA8C;IAC9C,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;IAC3B,0CAA0C;IAC1C,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,gCAAgC;IAChC,MAAM,EAAE,OAAO,CAAA;IACf,gFAAgF;IAChF,KAAK,EAAE,MAAM,CAAA;CACd,CAAA;AAED,MAAM,MAAM,eAAe,CAAC,CAAC,IAAI,IAAI,CACnC,mBAAmB,CAAC,CAAC,EAAE,MAAM,CAAC,EAC9B,WAAW,GAAG,QAAQ,GAAG,QAAQ,GAAG,OAAO,GAAG,WAAW,GAAG,OAAO,CACpE,GAAG;IACF,qCAAqC;IACrC,MAAM,EAAE,SAAS,WAAW,CAAC,CAAC,CAAC,EAAE,CAAA;IACjC,6FAA6F;IAC7F,OAAO,EAAE,CAAC,GAAG,EAAE,YAAY,KAAK,mBAAmB,CAAA;IACnD,+EAA+E;IAC/E,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB,CAAA;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,KAAK,EAAE,eAAe,CAAC,CAAC,CAAC,GAAG,YAAY,CAuErE;AAED,wBAAgB,aAAa,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,EAC/C,KAAK,EAAE,mBAAmB,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,WAAW,GAC7C,YAAY,CAmBd;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,EAChD,KAAK,EAAE,mBAAmB,CAAC,CAAC,EAAE,CAAC,CAAC,GAC/B,YAAY,CAEd"}
1
+ {"version":3,"file":"CartesianChart.d.ts","sourceRoot":"","sources":["../../src/charts/CartesianChart.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAiB,YAAY,EAAa,MAAM,OAAO,CAAA;AAGnE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAA;AAKpD,OAAO,KAAK,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAEvE,6DAA6D;AAC7D,MAAM,MAAM,WAAW,GAAG;IACxB,6BAA6B;IAC7B,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,yDAAyD;IACzD,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,sDAAsD;IACtD,KAAK,CAAC,EAAE,SAAS,GAAG,YAAY,CAAA;CACjC,CAAA;AAgCD,kGAAkG;AAClG,MAAM,MAAM,YAAY,GAAG;IACzB,gDAAgD;IAChD,OAAO,EAAE,MAAM,CAAA;IACf,8CAA8C;IAC9C,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;IAC3B,0CAA0C;IAC1C,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,gCAAgC;IAChC,MAAM,EAAE,OAAO,CAAA;IACf,gFAAgF;IAChF,KAAK,EAAE,MAAM,CAAA;CACd,CAAA;AAED,MAAM,MAAM,eAAe,CAAC,CAAC,IAAI,IAAI,CACnC,mBAAmB,CAAC,CAAC,EAAE,MAAM,CAAC,EAC9B,WAAW,GAAG,QAAQ,GAAG,QAAQ,GAAG,OAAO,GAAG,WAAW,GAAG,OAAO,CACpE,GAAG;IACF,qCAAqC;IACrC,MAAM,EAAE,SAAS,WAAW,CAAC,CAAC,CAAC,EAAE,CAAA;IACjC,6FAA6F;IAC7F,OAAO,EAAE,CAAC,GAAG,EAAE,YAAY,KAAK,mBAAmB,CAAA;IACnD,+EAA+E;IAC/E,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB,CAAA;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,KAAK,EAAE,eAAe,CAAC,CAAC,CAAC,GAAG,YAAY,CAuErE;AAED,wBAAgB,aAAa,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,EAC/C,KAAK,EAAE,mBAAmB,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,WAAW,GAC7C,YAAY,CAwBd;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,EAChD,KAAK,EAAE,mBAAmB,CAAC,CAAC,EAAE,CAAC,CAAC,GAC/B,YAAY,CAEd"}
@@ -1,7 +1,7 @@
1
1
  import { jsx, jsxs } from "react/jsx-runtime";
2
2
  import { useCallback, useId, useMemo, useState } from "react";
3
3
  import { useInChartCard } from "./card-context.js";
4
- import { compileCartesian } from "./compile.js";
4
+ import { compileCartesian, refLegendSeries } from "./compile.js";
5
5
  import { ChartEngine, idPrefixOf } from "./host.js";
6
6
  import { ChartLegend, legendEntries } from "./legend.js";
7
7
  import { INITIAL_WIDTH, useChartSize } from "./sizing.js";
@@ -97,10 +97,14 @@ function CartesianRung(props) {
97
97
  (ctx) => compileCartesian({ ...stable, ...ctx }),
98
98
  [stable]
99
99
  );
100
+ const legendSeries = useMemo(
101
+ () => [...stable.series, ...refLegendSeries(stable.refLines)],
102
+ [stable.series, stable.refLines]
103
+ );
100
104
  return /* @__PURE__ */ jsx(
101
105
  ChartShell,
102
106
  {
103
- series,
107
+ series: legendSeries,
104
108
  compile,
105
109
  ariaLabel,
106
110
  ...legend !== void 0 && { legend },
@@ -10,8 +10,10 @@ export type DualPanelBar<T> = {
10
10
  positive: string;
11
11
  /** The fill below zero. */
12
12
  negative: string;
13
- /** Tick and tooltip formatter. */
13
+ /** Tick formatter, and the tooltip's too unless `tooltipFormat` is given. */
14
14
  format: (v: number) => string;
15
+ /** The tooltip row's formatter. Default: `format`. */
16
+ tooltipFormat?: ((v: number) => string) | undefined;
15
17
  /** The tooltip row's value, for a unit or a decimal `format` cannot carry. */
16
18
  formatValue?: ((v: number, d: T) => string) | undefined;
17
19
  /** Default `'auto'`: a symmetric `[-maxAbs, maxAbs]` from the data, rounded to nice ticks. A tuple
@@ -28,6 +30,8 @@ export type DualPanelProps<T, X extends Date | number = Date | number> = Pick<Ca
28
30
  top?: {
29
31
  domain?: readonly [number, number] | 'auto' | undefined;
30
32
  format?: ((v: number) => string) | undefined;
33
+ /** The lines' tooltip formatter. Default: `format`. */
34
+ tooltipFormat?: ((v: number) => string) | undefined;
31
35
  } | undefined;
32
36
  /**
33
37
  * Shades the band between two top lines (by key), where both are visible. `aboveFill` colours the
@@ -1 +1 @@
1
- {"version":3,"file":"DualPanel.d.ts","sourceRoot":"","sources":["../../src/charts/DualPanel.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAA;AASzC,OAAO,KAAK,EAAE,mBAAmB,EAAE,WAAW,EAAwB,MAAM,SAAS,CAAA;AAcrF,uBAAuB;AACvB,MAAM,MAAM,aAAa,CAAC,CAAC,IAAI,IAAI,CACjC,WAAW,CAAC,CAAC,CAAC,EACZ,KAAK,GACL,OAAO,GACP,OAAO,GACP,UAAU,GACV,aAAa,GACb,SAAS,GACT,QAAQ,GACR,MAAM,GACN,MAAM,GACN,MAAM,GACN,OAAO,GACP,aAAa,GACb,eAAe,GACf,WAAW,CACd,CAAA;AAED,mEAAmE;AACnE,MAAM,MAAM,YAAY,CAAC,CAAC,IAAI;IAC5B,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,GAAG,IAAI,CAAA;IACjC,kDAAkD;IAClD,QAAQ,EAAE,MAAM,CAAA;IAChB,2BAA2B;IAC3B,QAAQ,EAAE,MAAM,CAAA;IAChB,kCAAkC;IAClC,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAA;IAC7B,8EAA8E;IAC9E,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,KAAK,MAAM,CAAC,GAAG,SAAS,CAAA;IACvD;2BACuB;IACvB,MAAM,CAAC,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,GAAG,SAAS,CAAA;IACvD,sFAAsF;IACtF,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CACjC,CAAA;AAED,MAAM,MAAM,cAAc,CAAC,CAAC,EAAE,CAAC,SAAS,IAAI,GAAG,MAAM,GAAG,IAAI,GAAG,MAAM,IAAI,IAAI,CAC3E,mBAAmB,CAAC,CAAC,EAAE,CAAC,CAAC,EACvB,WAAW,GACX,MAAM,GACN,GAAG,GACH,SAAS,GACT,QAAQ,GACR,QAAQ,GACR,OAAO,GACP,aAAa,GACb,kBAAkB,GAClB,SAAS,GACT,WAAW,GACX,OAAO,CACV,GAAG;IACF,4BAA4B;IAC5B,MAAM,EAAE,SAAS,aAAa,CAAC,CAAC,CAAC,EAAE,CAAA;IACnC;6FACyF;IACzF,GAAG,CAAC,EACA;QACE,MAAM,CAAC,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,GAAG,SAAS,CAAA;QACvD,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC,GAAG,SAAS,CAAA;KAC7C,GACD,SAAS,CAAA;IACb;;;OAGG;IACH,WAAW,CAAC,EACR;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE,GAC1E,SAAS,CAAA;IACb,GAAG,EAAE,YAAY,CAAC,CAAC,CAAC,CAAA;IACpB,8DAA8D;IAC9D,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CACjC,CAAA;AAiBD,wBAAgB,SAAS,CAAC,CAAC,EAAE,CAAC,SAAS,IAAI,GAAG,MAAM,GAAG,IAAI,GAAG,MAAM,EAClE,KAAK,EAAE,cAAc,CAAC,CAAC,EAAE,CAAC,CAAC,GAC1B,YAAY,CA4Md"}
1
+ {"version":3,"file":"DualPanel.d.ts","sourceRoot":"","sources":["../../src/charts/DualPanel.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAA;AASzC,OAAO,KAAK,EAAE,mBAAmB,EAAE,WAAW,EAAwB,MAAM,SAAS,CAAA;AAcrF,uBAAuB;AACvB,MAAM,MAAM,aAAa,CAAC,CAAC,IAAI,IAAI,CACjC,WAAW,CAAC,CAAC,CAAC,EACZ,KAAK,GACL,OAAO,GACP,OAAO,GACP,UAAU,GACV,aAAa,GACb,SAAS,GACT,QAAQ,GACR,MAAM,GACN,MAAM,GACN,MAAM,GACN,OAAO,GACP,aAAa,GACb,eAAe,GACf,WAAW,CACd,CAAA;AAED,mEAAmE;AACnE,MAAM,MAAM,YAAY,CAAC,CAAC,IAAI;IAC5B,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,GAAG,IAAI,CAAA;IACjC,kDAAkD;IAClD,QAAQ,EAAE,MAAM,CAAA;IAChB,2BAA2B;IAC3B,QAAQ,EAAE,MAAM,CAAA;IAChB,6EAA6E;IAC7E,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAA;IAC7B,sDAAsD;IACtD,aAAa,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC,GAAG,SAAS,CAAA;IACnD,8EAA8E;IAC9E,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,KAAK,MAAM,CAAC,GAAG,SAAS,CAAA;IACvD;2BACuB;IACvB,MAAM,CAAC,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,GAAG,SAAS,CAAA;IACvD,sFAAsF;IACtF,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CACjC,CAAA;AAED,MAAM,MAAM,cAAc,CAAC,CAAC,EAAE,CAAC,SAAS,IAAI,GAAG,MAAM,GAAG,IAAI,GAAG,MAAM,IAAI,IAAI,CAC3E,mBAAmB,CAAC,CAAC,EAAE,CAAC,CAAC,EACvB,WAAW,GACX,MAAM,GACN,GAAG,GACH,SAAS,GACT,QAAQ,GACR,QAAQ,GACR,OAAO,GACP,aAAa,GACb,kBAAkB,GAClB,SAAS,GACT,WAAW,GACX,OAAO,CACV,GAAG;IACF,4BAA4B;IAC5B,MAAM,EAAE,SAAS,aAAa,CAAC,CAAC,CAAC,EAAE,CAAA;IACnC;6FACyF;IACzF,GAAG,CAAC,EACA;QACE,MAAM,CAAC,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,GAAG,SAAS,CAAA;QACvD,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC,GAAG,SAAS,CAAA;QAC5C,uDAAuD;QACvD,aAAa,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC,GAAG,SAAS,CAAA;KACpD,GACD,SAAS,CAAA;IACb;;;OAGG;IACH,WAAW,CAAC,EACR;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE,GAC1E,SAAS,CAAA;IACb,GAAG,EAAE,YAAY,CAAC,CAAC,CAAC,CAAA;IACpB,8DAA8D;IAC9D,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CACjC,CAAA;AAiBD,wBAAgB,SAAS,CAAC,CAAC,EAAE,CAAC,SAAS,IAAI,GAAG,MAAM,GAAG,IAAI,GAAG,MAAM,EAClE,KAAK,EAAE,cAAc,CAAC,CAAC,EAAE,CAAC,CAAC,GAC1B,YAAY,CA8Nd"}
@@ -7,7 +7,7 @@ import { scaleUtc } from "d3-scale";
7
7
  import { useCallback, useMemo } from "react";
8
8
  import { VX, alpha } from "../tokens/index.js";
9
9
  import { resolveContainerClass } from "../tokens/size-classes.js";
10
- import { defaultFormatX, defaultNumberFormat, visibleSeries } from "./compile.js";
10
+ import { defaultFormatX, defaultNumberFormat, engineRow, seriesRow, visibleSeries } from "./compile.js";
11
11
  import { barMark, emphasis, lineMark, markersOf, thinFill } from "./marks.js";
12
12
  import { PanelRung, paneX, paneY, rowsOf } from "./panel.js";
13
13
  import { xScaleFor } from "./scales.js";
@@ -60,6 +60,8 @@ function DualPanel(props) {
60
60
  );
61
61
  const all = useMemo(() => [...lines, barSeries], [lines, barSeries]);
62
62
  const topFormat = top?.format ?? defaultNumberFormat;
63
+ const topTooltipFormat = top?.tooltipFormat ?? topFormat;
64
+ const barTooltipFormat = bar.tooltipFormat ?? bar.format;
63
65
  const plan = useCallback(
64
66
  ({ hidden, highlighted }) => {
65
67
  const model = xScaleFor(data.map(x), false);
@@ -186,26 +188,42 @@ function DualPanel(props) {
186
188
  for (const s of visible) {
187
189
  const v2 = s.getValue(d);
188
190
  if (s.tooltip === false || v2 === null || !Number.isFinite(v2)) continue;
189
- out.push({
190
- label: s.note === void 0 ? s.label : `${s.label} \xB7 ${s.note}`,
191
- value: s.formatValue ? s.formatValue(v2, d) : topFormat(v2),
192
- color: s.color,
193
- ...highlighted === s.key && { active: true }
194
- });
191
+ out.push(
192
+ seriesRow(
193
+ s,
194
+ s.formatValue ? s.formatValue(v2, d) : topTooltipFormat(v2),
195
+ highlighted === s.key
196
+ )
197
+ );
195
198
  }
196
199
  const v = barOn ? bar.getValue(d) : null;
197
200
  if (v !== null && Number.isFinite(v))
198
- out.push({
199
- label: bar.label,
200
- value: bar.formatValue ? bar.formatValue(v, d) : bar.format(v),
201
- color: v >= 0 ? bar.positive : bar.negative,
202
- ...highlighted === BAR_KEY && { active: true }
203
- });
201
+ out.push(
202
+ engineRow({
203
+ label: bar.label,
204
+ value: bar.formatValue ? bar.formatValue(v, d) : barTooltipFormat(v),
205
+ color: v >= 0 ? bar.positive : bar.negative,
206
+ active: highlighted === BAR_KEY
207
+ })
208
+ );
204
209
  return out;
205
210
  }
206
211
  };
207
212
  },
208
- [data, x, lines, barSeries, top, fillBetween, bar, topFraction, topFormat, formatX]
213
+ [
214
+ data,
215
+ x,
216
+ lines,
217
+ barSeries,
218
+ top,
219
+ fillBetween,
220
+ bar,
221
+ topFraction,
222
+ topFormat,
223
+ topTooltipFormat,
224
+ barTooltipFormat,
225
+ formatX
226
+ ]
209
227
  );
210
228
  return /* @__PURE__ */ jsx(PanelRung, { ...rung, series: all, plan });
211
229
  }
@@ -9,7 +9,7 @@ import { scaleQuantize } from "d3-scale";
9
9
  import { useId, useMemo } from "react";
10
10
  import { alpha, VX } from "../tokens/index.js";
11
11
  import { resolveContainerClass } from "../tokens/size-classes.js";
12
- import { strideTicks } from "./compile.js";
12
+ import { engineRow, strideTicks } from "./compile.js";
13
13
  import { ChartEngine, idPrefixOf } from "./host.js";
14
14
  import { useCoarsePointer } from "../common/use-media-query.js";
15
15
  import { HEIGHT_MAX, HEIGHT_MIN } from "./box.js";
@@ -176,7 +176,7 @@ function Heatmap(props) {
176
176
  ...point.color && { color: point.color }
177
177
  }
178
178
  ];
179
- return { title: header(c), rows: [...value, ...extra] };
179
+ return { title: header(c), rows: [...value, ...extra].map(engineRow) };
180
180
  }
181
181
  } : false
182
182
  };
@@ -8,7 +8,7 @@ import { VX } from "../tokens/index.js";
8
8
  import { CartesianRung } from "./CartesianChart.js";
9
9
  import { areaGradientId } from "./compile.js";
10
10
  import { chartCurve } from "./curves.js";
11
- import { lineMark, markersOf, yScaleOf } from "./marks.js";
11
+ import { drawnRows, lineMark, markersOf, yScaleOf } from "./marks.js";
12
12
  import { rowX } from "./types.js";
13
13
  const MAX_END_LABELS = 3;
14
14
  const END_LABEL_MIN_GAP = 13;
@@ -80,7 +80,7 @@ function Lines(props) {
80
80
  if (!s.area) continue;
81
81
  out.push(
82
82
  decorative(
83
- areaY(plot.rows(s.key), {
83
+ areaY(drawnRows(plot, s), {
84
84
  id: `${s.key}-area`,
85
85
  x: rowX,
86
86
  y2: "y",
@@ -1 +1 @@
1
- {"version":3,"file":"MirroredBars.d.ts","sourceRoot":"","sources":["../../src/charts/MirroredBars.tsx"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAA;AASzC,OAAO,KAAK,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,EAAW,MAAM,SAAS,CAAA;AAEhF,4BAA4B;AAC5B,MAAM,MAAM,eAAe,GAAG;IAC5B;8EAC0E;IAC1E,GAAG,EAAE,MAAM,CAAA;IACX,+FAA+F;IAC/F,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAA;IACjC,sGAAsG;IACtG,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACjC,sDAAsD;IACtD,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC1B,2DAA2D;IAC3D,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAA;CAC9B,CAAA;AAED,oGAAoG;AACpG,MAAM,MAAM,kBAAkB,CAAC,CAAC,IAAI,IAAI,CACtC,WAAW,CAAC,CAAC,CAAC,EACd,KAAK,GAAG,OAAO,GAAG,OAAO,GAAG,UAAU,GAAG,aAAa,GAAG,SAAS,GAAG,QAAQ,GAAG,MAAM,GAAG,MAAM,CAChG,CAAA;AAED,MAAM,MAAM,iBAAiB,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,GAAG,MAAM,IAAI,IAAI,CAChE,mBAAmB,CAAC,CAAC,EAAE,CAAC,CAAC,EACvB,WAAW,GACX,MAAM,GACN,GAAG,GACH,SAAS,GACT,QAAQ,GACR,QAAQ,GACR,OAAO,GACP,aAAa,GACb,SAAS,GACT,WAAW,GACX,OAAO,CACV,GAAG;IACF,qEAAqE;IACrE,MAAM,EAAE,SAAS,kBAAkB,CAAC,CAAC,CAAC,EAAE,CAAA;IACxC,gCAAgC;IAChC,EAAE,EAAE,eAAe,CAAA;IACnB,gCAAgC;IAChC,IAAI,EAAE,eAAe,CAAA;IACrB,uFAAuF;IACvF,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC/B,2FAA2F;IAC3F,iBAAiB,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,CAAC,GAAG,SAAS,CAAA;IAClD,6FAA6F;IAC7F,aAAa,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,CAAC,GAAG,SAAS,CAAA;IAC9C;;;OAGG;IACH,IAAI,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;QAAC,KAAK,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,KAAK,CAAC,CAAA;KAAE,GAAG,SAAS,CAAA;IAC/E,gDAAgD;IAChD,gBAAgB,CAAC,EAAE,mBAAmB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,kBAAkB,CAAC,GAAG,SAAS,CAAA;CAC7E,CAAA;AAgDD,wBAAgB,YAAY,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,GAAG,MAAM,EACvD,KAAK,EAAE,iBAAiB,CAAC,CAAC,EAAE,CAAC,CAAC,GAC7B,YAAY,CAuKd"}
1
+ {"version":3,"file":"MirroredBars.d.ts","sourceRoot":"","sources":["../../src/charts/MirroredBars.tsx"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAA;AASzC,OAAO,KAAK,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,EAAW,MAAM,SAAS,CAAA;AAEhF,4BAA4B;AAC5B,MAAM,MAAM,eAAe,GAAG;IAC5B;8EAC0E;IAC1E,GAAG,EAAE,MAAM,CAAA;IACX,+FAA+F;IAC/F,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAA;IACjC,sGAAsG;IACtG,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACjC,sDAAsD;IACtD,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC1B,2DAA2D;IAC3D,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAA;CAC9B,CAAA;AAED,oGAAoG;AACpG,MAAM,MAAM,kBAAkB,CAAC,CAAC,IAAI,IAAI,CACtC,WAAW,CAAC,CAAC,CAAC,EACd,KAAK,GAAG,OAAO,GAAG,OAAO,GAAG,UAAU,GAAG,aAAa,GAAG,SAAS,GAAG,QAAQ,GAAG,MAAM,GAAG,MAAM,CAChG,CAAA;AAED,MAAM,MAAM,iBAAiB,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,GAAG,MAAM,IAAI,IAAI,CAChE,mBAAmB,CAAC,CAAC,EAAE,CAAC,CAAC,EACvB,WAAW,GACX,MAAM,GACN,GAAG,GACH,SAAS,GACT,QAAQ,GACR,QAAQ,GACR,OAAO,GACP,aAAa,GACb,SAAS,GACT,WAAW,GACX,OAAO,CACV,GAAG;IACF,qEAAqE;IACrE,MAAM,EAAE,SAAS,kBAAkB,CAAC,CAAC,CAAC,EAAE,CAAA;IACxC,gCAAgC;IAChC,EAAE,EAAE,eAAe,CAAA;IACnB,gCAAgC;IAChC,IAAI,EAAE,eAAe,CAAA;IACrB,uFAAuF;IACvF,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC/B,2FAA2F;IAC3F,iBAAiB,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,CAAC,GAAG,SAAS,CAAA;IAClD,6FAA6F;IAC7F,aAAa,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,CAAC,GAAG,SAAS,CAAA;IAC9C;;;OAGG;IACH,IAAI,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;QAAC,KAAK,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,KAAK,CAAC,CAAA;KAAE,GAAG,SAAS,CAAA;IAC/E,gDAAgD;IAChD,gBAAgB,CAAC,EAAE,mBAAmB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,kBAAkB,CAAC,GAAG,SAAS,CAAA;CAC7E,CAAA;AAgDD,wBAAgB,YAAY,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,GAAG,MAAM,EACvD,KAAK,EAAE,iBAAiB,CAAC,CAAC,EAAE,CAAC,CAAC,GAC7B,YAAY,CAwKd"}
@@ -6,7 +6,7 @@ import { scaleLinear } from "@tanstack/charts/scales/linear";
6
6
  import { useCallback, useMemo } from "react";
7
7
  import { VX, alpha } from "../tokens/index.js";
8
8
  import { resolveContainerClass } from "../tokens/size-classes.js";
9
- import { defaultFormatX, defaultNumberFormat, visibleSeries } from "./compile.js";
9
+ import { defaultFormatX, defaultNumberFormat, seriesRow, visibleSeries } from "./compile.js";
10
10
  import { barMark, emphasis } from "./marks.js";
11
11
  import { PanelRung, paneX, paneY, rowsOf } from "./panel.js";
12
12
  import { xScaleFor } from "./scales.js";
@@ -161,12 +161,13 @@ function MirroredBars(props) {
161
161
  const v = s.getValue(d);
162
162
  if (s.tooltip === false || v === null || !Number.isFinite(v)) continue;
163
163
  const fallback = s.key === up.key ? up.format : s.key === down.key ? down.format : defaultNumberFormat;
164
- out.push({
165
- label: s.note === void 0 ? s.label : `${s.label} \xB7 ${s.note}`,
166
- value: s.formatValue ? s.formatValue(v, d) : fallback(v),
167
- color: s.color,
168
- ...highlighted === s.key && { active: true }
169
- });
164
+ out.push(
165
+ seriesRow(
166
+ s,
167
+ s.formatValue ? s.formatValue(v, d) : fallback(v),
168
+ highlighted === s.key
169
+ )
170
+ );
170
171
  }
171
172
  return out;
172
173
  }
@@ -1,7 +1,7 @@
1
- import type { ChartGradient, ChartPositionScaleOptions, ChartValue, ResponsiveChartDefinition } from '@tanstack/charts/types/core';
1
+ import type { ChartGradient, ChartPositionScaleOptions, ChartTooltipRow as EngineTooltipRow, ChartValue, ResponsiveChartDefinition } from '@tanstack/charts/types/core';
2
2
  import type { ContainerClass } from '../tokens/size-classes.js';
3
3
  import type { XScaleModel } from './scales.js';
4
- import type { AxisConfig, CartesianChartProps, ChartSeries, ChartX, ZoneSpec } from './types.js';
4
+ import type { AxisConfig, CartesianChartProps, ChartSeries, ChartTooltipRow, ChartX, RefLine, ZoneSpec } from './types.js';
5
5
  /**
6
6
  * The compiled definition. Annotated on purpose: TanStack's inferred definition type names internal
7
7
  * modules (`dist/scene`, `cursor-host-contract`) and fails declaration emit (TS2883 / TS4058).
@@ -35,6 +35,19 @@ export declare function utcHeaderDate(d: Date): string;
35
35
  */
36
36
  export declare function dateTicks(domain: readonly [Date, Date], count: number, stepMs: number): Date[];
37
37
  export declare function defaultFormatX(v: ChartValue): string;
38
+ /**
39
+ * A tooltip swatch is the engine's `background` shorthand, so a dashed one is a gradient: a 2px
40
+ * dashed line across the swatch's middle, in the row color.
41
+ */
42
+ export declare const dashedSwatch: (color: string) => string;
43
+ /** A basalt tooltip row as the engine's: the swatch shape folded into the row color. */
44
+ export declare function engineRow(row: ChartTooltipRow & {
45
+ active?: boolean | undefined;
46
+ }): EngineTooltipRow;
47
+ /** A series row of a tooltip: the label with its note, the swatch following the series' dash. */
48
+ export declare function seriesRow(s: Pick<ChartSeries<never>, 'label' | 'note' | 'color' | 'dash'>, value: string, active: boolean): EngineTooltipRow;
49
+ /** Legend-only entries for the reference lines that name themselves, in line order. */
50
+ export declare function refLegendSeries<T>(refLines: readonly RefLine[] | undefined): ChartSeries<T>[];
38
51
  /** The visible series: not toggled off, and not a companion whose parent is. */
39
52
  export declare function visibleSeries<T>(series: readonly ChartSeries<T>[], hidden: ReadonlySet<string>): ChartSeries<T>[];
40
53
  type YAxis = {
@@ -1 +1 @@
1
- {"version":3,"file":"compile.d.ts","sourceRoot":"","sources":["../../src/charts/compile.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"compile.d.ts","sourceRoot":"","sources":["../../src/charts/compile.ts"],"names":[],"mappings":"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"}