Skip to content

Charts: Tokenize spacing and border values with WPDS dimension/border tokens#48019

Merged
adamwoodnz merged 9 commits intotrunkfrom
charts-199-spacingborder-tokenization
Apr 17, 2026
Merged

Charts: Tokenize spacing and border values with WPDS dimension/border tokens#48019
adamwoodnz merged 9 commits intotrunkfrom
charts-199-spacingborder-tokenization

Conversation

@adamwoodnz
Copy link
Copy Markdown
Contributor

@adamwoodnz adamwoodnz commented Apr 9, 2026

Fixes CHARTS-199

Proposed changes

  • Replace hardcoded spacing values (padding, margin, gap) in chart module SCSS with --wpds-dimension-padding-* and --wpds-dimension-gap-* design tokens.
  • Replace hardcoded border-radius: 4px values with --wpds-border-radius-md (note: WPDS border-radius-md = 4px; the suggested border-radius-sm in the Linear ticket is actually 2px).
  • Replace hardcoded 1px border width on the funnel tooltip wrapper with --wpds-border-width-xs.
  • Align fallbacks to the literal pixel values defined by the WPDS tokens (0.5rem8px, 1rem16px) so the rendered value doesn't depend on the document root font-size.
  • Eliminate hardcoded values that originally had no matching token by restructuring layout instead of leaving them as literals:
    • Funnel step-label 2px margin → wrap label and rate in a Stack with gap-xs (4px) and use line-height-xs on both. Bonus: drop redundant display: block/margin: 0/font-style: normal rules (flex items are auto-blockified) and add the missing white-space: nowrap so the label's existing text-overflow: ellipsis actually truncates.
    • Funnel empty-state 48px 24px padding → add align="center" justify="center" to the parent Stack so the message is centered both axes within the chart's resolved height (matching the SvgEmptyState pattern). The 48px literal (which had no token) goes away entirely.
    • Line-chart tooltip-date padding-bottom: 10px → tokenized to padding-md (12px), the closer of the two adjacent tokens (sm = 8px, md = 12px).
  • Token names verified against the authoritative source: node_modules/@wordpress/theme/src/prebuilt/css/design-tokens.css.

Intentionally untouched

  • Leaderboard row-gap: 6px — the leaderboard's bar rows use a compact bar + gap + bar rhythm (6px bar, 6px row-gap, 6px bar) that doesn't align to the WPDS dimension scale; the closest token (gap-sm = 8px) visibly breaks the balance. Documented inline as an outlier.
  • Leaderboard --a8c--charts--leaderboard--bar--border-radius — the legacy CSS variable is left for CHARTS-201.
  • Story and test scaffolding — all hardcoded spacing in stories//test/ files is demo-only and out of scope for the consumer-facing API.

Related product discussion/links

Does this pull request change what data or activity we track or use?

No.

Testing instructions

  • Run unit tests from projects/js-packages/charts: pnpm test — all 853 tests should pass.
  • Open Storybook locally and visually inspect the affected stories — they should be visually identical to trunk except for the deliberate layout fixes called out below:
    • Charts → Tooltip → Default — base tooltip padding/border-radius unchanged.
    • Charts → Line Chart → Annotations — open an annotation popover; padding, margin, and border-radius unchanged.
    • Charts → Conversion Funnel Chart → Default — bar/funnel-bar border-radius unchanged. Hover a bar to confirm tooltip-wrapper padding/border-radius/border-bottom unchanged. The funnel bar position shifts up ~2px relative to trunk because the label/rate group is now slightly more compact (line-height-xs on both, gap-xs Stack between them).
    • Charts → Conversion Funnel Chart → EmptyData — the "No data available" message is now centered both axes within the chart's height (previously sat near the top with 48px/24px padding).
    • Charts → Leaderboard Chart → Empty Data — empty state padding (32px 16px) unchanged.
    • Charts → Legend → * — focus a legend item with the keyboard; the focus-ring border-radius is unchanged.
  • Optional: in DevTools, inspect a tokenized property (e.g. .tooltip padding) and confirm the resolved value matches the previous literal. The WPDS provider is not active in default Storybook, so the CSS fallback should drive the rendered value.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 9, 2026

