basalt-ui 1.16.0 → 1.18.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 +14 -0
- package/agent/rules/basalt-charts.md +58 -4
- package/agent/skills/basalt-design/SKILL.md +2 -2
- package/dist/charts/cursor/resolve.d.ts +29 -5
- package/dist/charts/cursor/resolve.d.ts.map +1 -1
- package/dist/charts/cursor/resolve.js +25 -4
- package/dist/charts/hooks/useChartCursor.d.ts +8 -1
- package/dist/charts/hooks/useChartCursor.d.ts.map +1 -1
- package/dist/charts/hooks/useChartCursor.js +6 -2
- package/dist/charts/index.d.ts +1 -0
- package/dist/charts/index.d.ts.map +1 -1
- package/dist/charts/kinds/Bars.d.ts +9 -0
- package/dist/charts/kinds/Bars.d.ts.map +1 -1
- package/dist/charts/kinds/Bars.js +4 -0
- package/dist/charts/kinds/DualPanel.d.ts +24 -0
- package/dist/charts/kinds/DualPanel.d.ts.map +1 -1
- package/dist/charts/kinds/DualPanel.js +39 -9
- package/dist/charts/kinds/MultiLine.d.ts +9 -0
- package/dist/charts/kinds/MultiLine.d.ts.map +1 -1
- package/dist/charts/kinds/MultiLine.js +10 -8
- package/dist/charts/kinds/StackedArea.d.ts +9 -0
- package/dist/charts/kinds/StackedArea.d.ts.map +1 -1
- package/dist/charts/kinds/StackedArea.js +16 -1
- package/dist/charts/kinds/StackedArea.test.d.ts +2 -0
- package/dist/charts/kinds/StackedArea.test.d.ts.map +1 -0
- package/dist/charts/kinds/ZonedLine.d.ts +9 -0
- package/dist/charts/kinds/ZonedLine.d.ts.map +1 -1
- package/dist/charts/kinds/ZonedLine.js +4 -0
- package/dist/charts/primitives/CartesianChart.d.ts +40 -2
- package/dist/charts/primitives/CartesianChart.d.ts.map +1 -1
- package/dist/charts/primitives/CartesianChart.js +16 -6
- package/dist/charts/primitives/ChartFrame.d.ts +8 -1
- package/dist/charts/primitives/ChartFrame.d.ts.map +1 -1
- package/dist/charts/primitives/ChartFrame.js +1 -1
- package/dist/charts/primitives/ChartTooltip.d.ts +12 -2
- package/dist/charts/primitives/ChartTooltip.d.ts.map +1 -1
- package/dist/charts/primitives/ChartTooltip.js +5 -3
- package/dist/charts/primitives/ChartTooltip.test.d.ts +2 -0
- package/dist/charts/primitives/ChartTooltip.test.d.ts.map +1 -0
- package/dist/charts/series.d.ts +9 -1
- package/dist/charts/series.d.ts.map +1 -1
- package/dist/charts/utils/domain.d.ts +15 -0
- package/dist/charts/utils/domain.d.ts.map +1 -1
- package/dist/charts/utils/domain.js +6 -1
- package/llms.txt +2 -2
- package/package.json +1 -1
- package/src/charts/cursor/resolve.test.ts +62 -0
- package/src/charts/cursor/resolve.ts +71 -7
- package/src/charts/hooks/useChartCursor.ts +12 -1
- package/src/charts/index.ts +1 -0
- package/src/charts/kinds/Bars.test.tsx +85 -0
- package/src/charts/kinds/Bars.tsx +13 -0
- package/src/charts/kinds/DualPanel.test.tsx +391 -1
- package/src/charts/kinds/DualPanel.tsx +74 -8
- package/src/charts/kinds/MultiLine.test.tsx +181 -0
- package/src/charts/kinds/MultiLine.tsx +19 -8
- package/src/charts/kinds/StackedArea.test.tsx +114 -0
- package/src/charts/kinds/StackedArea.tsx +25 -1
- package/src/charts/kinds/ZonedLine.test.tsx +110 -0
- package/src/charts/kinds/ZonedLine.tsx +13 -0
- package/src/charts/primitives/CartesianChart.test.tsx +284 -3
- package/src/charts/primitives/CartesianChart.tsx +64 -12
- package/src/charts/primitives/ChartFrame.test.tsx +42 -0
- package/src/charts/primitives/ChartFrame.tsx +9 -2
- package/src/charts/primitives/ChartTooltip.test.tsx +44 -0
- package/src/charts/primitives/ChartTooltip.tsx +14 -2
- package/src/charts/series.ts +8 -2
- package/src/charts/utils/domain.test.ts +31 -1
- package/src/charts/utils/domain.ts +19 -0
|
@@ -36,6 +36,8 @@ function MultiLineInner(props) {
|
|
|
36
36
|
xZones,
|
|
37
37
|
refLines,
|
|
38
38
|
xTicks,
|
|
39
|
+
formatX,
|
|
40
|
+
cursorResolution,
|
|
39
41
|
tooltip,
|
|
40
42
|
markerShape = "circle",
|
|
41
43
|
height,
|
|
@@ -60,6 +62,8 @@ function MultiLineInner(props) {
|
|
|
60
62
|
...xZones !== void 0 && { xZones },
|
|
61
63
|
...refLines !== void 0 && { refLines },
|
|
62
64
|
...xTicks !== void 0 && { xTicks },
|
|
65
|
+
...formatX !== void 0 && { formatX },
|
|
66
|
+
...cursorResolution !== void 0 && { cursorResolution },
|
|
63
67
|
...tooltip !== void 0 && { tooltip },
|
|
64
68
|
...height !== void 0 && { height },
|
|
65
69
|
...legend !== void 0 && { legend },
|
|
@@ -102,16 +106,16 @@ function MultiLineMarks({
|
|
|
102
106
|
const cy = scale(p.__y);
|
|
103
107
|
const color = m.color ?? s.color;
|
|
104
108
|
const r = m.r ?? (markerShape === "star" ? STAR_R : VX.dotR);
|
|
109
|
+
const ring = m.ring ?? true;
|
|
110
|
+
const fillOpacity = (m.fillOpacity ?? 1) * op;
|
|
105
111
|
markers.push(
|
|
106
112
|
markerShape === "star" ? /* @__PURE__ */ jsx(
|
|
107
113
|
"path",
|
|
108
114
|
{
|
|
109
115
|
d: starPath(cx, cy, r),
|
|
110
116
|
fill: color,
|
|
111
|
-
|
|
112
|
-
strokeWidth: 1.5,
|
|
113
|
-
fillOpacity: op,
|
|
114
|
-
strokeOpacity: op
|
|
117
|
+
fillOpacity,
|
|
118
|
+
...ring && { stroke: VX.dotStroke, strokeWidth: 1.5, strokeOpacity: op }
|
|
115
119
|
},
|
|
116
120
|
`mk-${s.key}-${getX(p.__d)}`
|
|
117
121
|
) : /* @__PURE__ */ jsx(
|
|
@@ -121,10 +125,8 @@ function MultiLineMarks({
|
|
|
121
125
|
cy,
|
|
122
126
|
r,
|
|
123
127
|
fill: color,
|
|
124
|
-
|
|
125
|
-
strokeWidth: 2,
|
|
126
|
-
fillOpacity: op,
|
|
127
|
-
strokeOpacity: op
|
|
128
|
+
fillOpacity,
|
|
129
|
+
...ring && { stroke: VX.dotStroke, strokeWidth: 2, strokeOpacity: op }
|
|
128
130
|
},
|
|
129
131
|
`mk-${s.key}-${getX(p.__d)}`
|
|
130
132
|
)
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { CursorResolution } from '../cursor/resolve.js';
|
|
1
2
|
import type { AxisConfig } from '../primitives/CartesianChart.js';
|
|
2
3
|
import type { ChartLegendConfig, ChartSeries } from '../series.js';
|
|
3
4
|
export type StackedAreaProps<T> = {
|
|
@@ -16,6 +17,14 @@ export type StackedAreaProps<T> = {
|
|
|
16
17
|
y?: AxisConfig<T>;
|
|
17
18
|
/** X tick count override. Default: as many as fit. */
|
|
18
19
|
xTicks?: number;
|
|
20
|
+
/** X tick label formatter. Default `fmtAxisDate` (DD.MM). */
|
|
21
|
+
formatX?: (key: string) => string;
|
|
22
|
+
/**
|
|
23
|
+
* How a sibling chart's broadcast cursor key resolves against this chart's points. Default
|
|
24
|
+
* `'nearest'`. Pass `'leading'` when `getX` returns a bucket's leading edge (a weekly series
|
|
25
|
+
* keyed by its Monday) — see `CursorResolution`.
|
|
26
|
+
*/
|
|
27
|
+
cursorResolution?: CursorResolution;
|
|
19
28
|
/** Legend config forwarded to `CartesianChart`; `false` disables the legend (sparkline escape).
|
|
20
29
|
* Default `{ placement: 'bottom' }`. */
|
|
21
30
|
legend?: ChartLegendConfig | false;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StackedArea.d.ts","sourceRoot":"","sources":["../../../src/charts/kinds/StackedArea.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"StackedArea.d.ts","sourceRoot":"","sources":["../../../src/charts/kinds/StackedArea.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AAEzD,OAAO,KAAK,EAAE,UAAU,EAAe,MAAM,8BAA8B,CAAA;AAC3E,OAAO,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AAE/D,MAAM,MAAM,gBAAgB,CAAC,CAAC,IAAI;IAChC,IAAI,EAAE,CAAC,EAAE,CAAA;IACT,0EAA0E;IAC1E,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,CAAA;IACtB;4FACwF;IACxF,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,EAAE,CAAA;IACxB;;;qEAGiE;IACjE,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,CAAA;IACjB,sDAAsD;IACtD,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,6DAA6D;IAC7D,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAA;IACjC;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,gBAAgB,CAAA;IACnC;4CACwC;IACxC,MAAM,CAAC,EAAE,iBAAiB,GAAG,KAAK,CAAA;IAClC,+EAA+E;IAC/E,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,gGAAgG;IAChG,SAAS,CAAC,EAAE,OAAO,CAAA;CACpB,CAAA;AAED;;;;;;;;;;;;GAYG;AACH,iBAAS,gBAAgB,CAAC,CAAC,EAAE,KAAK,EAAE,gBAAgB,CAAC,CAAC,CAAC,+BA+EtD;AA+CD;;;;GAIG;AACH,eAAO,MAAM,WAAW,EAA6B,OAAO,gBAAgB,CAAA"}
|
|
@@ -4,7 +4,20 @@ import { AreaStack } from "@visx/shape";
|
|
|
4
4
|
import { memo, useCallback, useMemo } from "react";
|
|
5
5
|
import { CartesianChart } from "../primitives/CartesianChart.js";
|
|
6
6
|
function StackedAreaInner(props) {
|
|
7
|
-
const {
|
|
7
|
+
const {
|
|
8
|
+
data,
|
|
9
|
+
chartId,
|
|
10
|
+
getX,
|
|
11
|
+
series,
|
|
12
|
+
y,
|
|
13
|
+
xTicks,
|
|
14
|
+
formatX,
|
|
15
|
+
cursorResolution,
|
|
16
|
+
height,
|
|
17
|
+
legend,
|
|
18
|
+
ariaLabel,
|
|
19
|
+
isPending
|
|
20
|
+
} = props;
|
|
8
21
|
const yConfig = useMemo(() => {
|
|
9
22
|
const base = y ?? {};
|
|
10
23
|
if (base.domain !== void 0 && base.domain !== "auto") return base;
|
|
@@ -47,6 +60,8 @@ function StackedAreaInner(props) {
|
|
|
47
60
|
y: yConfig,
|
|
48
61
|
cursorValue: stackedCursorValue,
|
|
49
62
|
...xTicks !== void 0 && { xTicks },
|
|
63
|
+
...formatX !== void 0 && { formatX },
|
|
64
|
+
...cursorResolution !== void 0 && { cursorResolution },
|
|
50
65
|
...height !== void 0 && { height },
|
|
51
66
|
...legend !== void 0 && { legend },
|
|
52
67
|
...ariaLabel !== void 0 && { ariaLabel },
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StackedArea.test.d.ts","sourceRoot":"","sources":["../../../src/charts/kinds/StackedArea.test.tsx"],"names":[],"mappings":""}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { CursorResolution } from '../cursor/resolve.js';
|
|
1
2
|
import type { CartesianTooltipConfig, AxisConfig } from '../primitives/CartesianChart.js';
|
|
2
3
|
import type { XZoneSpec } from '../primitives/XZoneRects.js';
|
|
3
4
|
import type { ZoneSpec } from '../primitives/ZoneRects.js';
|
|
@@ -39,6 +40,14 @@ export type ZonedLineProps<T> = {
|
|
|
39
40
|
refLines?: ZonedLineRefLine[];
|
|
40
41
|
/** Exact number of x ticks. Default: as many as fit. */
|
|
41
42
|
xTicks?: number;
|
|
43
|
+
/** X tick label formatter. Default `fmtAxisDate` (DD.MM). */
|
|
44
|
+
formatX?: (key: string) => string;
|
|
45
|
+
/**
|
|
46
|
+
* How a sibling chart's broadcast cursor key resolves against this chart's points. Default
|
|
47
|
+
* `'nearest'`. Pass `'leading'` when `getX` returns a bucket's leading edge (a weekly series
|
|
48
|
+
* keyed by its Monday) — see `CursorResolution`.
|
|
49
|
+
*/
|
|
50
|
+
cursorResolution?: CursorResolution;
|
|
42
51
|
/** Tooltip config — `label` for a right-aligned header badge (e.g. zone name with zone color),
|
|
43
52
|
* `extraRows` for rows appended after the derived row. `false` disables the tooltip entirely. */
|
|
44
53
|
tooltip?: CartesianTooltipConfig<T> | false;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ZonedLine.d.ts","sourceRoot":"","sources":["../../../src/charts/kinds/ZonedLine.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ZonedLine.d.ts","sourceRoot":"","sources":["../../../src/charts/kinds/ZonedLine.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AAEzD,OAAO,KAAK,EAAE,sBAAsB,EAAE,UAAU,EAAe,MAAM,8BAA8B,CAAA;AAEnG,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAA;AACzD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AAEvD,OAAO,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AAG/D,4FAA4F;AAC5F,MAAM,MAAM,aAAa,GAAG,QAAQ,CAAA;AAEpC,mFAAmF;AACnF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,OAAO,GAAG,OAAO,CAAA;IACvB,IAAI,EAAE,MAAM,CAAA;CACb,CAAA;AAED,0EAA0E;AAC1E,MAAM,MAAM,gBAAgB,GAAG;IAC7B,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,oDAAoD;IACpD,MAAM,CAAC,EAAE,OAAO,CAAA;CACjB,CAAA;AAED,MAAM,MAAM,cAAc,CAAC,CAAC,IAAI;IAC9B,IAAI,EAAE,CAAC,EAAE,CAAA;IACT,0EAA0E;IAC1E,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,oEAAoE;IACpE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,CAAA;IACtB;;wEAEoE;IACpE,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,EAAE,CAAA;IACxB;gEAC4D;IAC5D,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,CAAA;IACjB,KAAK,CAAC,EAAE,aAAa,EAAE,CAAA;IACvB;sBACkB;IAClB,MAAM,CAAC,EAAE,SAAS,EAAE,CAAA;IACpB,UAAU,CAAC,EAAE,kBAAkB,EAAE,CAAA;IACjC,QAAQ,CAAC,EAAE,gBAAgB,EAAE,CAAA;IAC7B,wDAAwD;IACxD,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,6DAA6D;IAC7D,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAA;IACjC;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,gBAAgB,CAAA;IACnC;qGACiG;IACjG,OAAO,CAAC,EAAE,sBAAsB,CAAC,CAAC,CAAC,GAAG,KAAK,CAAA;IAC3C;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;IAC3B;4CACwC;IACxC,MAAM,CAAC,EAAE,iBAAiB,GAAG,KAAK,CAAA;IAClC,mGAAmG;IACnG,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,gGAAgG;IAChG,SAAS,CAAC,EAAE,OAAO,CAAA;CACpB,CAAA;AAiBD;;;;;;;;;;;;GAYG;AACH,iBAAS,cAAc,CAAC,CAAC,EAAE,KAAK,EAAE,cAAc,CAAC,CAAC,CAAC,+BA+DlD;AA+ED;;;GAGG;AACH,eAAO,MAAM,SAAS,EAA2B,OAAO,cAAc,CAAA"}
|
|
@@ -30,6 +30,8 @@ function ZonedLineInner(props) {
|
|
|
30
30
|
thresholds,
|
|
31
31
|
refLines,
|
|
32
32
|
xTicks,
|
|
33
|
+
formatX,
|
|
34
|
+
cursorResolution,
|
|
33
35
|
tooltip,
|
|
34
36
|
areaFill,
|
|
35
37
|
height,
|
|
@@ -56,6 +58,8 @@ function ZonedLineInner(props) {
|
|
|
56
58
|
...xZones !== void 0 && { xZones },
|
|
57
59
|
...refLines !== void 0 && { refLines },
|
|
58
60
|
...xTicks !== void 0 && { xTicks },
|
|
61
|
+
...formatX !== void 0 && { formatX },
|
|
62
|
+
...cursorResolution !== void 0 && { cursorResolution },
|
|
59
63
|
...tooltip !== void 0 && { tooltip },
|
|
60
64
|
...height !== void 0 && { height },
|
|
61
65
|
...legend !== void 0 && { legend },
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { scaleLinear, scalePoint } from '@visx/scale';
|
|
2
2
|
import type { ReactNode } from 'react';
|
|
3
3
|
import type { ChartMargin } from '../../tokens/index.js';
|
|
4
|
+
import type { CursorResolution } from '../cursor/resolve.js';
|
|
4
5
|
import type { ChartLegendConfig, ChartSeries } from '../series.js';
|
|
5
6
|
import type { XZoneSpec } from './XZoneRects.js';
|
|
6
7
|
import type { ZoneSpec } from './ZoneRects.js';
|
|
@@ -16,7 +17,11 @@ export type AxisConfig<T> = {
|
|
|
16
17
|
* (summing `props.series` there would leave a permanent gap above the stack).
|
|
17
18
|
*/
|
|
18
19
|
domain?: [number, number] | 'auto' | ((data: readonly T[], visible: readonly ChartSeries<T>[]) => [number, number]);
|
|
19
|
-
/**
|
|
20
|
+
/**
|
|
21
|
+
* When 'auto': the raw upper bound is at least this, and padding is applied AFTER — mirroring
|
|
22
|
+
* `autoMinCeil`, which clamps first and pads second. A floor that padded before the clamp used
|
|
23
|
+
* to land the axis top exactly on the floor value with zero headroom.
|
|
24
|
+
*/
|
|
20
25
|
autoMaxFloor?: number;
|
|
21
26
|
/** When 'auto': the lower bound is at most this. Default 0 (forced zero baseline). `Infinity`
|
|
22
27
|
* pads down from the raw data minimum instead. */
|
|
@@ -58,12 +63,37 @@ export type CartesianTooltipConfig<T> = {
|
|
|
58
63
|
text: string;
|
|
59
64
|
color: string;
|
|
60
65
|
} | null;
|
|
66
|
+
/**
|
|
67
|
+
* Overrides the tooltip header's date text. Default: `TooltipHeader`'s own `fmtTooltipDate`
|
|
68
|
+
* behavior, unchanged. `fmtTooltipDate` regexes `YYYY-MM-DD` out of the domain key and builds a
|
|
69
|
+
* LOCAL `Date` from it — a UTC ISO key then names the wrong day next to `formatX`, the tooltip
|
|
70
|
+
* badge, and every sibling chart, which all resolve locally. Receives the raw `getX` key
|
|
71
|
+
* alongside the hovered datum, so a caller can format from either.
|
|
72
|
+
*/
|
|
73
|
+
formatHeader?: (key: string, d: T) => string;
|
|
61
74
|
/** Rows rendered BEFORE the derived per-series rows (a total, a context line). The second
|
|
62
75
|
* argument carries the same `visible`/`hidden` the plot draws from, so a hand-authored row
|
|
63
76
|
* stays in sync with legend toggling instead of naming a series the plot no longer draws. */
|
|
64
77
|
prependRows?: (d: T, ctx: CartesianTooltipRowContext<T>) => ReactNode;
|
|
65
78
|
/** Rows appended after the derived per-series rows. Same `ctx` as {@link prependRows}. */
|
|
66
79
|
extraRows?: (d: T, ctx: CartesianTooltipRowContext<T>) => ReactNode;
|
|
80
|
+
/**
|
|
81
|
+
* Render this chart's tooltip when it is a cursor FOLLOWER (the crosshair came from a sibling
|
|
82
|
+
* chart sharing the cursor), not only when this chart is the SOURCE. Default false — today's
|
|
83
|
+
* behaviour, nothing moves. A follower has no pointer under it, so its tooltip is always ANCHORED
|
|
84
|
+
* to the crosshair — the same positioning `follow: false` gives the source — regardless of what
|
|
85
|
+
* `follow` is set to on this chart: there is no other valid position for a chart nobody is
|
|
86
|
+
* hovering. `follow` keeps governing the SOURCE's own tooltip exactly as before; the two options
|
|
87
|
+
* only interact for a follower, where `onFollow` always wins on positioning. Only the SOURCE's
|
|
88
|
+
* tooltip is `aria-live` — followers announce nothing, so a shared-cursor page doesn't fire N
|
|
89
|
+
* live-region updates per pointer move.
|
|
90
|
+
*
|
|
91
|
+
* Cost, since it scales with the page rather than the chart: anchoring reads one
|
|
92
|
+
* `getBoundingClientRect` per hovered frame (the same cost `follow: false` documents), so N
|
|
93
|
+
* opted-in followers pay N of them per frame. That is the reason this is opt-in per chart rather
|
|
94
|
+
* than a page-level switch — turn it on for the charts a reader actually correlates.
|
|
95
|
+
*/
|
|
96
|
+
onFollow?: boolean;
|
|
67
97
|
};
|
|
68
98
|
/** Everything a mark renderer needs. Handed to `CartesianChart`'s child on every render. */
|
|
69
99
|
export type PlotContext<T> = {
|
|
@@ -124,6 +154,14 @@ export type CartesianChartProps<T> = {
|
|
|
124
154
|
* line the reader is actually looking at.
|
|
125
155
|
*/
|
|
126
156
|
cursorValue?: (point: T, series: ChartSeries<T>, visible: readonly ChartSeries<T>[]) => number | null;
|
|
157
|
+
/**
|
|
158
|
+
* How a sibling chart's broadcast cursor key resolves against THIS chart's points. Default
|
|
159
|
+
* `'nearest'`, correct when `getX` returns an instant. Pass `'leading'` when it returns a
|
|
160
|
+
* bucket's leading edge (a weekly series keyed by its Monday): under `'nearest'` a hover landing
|
|
161
|
+
* in the back half of a bucket resolves to the FOLLOWING bucket, so the shared crosshair sits
|
|
162
|
+
* one column right of the data the reader is pointing at.
|
|
163
|
+
*/
|
|
164
|
+
cursorResolution?: CursorResolution;
|
|
127
165
|
ariaLabel?: string;
|
|
128
166
|
isPending?: boolean;
|
|
129
167
|
/** Draw ONLY the marks. Everything around them is the primitive's job. */
|
|
@@ -156,6 +194,6 @@ extraBounds?: readonly number[]): [number, number];
|
|
|
156
194
|
* Margins are MEASURED from the labels that will actually be painted, so a wide tick label widens
|
|
157
195
|
* its own gutter instead of clipping or needing a hand-tuned `margin` prop.
|
|
158
196
|
*/
|
|
159
|
-
export declare function CartesianChart<T>({ data, chartId, getX, series, y, y2, xTicks, formatX, zones, xZones, refLines, height, aspectRatio, fill, legend, tooltip, margin: marginOverride, cursorValue, ariaLabel, isPending, children, }: CartesianChartProps<T>): ReactNode;
|
|
197
|
+
export declare function CartesianChart<T>({ data, chartId, getX, series, y, y2, xTicks, formatX, zones, xZones, refLines, height, aspectRatio, fill, legend, tooltip, margin: marginOverride, cursorValue, cursorResolution, ariaLabel, isPending, children, }: CartesianChartProps<T>): ReactNode;
|
|
160
198
|
export {};
|
|
161
199
|
//# sourceMappingURL=CartesianChart.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CartesianChart.d.ts","sourceRoot":"","sources":["../../../src/charts/primitives/CartesianChart.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAErD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAEtC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;
|
|
1
|
+
{"version":3,"file":"CartesianChart.d.ts","sourceRoot":"","sources":["../../../src/charts/primitives/CartesianChart.tsx"],"names":[],"mappings":"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"}
|
|
@@ -7,7 +7,7 @@ import { VX } from "../../tokens/index.js";
|
|
|
7
7
|
import { useChartCursor } from "../hooks/useChartCursor.js";
|
|
8
8
|
import { autoMargin, probeAxisLabels } from "../layout/auto-margin.js";
|
|
9
9
|
import { deriveTooltipRows } from "../series.js";
|
|
10
|
-
import { padAutoLower } from "../utils/domain.js";
|
|
10
|
+
import { padAutoLower, padAutoUpper } from "../utils/domain.js";
|
|
11
11
|
import { fmtAxisDate } from "../utils/format.js";
|
|
12
12
|
import { smartTicks, smartTicksEvery } from "../utils/ticks.js";
|
|
13
13
|
import { AxisBottomDate, AxisLeftNumeric, AxisRightNumeric } from "./Axes.js";
|
|
@@ -41,8 +41,7 @@ function resolveAxisDomain(cfg, data, series, extraBounds = []) {
|
|
|
41
41
|
if (min === Infinity) return [0, cfg?.autoMaxFloor ?? 1];
|
|
42
42
|
const pad = cfg?.autoPad ?? DEFAULT_AUTO_PAD;
|
|
43
43
|
const ceil = cfg?.autoMinCeil ?? 0;
|
|
44
|
-
const
|
|
45
|
-
const upper = Math.max(paddedMax, cfg?.autoMaxFloor ?? -Infinity);
|
|
44
|
+
const upper = padAutoUpper(Math.max(max, cfg?.autoMaxFloor ?? -Infinity), pad);
|
|
46
45
|
const lower = padAutoLower(Math.min(min, ceil), pad);
|
|
47
46
|
if (lower === upper) return [Math.min(lower, 0), upper === 0 ? 1 : upper * pad];
|
|
48
47
|
return [lower, upper];
|
|
@@ -66,6 +65,7 @@ function CartesianChart({
|
|
|
66
65
|
tooltip,
|
|
67
66
|
margin: marginOverride,
|
|
68
67
|
cursorValue,
|
|
68
|
+
cursorResolution,
|
|
69
69
|
ariaLabel,
|
|
70
70
|
isPending,
|
|
71
71
|
children
|
|
@@ -99,6 +99,7 @@ function CartesianChart({
|
|
|
99
99
|
...tooltip !== void 0 && { tooltip },
|
|
100
100
|
...marginOverride !== void 0 && { marginOverride },
|
|
101
101
|
...cursorValue !== void 0 && { cursorValue },
|
|
102
|
+
...cursorResolution !== void 0 && { cursorResolution },
|
|
102
103
|
...ariaLabel !== void 0 && { ariaLabel },
|
|
103
104
|
plot,
|
|
104
105
|
highlighted,
|
|
@@ -123,6 +124,7 @@ function CartesianPlot({
|
|
|
123
124
|
tooltip,
|
|
124
125
|
marginOverride,
|
|
125
126
|
cursorValue,
|
|
127
|
+
cursorResolution,
|
|
126
128
|
ariaLabel,
|
|
127
129
|
plot,
|
|
128
130
|
highlighted,
|
|
@@ -209,7 +211,8 @@ function CartesianPlot({
|
|
|
209
211
|
chartId,
|
|
210
212
|
getKey: getX,
|
|
211
213
|
xScale,
|
|
212
|
-
marginLeft: margin.left
|
|
214
|
+
marginLeft: margin.left,
|
|
215
|
+
...cursorResolution !== void 0 && { resolution: cursorResolution }
|
|
213
216
|
});
|
|
214
217
|
const svgRef = useRef(null);
|
|
215
218
|
const tooltipEnabled = tooltip !== false;
|
|
@@ -217,6 +220,7 @@ function CartesianPlot({
|
|
|
217
220
|
const point = cursor.point;
|
|
218
221
|
const cursorX = point === null ? null : xScale(getX(point)) ?? null;
|
|
219
222
|
const badge = tooltipCfg?.label === void 0 || point === null ? null : tooltipCfg.label(point);
|
|
223
|
+
const formatHeader = tooltipCfg?.formatHeader;
|
|
220
224
|
const tooltipSeries = useMemo(
|
|
221
225
|
() => visible.map(
|
|
222
226
|
(s) => s.formatValue === void 0 ? { ...s, formatValue: s.axis === "right" ? rightFormat : leftFormat } : s
|
|
@@ -224,7 +228,10 @@ function CartesianPlot({
|
|
|
224
228
|
[visible, leftFormat, rightFormat]
|
|
225
229
|
);
|
|
226
230
|
const rows = tooltipEnabled && point !== null ? deriveTooltipRows(tooltipSeries, point, leftFormat) : [];
|
|
227
|
-
const
|
|
231
|
+
const isFollowerRender = !cursor.isSource && tooltipCfg?.onFollow === true;
|
|
232
|
+
const showTooltip = tooltipEnabled && point !== null && (cursor.isSource || isFollowerRender);
|
|
233
|
+
const useAnchoredPosition = tooltipCfg?.follow === false || isFollowerRender;
|
|
234
|
+
const anchorX = useAnchoredPosition && point !== null && cursorX !== null ? cursorX : null;
|
|
228
235
|
const svgRect = anchorX === null ? void 0 : svgRef.current?.getBoundingClientRect();
|
|
229
236
|
const tooltipAnchor = svgRect === void 0 || anchorX === null ? cursor.anchor : { x: svgRect.left + margin.left + anchorX, y: svgRect.top + margin.top };
|
|
230
237
|
const ctx = {
|
|
@@ -326,11 +333,14 @@ function CartesianPlot({
|
|
|
326
333
|
}
|
|
327
334
|
)
|
|
328
335
|
] }) }),
|
|
329
|
-
|
|
336
|
+
showTooltip && /* @__PURE__ */ jsxs(ChartTooltipFloat, { anchor: tooltipAnchor, ariaLive: cursor.isSource, children: [
|
|
330
337
|
/* @__PURE__ */ jsx(
|
|
331
338
|
TooltipHeader,
|
|
332
339
|
{
|
|
333
340
|
date: getX(point),
|
|
341
|
+
...formatHeader !== void 0 && {
|
|
342
|
+
format: (key) => formatHeader(key, point)
|
|
343
|
+
},
|
|
334
344
|
...badge !== null && { label: badge.text, labelColor: badge.color }
|
|
335
345
|
}
|
|
336
346
|
),
|
|
@@ -43,9 +43,16 @@ export type ChartFrameProps = {
|
|
|
43
43
|
*/
|
|
44
44
|
isPending?: boolean;
|
|
45
45
|
/**
|
|
46
|
-
* Accessible text alternative for the chart, applied as `aria-label` (+ `role="
|
|
46
|
+
* Accessible text alternative for the chart, applied as `aria-label` (+ `role="group"`) on the
|
|
47
47
|
* outer container so screen readers announce something other than an unlabeled graphic. Every
|
|
48
48
|
* kind composing `ChartFrame` should accept and forward this from its own props.
|
|
49
|
+
*
|
|
50
|
+
* MUST stay `role="group"`, never `role="img"`. Per the ARIA spec, every descendant of an
|
|
51
|
+
* `role="img"` element is presentational, which erases the `HoverOverlay`'s `role="slider"` from
|
|
52
|
+
* the accessibility tree entirely — a screen reader announces the label and then the
|
|
53
|
+
* keyboard-scrubbable slider underneath it is simply unreachable, silently, with no error
|
|
54
|
+
* anywhere. `role="group"` announces the same label while keeping descendants exposed. Do not
|
|
55
|
+
* "simplify" this back to `img` — it looks like a no-op refactor and it is not.
|
|
49
56
|
*/
|
|
50
57
|
ariaLabel?: string;
|
|
51
58
|
/** Draw the SVG marks given the plot rect that already excludes the legend band, plus the set
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChartFrame.d.ts","sourceRoot":"","sources":["../../../src/charts/primitives/ChartFrame.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAiB,SAAS,EAAE,MAAM,OAAO,CAAA;AAIrD,OAAO,KAAK,EAAE,iBAAiB,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AAOhF;0EAC0E;AAC1E,MAAM,MAAM,gBAAgB,GAAG;IAC7B,wBAAwB;IACxB,SAAS,CAAC,EAAE,eAAe,CAAA;IAC3B,uDAAuD;IACvD,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,4DAA4D;IAC5D,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,wDAAwD;IACxD,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAA;IAC1C;;;;;OAKG;IACH,MAAM,CAAC,EAAE,OAAO,CAAA;CACjB,CAAA;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,uGAAuG;IACvG,MAAM,EAAE,SAAS,WAAW,EAAE,CAAA;IAC9B,8FAA8F;IAC9F,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,qFAAqF;IACrF,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,uFAAuF;IACvF,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,6EAA6E;IAC7E,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,iGAAiG;IACjG,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,6FAA6F;IAC7F,MAAM,CAAC,EAAE,gBAAgB,GAAG,KAAK,CAAA;IACjC;;;;;OAKG;IACH,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB
|
|
1
|
+
{"version":3,"file":"ChartFrame.d.ts","sourceRoot":"","sources":["../../../src/charts/primitives/ChartFrame.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAiB,SAAS,EAAE,MAAM,OAAO,CAAA;AAIrD,OAAO,KAAK,EAAE,iBAAiB,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AAOhF;0EAC0E;AAC1E,MAAM,MAAM,gBAAgB,GAAG;IAC7B,wBAAwB;IACxB,SAAS,CAAC,EAAE,eAAe,CAAA;IAC3B,uDAAuD;IACvD,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,4DAA4D;IAC5D,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,wDAAwD;IACxD,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAA;IAC1C;;;;;OAKG;IACH,MAAM,CAAC,EAAE,OAAO,CAAA;CACjB,CAAA;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,uGAAuG;IACvG,MAAM,EAAE,SAAS,WAAW,EAAE,CAAA;IAC9B,8FAA8F;IAC9F,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,qFAAqF;IACrF,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,uFAAuF;IACvF,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,6EAA6E;IAC7E,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,iGAAiG;IACjG,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,6FAA6F;IAC7F,MAAM,CAAC,EAAE,gBAAgB,GAAG,KAAK,CAAA;IACjC;;;;;OAKG;IACH,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB;;;;;;;;;;;OAWG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;oDACgD;IAChD,QAAQ,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK,SAAS,CAAA;CACxC,CAAA;AAED,0FAA0F;AAC1F,MAAM,MAAM,QAAQ,GAAG;IACrB,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;CAC5B,CAAA;AAcD;oFACoF;AACpF,MAAM,MAAM,qBAAqB,GAAG;IAClC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,WAAW,EAAE,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAA;CAC1C,CAAA;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,iBAAiB,GAAG,KAAK,GAAG,SAAS,EAC7C,KAAK,CAAC,EAAE,qBAAqB,GAC5B,gBAAgB,GAAG,KAAK,CAS1B;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,UAAU,CAAC,EACzB,MAAM,EACN,MAAM,EACN,WAAW,EACX,IAAY,EACZ,QAA4B,EAC5B,OAAO,EACP,MAAW,EACX,SAAS,EACT,SAAiB,EACjB,QAAQ,GACT,EAAE,eAAe,GAAG,SAAS,CAsE7B"}
|
|
@@ -80,7 +80,7 @@ function ChartFrame({
|
|
|
80
80
|
{
|
|
81
81
|
ref: containerRef,
|
|
82
82
|
style: outerStyle(fill, vertical),
|
|
83
|
-
...ariaLabel !== void 0 && { role: "
|
|
83
|
+
...ariaLabel !== void 0 && { role: "group", "aria-label": ariaLabel },
|
|
84
84
|
...isPending && { "aria-busy": "true" },
|
|
85
85
|
children: [
|
|
86
86
|
legendNode !== null && (placement === "top" || placement === "left") && legendNode,
|
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import type { ReactNode } from 'react';
|
|
2
2
|
/** Tooltip header — shows formatted date + optional right-aligned label with color. */
|
|
3
|
-
export declare function TooltipHeader({ date, label, labelColor, }: {
|
|
3
|
+
export declare function TooltipHeader({ date, label, labelColor, format, }: {
|
|
4
4
|
date: string;
|
|
5
5
|
label?: string;
|
|
6
6
|
labelColor?: string;
|
|
7
|
+
/** Overrides `fmtTooltipDate` for the header text. Default: today's `fmtTooltipDate` behavior,
|
|
8
|
+
* unchanged. The seam exists because `fmtTooltipDate` regexes `YYYY-MM-DD` out of the key and
|
|
9
|
+
* builds a LOCAL `Date`, so a UTC ISO domain key names the wrong day next to `formatX`/the
|
|
10
|
+
* tooltip badge, which both resolve locally — a caller with a UTC key needs to supply its own. */
|
|
11
|
+
format?: (date: string) => string;
|
|
7
12
|
}): import("react").JSX.Element;
|
|
8
13
|
/** Tooltip row — swatch + label + value. */
|
|
9
14
|
export declare function TooltipRow({ color, label, value, valueColor, shape, strokeWidth, dashed, }: {
|
|
@@ -27,11 +32,16 @@ export declare function TooltipBody({ children }: {
|
|
|
27
32
|
* The box is measured after mount via `useLayoutEffect`, so the first paint of a given tooltip is
|
|
28
33
|
* hidden rather than misplaced — a tooltip that flashes at the wrong corner reads as a bug.
|
|
29
34
|
*/
|
|
30
|
-
export declare function ChartTooltipFloat({ anchor, children, }: {
|
|
35
|
+
export declare function ChartTooltipFloat({ anchor, ariaLive, children, }: {
|
|
31
36
|
anchor: {
|
|
32
37
|
x: number;
|
|
33
38
|
y: number;
|
|
34
39
|
} | null;
|
|
40
|
+
/** Whether this tooltip announces itself to screen readers on every position change. Default
|
|
41
|
+
* true. Pass false for a cursor FOLLOWER's tooltip — N followers on a shared-cursor page all
|
|
42
|
+
* announcing on every pointer move would make the page unusable with a screen reader; only the
|
|
43
|
+
* cursor SOURCE should be `aria-live`. */
|
|
44
|
+
ariaLive?: boolean;
|
|
35
45
|
children: ReactNode;
|
|
36
46
|
}): import("react").ReactPortal | null;
|
|
37
47
|
//# sourceMappingURL=ChartTooltip.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChartTooltip.d.ts","sourceRoot":"","sources":["../../../src/charts/primitives/ChartTooltip.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAiB,SAAS,EAAE,MAAM,OAAO,CAAA;AAuBrD,uFAAuF;AACvF,wBAAgB,aAAa,CAAC,EAC5B,IAAI,EACJ,KAAK,EACL,UAAU,
|
|
1
|
+
{"version":3,"file":"ChartTooltip.d.ts","sourceRoot":"","sources":["../../../src/charts/primitives/ChartTooltip.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAiB,SAAS,EAAE,MAAM,OAAO,CAAA;AAuBrD,uFAAuF;AACvF,wBAAgB,aAAa,CAAC,EAC5B,IAAI,EACJ,KAAK,EACL,UAAU,EACV,MAAuB,GACxB,EAAE;IACD,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;;;sGAGkG;IAClG,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAA;CAClC,+BAoCA;AAED,4CAA4C;AAC5C,wBAAgB,UAAU,CAAC,EACzB,KAAK,EACL,KAAK,EACL,KAAK,EACL,UAAU,EACV,KAAK,EACL,WAAW,EACX,MAAM,GACP,EAAE;IACD,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,KAAK,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,KAAK,CAAA;IAC9B,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,uEAAuE;IACvE,MAAM,CAAC,EAAE,OAAO,CAAA;CACjB,+BA0CA;AAED,wBAAgB,WAAW,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,EAAE,SAAS,CAAA;CAAE,+BAEhE;AAOD;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,MAAM,EACN,QAAe,EACf,QAAQ,GACT,EAAE;IACD,MAAM,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAA;IACvC;;;8CAG0C;IAC1C,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,QAAQ,EAAE,SAAS,CAAA;CACpB,sCA4CA"}
|
|
@@ -19,7 +19,8 @@ const TOOLTIP_STYLES = {
|
|
|
19
19
|
function TooltipHeader({
|
|
20
20
|
date,
|
|
21
21
|
label,
|
|
22
|
-
labelColor
|
|
22
|
+
labelColor,
|
|
23
|
+
format = fmtTooltipDate
|
|
23
24
|
}) {
|
|
24
25
|
return /* @__PURE__ */ jsxs(
|
|
25
26
|
"div",
|
|
@@ -42,7 +43,7 @@ function TooltipHeader({
|
|
|
42
43
|
fontFamily: "var(--basalt-font-mono)",
|
|
43
44
|
color: VX.ink
|
|
44
45
|
},
|
|
45
|
-
children:
|
|
46
|
+
children: format(date)
|
|
46
47
|
}
|
|
47
48
|
),
|
|
48
49
|
label !== void 0 && /* @__PURE__ */ jsx(
|
|
@@ -120,6 +121,7 @@ const TOOLTIP_GAP = 12;
|
|
|
120
121
|
const VIEWPORT_MARGIN = 8;
|
|
121
122
|
function ChartTooltipFloat({
|
|
122
123
|
anchor,
|
|
124
|
+
ariaLive = true,
|
|
123
125
|
children
|
|
124
126
|
}) {
|
|
125
127
|
const ref = useRef(null);
|
|
@@ -150,7 +152,7 @@ function ChartTooltipFloat({
|
|
|
150
152
|
{
|
|
151
153
|
ref,
|
|
152
154
|
role: "tooltip",
|
|
153
|
-
"aria-live": "polite",
|
|
155
|
+
...ariaLive && { "aria-live": "polite" },
|
|
154
156
|
style: { ...TOOLTIP_STYLES, left, top, visibility: box === null ? "hidden" : "visible" },
|
|
155
157
|
children
|
|
156
158
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChartTooltip.test.d.ts","sourceRoot":"","sources":["../../../src/charts/primitives/ChartTooltip.test.tsx"],"names":[],"mappings":""}
|
package/dist/charts/series.d.ts
CHANGED
|
@@ -58,6 +58,11 @@ export type SeriesStyle = {
|
|
|
58
58
|
* that lies is the thing the derived-legend rule exists to prevent). The TOOLTIP ROW swatch and
|
|
59
59
|
* the CROSSHAIR DOT deliberately do NOT honor it: those are 12px value-readout chips where a
|
|
60
60
|
* sub-1 opacity reads as a rendering bug, not as data.
|
|
61
|
+
*
|
|
62
|
+
* Applies to STROKES only, so it silently no-ops on a `mark: 'bar'`/`'area'` series — a bar
|
|
63
|
+
* swatch has no stroke to dim. Dim those with `fillOpacity` instead. This bites the
|
|
64
|
+
* zone/reference-legend idiom in particular (`mark: 'bar'`, `getValue: () => null`), where
|
|
65
|
+
* reaching for `strokeOpacity` looks right and does nothing.
|
|
61
66
|
*/
|
|
62
67
|
strokeOpacity?: number;
|
|
63
68
|
/** Which y-axis this series is measured against. Default 'left'. `'right'` is what makes a
|
|
@@ -87,10 +92,13 @@ export type ChartSeries<T> = SeriesStyle & {
|
|
|
87
92
|
* alongside the value so a row can read fields beyond the plotted number (e.g. `97.5 kg (92.5 ×
|
|
88
93
|
* 3)`). */
|
|
89
94
|
formatValue?: (v: number, d: T) => string;
|
|
90
|
-
/** PR star / status dot. Return null for no marker at that point.
|
|
95
|
+
/** PR star / status dot. Return null for no marker at that point. `ring` defaults true (today's
|
|
96
|
+
* punched-out stroke, unchanged); `false` omits the stroke entirely. `fillOpacity` defaults 1. */
|
|
91
97
|
getMarker?: (d: T) => {
|
|
92
98
|
color?: string;
|
|
93
99
|
r?: number;
|
|
100
|
+
fillOpacity?: number;
|
|
101
|
+
ring?: boolean;
|
|
94
102
|
} | null;
|
|
95
103
|
};
|
|
96
104
|
/** A single derived tooltip row, ready for `TooltipRow`. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"series.d.ts","sourceRoot":"","sources":["../../src/charts/series.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAA;AAE3D;;;;;;GAMG;AACH,eAAO,MAAM,yBAAyB,MAAM,CAAA;AAE5C,iEAAiE;AACjE,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,KAAK,GAAG,MAAM,CAAA;AAEhD,0CAA0C;AAC1C,MAAM,MAAM,UAAU,GAAG,OAAO,GAAG,QAAQ,CAAA;AAE3C,uCAAuC;AACvC,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,SAAS,GAAG,WAAW,CAAA;AAE3D,6DAA6D;AAC7D,MAAM,MAAM,eAAe,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAA;AAEjE;;;;;GAKG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,wBAAwB;IACxB,SAAS,CAAC,EAAE,eAAe,CAAA;IAC3B,4DAA4D;IAC5D,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,uDAAuD;IACvD,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,8FAA8F;IAC9F,MAAM,CAAC,EAAE,OAAO,CAAA;CACjB,CAAA;AAED,uGAAuG;AACvG,MAAM,MAAM,WAAW,GAAG;IACxB,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;IACb,mDAAmD;IACnD,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,UAAU,CAAA;IAChB,uBAAuB;IACvB,IAAI,CAAC,EAAE,UAAU,CAAA;IACjB,oDAAoD;IACpD,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,yDAAyD;IACzD,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB
|
|
1
|
+
{"version":3,"file":"series.d.ts","sourceRoot":"","sources":["../../src/charts/series.ts"],"names":[],"mappings":"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"}
|
|
@@ -17,4 +17,19 @@
|
|
|
17
17
|
* pre-existing, still-correct behavior for genuinely negative-swinging metrics.
|
|
18
18
|
*/
|
|
19
19
|
export declare function padAutoLower(candidate: number, pad: number): number;
|
|
20
|
+
/**
|
|
21
|
+
* Auto y-domain upper-bound padding — the exact mirror of {@link padAutoLower}, sharing its
|
|
22
|
+
* sign-safety: pad AWAY from zero (`upper >= candidate`), never toward it. `candidate` is the
|
|
23
|
+
* caller's `Math.max(dataMax, floor)` — the `autoMaxFloor` clamp has already been applied, so
|
|
24
|
+
* padding runs AFTER the floor, not before it. Applying the floor post-pad (the pre-existing bug)
|
|
25
|
+
* lands a floored axis top exactly on the floor value with zero headroom — a target line pinned to
|
|
26
|
+
* that floor then sits glued to the plot edge instead of getting the same breathing room every
|
|
27
|
+
* other bound gets.
|
|
28
|
+
*
|
|
29
|
+
* - `candidate === 0` stays exactly 0 — never pushed positive.
|
|
30
|
+
* - `candidate > 0` multiplies by `pad`, moving the ceiling further UP (away from zero).
|
|
31
|
+
* - `candidate < 0` divides by `pad`, moving the ceiling UP toward (and past) zero — the mirror of
|
|
32
|
+
* `padAutoLower`'s `candidate > 0` branch.
|
|
33
|
+
*/
|
|
34
|
+
export declare function padAutoUpper(candidate: number, pad: number): number;
|
|
20
35
|
//# sourceMappingURL=domain.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"domain.d.ts","sourceRoot":"","sources":["../../../src/charts/utils/domain.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAGnE"}
|
|
1
|
+
{"version":3,"file":"domain.d.ts","sourceRoot":"","sources":["../../../src/charts/utils/domain.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAGnE;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAGnE"}
|
|
@@ -2,6 +2,11 @@ function padAutoLower(candidate, pad) {
|
|
|
2
2
|
if (candidate === 0) return 0;
|
|
3
3
|
return candidate > 0 ? candidate / pad : candidate * pad;
|
|
4
4
|
}
|
|
5
|
+
function padAutoUpper(candidate, pad) {
|
|
6
|
+
if (candidate === 0) return 0;
|
|
7
|
+
return candidate > 0 ? candidate * pad : candidate / pad;
|
|
8
|
+
}
|
|
5
9
|
export {
|
|
6
|
-
padAutoLower
|
|
10
|
+
padAutoLower,
|
|
11
|
+
padAutoUpper
|
|
7
12
|
};
|
package/llms.txt
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# basalt-ui v1.
|
|
1
|
+
# basalt-ui v1.18.0
|
|
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.
|
|
22
|
+
Version: 1.18.0
|
|
23
23
|
|
|
24
24
|
## basalt-ui
|
|
25
25
|
Import: import { ... } from 'basalt-ui'
|