Repository navigation
Global Styles: List the blocks that override an element - #84671
aaronrobertshaw wants to merge 10 commits into
Conversation
🤖 PR meta 🤖🎉 PropsIf you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message. To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. Updated as activity occurs, without notifying anyone named here. Add the 📦 Bundle sizeSize Change: +525 B (+0.01%) Total Size: 9.05 MB 📦 View Changed
⚡ PerformanceShow the resultsClient side metrics exclude the server response time. front-end-block-theme
front-end-classic-theme
media-processing
media-upload
post-editor
site-editor
🏁 Flaky testsSome tests passed with failed attempts. The failures may not be related to this commit but are still reported for visibility. See the documentation for more information. Regression: updating a specific option will only change its value and will not corrupt others in
|
6f08e65 to
5fc785f
Compare
5fc785f to
c1a295b
Compare
c1a295b to
0e5b364
Compare
|
Noting that I like this a lot, mostly at a glance. |
0e5b364 to
723ec71
Compare
Lift the getElementLayers switch into a table keyed by element and add getBlockTypesForElement, exposed as a private API, so Global Styles can list the block types an element paints.
On the Headings, Links and Buttons screens, show an "Applies to" list of the block types whose own styles beat the element for a property it sets, each linking to the block's screen. Overrides come from the inherited value resolver, with and without block styles.
…ests" This reverts commit 8222aaf.
f6b0ea1 to
6a4e9ba
Compare
Move getOverridingBlockTypes and its helpers into element-block-overrides.tsx, reuse BlockMenuItem for the items and ScreenBody for the padding, and drop the extra style rule. Make the state test cover the state filter, drop the unreachable nested elements check, and trim the tests. Rename the component test to .jsx, like screen-header.jsdom.test.jsx, so lint:tsconfig passes without a dev project. Export getBlockTypesForElement from the global-styles index instead of its own private-apis import.
Give global-styles-ui a dev project, as the TypeScript packages do: tsconfig.build.json builds src, and tsconfig.json checks the tests. Point the packages and routes that reference it at the build project. Rename the component test back to .tsx, type it, and drop its two lint suppressions.
Drops the package tsconfig split, so the PR no longer touches any tsconfig file.
| 'core/accordion-heading', | ||
| 'core/heading', | ||
| 'core/post-title', | ||
| 'core/site-title', |
There was a problem hiding this comment.
Some themes (like TT4 and TT5) set "level":0 for site title, which will render as <p />
See
How should we handle those cases do you think?
Maybe we could drop them if they're level 0, e.g.,
.filter(
( blockType ): blockType is BlockType =>
!! blockType &&
// Renders as a paragraph unless a heading level is picked.
blockType.attributes?.level?.default !== 0
)|
While testing I discovered the "Reset all" on typography doesn't clear the color of the site title text: 2026-10-22.19.23.53.mp4Fix here |
andrewserong
left a comment
There was a problem hiding this comment.
I like the ability to drill down from the elements screen to other blocks that use the element! While the PR description (and linked discussions) help explain the rationale for only showing those blocks that have overrides for the element, while testing I found myself wondering the following when I saw the UI:
- "Applies to" doesn't show the Heading block, does that mean this isn't meant to apply to the Heading block?
- Likewise since Accordion Heading isn't listed does that mean this isn't meant to apply to the accordion?
So, my first impression was that the drilldown here was meant to list every block that contains that element so that you can go from Heading element down to whichever other heading blocks you want to customise.
I think for me this comes down to the label that's used. Would it help to label this something like "Blocks that override this element"? Terrible example of wording to actually use, but I guess what I'm trying to say is, "Applies to" seems a bit general / possibly ambiguous, and I'm wondering if there's a way to be more specific here, either via the label or adding help text? 🤔
There was a problem hiding this comment.
🟡 Changes recommended
The new helper lacks a runtime compatibility guard, and override detection can both omit affected blocks and list unaffected ones.
4 open issues
What changed in this PR
Adds an “Applies to” list to Global Styles element screens so users can navigate to blocks whose styles override the selected element.
Changes:
- Extracts a shared block-to-element map and exposes its inverse through a block-editor private API.
- Adds override detection and linked block lists to the shared element screen.
- Adds focused tests, a changelog entry, and a lint suppression.
| File | Description |
|---|---|
tools/eslint/suppressions.json |
Adds a restricted-import suppression. |
packages/global-styles-ui/src/test/screen-block-list.jsdom.test.js |
Tests override detection and exclusions. |
packages/global-styles-ui/src/screen-element.tsx |
Displays the override list. |
packages/global-styles-ui/src/screen-block-list.tsx |
Exports the reusable block menu item. |
packages/global-styles-ui/src/element-block-overrides.tsx |
Detects overriding blocks and renders navigation links. |
packages/global-styles-ui/CHANGELOG.md |
Documents the element-screen enhancement. |
packages/block-editor/src/components/global-styles/test/inherited-value-context-elements.jsdom.test.ts |
Tests inverse element mappings. |
packages/block-editor/src/components/global-styles/inherited-value-context.ts |
Extracts the shared map and adds inverse lookup. |
packages/block-editor/src/components/global-styles/index.ts |
Exposes the inverse lookup through private APIs. |
Review effort: Balanced
| config: GlobalStylesConfig | undefined, | ||
| element: string | ||
| ): string[] { | ||
| const blockNames: string[] = getBlockTypesForElement( element ); |
| return Object.hasOwn( ELEMENT_BLOCK_TYPES, key ) | ||
| ? ELEMENT_BLOCK_TYPES[ key ] |
| const elements = getElementKeys( element ); | ||
| // Any block name works here: with block styles dropped, only root and element layers remain. | ||
| const { sources: elementSources } = resolveStyle( | ||
| { ...config, styles: { ...config.styles, blocks: undefined } }, |
| ( path ) => | ||
| isOwnStylePath( path ) && | ||
| sources[ path ].layer === 'block' && | ||
| elementSources[ path ]?.layer === 'element' |


Related:
What?
Element screens in Global Styles (Headings, Links, Buttons) now list the block types whose own styles override the element. Each item opens that block's screen.
Why?
A site owner sets Headings to bold and the Title stays regular. Twenty Twenty-Three gives the Title block its own font weight, and a block-type style beats the element style. Nothing on the Headings screen says so.
How?
getElementLayersis now a table. Its inverse,getBlockTypesForElement(), is a block editor private API.resolveStyleruns with and without block styles. A block type is listed when a leaf the element sets comes from the block layer.element-block-overrides.tsxkeeps ano-restricted-importssuppression for./lock-unlock, like the 13 other files in this package that callunlock.Limits
Testing Instructions
gutenberg-extensible-site-editorexperiment).Screenshots or screencast
Use of AI Tools
Implemented and tested by a Claude Code agent from a predefined task.