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
package/src/charts/series.ts
CHANGED
|
@@ -66,6 +66,11 @@ export type SeriesStyle = {
|
|
|
66
66
|
* that lies is the thing the derived-legend rule exists to prevent). The TOOLTIP ROW swatch and
|
|
67
67
|
* the CROSSHAIR DOT deliberately do NOT honor it: those are 12px value-readout chips where a
|
|
68
68
|
* sub-1 opacity reads as a rendering bug, not as data.
|
|
69
|
+
*
|
|
70
|
+
* Applies to STROKES only, so it silently no-ops on a `mark: 'bar'`/`'area'` series — a bar
|
|
71
|
+
* swatch has no stroke to dim. Dim those with `fillOpacity` instead. This bites the
|
|
72
|
+
* zone/reference-legend idiom in particular (`mark: 'bar'`, `getValue: () => null`), where
|
|
73
|
+
* reaching for `strokeOpacity` looks right and does nothing.
|
|
69
74
|
*/
|
|
70
75
|
strokeOpacity?: number
|
|
71
76
|
/** Which y-axis this series is measured against. Default 'left'. `'right'` is what makes a
|
|
@@ -96,8 +101,9 @@ export type ChartSeries<T> = SeriesStyle & {
|
|
|
96
101
|
* alongside the value so a row can read fields beyond the plotted number (e.g. `97.5 kg (92.5 ×
|
|
97
102
|
* 3)`). */
|
|
98
103
|
formatValue?: (v: number, d: T) => string
|
|
99
|
-
/** PR star / status dot. Return null for no marker at that point.
|
|
100
|
-
|
|
104
|
+
/** PR star / status dot. Return null for no marker at that point. `ring` defaults true (today's
|
|
105
|
+
* punched-out stroke, unchanged); `false` omits the stroke entirely. `fillOpacity` defaults 1. */
|
|
106
|
+
getMarker?: (d: T) => { color?: string; r?: number; fillOpacity?: number; ring?: boolean } | null
|
|
101
107
|
}
|
|
102
108
|
|
|
103
109
|
/** A single derived tooltip row, ready for `TooltipRow`. */
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { describe, expect, test } from 'bun:test'
|
|
2
|
-
import { padAutoLower } from './domain'
|
|
2
|
+
import { padAutoLower, padAutoUpper } from './domain'
|
|
3
3
|
|
|
4
4
|
describe('padAutoLower', () => {
|
|
5
5
|
test('stays at 0 for the default zero-baseline case (never goes negative)', () => {
|
|
@@ -22,3 +22,33 @@ describe('padAutoLower', () => {
|
|
|
22
22
|
}
|
|
23
23
|
})
|
|
24
24
|
})
|
|
25
|
+
|
|
26
|
+
describe('padAutoUpper', () => {
|
|
27
|
+
test('stays at 0 (never pushed positive)', () => {
|
|
28
|
+
expect(padAutoUpper(0, 1.1)).toBe(0)
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
test('pads UP above a positive candidate', () => {
|
|
32
|
+
expect(padAutoUpper(78, 1.1)).toBeCloseTo(85.8, 5)
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
test('pads further up (toward and past zero) for a negative candidate', () => {
|
|
36
|
+
expect(padAutoUpper(-5, 1.1)).toBeCloseTo(-4.5454, 3)
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
test('upper never lands below the candidate it was derived from', () => {
|
|
40
|
+
for (const candidate of [-10, -0.5, 0, 0.5, 10, 78]) {
|
|
41
|
+
expect(padAutoUpper(candidate, 1.1)).toBeGreaterThanOrEqual(candidate)
|
|
42
|
+
}
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
test('the autoMaxFloor case: dataMax 3.2, pad 1.1, floor 6 -> 6.6', () => {
|
|
46
|
+
expect(padAutoUpper(Math.max(3.2, 6), 1.1)).toBeCloseTo(6.6, 5)
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
test('is the exact mirror of padAutoLower — same magnitude, opposite direction', () => {
|
|
50
|
+
for (const candidate of [-10, -0.5, 0.5, 10, 78]) {
|
|
51
|
+
expect(padAutoUpper(candidate, 1.1)).toBeCloseTo(-padAutoLower(-candidate, 1.1), 5)
|
|
52
|
+
}
|
|
53
|
+
})
|
|
54
|
+
})
|
|
@@ -20,3 +20,22 @@ export function padAutoLower(candidate: number, pad: number): number {
|
|
|
20
20
|
if (candidate === 0) return 0
|
|
21
21
|
return candidate > 0 ? candidate / pad : candidate * pad
|
|
22
22
|
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Auto y-domain upper-bound padding — the exact mirror of {@link padAutoLower}, sharing its
|
|
26
|
+
* sign-safety: pad AWAY from zero (`upper >= candidate`), never toward it. `candidate` is the
|
|
27
|
+
* caller's `Math.max(dataMax, floor)` — the `autoMaxFloor` clamp has already been applied, so
|
|
28
|
+
* padding runs AFTER the floor, not before it. Applying the floor post-pad (the pre-existing bug)
|
|
29
|
+
* lands a floored axis top exactly on the floor value with zero headroom — a target line pinned to
|
|
30
|
+
* that floor then sits glued to the plot edge instead of getting the same breathing room every
|
|
31
|
+
* other bound gets.
|
|
32
|
+
*
|
|
33
|
+
* - `candidate === 0` stays exactly 0 — never pushed positive.
|
|
34
|
+
* - `candidate > 0` multiplies by `pad`, moving the ceiling further UP (away from zero).
|
|
35
|
+
* - `candidate < 0` divides by `pad`, moving the ceiling UP toward (and past) zero — the mirror of
|
|
36
|
+
* `padAutoLower`'s `candidate > 0` branch.
|
|
37
|
+
*/
|
|
38
|
+
export function padAutoUpper(candidate: number, pad: number): number {
|
|
39
|
+
if (candidate === 0) return 0
|
|
40
|
+
return candidate > 0 ? candidate * pad : candidate / pad
|
|
41
|
+
}
|