Theme: apply ThemeProvider styles inline (I2)#78678
Draft
ciampo wants to merge 2 commits into
Draft
Conversation
24 tasks
|
Size Change: -30 B (0%) Total Size: 8.58 MB 📦 View Changed
|
|
Flaky tests detected in fed1832. 🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/26456497499
|
ciampo
commented
May 26, 2026
ciampo
added a commit
that referenced
this pull request
May 27, 2026
In anticipation of #78678, which replaces ThemeProvider's per-instance `<style>` element with inline custom properties on the wrapper, reword the comments / CHANGELOG / README / PR description to describe the optimization as "skip applying per-instance overrides" rather than "skip emitting the `<style>` element". The savings are real in either mechanism (no CSS string assembly + no DOM write). Also simplify the `AcrossIframes` story: - The previous filter cloned `<style data-wpds-theme-provider-id>` elements from `document.head`, which is dead code (React-rendered `<style>` is not in head) and would be doubly dead post-#78678 (the attribute is removed entirely). Drop it. - Per-instance overrides ride into the iframe with the portalled `<ThemeProvider>` itself (whether the mechanism is a `<style>` child or an inline `style` prop on the wrapper). The story only needs to clone the prebuilt token stylesheet `<link>`.
ciampo
added a commit
that referenced
this pull request
May 27, 2026
In anticipation of #78678, which replaces ThemeProvider's per-instance `<style>` element with inline custom properties on the wrapper, reword the comments / CHANGELOG / README / PR description to describe the optimization as "skip applying per-instance overrides" rather than "skip emitting the `<style>` element". The savings are real in either mechanism (no CSS string assembly + no DOM write). Also simplify the `AcrossIframes` story: - The previous filter cloned `<style data-wpds-theme-provider-id>` elements from `document.head`, which is dead code (React-rendered `<style>` is not in head) and would be doubly dead post-#78678 (the attribute is removed entirely). Drop it. - Per-instance overrides ride into the iframe with the portalled `<ThemeProvider>` itself (whether the mechanism is a `<style>` child or an inline `style` prop on the wrapper). The story only needs to clone the prebuilt token stylesheet `<link>`.
Replaces the per-instance `<style>` element with inline `style` on the wrapper. When `isRoot`, mirrors the same custom properties onto `document.documentElement` via `useLayoutEffect` so portals and the `html`/`body` background pick them up. - Drops `useId`, `data-wpds-theme-provider-id`, `data-wpds-root-provider`, and the generated `:root:has(...)` selector. - Updates `ThemeProvider` tests to scope by the wrapper's CSS module class (the previous attribute is gone). - Fixes the storybook iframe stylesheet filter, which still looked for the removed attribute, to match the `--wpds-` token prefix instead.
623c53a to
2c668ee
Compare
Restores `data-wpds-root-provider="true"` on the wrapper when `isRoot`, so prebuilt CSS can forward preset-based settings (e.g. `cornerRadius` in #79153) to `:root` via `:root:has([data-wpds-root-provider="true"]…)`. Dynamic color/cursor values keep using the JS sync in `useLayoutEffect` (they can't be expressed in a static stylesheet). Comment updated to explain the deliberate split.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What?
Addresses I2 from #77462. Replaces
ThemeProvider's per-instance<style>with inline custom properties on the wrapper, mirrored ontodocument.documentElementwhenisRoot.Why?
One fewer DOM node per provider and a simpler mental model — no per-instance scoping selector to build, no doubled-class specificity hack.
How?
styleprop.isRoot, auseLayoutEffectmirrors them ontodocument.documentElement.styleand restores on cleanup.<style>,useId, the doubled-class hack, the runtime:root:has(…)selector, anddata-wpds-theme-provider-id.data-wpds-root-provider="true"on the wrapper so prebuilt CSS can forward preset-based settings to:root(see Theme: forward ThemeProvider cornerRadius preset to :root for root providers #79153).Why the asymmetry between color/cursor and cornerRadius forwarding?
Dynamic values (color seeds, cursor) are per-instance and can't be expressed in a static stylesheet, so JS syncs them to
<html>. Preset-based values (e.g.cornerRadius) are a small known set fully resolved in the prebuilt CSS, where:root:has([data-wpds-root-provider="true"][data-wpds-corner-radius="…"])is the cleanest forwarding mechanism.Testing Instructions
<ThemeProvider isRoot color={…} cursor={…} cornerRadius="…">with a few nested<ThemeProvider>s.<style>element under the provider, color/cursor tokens are inline on the wrapper, and the root wrapper hasdata-wpds-root-provider="true".<html>and revert on unmount.npm run test:unit -- packages/themepasses.Testing Instructions for Keyboard
No UI-facing changes.
Screenshots or screencast
N/A — no visual changes intended.
Use of AI Tools
Made with Cursor.