Skip to content

Post Stats: draw the chart chrome in tokens instead of hardcoded black - #793

Merged
epeicher merged 3 commits into
WordPress:trunkfrom
juanlentino:fix/post-stats-canvas-tokens
Sep 11, 2026
Merged

Post Stats: draw the chart chrome in tokens instead of hardcoded black#793
epeicher merged 3 commits into
WordPress:trunkfrom
juanlentino:fix/post-stats-canvas-tokens

Conversation

@juanlentino

@juanlentino juanlentino commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

Fixes #762.

The change

Three canvas paints in src/plugins/post-stats-widget/index.ts were literal black:

line draws was now
131 horizontal grid lines rgba(0,0,0,0.07) --os-ui-color-border
139 y-axis tick numbers rgba(0,0,0,0.35) --os-ui-color-text-subtle
166 month labels rgba(0,0,0,0.5) --os-ui-color-text-subtle

These are the same two custom properties the widget's own stylesheet already uses for its DOM text — which is precisely why the title, the 39 posts in 6 mo metadata and the legend were legible while everything on the canvas was not. The bars survived because they use the explicit COLORS map.

Two decisions worth flagging

The ad-hoc alphas go with the black. 0.07 / 0.35 / 0.5 were compensating for black ink on a light assumption; the tokens already encode the rule-vs-label hierarchy, and a canvas cannot cheaply apply an alpha to an arbitrary colour string without parsing it. If you'd rather keep a weight difference between the ticks and the month labels, globalAlpha around the tick pass is the clean way and I'm happy to take direction on it.

The fallbacks are deliberately not black. getPropertyValue() returns '' when a token has not resolved, so the fallback is what ships in exactly the case the token exists to cover. Falling back to black would restore the bug there. Both fallbacks are the dark-glass values from variables.css.

Tests

Two cases added to tests/vitest/widget-card-token-contract.test.ts, which already exists for this class of bug. One asserts the source carries no literal black and reads both tokens; the other asserts the fallbacks are legible on the glass — without that, a future edit could satisfy the first pin and still ship black as the fallback.

A canvas cannot be asserted in jsdom without a 2D context, so these are source-level pins rather than rendered-pixel ones. That is a real limitation of the check and worth knowing when reading it.

Verification caveat, same as my other PRs: I could not run your vitest suite — devEngines pins Node to >=24 <25 and this machine is on v26, so npm refuses before install. I ran each pin's logic in plain node against the real file in both directions: it passes on the patched source and trips on the pre-patch source, so the guard is failable rather than vacuous. The vitest harness itself is unexercised.

Open WordPress Playground Preview

The grid lines, y-axis ticks and month labels were painted with literal
black — rgba(0,0,0,0.07) / 0.35 / 0.5. `.os-widgets__card` is a fixed
dark glass in every desktop theme, so composited over the wallpaper they
measured 1.01:1 and 1.02:1: invisible. The bars survived only because
they use the explicit COLORS map, and the widget's own DOM text stayed
legible because its stylesheet already reads the tokens.

The canvas now reads the same two custom properties that stylesheet uses
— `--os-ui-color-border` for the rules, `--os-ui-color-text-subtle` for
both sets of labels. The ad-hoc alphas go with the black: the tokens
already encode the intended hierarchy, and a canvas cannot cheaply apply
an alpha to an arbitrary colour string.

The fallbacks are the dark-glass values from variables.css, not the old
black. A fallback is what ships when the token does not resolve, so a
black one would restore the bug in exactly the case it exists to cover.

Fixes WordPress#762
@epeicher

Copy link
Copy Markdown
Collaborator

Thanks for your contribution @juanlentino! Two small things:

  • CI's ESLint step fails on src/plugins/post-stats-widget/index.ts (lines 128–129): @wordpress/no-unused-vars-before-return, the variables are assigned before an early return. Moving those assignments below the return should clear it.
  • Trunk now admits Node 26 (Tooling: admit Node 26 alongside Node 24 #794), so a merge with trunk will let you run npm ci and the vitest suite locally without the devEngines refusal.

juanlentino and others added 2 commits September 11, 2026 11:17
Satisfies @wordpress/no-unused-vars-before-return: RULE and LABEL were
assigned before the chartW/chartH guard could return without using them.
Behaviour unchanged.

@epeicher epeicher left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thanks @juanlentino! It looks much better now. Changes also LGTM!

Before After
Image Image

@epeicher
epeicher merged commit 9acaa37 into WordPress:trunk Sep 11, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Post Stats: the chart's axis labels and grid are drawn in hardcoded black, invisible on the widget card's dark glass

2 participants