You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Adds a second scope to the Styles control in the block Advanced panel, so a block's styles can be applied to the other blocks of its type inside the parent they share, as well as to every block of that type across the site.
Why?
There's currently no way to share the styles of an inner block with its siblings. If an Accordion has five headings, or a Tabs block has four panels, each one has to be styled by hand, and adding a new item means re-applying everything. See #76330 for more details.
This PR takes the approach from #77097, but builds it on the current version of the control rather than the one #77097 was written against. Since that PR was opened, #79839 gave "Apply globally" a review modal where each style is a row you can tick, and #80990 renamed the file. Reusing the review modal also fixes the main weakness of the earlier prototype, which copied every style attribute at once and overwrote whatever the siblings already had.
How?
A new useSiblingScope hook walks up from the selected block to the nearest ancestor that holds more than one block of the same type, and returns that ancestor's title along with the blocks to apply to. For an Accordion Heading that ancestor is the Accordion; for a Tab Panel it's Tab Panels; for a Button it's Buttons. Blocks of the same type anywhere inside the ancestor count, not just immediate children, because the blocks that should match are usually a level or two down.
When both scopes are available the control shows a radio group, and Global Styles stays selected by default, so nothing changes for existing users unless the sibling scope is chosen. Both scopes then open the same review modal, and only the ticked rows are applied. On the sibling scope the "Current" column means the value the siblings already share, or "Varies" when they disagree, since there's no single current value to show across several blocks.
Testing Instructions
Insert a Buttons block and add three buttons with some text in each.
Select the first button, then open Settings → Advanced in the sidebar. You should see a "Styles" section with an "Apply styles to" radio group and a "Review and apply" button.
Check that "All Button blocks on the site" is selected by default.
Switch to the Styles tab and give the first button a text colour and a font size.
Back in Advanced, choose "All Button blocks in this Buttons" and press "Review and apply".
Check the modal is titled "Apply Button styles in this Buttons", lists the two styles you changed with "Current" and "New" columns, and starts with every row ticked.
Untick one of the rows and press Apply. Only the ticked style should be copied to the other two buttons, and a snackbar should read "Button styles applied in this Buttons."
Check the unticked style is unchanged on the other buttons, and that any styles they already had of their own are untouched.
Undo those changes. All the siblings should revert together in a single undo step.
Give the second and third buttons two different background colours. Select the first button, set a background colour on it, choose the sibling scope, and press "Review and apply". The "Current" column for Background colour should read "Varies".
Set a colour from the theme palette on the first button rather than a custom one, then apply it to the siblings. The other buttons should pick up the palette colour as a preset, not a hardcoded hex value.
Select a block with no same-type siblings, such as a standalone Heading. Advanced should show only the "Apply globally" button with no radio group, and pushing to Global Styles should behave exactly as it does on trunk.
Try the same steps with an Accordion. Select an Accordion Heading inside one of the items, and check the sibling option reads "in this Accordion" and applies to the headings in the other items.
Activate a classic theme, such as Twenty Twenty-One. The "Styles" control should now appear for a button inside Buttons, with the sibling scope only and no radio group, and should not appear for a standalone Heading.
Not every `var:preset|…` value is backed by a block attribute. A spacing
size, a link colour and a per-side border colour are all stored in `style`
on the source block, but `getSiblingStylesUpdate` treated any preset value
as attribute-carried: it cleared the sibling's value at that path and never
wrote the new one, so applying such a row silently did nothing.
Only clear the path when the row actually has a preset attribute to carry
the value, and copy everything else into `style` as-is.
Also clear a preset attribute the sibling already has when a custom value is
copied over the same path, so the leftover preset class can't keep winning.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
`getSiblingCurrentValue` read a single `primaryPath`, which doesn't describe
a grouped row. For the flat border row that path is `border`, so the whole
object came back including the radius and the per-side sub-objects that have
rows of their own: siblings differing only in radius reported "Varies", and
because `border` has no entry in `STYLE_PATH_TO_PRESET_BLOCK_ATTRIBUTE`, a
sibling's `borderColor` preset was invisible. A link colour row also writes
the hover colour but never compared it, hiding a difference it overwrites.
Compare across every path the row writes, and assemble a border row's
displayed value from the properties it actually covers.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
When a link-color row contains only the hover path, primaryPath still points to the unset base color, so siblings sharing a hover color show “—” even though Apply will overwrite that value. Derive the displayed value from the covered hover path when the primary path is unset.
Resolve inherited global styles when displaying current values
The “Current” value is derived only from local sibling attributes, so siblings that all inherit the same Global Styles value show “—” (and an explicit equivalent on one sibling becomes “Varies”) instead of the value they currently share. Resolve unset paths against the merged block style before displaying and comparing them.
When a sibling inherits this style from Global Styles, these reads return undefined, so “Current” shows “—” (or “Varies” against an equivalent explicit override) even though applying will replace a real rendered value. Resolve missing local paths against the merged block-type styles before comparing and formatting them.
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.
If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.
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
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?
Part of #76330
Alternative to #77097
Adds a second scope to the Styles control in the block Advanced panel, so a block's styles can be applied to the other blocks of its type inside the parent they share, as well as to every block of that type across the site.
Why?
There's currently no way to share the styles of an inner block with its siblings. If an Accordion has five headings, or a Tabs block has four panels, each one has to be styled by hand, and adding a new item means re-applying everything. See #76330 for more details.
This PR takes the approach from #77097, but builds it on the current version of the control rather than the one #77097 was written against. Since that PR was opened, #79839 gave "Apply globally" a review modal where each style is a row you can tick, and #80990 renamed the file. Reusing the review modal also fixes the main weakness of the earlier prototype, which copied every style attribute at once and overwrote whatever the siblings already had.
How?
A new
useSiblingScopehook walks up from the selected block to the nearest ancestor that holds more than one block of the same type, and returns that ancestor's title along with the blocks to apply to. For an Accordion Heading that ancestor is the Accordion; for a Tab Panel it's Tab Panels; for a Button it's Buttons. Blocks of the same type anywhere inside the ancestor count, not just immediate children, because the blocks that should match are usually a level or two down.When both scopes are available the control shows a radio group, and Global Styles stays selected by default, so nothing changes for existing users unless the sibling scope is chosen. Both scopes then open the same review modal, and only the ticked rows are applied. On the sibling scope the "Current" column means the value the siblings already share, or "Varies" when they disagree, since there's no single current value to show across several blocks.
Testing Instructions
Screenshots or screencast
Use of AI Tools
Claude Code