Theme: apply ThemeProvider styles inline (I2)#78678
Draft
ciampo wants to merge 3 commits into
Draft
Conversation
Addresses A8 and I2 from #77462. * `ThemeProvider` now applies the resolved CSS custom properties (color tokens, `--wpds-cursor-control`, and density overrides) inline on the wrapper element instead of injecting a per-instance `<style>` tag with a `:root:has(...)` selector. The doubled-class specificity hack goes away with it. * `density` no longer relies on `[data-wpds-density='…']` attribute selectors emitted in the prebuilt CSS. The dimension overrides each mode applies are generated by a new `terrazzo-plugin-density-overrides` plugin into a small TypeScript module read at runtime, so density propagates through the same inline-style channel as `color` and `cursor`. * For `isRoot` providers, the same custom properties are mirrored onto `document.documentElement.style` from a `useLayoutEffect` (with cleanup), removing the `:root:has(...)` workaround.
The drawer's `[data-wpds-theme-provider-id]:has(> .popup)` rule worked around a Base UI tabbability regression with `display: contents` (mui/base-ui#4622). The Base UI bump that removed the bug has since landed, and every other overlay dropped the same workaround in #77520, so the marker attribute on the ThemeProvider wrapper no longer has any consumer. Remove both the attribute and the drawer-side selector.
24 tasks
A8 from #77462 swapped a simple `[data-wpds-density]` attribute selector for a runtime lookup table generated by a dedicated terrazzo plugin. The consistency gain doesn't justify the added build-system complexity, so revert that part and keep `density` on a `data-*` attribute. With the per-instance `data-wpds-theme-provider-id` now gone, the density attribute selectors can be simplified to plain `[data-wpds-density='…']`. I2 (inline `style` for color/cursor, `useLayoutEffect` for `isRoot`) is unaffected.
|
Size Change: -47 B (0%) Total Size: 8.18 MB 📦 View Changed
ℹ️ View Unchanged
|
|
Flaky tests detected in fed1832. 🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/26456497499
|
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?
See #77462 (item I2).
Replaces the per-instance
<style>element rendered byThemeProviderwith inline CSS custom properties on the wrapper element, plus a small effect to mirror those properties ontodocument.documentElementfor root providers.Why?
The
<style>approach needed several pieces of scaffolding to scope a global stylesheet to one provider instance: a doubled-class specificity hack,data-wpds-theme-provider-id/data-wpds-root-providerattributes, and a:root:has(…)rule forisRoot. Inlinestyleon the wrapper does the same job with one fewer DOM node per provider and a much simpler mental model.How?
ThemeProviderwrites color tokens and--wpds-cursor-controldirectly to the wrapper'sstyleprop.isRoot, auseLayoutEffectwrites the same properties todocument.documentElement.styleand restores the previous values on cleanup.<style>element, the doubled-class hack, the:root:has(…)selector, and thedata-wpds-theme-provider-id/data-wpds-root-providerattributes. The drawer's[data-wpds-theme-provider-id]:has(> .popup)Base UI workaround is removed too, matching UI: Update@base-ui/reactfrom1.4.0to1.4.1#77520.densityis unchanged: still adata-wpds-densityattribute paired with[data-wpds-density='…']rules in the prebuilt CSS.What about A8?
An earlier revision of this PR also took on A8 (unify density's propagation with color/cursor by moving it onto inline custom properties too). That required a new Terrazzo plugin and a generated runtime lookup table, and the consistency gain didn't justify the added build-system complexity, so it was reverted. The commit history still shows the attempt.
Scope notes
useThemeProviderStylesis internal (private API). No public API change.[data-wpds-density='…']selectors are simplified to plain attribute selectors now that the per-instancedata-wpds-theme-provider-idis gone.Testing Instructions
<ThemeProvider isRoot>at the top and a few nested<ThemeProvider>s with variouscolor/cursor/densityprops.ThemeProviderno longer renders a<style>element and no longer carriesdata-wpds-theme-provider-id/data-wpds-root-provider.<html>(e.g. background color, focus ring width) and that they revert when the root provider unmounts.densitybehavior (default/compact/comfortable) is unchanged.Testing Instructions for Keyboard
No UI-facing changes; existing keyboard behavior is unaffected.
Screenshots or screencast
N/A — no visual changes intended.
Use of AI Tools
This PR was authored with Cursor (Claude). All code was reviewed before committing.