Are you an Automattician? Please test your changes on all WordPress.com environments to help mitigate accidental explosions.

  • To test on WoA, go to the Plugins menu on a WoA dev site. Click on the "Upload" button and follow the upgrade flow to be able to upload, install, and activate the Jetpack Beta plugin. Once the plugin is active, go to Jetpack > Jetpack Beta, select your plugin (Jetpack), and enable the charts-199-spacingborder-tokenization branch.
  • To test on Simple, run the following command on your sandbox:
bin/jetpack-downloader test jetpack charts-199-spacingborder-tokenization

Interested in more tips and information?

  • In your local development environment, use the jetpack rsync command to sync your changes to a WoA dev blog.
  • Read more about our development workflow here: PCYsg-eg0-p2
  • Figure out when your changes will be shipped to customers here: PCYsg-eg5-p2

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 9, 2026

Thank you for your PR!

When contributing to Jetpack, we have a few suggestions that can help us test and review your patch:

  • ✅ Include a description of your PR changes.
  • ✅ Add a "[Status]" label (In Progress, Needs Review, ...).
  • ✅ Add testing instructions.
  • ✅ Specify whether this PR includes any changes to data or privacy.
  • ✅ Add changelog entries to affected projects

This comment will be updated as you work on your PR and make changes. If you think that some of those checks are not needed for your PR, please explain why you think so. Thanks for cooperation 🤖


Follow this PR Review Process:

  1. Ensure all required checks appearing at the bottom of this PR are passing.
  2. Make sure to test your changes on all platforms that it applies to. You're responsible for the quality of the code you ship.
  3. You can use GitHub's Reviewers functionality to request a review.
  4. When it's reviewed and merged, you will be pinged in Slack to deploy the changes to WordPress.com simple once the build is done.

If you have questions about anything, reach out in #jetpack-developers for guidance!

@adamwoodnz adamwoodnz changed the base branch from trunk to charts-175-use-stack-for-layout April 9, 2026 03:14
@jp-launch-control
Copy link
Copy Markdown

jp-launch-control Bot commented Apr 9, 2026

Code Coverage Summary

This PR did not change code coverage!

That could be good or bad, depending on the situation. Everything covered before, and still is? Great! Nothing was covered before? Not so great. 🤷

Full summary · PHP report · JS report

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the Charts package styling to rely on WPDS dimension/border tokens instead of hardcoded spacing/border values, keeping rendered output stable via pixel fallbacks and making a couple of small layout adjustments in the conversion funnel chart.

Changes:

  • Tokenize padding/margin/gap and border-radius/border-width values across tooltip, legend, line chart, leaderboard chart, and conversion funnel chart styles.
  • Adjust conversion funnel empty-state layout to center content via Stack alignment and refine step label/rate layout via a Stack + typography tweaks.
  • Add a changelog fragment documenting the styling/tokenization update.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated no comments.

Show a summary per file
File Description
projects/js-packages/charts/src/components/tooltip/base-tooltip.module.scss Tokenizes tooltip padding and border radius with WPDS tokens and pixel fallbacks.
projects/js-packages/charts/src/components/legend/private/base-legend.module.scss Tokenizes focus-ring border radius with WPDS token + fallback.
projects/js-packages/charts/src/charts/line-chart/line-chart.module.scss Tokenizes tooltip/popover spacing and border radius; aligns spacing fallbacks to pixel values.
projects/js-packages/charts/src/charts/leaderboard-chart/leaderboard-chart.module.scss Tokenizes label/empty-state padding; documents intentional non-tokenized 6px row-gap.
projects/js-packages/charts/src/charts/conversion-funnel-chart/conversion-funnel-chart.tsx Centers empty-state via Stack alignment; wraps step label/rate in a Stack with tokenized gap.
projects/js-packages/charts/src/charts/conversion-funnel-chart/conversion-funnel-chart.module.scss Tokenizes border radius/border width/padding; updates label/rate typography and truncation behavior; removes empty-state padding.
projects/js-packages/charts/changelog/charts-199-spacing-border-tokenization Adds changelog entry for WPDS tokenization work.

