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.
Files changed (69) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/agent/rules/basalt-charts.md +58 -4
  3. package/agent/skills/basalt-design/SKILL.md +2 -2
  4. package/dist/charts/cursor/resolve.d.ts +29 -5
  5. package/dist/charts/cursor/resolve.d.ts.map +1 -1
  6. package/dist/charts/cursor/resolve.js +25 -4
  7. package/dist/charts/hooks/useChartCursor.d.ts +8 -1
  8. package/dist/charts/hooks/useChartCursor.d.ts.map +1 -1
  9. package/dist/charts/hooks/useChartCursor.js +6 -2
  10. package/dist/charts/index.d.ts +1 -0
  11. package/dist/charts/index.d.ts.map +1 -1
  12. package/dist/charts/kinds/Bars.d.ts +9 -0
  13. package/dist/charts/kinds/Bars.d.ts.map +1 -1
  14. package/dist/charts/kinds/Bars.js +4 -0
  15. package/dist/charts/kinds/DualPanel.d.ts +24 -0
  16. package/dist/charts/kinds/DualPanel.d.ts.map +1 -1
  17. package/dist/charts/kinds/DualPanel.js +39 -9
  18. package/dist/charts/kinds/MultiLine.d.ts +9 -0
  19. package/dist/charts/kinds/MultiLine.d.ts.map +1 -1
  20. package/dist/charts/kinds/MultiLine.js +10 -8
  21. package/dist/charts/kinds/StackedArea.d.ts +9 -0
  22. package/dist/charts/kinds/StackedArea.d.ts.map +1 -1
  23. package/dist/charts/kinds/StackedArea.js +16 -1
  24. package/dist/charts/kinds/StackedArea.test.d.ts +2 -0
  25. package/dist/charts/kinds/StackedArea.test.d.ts.map +1 -0
  26. package/dist/charts/kinds/ZonedLine.d.ts +9 -0
  27. package/dist/charts/kinds/ZonedLine.d.ts.map +1 -1
  28. package/dist/charts/kinds/ZonedLine.js +4 -0
  29. package/dist/charts/primitives/CartesianChart.d.ts +40 -2
  30. package/dist/charts/primitives/CartesianChart.d.ts.map +1 -1
  31. package/dist/charts/primitives/CartesianChart.js +16 -6
  32. package/dist/charts/primitives/ChartFrame.d.ts +8 -1
  33. package/dist/charts/primitives/ChartFrame.d.ts.map +1 -1
  34. package/dist/charts/primitives/ChartFrame.js +1 -1
  35. package/dist/charts/primitives/ChartTooltip.d.ts +12 -2
  36. package/dist/charts/primitives/ChartTooltip.d.ts.map +1 -1
  37. package/dist/charts/primitives/ChartTooltip.js +5 -3
  38. package/dist/charts/primitives/ChartTooltip.test.d.ts +2 -0
  39. package/dist/charts/primitives/ChartTooltip.test.d.ts.map +1 -0
  40. package/dist/charts/series.d.ts +9 -1
  41. package/dist/charts/series.d.ts.map +1 -1
  42. package/dist/charts/utils/domain.d.ts +15 -0
  43. package/dist/charts/utils/domain.d.ts.map +1 -1
  44. package/dist/charts/utils/domain.js +6 -1
  45. package/llms.txt +2 -2
  46. package/package.json +1 -1
  47. package/src/charts/cursor/resolve.test.ts +62 -0
  48. package/src/charts/cursor/resolve.ts +71 -7
  49. package/src/charts/hooks/useChartCursor.ts +12 -1
  50. package/src/charts/index.ts +1 -0
  51. package/src/charts/kinds/Bars.test.tsx +85 -0
  52. package/src/charts/kinds/Bars.tsx +13 -0
  53. package/src/charts/kinds/DualPanel.test.tsx +391 -1
  54. package/src/charts/kinds/DualPanel.tsx +74 -8
  55. package/src/charts/kinds/MultiLine.test.tsx +181 -0
  56. package/src/charts/kinds/MultiLine.tsx +19 -8
  57. package/src/charts/kinds/StackedArea.test.tsx +114 -0
  58. package/src/charts/kinds/StackedArea.tsx +25 -1
  59. package/src/charts/kinds/ZonedLine.test.tsx +110 -0
  60. package/src/charts/kinds/ZonedLine.tsx +13 -0
  61. package/src/charts/primitives/CartesianChart.test.tsx +284 -3
  62. package/src/charts/primitives/CartesianChart.tsx +64 -12
  63. package/src/charts/primitives/ChartFrame.test.tsx +42 -0
  64. package/src/charts/primitives/ChartFrame.tsx +9 -2
  65. package/src/charts/primitives/ChartTooltip.test.tsx +44 -0
  66. package/src/charts/primitives/ChartTooltip.tsx +14 -2
  67. package/src/charts/series.ts +8 -2
  68. package/src/charts/utils/domain.test.ts +31 -1
  69. package/src/charts/utils/domain.ts +19 -0
@@ -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
- getMarker?: (d: T) => { color?: string; r?: number } | null
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
+ }