@automattic/charts 3.2.0 → 4.1.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 +47 -0
- package/SECURITY.md +1 -0
- package/TOKENS.md +53 -58
- package/dist/index.cjs +1483 -664
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +93 -29
- package/dist/index.d.cts +233 -247
- package/dist/index.d.ts +233 -247
- package/dist/index.js +1484 -667
- package/dist/index.js.map +1 -1
- package/package.json +7 -6
- package/src/charts/area-chart/area-chart.tsx +39 -25
- package/src/charts/area-chart/test/area-chart.test.tsx +4 -33
- package/src/charts/area-chart/test/tick-placement.test.tsx +55 -0
- package/src/charts/area-chart/test/tooltip-resolution-branches.test.tsx +86 -0
- package/src/charts/area-chart/test/tooltip-resolution.test.tsx +69 -0
- package/src/charts/area-chart/types.ts +4 -7
- package/src/charts/bar-chart/bar-chart.tsx +2 -1
- package/src/charts/bar-chart/private/test/use-bar-chart-options-formatting.test.tsx +69 -0
- package/src/charts/bar-chart/private/use-bar-chart-options.ts +27 -15
- package/src/charts/bar-list-chart/bar-list-chart.tsx +5 -0
- package/src/charts/conversion-funnel-chart/conversion-funnel-chart.module.scss +33 -23
- package/src/charts/conversion-funnel-chart/conversion-funnel-chart.tsx +138 -182
- package/src/charts/conversion-funnel-chart/test/conversion-funnel-chart.test.tsx +46 -0
- package/src/charts/geo-chart/geo-chart.module.scss +1 -0
- package/src/charts/geo-chart/geo-chart.tsx +5 -10
- package/src/charts/geo-chart/test/geo-chart.test.tsx +2 -2
- package/src/charts/heatmap-chart/heatmap-chart.module.scss +52 -16
- package/src/charts/heatmap-chart/heatmap-chart.tsx +89 -37
- package/src/charts/heatmap-chart/index.ts +2 -1
- package/src/charts/heatmap-chart/private/build-calendar-data.ts +126 -89
- package/src/charts/heatmap-chart/private/civil-day.ts +174 -0
- package/src/charts/heatmap-chart/private/heatmap-legend.tsx +11 -4
- package/src/charts/heatmap-chart/private/index.ts +1 -1
- package/src/charts/heatmap-chart/private/use-heatmap-colors.ts +5 -1
- package/src/charts/heatmap-chart/test/build-calendar-data.test.ts +3 -0
- package/src/charts/heatmap-chart/test/civil-day.test.ts +70 -0
- package/src/charts/heatmap-chart/test/heatmap-chart.test.tsx +142 -12
- package/src/charts/heatmap-chart/test/use-calendar-heatmap-data.test.tsx +118 -0
- package/src/charts/heatmap-chart/test/use-heatmap-colors.test.ts +8 -0
- package/src/charts/heatmap-chart/test/zoned-calendar-data.test.ts +248 -0
- package/src/charts/heatmap-chart/types.ts +8 -2
- package/src/charts/heatmap-chart/use-calendar-heatmap-data.ts +42 -0
- package/src/charts/leaderboard-chart/hooks/use-fitted-row-count.ts +2 -2
- package/src/charts/leaderboard-chart/hooks/use-leaderboard-legend-items.ts +3 -5
- package/src/charts/leaderboard-chart/leaderboard-chart.module.scss +31 -19
- package/src/charts/leaderboard-chart/leaderboard-chart.tsx +27 -17
- package/src/charts/leaderboard-chart/test/leaderboard-chart.test.tsx +14 -0
- package/src/charts/leaderboard-chart/test/use-leaderboard-legend-items.test.tsx +2 -9
- package/src/charts/leaderboard-chart/types.ts +2 -2
- package/src/charts/line-chart/line-chart.module.scss +10 -18
- package/src/charts/line-chart/line-chart.tsx +128 -26
- package/src/charts/line-chart/private/line-chart-annotation.tsx +18 -19
- package/src/charts/line-chart/test/crosshair-style-types.test.ts +31 -0
- package/src/charts/line-chart/test/default-tooltip-formatting.test.tsx +74 -0
- package/src/charts/line-chart/test/line-chart.test.tsx +174 -41
- package/src/charts/line-chart/test/tick-placement.test.tsx +84 -0
- package/src/charts/line-chart/test/tooltip-resolution.test.tsx +140 -0
- package/src/charts/line-chart/test/zoned-date-string.test.tsx +37 -0
- package/src/charts/line-chart/types.ts +17 -3
- package/src/charts/pie-chart/pie-chart.module.scss +13 -1
- package/src/charts/pie-chart/pie-chart.tsx +30 -40
- package/src/charts/pie-chart/test/pie-chart.test.tsx +59 -12
- package/src/charts/pie-semi-circle-chart/pie-semi-circle-chart.module.scss +8 -3
- package/src/charts/pie-semi-circle-chart/pie-semi-circle-chart.tsx +23 -37
- package/src/charts/pie-semi-circle-chart/test/pie-semi-circle-chart.test.tsx +50 -0
- package/src/charts/private/chart-layout/chart-layout.module.scss +3 -2
- package/src/charts/private/svg-empty-state/svg-empty-state.module.scss +1 -1
- package/src/charts/private/test/axis-formatting.test.tsx +85 -0
- package/src/charts/private/test/time-axis-formatting.test.ts +109 -0
- package/src/charts/private/test/time-axis-options.test.ts +267 -0
- package/src/charts/private/test/time-axis-tick-invariants.test.ts +153 -0
- package/src/charts/private/test/time-axis-tick-values.test.ts +280 -0
- package/src/charts/private/test/time-axis.test.ts +9 -69
- package/src/charts/private/time-axis-options.ts +106 -0
- package/src/charts/private/time-axis.ts +318 -136
- package/src/charts/private/x-zoom/x-zoom.module.scss +3 -3
- package/src/charts/private/xy-plot/xy-plot.module.scss +8 -0
- package/src/charts/sparkline/test/sparkline.test.tsx +29 -56
- package/src/charts/sparkline/types.ts +1 -1
- package/src/components/legend/private/base-legend.module.scss +9 -5
- package/src/components/tooltip/accessible-tooltip.tsx +21 -17
- package/src/components/tooltip/base-tooltip.module.scss +3 -3
- package/src/components/tooltip/private/bounded-tooltip.tsx +227 -0
- package/src/components/tooltip/test/accessible-tooltip.test.tsx +30 -4
- package/src/components/tooltip/test/bounded-tooltip.test.tsx +225 -0
- package/src/components/tooltip/test/xy-chart-tooltip.test.tsx +379 -0
- package/src/components/tooltip/xy-chart-tooltip.tsx +326 -0
- package/src/components/trend-indicator/trend-indicator.module.scss +2 -2
- package/src/hooks/test/use-chart-data-transform-zone.test.tsx +36 -0
- package/src/hooks/test/use-chart-margin.test.tsx +173 -3
- package/src/hooks/test/use-xychart-theme.test.tsx +16 -3
- package/src/hooks/use-chart-data-transform.ts +10 -3
- package/src/hooks/use-chart-margin.tsx +54 -9
- package/src/hooks/use-xychart-theme.ts +25 -9
- package/src/index.ts +8 -0
- package/src/providers/chart-context/global-charts-provider.tsx +37 -38
- package/src/providers/chart-context/hooks/use-chart-formatting.ts +22 -0
- package/src/providers/chart-context/index.ts +1 -0
- package/src/providers/chart-context/private/catalog-pointers.ts +42 -0
- package/src/providers/chart-context/private/series-palette.ts +3 -13
- package/src/providers/chart-context/test/{sparse-theme.test.ts → catalog-pointers.test.ts} +22 -10
- package/src/providers/chart-context/test/chart-context.test.tsx +177 -792
- package/src/providers/chart-context/test/use-global-charts-theme.test.tsx +7 -25
- package/src/providers/chart-context/themes.ts +7 -52
- package/src/providers/chart-context/types.ts +3 -0
- package/src/styles/chart-scope.scss +39 -62
- package/src/styles/test/chart-scope.test.ts +19 -47
- package/src/test-utils/series-fixtures.ts +31 -0
- package/src/test-utils/zoned-parsing-suite.ts +90 -0
- package/src/types.ts +79 -166
- package/src/utils/bucket-info.ts +87 -0
- package/src/utils/color-utils.ts +0 -27
- package/src/utils/date-formatting.ts +157 -0
- package/src/utils/date-parsing.ts +103 -52
- package/src/utils/get-edge-tick-widths.ts +33 -0
- package/src/utils/index.ts +4 -0
- package/src/utils/test/bucket-info.test.ts +185 -0
- package/src/utils/test/color-utils.test.ts +1 -48
- package/src/utils/test/date-formatting.test.ts +89 -0
- package/src/utils/test/date-parsing.auckland.test.ts +6 -0
- package/src/utils/test/date-parsing.santiago.test.ts +6 -0
- package/src/utils/test/date-parsing.test.ts +16 -1
- package/src/utils/test/get-edge-tick-widths.test.ts +55 -0
- package/src/utils/test/get-styles.test.ts +10 -7
- package/src/utils/test/merge-themes.test.ts +18 -46
- package/src/utils/warn-once.ts +23 -0
- package/src/visx/types.ts +56 -5
- package/src/hooks/test/use-xychart-theme-provider-override.test.tsx +0 -28
- package/src/providers/chart-context/private/theme-override-vars.ts +0 -131
- package/src/providers/chart-context/private/with-catalog-pointers.ts +0 -93
- package/src/providers/chart-context/test/theme-override-vars-guard.test.tsx +0 -29
- package/src/providers/chart-context/test/theme-override-vars.test.ts +0 -183
- package/src/providers/chart-context/test/with-catalog-pointers.test.ts +0 -104
- package/src/styles/test/wpds-fallbacks.test.ts +0 -131
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,51 @@ 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.1.0] - 2026-09-14
|
|
9
|
+
### Added
|
|
10
|
+
- Heatmap: add `locale` and `timeZone` options and a `useCalendarHeatmapData` hook, so a host can bucket and label the calendar in its own zone and language instead of the viewer's. Labels with no `locale` now follow the runtime locale rather than always rendering in English, and a calendar `dateString` must start `yyyy-MM-dd`. [#52114]
|
|
11
|
+
- HeatmapChart: Add summary columns, per-row roll-ups drawn outside the color scale. [#52135]
|
|
12
|
+
- Line chart: Add options to place tooltips below the x-axis label band and customize tooltip and crosshair styles. [#52143]
|
|
13
|
+
|
|
14
|
+
### Changed
|
|
15
|
+
- AccessibleTooltip: Merge supplied styles with the default box styles instead of replacing them; use unstyled to remove the box styles. [#52143]
|
|
16
|
+
- LeaderboardChart: Let valueFormatter return a React node, so a value can carry a tooltip. [#52177]
|
|
17
|
+
- Line chart: Keep the page from scrolling when keyboard focus moves to a below-axis tooltip. [#52143]
|
|
18
|
+
|
|
19
|
+
### Fixed
|
|
20
|
+
- Flip the tooltip to the side of the anchor that stays inside the chart wrapper, so a box that fits in the chart no longer reaches past it into page content that paints over it. [#52123]
|
|
21
|
+
- HeatmapChart: Fix an endless re-render when the keyboard tooltip opens on a chart without row labels. [#52135]
|
|
22
|
+
- LineChart, AreaChart, BarChart: Date a naive dateString point in the provider's time zone, so every viewer reads the same day. [#52113]
|
|
23
|
+
- Reserve room for the first and last labels on a time axis, size the y-axis gutter from a pinned domain, and reserve nothing for a hidden y axis. [#52112]
|
|
24
|
+
|
|
25
|
+
## [4.0.0] - 2026-09-04
|
|
26
|
+
### Changed
|
|
27
|
+
- Inject WPDS design-token fallbacks at build time via @wordpress/theme's LightningCSS plugin. [#51722]
|
|
28
|
+
- Render chart tooltips inside the chart instead of a document.body portal, so they stack correctly under sticky and fixed page elements. `detectBounds` now keeps the box inside the nearest ancestor that clips its overflow, or the viewport. The tooltip's `scroll`, `debounce` and `resizeObserverPolyfill` options are deprecated and ignored. [#51640]
|
|
29
|
+
- Render time-axis and tooltip dates in a host-supplied locale and time zone, set on GlobalChartsProvider. Both default to the browser's, as before. [#51812]
|
|
30
|
+
- Update package dependencies. [#51701]
|
|
31
|
+
|
|
32
|
+
### Removed
|
|
33
|
+
- Remove every color field from the chart theme. Set the matching `--a8c-charts-color-*` custom property inside the provider tree instead — every removed field named one, and they were deprecated in the previous release. `TOKENS.md` lists the catalog. `LeaderboardChart`'s `primaryColor` and `secondaryColor` props and `HeatmapChart`'s `primaryColor` prop are unaffected, and a single annotation still takes colors through its own `styles` prop.
|
|
34
|
+
|
|
35
|
+
Remove `gridColor` and `gridColorDark`, which were undocumented visx passthroughs. `gridColor` painted the y axis line and y tick marks, which no other field could reach. Add `--a8c-charts-color-axis-y` and `--a8c-charts-color-tick-y` to replace it: both resolve to `none`, so the y axis still carries labels only by default, and a chart that wants a painted y axis declares them.
|
|
36
|
+
|
|
37
|
+
Rename `--a8c-charts-color-axis` to `--a8c-charts-color-axis-x` and `--a8c-charts-color-tick` to `--a8c-charts-color-tick-x`. Both only ever painted the x axis; now that the y axis has roles of its own, the names say which one they move.
|
|
38
|
+
|
|
39
|
+
Add `leaderboard-chart`, `conversion-funnel-chart` and `bar-list-chart` classes to those charts' roots, and add the `pie-semi-circle-chart` class to that chart's error state, which was missing it. This matches the `bar-chart`, `line-chart` and `pie-chart` classes the other charts already carry, and gives a consumer somewhere to scope a role to one chart — which matters for a role more than one chart reads, since `--a8c-charts-color-surface-secondary` paints the funnel's track and `GeoChart`'s dataless regions, and the trend pair paints the funnel's change indicator and the leaderboard's deltas.
|
|
40
|
+
|
|
41
|
+
`BarListChart` and `PieSemiCircleChart`'s error state now also pass a caller's own `className` through, which they previously dropped.
|
|
42
|
+
|
|
43
|
+
Remove `--a8c-charts-color-label-on-fill`. Set `--a8c-charts-color-label-inverse` instead: both meant label text on a filled surface, and one role covers the pie segment labels and the heatmap cell values together. Pie labels follow that role's `--wpds-color-foreground-interactive-neutral-strong` mapping now, so they are off-white rather than pure white until a consumer sets the role.
|
|
44
|
+
|
|
45
|
+
Remove `theme.leaderboardChart.rowGap` and `.columnGap`. Declare `--a8c-charts-dimension-leaderboard-row-gap` or `--a8c-charts-dimension-leaderboard-column-gap` inside the provider tree instead; they map to `--wpds-dimension-gap-md` and `--wpds-dimension-gap-xs`, so the default spacing follows the design system. `TOKENS.md` lists both roles.
|
|
46
|
+
|
|
47
|
+
Remove the two remaining deprecated APIs, so this major carries every removal at once rather than spending a second one later. `AreaChart`'s `rescaleYOnLegendToggle` prop goes — use `rescaleYOnVisibilityChange`, which is the same setting under a name that matches when it applies. The `parseRgbString` helper goes — use `normalizeColorToHex`, which handles `rgb()` alongside every other format. [#51748]
|
|
48
|
+
|
|
49
|
+
### Fixed
|
|
50
|
+
- Place line and area chart date ticks on the host time zone's calendar boundaries, name the hour in tooltips on hourly data, let the locale rather than a forced 12-hour clock choose how every chart's hour labels read, and hand a custom tooltip the chart's date bucket classification. [#51813]
|
|
51
|
+
- Tooltip: Keep the drop shadow when `--a8c-charts-color-label-axis` resolves to something other than a 6-digit hex. visx appends an alpha suffix to that color to build the shadow, which only parses after a hex, so an `rgb()` or `hsl()` value silently dropped the shadow entirely. [#51748]
|
|
52
|
+
|
|
8
53
|
## [3.2.0] - 2026-09-01
|
|
9
54
|
### Added
|
|
10
55
|
- Bar and line charts: Report a click through the pointer event handlers and Enter or Space through an activation callback, so a chart can open the point under the pointer or the keyboard selection. [#51544]
|
|
@@ -1018,6 +1063,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
1018
1063
|
- Fixed lints following ESLint rule changes for TS [#40584]
|
|
1019
1064
|
- Fixing a bug in Chart storybook data. [#40640]
|
|
1020
1065
|
|
|
1066
|
+
[4.1.0]: https://github.com/Automattic/charts/compare/v4.0.0...v4.1.0
|
|
1067
|
+
[4.0.0]: https://github.com/Automattic/charts/compare/v3.2.0...v4.0.0
|
|
1021
1068
|
[3.2.0]: https://github.com/Automattic/charts/compare/v3.1.1...v3.2.0
|
|
1022
1069
|
[3.1.1]: https://github.com/Automattic/charts/compare/v3.1.0...v3.1.1
|
|
1023
1070
|
[3.1.0]: https://github.com/Automattic/charts/compare/v3.0.0...v3.1.0
|
package/SECURITY.md
CHANGED
|
@@ -16,6 +16,7 @@ Our HackerOne program covers the below plugin software, as well as a variety of
|
|
|
16
16
|
* Jetpack Protect
|
|
17
17
|
* Jetpack Search
|
|
18
18
|
* Jetpack Social
|
|
19
|
+
* Jetpack Stats
|
|
19
20
|
* Jetpack VideoPress
|
|
20
21
|
|
|
21
22
|
**For responsible disclosure of security issues and to be eligible for our bug bounty program, please submit your report via the [HackerOne](https://hackerone.com/automattic) portal.**
|
package/TOKENS.md
CHANGED
|
@@ -8,15 +8,15 @@
|
|
|
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
|
+
Tooltips render inside the chart, so they carry the class only when no provider is above them, the same as `TrendIndicator`, `BaseTooltip` and `BaseLegend` (`useStandaloneScopeClass()`).
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
Inside a provider a tooltip therefore inherits the provider's inline `theme` var and any consumer rule scoped to the provider wrapper, the same as the chart it belongs to.
|
|
14
14
|
|
|
15
|
-
Each catalog entry maps to a WPDS token
|
|
15
|
+
Each catalog entry maps to a WPDS token. Source writes the mapping bare; the LightningCSS plugin in `tsdown.config.ts` injects the WPDS spec value as a fallback into `dist/`:
|
|
16
16
|
|
|
17
17
|
```scss
|
|
18
18
|
:where(.a8c-charts-scope) {
|
|
19
|
-
--a8c-charts-color-grid: var(--wpds-color-stroke-surface-neutral
|
|
19
|
+
--a8c-charts-color-grid: var(--wpds-color-stroke-surface-neutral);
|
|
20
20
|
}
|
|
21
21
|
```
|
|
22
22
|
|
|
@@ -28,62 +28,43 @@ Highest first:
|
|
|
28
28
|
|
|
29
29
|
1. The role set on any element between the chart and the provider — the closest declaration wins. A role set on the chart's *own* element reaches only what CSS paints; see "The SVG bridge".
|
|
30
30
|
2. The role set by a consumer rule targeting the provider wrapper. It beats the catalog default because `:where()` is zero-specificity.
|
|
31
|
-
3. The
|
|
32
|
-
4. The
|
|
33
|
-
5. The WPDS spec-value fallback, when no `--wpds-*` token is set either (SSR, jsdom, or WPDS not loaded). This is not a rare corner: WordPress itself defines no `--wpds-*` typography tokens, so in wp-admin the fallback is what renders. It is written by hand — see `src/styles/test/wpds-fallbacks.test.ts`, which checks each one against the installed `@wordpress/theme`.
|
|
31
|
+
3. The catalog default on the provider wrapper, resolving the mapped `--wpds-*` token.
|
|
32
|
+
4. The WPDS spec-value fallback, when no `--wpds-*` token is set either (SSR, jsdom, or WPDS not loaded). This is not a rare corner: WordPress itself defines no `--wpds-*` typography tokens, so in wp-admin the fallback is what renders. It is injected at build time by `@wordpress/theme`'s LightningCSS plugin.
|
|
34
33
|
|
|
35
|
-
|
|
34
|
+
Configure catalog colors through CSS; the `theme` prop carries no colors. For local LineChart tooltip overrides, see [Below-Axis Tooltips](./?path=/docs/js-packages-charts-library-charts-line-chart--docs#below-axis-tooltips).
|
|
36
35
|
|
|
37
|
-
An override set **above** `GlobalChartsProvider` does not apply: the provider's own declaration on its wrapper beats a value merely inherited from an ancestor. Set overrides inside the provider tree, or target the scope class itself — `.a8c-charts-scope { --a8c-charts-color-grid: #e0e0e0; }` matches every provider wrapper on the page, including the one a bare chart mounts for itself
|
|
36
|
+
An override set **above** `GlobalChartsProvider` does not apply: the provider's own declaration on its wrapper beats a value merely inherited from an ancestor. Set overrides inside the provider tree, or target the scope class itself — `.a8c-charts-scope { --a8c-charts-color-grid: #e0e0e0; }` matches every provider wrapper on the page, including the one a bare chart mounts for itself, and outranks the zero-specificity catalog default. That rule is the replacement for a page-level `:root` override. The same rule limits `@wordpress/theme`'s `ThemeProvider` to *above* the charts provider: the catalog substitutes its `--wpds-*` tokens at the wrapper, so a `ThemeProvider` mounted between the wrapper and a chart is never consulted and CSS-painted colors keep their light-mode spec fallbacks. The JS-consumed ones do not — `getElementStyles` resolves at the chart element — so that nesting shows up as a chart whose series marks retint while its gridlines, axis and surfaces do not.
|
|
38
37
|
|
|
39
|
-
####
|
|
38
|
+
#### Broad roles and narrow ones
|
|
40
39
|
|
|
41
|
-
|
|
40
|
+
Some roles are deliberately narrower than the obvious name, so that moving one thing does not move four:
|
|
42
41
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
`GlobalChartsProvider` writes `--a8c-charts-color-grid-theme` inline from `theme.gridStyles.stroke`. Publishing the consumer's value one layer out is what keeps the catalog default reachable: a value that is invalid at computed-value time — `var(--wpds-color-stroke-surface-neutral)` with no fallback, in a host that never loaded the WPDS stylesheet — invalidates only the theme layer, and the role still resolves its mapped token. Written as the role itself, that same value made the role guaranteed-invalid, and that propagates to every bare `var(--a8c-charts-color-grid)` read site: `stroke` computed to `unset`, so the gridlines disappeared rather than degrading to the spec grey.
|
|
50
|
-
|
|
51
|
-
A value that reads the role it would override is not published at all. The role reads its theme layer, so such a value closes a cycle through the catalog entry, and CSS marks *every* custom property in a cycle invalid — the role's own fallback is not used, and the token resolves to nothing. `withCatalogPointers` restores the theme field to the catalog pointer whether or not the value was published, so visx never paints a literal the CSS side cannot see.
|
|
52
|
-
|
|
53
|
-
`src/styles/test/chart-scope.test.ts` pins which roles carry the layer, from the same list the provider maps fields with.
|
|
54
|
-
|
|
55
|
-
#### A `theme`-prop override keeps the reach of the field it was set from
|
|
56
|
-
|
|
57
|
-
A role is a shared name, so publishing an override as a custom property could widen it — `theme={ { svgLabelSmall: { fill: 'purple' } } }` recoloring legend labels, heatmap cell values, funnel labels and the line-chart tooltip along with the SVG axis labels it names.
|
|
58
|
-
|
|
59
|
-
It doesn't, because a mapped field publishes a role read by exactly the elements that field already controlled. Where the obvious role has wider readership, one side or the other gets a role of its own:
|
|
60
|
-
|
|
61
|
-
| Theme field | Publishes | Kept off it | How |
|
|
62
|
-
|---|---|---|---|
|
|
63
|
-
| `svgLabelSmall.fill` | `--a8c-charts-color-label-axis` | legend labels, `.heatmap-chart__cell-value`, funnel labels, the line-chart tooltip | the field takes a narrow role deriving from `--a8c-charts-color-label` |
|
|
64
|
-
| `backgroundColor` | `--a8c-charts-color-background` | the annotation label, `.x-zoom__reset`, tooltips | those readers take `--a8c-charts-color-surface` instead |
|
|
65
|
-
|
|
66
|
-
**The two are shaped differently, and the difference is load-bearing.** `--a8c-charts-color-label-axis` *derives* from `--a8c-charts-color-label`: the theme field publishes the narrow role, so the broad one stays free as a move-every-label knob. `--a8c-charts-color-surface` is a **sibling** of `--a8c-charts-color-background`, not a child — there the theme field publishes the broad role, so deriving would hand the override straight back to the surfaces it is meant to spare. Deriving is only safe when the narrow role is the one the `theme` prop writes.
|
|
42
|
+
| Narrow role | Broad role | What the broad one also reaches |
|
|
43
|
+
|---|---|---|
|
|
44
|
+
| `--a8c-charts-color-label-axis` | `--a8c-charts-color-label` | legend labels, `.heatmap-chart__cell-value`, funnel labels, the line-chart tooltip |
|
|
45
|
+
| `--a8c-charts-color-background` | — | — |
|
|
67
46
|
|
|
68
|
-
|
|
47
|
+
`--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.
|
|
69
48
|
|
|
70
|
-
`
|
|
49
|
+
`--a8c-charts-color-surface` — the annotation label, `.x-zoom__reset`, tooltips — 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.
|
|
71
50
|
|
|
72
51
|
### The SVG bridge
|
|
73
52
|
|
|
74
|
-
**A color that is only painted is not resolved at all.** The grid, axis line, tick marks and tick labels
|
|
53
|
+
**A color that is only painted is not resolved at all.** The grid, axis line, tick marks and tick labels reach visx as the `var(--a8c-charts-color-*, …)` chain `private/catalog-pointers.ts` holds: `useXYChartTheme` puts the chain into the theme it builds, `buildChartTheme` passes it on, and visx writes it onto the element it paints — an inline style for the grid, a presentation attribute elsewhere. A presentation attribute is mapped to a CSS declaration, so the chain resolves there natively, in Blink, WebKit and Gecko alike.
|
|
75
54
|
|
|
76
55
|
That is what makes the role read **at the painted element** rather than snapshot at the provider wrapper: an override on a chart's own class reaches it, a theme change repaints with no re-render, and SSR emits the chain for the client to resolve on paint. Resolving such a color in JS would freeze it and undo all three, which is why nothing does.
|
|
77
56
|
|
|
78
|
-
There is no stylesheet and no class involved. In particular the axes need neither:
|
|
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.
|
|
79
58
|
|
|
80
59
|
What else crosses in JS is what something reads as a *value*: the series palette, which visx turns into its `colorScale`, and 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.
|
|
81
60
|
|
|
82
|
-
**The tooltip
|
|
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
|
+
|
|
63
|
+
Two colors are still resolved before visx sees them. `htmlLabel.color`, in `useXYChartTheme`, for a reason the move does not touch: visx builds the tooltip's shadow as `` `0 1px 2px ${color}55` ``, and a `var()` chain cannot take a suffix — token streams do not merge across a substitution boundary, so the whole declaration is invalid and the tooltip renders flat. The crosshair stroke, in `AccessibleTooltip`, 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.
|
|
83
64
|
|
|
84
65
|
Being resolved in JS, both then carry the bridge's limitations rather than the CSS path's: they read 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 neither repaints on a theme change until something re-renders.
|
|
85
66
|
|
|
86
|
-
|
|
67
|
+
Where a value is *consumed* says nothing about where it is *set*. These are set the same way as every other 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.
|
|
87
68
|
|
|
88
69
|
The scope element is the wrapper a chart is rendered into, which sits **above** the element the chart's own `className` lands on, so a role declared on that inner element is invisible to the JS bridge. `.line-chart { --a8c-charts-color-background: red }` therefore does not reach the glyph strokes, while `.line-chart { --a8c-charts-color-grid: red }` does reach the gridlines — the CSS-painted roles read at the painted element, so any ancestor of it will do. Scope a rule for a JS-resolved role to a wrapper around the chart rather than to the chart itself. CHARTS-255 tracks closing the remainder.
|
|
89
70
|
|
|
@@ -96,17 +77,14 @@ The scope element is the wrapper a chart is rendered into, which sits **above**
|
|
|
96
77
|
| Role | Maps to | Fallback |
|
|
97
78
|
|---|---|---|
|
|
98
79
|
| `--a8c-charts-color-series-1` | `--wp-admin-theme-color` | `var(--wpds-color-foreground-interactive-brand, var(--wp-admin-theme-color, #3858e9))` |
|
|
99
|
-
| `--a8c-charts-color-series-2` | _(none — unset until a consumer sets it)_ | — |
|
|
100
|
-
| `--a8c-charts-color-series-3` | _(none — unset until a consumer sets it)_ | — |
|
|
101
|
-
| `--a8c-charts-color-series-4` | _(none — unset until a consumer sets it)_ | — |
|
|
102
|
-
| `--a8c-charts-color-series-5` | _(none — unset until a consumer sets it)_ | — |
|
|
103
80
|
| `--a8c-charts-color-grid` | `--wpds-color-stroke-surface-neutral` | `#dbdbdb` |
|
|
104
|
-
| `--a8c-charts-color-axis` | `--wpds-color-stroke-surface-neutral` | `#dbdbdb` |
|
|
105
|
-
| `--a8c-charts-color-tick` | `--wpds-color-stroke-surface-neutral` | `#dbdbdb` |
|
|
81
|
+
| `--a8c-charts-color-axis-x` | `--wpds-color-stroke-surface-neutral` | `#dbdbdb` |
|
|
82
|
+
| `--a8c-charts-color-tick-x` | `--wpds-color-stroke-surface-neutral` | `#dbdbdb` |
|
|
83
|
+
| `--a8c-charts-color-axis-y` | _(none — unpainted unless a consumer sets it)_ | `none` |
|
|
84
|
+
| `--a8c-charts-color-tick-y` | _(none — unpainted unless a consumer sets it)_ | `none` |
|
|
106
85
|
| `--a8c-charts-color-label` | `--wpds-color-foreground-content-neutral` | `#1e1e1e` |
|
|
107
86
|
| `--a8c-charts-color-label-secondary` | `--wpds-color-foreground-content-neutral-weak` | `#707070` |
|
|
108
87
|
| `--a8c-charts-color-label-inverse` | `--wpds-color-foreground-interactive-neutral-strong` | `#f0f0f0` |
|
|
109
|
-
| `--a8c-charts-color-label-on-fill` | _(none — white-on-series-fill, no WPDS fit)_ | `#fff` |
|
|
110
88
|
| `--a8c-charts-color-label-background` | _(none — transparent by default, no WPDS fit)_ | `transparent` |
|
|
111
89
|
| `--a8c-charts-color-label-axis` | _(derives from `--a8c-charts-color-label`)_ | — |
|
|
112
90
|
| `--a8c-charts-color-annotation` | `--wpds-color-foreground-content-neutral` | `#1e1e1e` |
|
|
@@ -119,13 +97,32 @@ The scope element is the wrapper a chart is rendered into, which sits **above**
|
|
|
119
97
|
| `--a8c-charts-color-track` | `--wpds-color-background-track-neutral-weak` | `#f0f0f0` |
|
|
120
98
|
| `--a8c-charts-color-tooltip-surface` | _(none — translucent dark surface, no WPDS fit)_ | `rgb(0 0 0 / 85%)` |
|
|
121
99
|
|
|
122
|
-
|
|
100
|
+
The x axis and tick roles share grid's WPDS token but stay distinct roles, so the three can be themed independently.
|
|
101
|
+
|
|
102
|
+
### One pair of roles per axis
|
|
103
|
+
|
|
104
|
+
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:
|
|
105
|
+
|
|
106
|
+
```css
|
|
107
|
+
.my-dashboard {
|
|
108
|
+
--a8c-charts-color-axis-y: #dbdbdb;
|
|
109
|
+
--a8c-charts-color-tick-y: #dbdbdb;
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
**There is deliberately no broad `--a8c-charts-color-axis` covering both.** It would have to mean one of two things, and neither is true: that setting it moves both axes — which cannot hold while the y side defaults to unpainted — or that it moves only x, which is a name that misleads exactly once per consumer, and silently. The tick *labels* are a different matter and do share a role (`--a8c-charts-color-label-axis`), because both axes label identically.
|
|
114
|
+
|
|
115
|
+
Gridlines also stay on one role, `--a8c-charts-color-grid`: visx paints rows and columns from a single style object, so the grid is genuinely one thing rather than two.
|
|
116
|
+
|
|
117
|
+
The terminal `none` in each chain is explicit rather than load-bearing: `stroke` already starts at `none`, so an undeclared role paints nothing either way.
|
|
118
|
+
|
|
119
|
+
**It would be load-bearing on a `fill`.** A `var()` naming an undeclared property with no fallback is invalid at computed-value time, which drops the declaration rather than leaving it absent — and `fill` starts at *black*. That is why `--a8c-charts-color-label-background` carries a terminal `transparent`: without it, an undeclared role would put a black plate behind every pie label. Give any role read by a `fill` a terminal literal, even when the intent is "paint nothing".
|
|
123
120
|
|
|
124
121
|
### The series palette
|
|
125
122
|
|
|
126
123
|
The five `--a8c-charts-color-series-*` slots are the palette. `GlobalChartsProvider` resolves them once, at its wrapper, and seeds its color cache with whatever resolves; charts generate accessible colors beyond the seeds, so five slots is a cap on *seeds*, not on series. A slot that resolves to nothing is skipped and the palette compacts — set only slots 1 and 3 and the palette is two colors, in that order.
|
|
127
124
|
|
|
128
|
-
Only slot 1
|
|
125
|
+
Only slot 1 is declared in the catalog, and it names `--wp-admin-theme-color` first, so series colors follow the WordPress admin color scheme with no host configuration. Slots 2 to 5 are names a consumer can declare, nothing more — the catalog leaves them undeclared so an unset slot resolves to nothing and compacts out, rather than repeating a color nobody chose.
|
|
129
126
|
|
|
130
127
|
The design system's brand token is the next leg rather than the first, because it only reaches the admin color scheme when a WPDS **root provider** is on the page. Measured on a live WordPress 7.1 wp-admin dashboard, `<html data-wpds-root-provider>` carries the whole generated ramp inline, derived from `--wp-admin-theme-color`. Where no root provider boots, the token falls back to the plain stylesheet rule — a static `#3858e9` with no reference to the admin color. So on WP 7.1 either order happens to work; everywhere else (WP 7.0.x, a page without a root provider, Calypso, SSR) only this one does.
|
|
131
128
|
|
|
@@ -135,12 +132,9 @@ Precedence for a series color, highest first:
|
|
|
135
132
|
|
|
136
133
|
1. `options.stroke` on that series, resolved at the chart element. This is the per-series override.
|
|
137
134
|
2. A CSS declaration of `--a8c-charts-color-series-N`, on the usual catalog rules above.
|
|
138
|
-
3.
|
|
139
|
-
4. The catalog default, which exists only for slot 1.
|
|
140
|
-
|
|
141
|
-
The palette is resolved per provider, so one `ColorCache` and one group-to-color map serve every chart under it and siblings agree on what a group is colored. The consequence is that a slot set on a *chart's own* element does not apply — the palette was resolved at the provider wrapper before that element existed. Use `options.stroke` for a per-chart color.
|
|
135
|
+
3. The catalog default, which exists only for slot 1.
|
|
142
136
|
|
|
143
|
-
`
|
|
137
|
+
The palette is resolved per provider, so one `ColorCache` and one group-to-color map serve every chart under it and siblings agree on what a group is colored. Two consequences. A slot set on a *chart's own* element does not apply — the palette was resolved at the provider wrapper before that element existed; use `options.stroke` for a per-chart color. And the palette is read once, when the provider mounts, so a slot changed at runtime needs the provider to remount before it is seen.
|
|
144
138
|
|
|
145
139
|
## Non-color roles
|
|
146
140
|
|
|
@@ -151,6 +145,8 @@ The palette is resolved per provider, so one `ColorCache` and one group-to-color
|
|
|
151
145
|
| `--a8c-charts-border-radius-bar` | `--wpds-border-radius-md` | `4px` |
|
|
152
146
|
| `--a8c-charts-border-radius-cell` | `--wpds-border-radius-sm` | `2px` |
|
|
153
147
|
| `--a8c-charts-border-radius-leaderboard-bar` | _(none — pill shape, no WPDS radius fits)_ | `9999px` |
|
|
148
|
+
| `--a8c-charts-dimension-leaderboard-row-gap` | `--wpds-dimension-gap-md` | `12px` |
|
|
149
|
+
| `--a8c-charts-dimension-leaderboard-column-gap` | `--wpds-dimension-gap-xs` | `4px` |
|
|
154
150
|
| `--a8c-charts-elevation-xs` | _(none — `--wpds-elevation-*` removed in theme 1.0.0)_ | `0 1px 1px 0 #00000008, 0 1px 2px 0 #00000005, 0 3px 3px 0 #00000005, 0 4px 4px 0 #00000003` |
|
|
155
151
|
| `--a8c-charts-elevation-sm` | _(none — `--wpds-elevation-*` removed in theme 1.0.0)_ | `0 1px 2px 0 #0000000d, 0 2px 3px 0 #0000000a, 0 6px 6px 0 #00000008, 0 8px 8px 0 #00000005` |
|
|
156
152
|
|
|
@@ -175,7 +171,7 @@ The heatmap Tier-2 variables and `--a8c-charts-dimension-leaderboard-bar-hover-i
|
|
|
175
171
|
|
|
176
172
|
## Removed override variables
|
|
177
173
|
|
|
178
|
-
|
|
174
|
+
These names no longer resolve. Set the replacement instead:
|
|
179
175
|
|
|
180
176
|
| Removed | Set instead |
|
|
181
177
|
|---|---|
|
|
@@ -184,5 +180,4 @@ Every role in the catalog is a supported override point, on the precedence rules
|
|
|
184
180
|
| `--charts-trend-neutral-color` | `--a8c-charts-color-trend-neutral` |
|
|
185
181
|
| `--a8c--charts--leaderboard--bar--border-radius` | `--a8c-charts-border-radius-leaderboard-bar` |
|
|
186
182
|
| `--a8c-charts-color-focus` | `--wpds-color-stroke-focus` |
|
|
187
|
-
|
|
188
|
-
Removing the first four also removes a second name for a role, read at its component's own call site rather than through the catalog: each sat inside the role as its fallback — `var(--a8c-charts-*, var(--deprecated-name, …))` — so it applied only where the role itself was unset. No `--a8c-charts-*` role is now read anywhere but bare.
|
|
183
|
+
| `--a8c-charts-color-label-on-fill` | `--a8c-charts-color-label-inverse` |
|