@adamwoodnz adamwoodnz force-pushed the charts-175-use-stack-for-layout branch from 0ed9f37 to 58b79c3 Compare April 13, 2026 23:52
Base automatically changed from charts-175-use-stack-for-layout to trunk April 14, 2026 02:32
adamwoodnz and others added 7 commits April 14, 2026 14:35
… tokens

Replace hardcoded padding, margin, border-radius, and border-width values
in module SCSS with --wpds-dimension-* and --wpds-border-* tokens
(fallbacks preserved). Scope is the package's component SCSS — story
and test scaffolding is unchanged.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The previous 10px value sat between two WPDS padding tokens (sm = 8px,
md = 12px) and was left hardcoded in the initial tokenization pass.
Round up to padding-md so the separator below the date keeps a touch
more breathing room when no WPDS provider is active. Visual delta is
2px in the fallback path.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace rem-based fallbacks (0.5rem, 1rem) with the literal pixel
values defined by the WPDS dimension tokens (8px, 16px). The previous
fallbacks would only resolve to the spec value when the document root
font-size is the default 16px; pinning the fallback removes that
dependency and matches what the WPDS provider actually emits.

No visual change for browsers using the default root font-size.
The 2px margin between the funnel step label and rate had no matching
WPDS dimension token, so the initial tokenization pass left it
hardcoded. Bumping the label's line-height from line-height-xs (16px)
to line-height-sm (20px) absorbs the spacing into the line box: the
label gains 2px below its text glyphs, replacing the previous margin,
and inter-text gap between label and rate is preserved at ~7.5px.

Side effect: the label/rate group is 2px taller overall, shifting the
funnel bar down by 2px. Verified in Storybook against the default
funnel story.
Replace the inflated label line-height from the previous commit with
a cleaner approach: wrap the funnel step label and rate in a Stack
with gap-xs (4px), and use line-height-xs (16px) on both. Inter-text
gap between label and rate is preserved at ~7.5px; the label/rate
group is 2px shorter than the original layout, so the funnel bar
shifts up 2px.

With the Stack handling vertical layout, the label and rate spans no
longer need explicit `display: block` (flex items are blockified by
the flexbox spec), `margin: 0` (spans have no default margin), or
`font-style: normal` (default). Drop those redundant rules.

Also add `white-space: nowrap` to step-label so its existing
`overflow: hidden; text-overflow: ellipsis` actually produces an
ellipsis on overflow. Without nowrap, the ellipsis declaration is
silently a no-op — the text wraps to multiple lines and gets clipped
instead of truncated.
The funnel empty state previously used `padding: 48px 24px` to push
its text away from the container edges, but it sat at the top of the
chart's fixed-height column rather than being vertically centered.
The 48px vertical padding was also the only spacing literal in the
package with no matching WPDS dimension token.

Add `align="center" justify="center"` to the parent Stack in the
empty-state branch so the message is centered both axes within the
chart's resolved height, matching the centering pattern used by
SvgEmptyState. Drop the now-unused padding from .empty-state.

Verified centering against the EmptyData story: chart bounds
(999.5, 492.75) and empty-state bounds match exactly on both axes.
The leaderboard's bar rows use a compact bar + gap + bar rhythm
(6px bar, 6px row-gap, 6px bar) that does not align to the WPDS
dimension scale — the closest token (gap-sm = 8px) visibly breaks
the balance between row spacing and bar thickness. Add a comment so
the next person to look at this doesn't try to tokenize the value.

Surfaced during the spacing/border tokenization pass for CHARTS-199.
@adamwoodnz adamwoodnz force-pushed the charts-199-spacingborder-tokenization branch from b7e00ef to c3d2512 Compare April 14, 2026 02:37
@adamwoodnz
Copy link
Copy Markdown
Contributor Author

@claude review please

@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Apr 16, 2026

Claude finished @adamwoodnz's task in 2m 25s —— View job


Code Review

  • Gather context and understand request
  • Read changed files
  • Review SCSS tokenization changes
  • Review TSX structural changes
  • Post review findings

