Skip to content

Commit 462946b

Browse files
committed
Theme: phrase the optimization in mechanism-neutral terms
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>`.
1 parent 3420d6d commit 462946b

4 files changed

Lines changed: 18 additions & 32 deletions

File tree

packages/theme/CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
### Internal
1616

1717
- Refactor color space registration to avoid module-level side effects ([#77653](https://github.com/WordPress/gutenberg/pull/77653)).
18-
- `ThemeProvider`: skip emitting the per-instance `<style>` element entirely when the resolved settings match the prebuilt defaults. `--wp-admin-theme-color*` overrides are now emitted only when the resolved `color.primary` differs from the prebuilt default, letting WP Core's admin color scheme show through otherwise ([#78664](https://github.com/WordPress/gutenberg/pull/78664)).
18+
- `ThemeProvider`: skip applying per-instance overrides entirely when the resolved settings match the prebuilt defaults. `--wp-admin-theme-color*` overrides are now applied only when the resolved `color.primary` differs from the prebuilt default, letting WP Core's admin color scheme show through otherwise ([#78664](https://github.com/WordPress/gutenberg/pull/78664)).
1919
- Within the block editor iframe, default WPDS tokens (`--wpds-*`) are now available at `:root` even without a `<ThemeProvider>` instance, matching the main admin document ([#78664](https://github.com/WordPress/gutenberg/pull/78664)).
2020

2121
## 0.13.0 (2026-05-14)

packages/theme/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@ The [`ThemeProvider`](#theme-provider) component can be used to customize token
2424
The design system splits token delivery into two complementary layers:
2525

2626
- **Static stylesheet (`design-tokens.css`)** — defines the default values for every `--wpds-*` and `--wp-components-*` custom property at the document `:root`. Loaded once per document (the main page, _and_ each iframe you render React into). Provides a working baseline even before any JavaScript runs.
27-
- **Runtime `<ThemeProvider>`**emits a per-instance `<style>` element only when the resolved settings differ from the static defaults. Use it to override individual settings (e.g. `color.primary`, `cursor.control`, `density`) for a subtree.
27+
- **Runtime `<ThemeProvider>`**applies per-instance overrides only when the resolved settings differ from the static defaults. Use it to override individual settings (e.g. `color.primary`, `cursor.control`, `density`) for a subtree.
2828

29-
A `<ThemeProvider>` whose resolved settings match the defaults is intentionally a no-op for CSS emission — the static stylesheet already supplies every variable.
29+
A `<ThemeProvider>` whose resolved settings match the defaults is intentionally a no-op — the static stylesheet already supplies every variable.
3030

3131
#### Within WordPress
3232

packages/theme/src/stories/index.story.tsx

Lines changed: 11 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -303,39 +303,24 @@ function IframeWithClonedTokenStyles( {
303303
const [ iframeLoaded, setIframeLoaded ] = useState( false );
304304

305305
// Make DS tokens available inside the iframe. In real WordPress this is
306-
// handled by enqueuing the prebuilt token stylesheet and routing per-
307-
// instance overrides through `StyleProvider`; Storybook has no enqueue
308-
// layer, so we replicate it by cloning the prebuilt token stylesheet
309-
// plus any `<style>` emitted by a nested `<ThemeProvider>`.
306+
// handled by enqueuing the prebuilt token stylesheet; Storybook has no
307+
// enqueue layer, so we clone its `<link>` into the iframe here. Any
308+
// per-instance overrides travel into the iframe with the portalled
309+
// `<ThemeProvider>` itself.
310310
useEffect( () => {
311311
const iframe = iframeRef.current;
312312
if ( ! iframe || ! iframe.contentDocument ) {
313313
return;
314314
}
315315

316-
const head = iframe.contentDocument.head;
317-
318-
const allNodes = Array.from(
319-
document.head.querySelectorAll( 'style, link[rel="stylesheet"]' )
316+
const tokensLink = document.head.querySelector(
317+
'link[rel="stylesheet"][href*="design-tokens"]'
320318
);
321-
322-
allNodes.forEach( ( node ) => {
323-
if ( node.tagName === 'STYLE' ) {
324-
// Per-instance overrides carry this data attribute.
325-
if (
326-
( node as HTMLStyleElement ).dataset.wpdsThemeProviderId !==
327-
undefined
328-
) {
329-
head.appendChild( node.cloneNode( true ) );
330-
}
331-
} else if (
332-
node.tagName === 'LINK' &&
333-
( node as HTMLLinkElement ).href.includes( 'design-tokens' )
334-
) {
335-
// Prebuilt token stylesheet.
336-
head.appendChild( node.cloneNode( true ) );
337-
}
338-
} );
319+
if ( tokensLink ) {
320+
iframe.contentDocument.head.appendChild(
321+
tokensLink.cloneNode( true )
322+
);
323+
}
339324

340325
setIframeLoaded( true );
341326
}, [] );

packages/theme/src/use-theme-provider-styles.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -140,9 +140,10 @@ export function useThemeProviderStyles( {
140140
);
141141

142142
// When everything resolves to the WPDS defaults, the prebuilt `:root` CSS
143-
// already provides every variable, so skip the per-instance `<style>`.
144-
// `colorjs.io`'s `equals` treats any parseable representation of the
145-
// same color as default (e.g. `#3858E9` ≡ `#3858e9` ≡ `rgb(56 88 233)`).
143+
// already provides every variable; return `undefined` so the provider
144+
// applies no per-instance overrides. `colorjs.io`'s `equals` treats any
145+
// parseable representation of the same color as default (e.g. `#3858E9`
146+
// ≡ `#3858e9` ≡ `rgb(56 88 233)`).
146147
let primaryIsDefault = false;
147148
let bgIsDefault = false;
148149
try {

0 commit comments

Comments
 (0)