@automattic/charts 4.6.0 → 4.8.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 +32 -0
- package/TOKENS.md +15 -10
- package/dist/index.cjs +427 -211
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +40 -26
- package/dist/index.d.cts +69 -29
- package/dist/index.d.ts +69 -29
- package/dist/index.js +427 -213
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/charts/area-chart/area-chart.tsx +2 -2
- package/src/charts/area-chart/test/area-chart.test.tsx +1 -1
- package/src/charts/area-chart/test/tooltip-resolution-branches.test.tsx +1 -1
- package/src/charts/bar-chart/bar-chart.module.scss +7 -0
- package/src/charts/bar-chart/bar-chart.tsx +20 -14
- package/src/charts/bar-chart/private/comparison-bars.tsx +1 -0
- package/src/charts/bar-chart/test/bar-chart.test.tsx +25 -0
- package/src/charts/conversion-funnel-chart/conversion-funnel-chart.module.scss +0 -10
- package/src/charts/conversion-funnel-chart/conversion-funnel-chart.tsx +5 -3
- package/src/charts/conversion-funnel-chart/test/conversion-funnel-chart.test.tsx +20 -1
- package/src/charts/conversion-funnel-chart/types.ts +3 -0
- package/src/charts/heatmap-chart/heatmap-chart.module.scss +16 -7
- package/src/charts/heatmap-chart/heatmap-chart.tsx +80 -53
- package/src/charts/heatmap-chart/private/heatmap-context.ts +2 -2
- package/src/charts/heatmap-chart/private/heatmap-legend.tsx +2 -2
- package/src/charts/heatmap-chart/private/heatmap-scale.ts +74 -0
- package/src/charts/heatmap-chart/private/index.ts +2 -1
- package/src/charts/heatmap-chart/private/use-heatmap-colors.ts +24 -6
- package/src/charts/heatmap-chart/test/heatmap-chart.test.tsx +221 -25
- package/src/charts/heatmap-chart/test/heatmap-scale.test.ts +78 -0
- package/src/charts/heatmap-chart/test/use-heatmap-colors.test.ts +18 -6
- package/src/charts/heatmap-chart/types.ts +6 -9
- package/src/charts/line-chart/crosshair-style-types.fixture.ts +23 -0
- package/src/charts/line-chart/line-chart.module.scss +0 -5
- package/src/charts/line-chart/line-chart.tsx +10 -42
- package/src/charts/line-chart/test/line-chart.test.tsx +19 -47
- package/src/charts/pie-chart/pie-chart.module.scss +9 -0
- package/src/charts/pie-chart/pie-chart.tsx +26 -80
- package/src/charts/pie-chart/test/pie-chart.test.tsx +21 -8
- package/src/charts/pie-semi-circle-chart/pie-semi-circle-chart.tsx +4 -4
- package/src/charts/pie-semi-circle-chart/test/pie-semi-circle-chart.test.tsx +1 -1
- package/src/charts/private/chart-composition/chart-html.tsx +1 -1
- package/src/charts/private/chart-composition/chart-svg.tsx +1 -1
- package/src/charts/private/label-text-color.ts +116 -0
- package/src/charts/private/radial-wipe-animation/radial-wipe-animation.tsx +2 -0
- package/src/charts/private/svg-empty-state/svg-empty-state.tsx +1 -1
- package/src/charts/private/test/label-text-color.test.ts +189 -0
- package/src/charts/private/with-responsive/test/with-responsive.test.tsx +1 -0
- package/src/charts/private/with-responsive/with-responsive.tsx +2 -5
- package/src/components/tooltip/base-tooltip.tsx +31 -30
- package/src/components/tooltip/index.ts +3 -1
- package/src/components/tooltip/private/bounded-tooltip.tsx +32 -13
- package/src/components/tooltip/private/label-value-content.tsx +8 -0
- package/src/components/tooltip/private/tooltip-theme.tsx +37 -0
- package/src/components/tooltip/private/xy-chart-tooltip-overlay.tsx +336 -0
- package/src/components/tooltip/test/bounded-tooltip.test.tsx +82 -1
- package/src/components/tooltip/test/tool-tip.test.tsx +10 -3
- package/src/components/tooltip/test/tooltip-box.test.tsx +53 -0
- package/src/components/tooltip/test/tooltip-theme.test.tsx +61 -0
- package/src/components/tooltip/test/xy-chart-tooltip-overlay.test.tsx +445 -0
- package/src/components/tooltip/test/xy-chart-tooltip.test.tsx +286 -356
- package/src/components/tooltip/tooltip-box.module.scss +21 -0
- package/src/components/tooltip/tooltip-box.tsx +43 -0
- package/src/components/tooltip/types.ts +7 -1
- package/src/components/tooltip/xy-chart-tooltip.tsx +411 -301
- package/src/components/trend-indicator/trend-indicator.tsx +1 -0
- package/src/hooks/index.ts +1 -0
- package/src/hooks/test/use-chart-margin.test.tsx +8 -4
- package/src/hooks/test/use-xychart-theme.test.tsx +3 -3
- package/src/hooks/use-chart-margin.tsx +21 -18
- package/src/hooks/use-isomorphic-layout-effect.ts +5 -0
- package/src/hooks/use-xychart-theme.ts +4 -12
- package/src/index.ts +8 -3
- package/src/providers/chart-context/global-charts-provider.tsx +5 -14
- package/src/providers/chart-context/hooks/use-default-hidden-series.ts +3 -5
- package/src/providers/chart-context/private/catalog-pointers.ts +1 -0
- package/src/providers/chart-context/private/perceptual-color.ts +45 -4
- package/src/providers/chart-context/private/resolve-opaque-hex.ts +16 -0
- package/src/providers/chart-context/test/perceptual-color.test.ts +31 -0
- package/src/providers/chart-context/test/use-default-hidden-series.test.tsx +1 -1
- package/src/styles/chart-scope-class.ts +5 -0
- package/src/styles/chart-scope.scss +10 -6
- package/src/styles/test/chart-scope.test.ts +3 -3
- package/src/test-utils/zoned-parsing-suite.ts +0 -10
- package/src/utils/color-utils.ts +2 -1
- package/src/utils/test/date-formatting.test.ts +0 -10
- package/src/visx/types.ts +1 -1
- package/src/charts/line-chart/test/crosshair-style-types.test.ts +0 -31
- package/src/components/tooltip/accessible-tooltip.tsx +0 -433
- package/src/components/tooltip/base-tooltip.module.scss +0 -20
- package/src/components/tooltip/test/accessible-tooltip.test.tsx +0 -331
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,36 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [4.8.0] - 2026-10-07
|
|
9
|
+
### Added
|
|
10
|
+
- Add `TooltipBox`, the chart tooltip box, and `XYChartTooltip`, the new name for `AccessibleTooltip`. [#53075]
|
|
11
|
+
- Bar Chart: Add the `--a8c-charts-border-radius-bar-chart` role to round bar corners. Bars stay square by default. [#53132]
|
|
12
|
+
|
|
13
|
+
### Deprecated
|
|
14
|
+
- Deprecate `AccessibleTooltip` in favor of `XYChartTooltip`, and `BaseTooltip`'s `data`, `component`, `renderContainer`, `top` and `left` props in favor of `TooltipBox`. [#53075]
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
- Bar chart: Stop drawing an axis set to display: false. [#53203]
|
|
18
|
+
- ConversionFunnelChart: Give the tooltip content `role="tooltip"`, like the other charts. [#53075]
|
|
19
|
+
- Heatmap chart: Keep the lowest step of the color scale at 3:1 contrast against the chart background and empty cells in every theme, deepen the highest step to 9:1, and draw zeros in data without negative values as empty cells. [#53085]
|
|
20
|
+
- Line, bar and area charts: Reserve no margin for a hidden x axis, matching a hidden y axis. [#53265]
|
|
21
|
+
- Tooltip: Keep the tooltip as wide as its content when the host page caps the width of visx tooltips. [#53135]
|
|
22
|
+
|
|
23
|
+
## [4.7.0] - 2026-10-05
|
|
24
|
+
### Added
|
|
25
|
+
- Conversion funnel chart: Add `tooltipStyle` to restyle the tooltip box. [#52850]
|
|
26
|
+
|
|
27
|
+
### Changed
|
|
28
|
+
- Tooltips: Draw every chart tooltip on one dark surface that matches the WordPress design system; set `--a8c-charts-color-tooltip-surface` for a light tooltip. [#52850]
|
|
29
|
+
|
|
30
|
+
### Deprecated
|
|
31
|
+
- Conversion funnel chart: Deprecate `className` in the custom `renderTooltip` props, which is no longer set. [#52850]
|
|
32
|
+
- Deprecate the `prefersLightText` color utility. [#52968]
|
|
33
|
+
- Heatmap chart: Deprecate `tooltipVariant`, which no longer has an effect. [#52850]
|
|
34
|
+
|
|
35
|
+
### Fixed
|
|
36
|
+
- Keep values drawn on heatmap and pie chart fills at WCAG AA contrast. [#52968]
|
|
37
|
+
|
|
8
38
|
## [4.6.0] - 2026-09-29
|
|
9
39
|
### Added
|
|
10
40
|
- Geo Chart: Add a displayMode prop to draw rows as markers. [#52859]
|
|
@@ -1131,6 +1161,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
1131
1161
|
- Fixed lints following ESLint rule changes for TS [#40584]
|
|
1132
1162
|
- Fixing a bug in Chart storybook data. [#40640]
|
|
1133
1163
|
|
|
1164
|
+
[4.8.0]: https://github.com/Automattic/charts/compare/v4.7.0...v4.8.0
|
|
1165
|
+
[4.7.0]: https://github.com/Automattic/charts/compare/v4.6.0...v4.7.0
|
|
1134
1166
|
[4.6.0]: https://github.com/Automattic/charts/compare/v4.5.0...v4.6.0
|
|
1135
1167
|
[4.5.0]: https://github.com/Automattic/charts/compare/v4.4.0...v4.5.0
|
|
1136
1168
|
[4.4.0]: https://github.com/Automattic/charts/compare/v4.3.0...v4.4.0
|
package/TOKENS.md
CHANGED
|
@@ -4,18 +4,18 @@
|
|
|
4
4
|
|
|
5
5
|
## How it resolves
|
|
6
6
|
|
|
7
|
-
`src/styles/chart-scope.scss` declares the whole catalog once, on the `GlobalChartsProvider` wrapper, via `:where(.a8c-charts-scope)`. `:where()` keeps the rule at zero specificity, so a consumer rule targeting that same element wins without `!important`. It is declared on the wrapper rather than `:root` because `@wordpress/theme`'s `ThemeProvider` emits its generated `--wpds-*` ramp as inline styles on its own wrapper div — a `:root` declaration would miss a `ThemeProvider` entirely.
|
|
7
|
+
`src/styles/chart-scope.scss` declares the whole catalog once, on the `GlobalChartsProvider` wrapper, via `:where(.a8c-charts-scope, .a8c-charts-tooltip-scope)`. `:where()` keeps the rule at zero specificity, so a consumer rule targeting that same element wins without `!important`. It is declared on the wrapper rather than `:root` because `@wordpress/theme`'s `ThemeProvider` emits its generated `--wpds-*` ramp as inline styles on its own wrapper div — a `:root` declaration would miss a `ThemeProvider` entirely.
|
|
8
8
|
|
|
9
9
|
Chart roots deliberately do *not* carry the `a8c-charts-scope` class. Custom properties inherit down the tree, and an element only shadows an inherited value by re-declaring it, so a chart root that re-declared the catalog would beat an override set between it and the provider — closing off the one place consumers are meant to set overrides. This inheritance rule drives every precedence question below.
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
The tooltip box, `TooltipBox`, is the exception, and on purpose. Like the `@wordpress/ui` Tooltip popup, it renders inside its own `ThemeProvider`, seeded with `--a8c-charts-color-tooltip-surface`, and carries its own `a8c-charts-tooltip-scope` class, so it re-declares the catalog under that dark theme. Every role read inside the box resolves for the dark surface, whatever theme the chart is in, and neither an override set on the chart nor a rule on `.a8c-charts-scope` reaches the box. To override a role inside every tooltip, target `.a8c-charts-tooltip-scope`. An `unstyled` box gets neither the theme nor the class.
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
`TrendIndicator` and `BaseLegend` carry the class only when no provider is above them (`useStandaloneScopeClass()`), so inside a provider they inherit its overrides like the chart they belong to.
|
|
14
14
|
|
|
15
15
|
Catalog entries normally map to WPDS tokens. Source writes these mappings bare; the LightningCSS plugin in `tsdown.config.ts` injects the WPDS spec value as a fallback into `dist/`:
|
|
16
16
|
|
|
17
17
|
```scss
|
|
18
|
-
:where(.a8c-charts-scope) {
|
|
18
|
+
:where(.a8c-charts-scope, .a8c-charts-tooltip-scope) {
|
|
19
19
|
--a8c-charts-color-grid: var(--wpds-color-stroke-surface-neutral);
|
|
20
20
|
}
|
|
21
21
|
```
|
|
@@ -41,12 +41,12 @@ Some roles are deliberately narrower than the obvious name, so that moving one t
|
|
|
41
41
|
|
|
42
42
|
| Narrow role | Broad role | What the broad one also reaches |
|
|
43
43
|
|---|---|---|
|
|
44
|
-
| `--a8c-charts-color-label-axis` | `--a8c-charts-color-label` | legend labels, `.heatmap-chart__cell-value`, funnel labels,
|
|
44
|
+
| `--a8c-charts-color-label-axis` | `--a8c-charts-color-label` | legend labels, `.heatmap-chart__cell-value`, funnel labels, pie labels on light slices |
|
|
45
45
|
| `--a8c-charts-color-background` | — | — |
|
|
46
46
|
|
|
47
47
|
Outside forced-colors mode, `--a8c-charts-color-label-axis` derives from `--a8c-charts-color-label`, so setting the broad role moves every label at once and setting the narrow one moves only the SVG axis labels. See [One pair of roles per axis](#one-pair-of-roles-per-axis) for forced-colors defaults.
|
|
48
48
|
|
|
49
|
-
`--a8c-charts-color-surface`
|
|
49
|
+
`--a8c-charts-color-surface` (the annotation label, `.x-zoom__reset`) is a **sibling** of `--a8c-charts-color-background`, not a child. The chart's own background and the surfaces floating over it are set apart from each other often enough that one has to be able to move without the other. The consequence: no single role repaints both.
|
|
50
50
|
|
|
51
51
|
### The SVG bridge
|
|
52
52
|
|
|
@@ -56,13 +56,13 @@ That is what makes the role read **at the painted element** rather than snapshot
|
|
|
56
56
|
|
|
57
57
|
There is no stylesheet and no class involved. In particular the axes need neither: visx takes a separate style object per axis, so each one is handed its own roles and nothing has to distinguish them after the fact.
|
|
58
58
|
|
|
59
|
-
What else crosses in JS is what something reads as a *value*: the series palette, which visx turns into its `colorScale`; the background, which the default glyph, the area-chart band, the line-chart gradient stops, the heatmap's contrast math and `GeoChart` each consume as a concrete string; and, for the pie chart, `label` and `label-inverse` against the resolved
|
|
59
|
+
What else crosses in JS is what something reads as a *value*: the series palette, which visx turns into its `colorScale`; the background, which the default glyph, the area-chart band, the line-chart gradient stops, the heatmap's fill scale and contrast math (with `track`, the empty-cell color), and `GeoChart` each consume as a concrete string; and, for the pie chart and the heatmap, `label` and `label-inverse` against the resolved fill, to pick which one contrasts more (or black or white, when neither reaches AA) before painting the label.
|
|
60
60
|
|
|
61
61
|
**The tooltip used to be the one painted exception, because visx painted it outside the scope.** `@visx/tooltip` appends each portal container straight to `document.body`, where the catalog is not declared, so a chain handed to one reached only its own hardcoded fallback — never the role, never a consumer's override. Charts no longer take that route: the box renders into the chart's own wrapper and the crosshairs and glyphs are drawn into the chart SVG, both inside the scope, so a chain handed to either resolves there natively.
|
|
62
62
|
|
|
63
|
-
|
|
63
|
+
One tooltip color is still resolved before visx sees it: the crosshair stroke, in `XYChartTooltip`, which only still matters where a consumer supplies a `ChartScopeContext` element that is not one of the chart's own ancestors; in the ordinary tree the CSS path now reaches it.
|
|
64
64
|
|
|
65
|
-
Being resolved in JS,
|
|
65
|
+
Being resolved in JS, it then carries the bridge's limitations rather than the CSS path's: it reads at the scope element, so a role declared on the chart's own class moves the gridlines but leaves the crosshair at the catalog value, and it does not repaint on a theme change until something re-renders.
|
|
66
66
|
|
|
67
67
|
Where a value is *consumed* says nothing about where it is *set*. These are set the same way as every other catalog color — `--a8c-charts-color-background`, `--a8c-charts-color-series-*` — and resolved through `getComputedStyle` against the chart's own scope element, never `document.documentElement`, so both delivery paths obey the same cascade. Each pointer carries a terminal literal (`var(--a8c-charts-color-background, #fff)`) as the last resort for SSR and jsdom, where `getComputedStyle` resolves nothing.
|
|
68
68
|
|
|
@@ -95,10 +95,12 @@ The scope element is the wrapper a chart is rendered into, which sits **above**
|
|
|
95
95
|
| `--a8c-charts-color-surface` | `--wpds-color-background-surface-neutral-strong` | `#fff` |
|
|
96
96
|
| `--a8c-charts-color-surface-secondary` | `--wpds-color-background-surface-neutral-weak` | `#f4f4f4` |
|
|
97
97
|
| `--a8c-charts-color-track` | `--wpds-color-background-track-neutral-weak` | `#f0f0f0` |
|
|
98
|
-
| `--a8c-charts-color-tooltip-surface` | _(none
|
|
98
|
+
| `--a8c-charts-color-tooltip-surface` | _(none: WPDS has no inverted surface token yet)_ | `#1e1e1e` |
|
|
99
99
|
|
|
100
100
|
The x axis and tick roles share grid's WPDS token but stay distinct roles, so the three can be themed independently.
|
|
101
101
|
|
|
102
|
+
`--a8c-charts-color-tooltip-surface` is the color the tooltip theme is generated from, as `@wordpress/ui` seeds its Tooltip popup with `#1e1e1e`. Set it on the provider wrapper to retheme every tooltip, light or dark: the box surface, its text, every catalog role and every `--wpds-*` token inside follow. It must be an opaque sRGB color; anything else falls back to `#1e1e1e`. To recolor one chart's tooltip, repoint `--a8c-charts-color-surface` and `--a8c-charts-color-label` in that chart's `tooltipStyle`. That moves only those two roles: content that reads a `--wpds-*` token keeps the dark theme's value.
|
|
103
|
+
|
|
102
104
|
### One pair of roles per axis
|
|
103
105
|
|
|
104
106
|
Each axis names itself: `--a8c-charts-color-axis-x` / `-tick-x` paint the x axis, `--a8c-charts-color-axis-y` / `-tick-y` the y. The y pair resolves to `none`, so by default that axis carries tick labels and nothing else. Declare either to paint it:
|
|
@@ -145,6 +147,7 @@ The palette is resolved per provider, so one `ColorCache` and one group-to-color
|
|
|
145
147
|
| `--a8c-charts-motion-duration-entrance` | `--wpds-motion-duration-xl` | `400ms` |
|
|
146
148
|
| `--a8c-charts-motion-easing-entrance` | `--wpds-motion-easing-expressive` | `cubic-bezier(0.25, 0, 0, 1)` |
|
|
147
149
|
| `--a8c-charts-border-radius-bar` | `--wpds-border-radius-md` | `4px` |
|
|
150
|
+
| `--a8c-charts-border-radius-bar-chart` | _(none — square bars by default)_ | `0` |
|
|
148
151
|
| `--a8c-charts-border-radius-cell` | `--wpds-border-radius-sm` | `2px` |
|
|
149
152
|
| `--a8c-charts-border-radius-leaderboard-bar` | _(none — pill shape, no WPDS radius fits)_ | `9999px` |
|
|
150
153
|
| `--a8c-charts-dimension-leaderboard-row-gap` | `--wpds-dimension-gap-md` | `12px` |
|
|
@@ -154,6 +157,8 @@ The palette is resolved per provider, so one `ColorCache` and one group-to-color
|
|
|
154
157
|
|
|
155
158
|
The motion pair carries the one-shot reveal a data mark plays on first paint, across all six charts that animate in. It deliberately does **not** cover interaction motion: hover and transition timings read `--wpds-motion-*` directly, as interface chrome rather than a chart role.
|
|
156
159
|
|
|
160
|
+
`--a8c-charts-border-radius-bar` rounds the conversion funnel's bars. `--a8c-charts-border-radius-bar-chart` rounds the bars of the bar chart and bar list chart; set it to a radius such as `var(--wpds-border-radius-sm)` to opt in. Bar charts apply it as the CSS `rx` property, so it rounds all four corners of a bar. It resolves in CSS at the bar, so an override set anywhere inside the provider tree applies, the chart's own class included; see [Precedence](#precedence) for overrides above the provider.
|
|
161
|
+
|
|
157
162
|
The elevation fallbacks hold the values their removed `--wpds-elevation-*` tokens used to resolve to, until a replacement exists.
|
|
158
163
|
|
|
159
164
|
## Tier 2 — component-specific variables
|