This is a clean, well-scoped tokenization PR. The design decisions are clearly documented, fallbacks are correctly anchored to pixel literals, and the intentional outliers (leaderboard row-gap, padding-3xl comment, etc.) are explained. A couple of small points worth raising:


Minor: Changelog entry missing Charts: prefix

changelog/charts-199-spacing-border-tokenization reads:

Replace hardcoded spacing and border values in module SCSS with WPDS dimension and border design tokens.

Per AGENTS.md, the convention is Charts: <user-facing change>.. All other entries in CHANGELOG.md follow this pattern:

Charts: Replace ad-hoc flexbox layouts with @wordpress/ui Stack ...
Charts: Document WordPress UI + Theme integration defaults.

Fix this →


Nit: gap-sm token used for a margin property

line-chart.module.scss line 68:

margin: var(--wpds-dimension-gap-sm, 8px);

gap-sm and padding-sm are both 8px, so the rendered value is identical. Semantically, --wpds-dimension-padding-sm (or a dedicated offset token if one exists) might be a more natural fit for a margingap tokens are typically intended for spacing between flex/grid children. Not a functional issue, just a semantic note.


Intentional visual diffs — confirmed acceptable?

The PR description is transparent about these, just checking they've been signed off:

  • tooltip-date padding-bottom: 10px → 12px (line-chart.module.scss:25) — nearest token. Small increase in spacing below the date header in line-chart tooltips.
  • step-rate line-height: 20px → 16px (conversion-funnel-chart.module.scss:68) — aligns with step-label, compacts the label+rate block by ~4px per step, which shifts funnel bars up slightly.
  • Funnel empty state: CSS padding removed in favour of Stack align="center" justify="center" in the TSX — content is now centered both axes rather than inset from the top. This is a visible layout change and a clear improvement.

These are all documented in the PR description, just confirming they had intentional review rather than being side-effects of the tokenization.


Everything else looks good

  • All token fallbacks correctly reflect WPDS spec pixel values (no rem-based fallbacks remaining).
  • white-space: nowrap added to .step-label is a genuine fix — without it, text-overflow: ellipsis had no effect.
  • Removed redundant display: block, margin: 0, font-style: normal on flex children is correct cleanup.
  • The row-gap: 6px outlier is well-documented inline.
  • !important on the tooltip-wrapper overrides is pre-existing and justified by the visx inline-style override comment.
  • The @wordpress/ui: 0.9.0 → 0.10.0 version difference in the diff is a branch-age artifact that will resolve on merge to trunk.

Overall: LGTM modulo the changelog prefix. The reasoning behind every deliberate deviation from a straight substitution is documented, which makes this easy to trust.

line-height: var(--wpds-font-line-height-xs, 16px);
margin: 0 0 2px 0;
display: block;
white-space: nowrap;
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Completes the overflow handling styles. Without this text will wrap and not get ellipsis.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixes for text with spaces.

Before After
Image Image


.empty-state {
text-align: center;
padding: 48px 24px;
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replaced with a centered layout, matching other charts, eg. GeoChart

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Image

Without an explicit margin, the fixed-position tooltip popover
inherits margin: auto, which offsets it from the trigger button.
The margin also creates the intended gap between the trigger and
the popover, making --wpds-dimension-gap-sm the right token.

Document this inline so the declaration isn't mistaken for a
hardcoded spacing workaround in future tokenization passes.
@adamwoodnz
Copy link
Copy Markdown
Contributor Author

@claude again

@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Apr 16, 2026

Claude finished @adamwoodnz's task in 1m 57s —— View job


Code Review

  • Gather context and read changed files
  • Review SCSS tokenization changes
  • Review TSX structural changes
  • Review changelog entry
  • Post review findings

Both concerns raised in the previous review have been addressed:

  • Changelog prefixCharts: Replace hardcoded… is present. ✓
  • gap-sm for margin — the inline comment now explains the reasoning clearly (margin:auto positioning issue; gap is semantically accurate since it creates space to the trigger). ✓

A few fresh observations below.


--wpds-dimension-padding-3xl for 32px — worth a quick sanity check

leaderboard-chart.module.scss:77:

padding: var(--wpds-dimension-padding-3xl, 32px) var(--wpds-dimension-padding-lg, 16px);

The PR description says tokens were verified against node_modules/@wordpress/theme/src/prebuilt/css/design-tokens.css. The 3xl suffix for 32px is plausible on a scale of xs=4 / sm=8 / md=12 / lg=16 / xl=24 / 2xl=? / 3xl=32, but I couldn't verify the file directly in this run. If it's confirmed correct, no change needed — just flagging since it's the most unusual-looking name in the diff.


Empty-state align/justify correctly scoped

conversion-funnel-chart.tsx:300-317 — the align="center" justify="center" additions land on the early-return Stack (the empty state path), not the data-present Stack at line 325. So the normal chart layout is unaffected. ✓


text-overflow truncation now fully wired

conversion-funnel-chart.module.scss:54-61white-space: nowrap was the missing link; overflow: hidden and text-overflow: ellipsis were already there. The combination is now complete and the ellipsis will actually fire. ✓


step-rate line-height alignment

conversion-funnel-chart.module.scss:64-71 — dropping line-height-sm (20px) in favour of line-height-xs (16px, matching .step-label) is a documented intentional diff that compacts the label+rate block. Combined with gap="xs" (4px) replacing the old 2px bottom-margin, the net visible change is ~2px of additional spacing but a more uniform typographic rhythm. Clear improvement. ✓


Everything else looks good

  • All pixel fallbacks correctly match WPDS spec values — no rem-based fallbacks remain.
  • --wpds-border-width-xs, 1px on the funnel tooltip-wrapper border is correct.
  • Redundant display: block, margin: 0, font-style: normal removals are valid for flex children.
  • border-radius shorthand repetition on .funnel-bar (var(…) var(…) 0 0) is verbose but correct.
  • row-gap: 6px outlier is well-documented inline.
  • The !important overrides are pre-existing and justified by the visx comment.

Overall: LGTM. Pending confirmation that --wpds-dimension-padding-3xl maps to 32px in the WPDS source, this is ready to merge.

@adamwoodnz adamwoodnz requested a review from a team April 16, 2026 00:56
@adamwoodnz adamwoodnz added [Status] Needs Review This PR is ready for review. and removed [Status] In Progress labels Apr 16, 2026
Comment on lines +24 to +27
// Outlier: not tokenized. The leaderboard's compact bar + gap + bar
// rhythm (6px bar, 6px row-gap, 6px bar) is intentional and does not
// map to any WPDS dimension token — gap-sm (8px) breaks the visual
// balance between the rows and the bars.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Image

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Image

Copy link
Copy Markdown
Contributor

@kangzj kangzj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Works as described and changes look good 👍

One issue that's not related to the PR:

  • The glyphs are off the lines
  • The glyphs render on top of the marker content, which feels odd. I'm not sure what should be the expected behaviour though.
Screen.Recording.2026-04-16.at.5.07.38.PM.mov

Copy link
Copy Markdown
Contributor

@dognose24 dognose24 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM and works as expected from my testing! 👍🏼

line-height: var(--wpds-font-line-height-sm, 20px);
margin: 0;
display: block;
line-height: var(--wpds-font-line-height-xs, 16px);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! 👍🏼

Image

line-height: var(--wpds-font-line-height-xs, 16px);
margin: 0 0 2px 0;
display: block;
white-space: nowrap;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixes for text with spaces.

Before After
Image Image


.empty-state {
text-align: center;
padding: 48px 24px;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Image

return (
<Stack
direction="column"
align="center"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Image

>
{ /* Step Label and Rate */ }
<div>
<Stack direction="column" gap="xs">
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Image

@adamwoodnz adamwoodnz added [Status] Ready to Merge Go ahead, you can push that green button! and removed [Status] Needs Review This PR is ready for review. labels Apr 17, 2026
@adamwoodnz adamwoodnz merged commit 38b8519 into trunk Apr 17, 2026
130 of 132 checks passed
@adamwoodnz adamwoodnz deleted the charts-199-spacingborder-tokenization branch April 17, 2026 02:10
@github-actions github-actions Bot removed the [Status] Ready to Merge Go ahead, you can push that green button! label Apr 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants