Global Styles: Show the inherited-from breadcrumb in the override indicator tooltip - #80757
Draft
annezazu wants to merge 21 commits into
Draft
Global Styles: Show the inherited-from breadcrumb in the override indicator tooltip#80757annezazu wants to merge 21 commits into
annezazu wants to merge 21 commits into
Conversation
…values Iterates on how block-inspector controls signal that a value locally overrides one inherited from Global Styles (follow-up to WordPress#77894 / WordPress#80506). - Nothing at rest: an inheriting control shows the inherited value with no marker (removes the at-rest dotted-underline label treatment). - On a local override, a small filled diamond appears next to the control with an "Overrides inherited styles" tooltip. - The diamond is a status indicator only and performs no action; clearing a local override relies on the panel's existing reset options. Replaces the interactive InheritanceResetButton with a shared InheritanceOverrideIndicator (a Button hosting a filled-diamond SVG wrapped in a @wordpress/ui Tooltip), used by the standard InheritanceToolsPanelItem controls and the custom color, gradient, shadow, duotone, and background image controls. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Addresses review feedback: the diamond's purpose is to reveal the "Overrides inherited styles" explanation, which is an infotip, not a tooltip (a tooltip is only for the accessible name of an icon button). Uses @wordpress/ui Popover with an openOnHover trigger so the content is reachable by hover, keyboard focus, and tap — a tooltip is unavailable to touch and screen-reader users. Also fills in the PR number in the CHANGELOG entry. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Reverts the infotip in favour of the @wordpress/ui Tooltip, per the accessibility review on WordPress#80649: the entire message is already the trigger's accessible name, so the infotip's Popover.Title and Popover.Description only duplicated it and screen readers announced the same string three times. A tooltip popup is visual-only, which keeps the aria-label as the single source of truth. The trigger goes back to an enabled Button whose only job is to host the tooltip, so tapping it still performs no action. Also inlines the Diamond SVG into the indicator and trims the JSDoc, which had grown to restate the review discussion. Co-Authored-By: Claude <noreply@anthropic.com>
`InheritanceOverrideIndicator` hand-rolled a Tooltip.Root/Trigger/Popup wrapper
around a Button, which is what Button already does for itself: with a `label`
and no children it renders its own tooltip and mirrors the string into
`aria-label`. Collapsing to a single `<Button label icon />` drops the wrapper,
the duplicated label constant and the `@wordpress/ui` import.
Passing the diamond through the `icon` prop instead of as children lets `Icon`
size the SVG and adds the `has-icon` class, so most of the CSS that existed to
undo the default Button chrome (sizing, padding, background, box-shadow,
cursor, text-transform) is no longer needed. `size="small"` replaces the
`__next40pxDefaultSize={ false }` opt-out and its lint exemption.
Co-Authored-By: Claude <noreply@anthropic.com>
The WordPress#77894 entry had been rewritten in place to describe the final diamond indicator, which erased the fact that the at-rest treatment shipped as a dotted underline plus inline reset and only later changed. Restore that entry to its original wording and add a separate WordPress#80649 entry for removing the dotted underline and reset affordance in favour of the local-override diamond. Co-Authored-By: Claude <noreply@anthropic.com>
Drop the redundant `carries no reset action or menu` case (the indicator's lack of a reset is already covered where it matters) and the explanatory comments that merely restated what the assertions already show. Also tighten the background-image `hasLocalOverride` comment. Co-Authored-By: Claude <noreply@anthropic.com>
Both tests asserted that no "Reset to inherited value" button renders, but the override indicator no longer has any reset control — that label exists nowhere in the source, so the assertions were always trivially true. Remove them and simplify the indicator test to just check the diamond renders. Co-Authored-By: Claude <noreply@anthropic.com>
Condense the JSDoc and SCSS comments in the inheritance module — they had grown to restate design rationale and CSS mechanics at length — to the point each one needs. Also drop the "Reset to inherited value" absence checks from the border-panel shadow tests; that label no longer exists in the source, so the assertions were always trivially true. The real "remove" button assertions, which cover actual behavior, stay. Co-Authored-By: Claude <noreply@anthropic.com>
The reset button, override indicator and contrast warning each claimed the same absolutely-positioned slot at the toggle's inline end, so they could only be shown one at a time and the label's reserved space was hardcoded per combination. Group them in a single positioned row instead, and derive the label's max-width from how many buttons that row actually holds, so all three can coexist and the label always keeps clear of them. Also make the label a FlexBlock so a long name shrinks itself rather than squashing the color indicator next to it. Co-Authored-By: Claude <noreply@anthropic.com>
The reset button and the override indicator shared one absolutely-positioned slot at the toggle's inline end, so they could only be shown one at a time, and the toggle reserved a fixed inline-end padding whether or not anything was rendered there. Group them in a single positioned row instead, and derive the toggle's padding from how many buttons that row actually holds, so both can coexist and the label reserves no space when there is no action at all. This mirrors the layout the color panel now uses. Co-Authored-By: Claude <noreply@anthropic.com>
The remove button and the override indicator shared one absolutely-positioned slot at the toggle's inline end, so they could only be shown one at a time. Group them in a single positioned row instead, and derive the toggle's inline-end padding from how many buttons that row actually holds, so both can coexist and no space is reserved when there is no action at all. The toggle label also had no truncation, so a long translation ran under the actions row. Render it as a FlexBlock and clip it with an ellipsis, which keeps the shadow icon from being squashed as well. This mirrors the layout the color and background image panels now use. Co-Authored-By: Claude <noreply@anthropic.com>
The reset button and the override indicator shared one absolutely-positioned slot at the toggle's inline end, so they could only be shown one at a time. Group them in a single positioned row instead, and derive the toggle's inline-end padding from how many buttons that row actually holds, so both can coexist and no space is reserved when there is no action at all. The toggle label had no truncation styles at all, so a long name ran under the actions row. Render it as a FlexBlock and clip it with an ellipsis, which keeps the duotone swatches from being squashed as well. With this the color, background image, shadow and duotone controls all use the same layout, so the override indicator no longer borrows any control's reset slot and the placement overrides it needed can go. Co-Authored-By: Claude <noreply@anthropic.com>
The toggle carried a -4px top margin that pulled it above the centered header row, which became visible once the override indicator sat next to it. The HStack already centers its children, so drop the styled wrapper and render the Button directly. Co-Authored-By: Claude <noreply@anthropic.com>
The shadow control no longer renders the override indicator or hides the remove button for a local override, so these assertions no longer describe the UI. Remove them, leaving the test as a render smoke check. Co-Authored-By: Claude <noreply@anthropic.com>
Remove the ENABLE_GLOBAL_STYLES_INHERITANCE flag that gated the inherited Global Styles treatment on IS_GUTENBERG_PLUGIN. The feature is now enabled in Core builds: panels default showInheritanceLabelIndicators to true, the useResolvedStyle cascade merge always runs, and the link-color sync uses the single inheritance-aware comparison. Drop the -core test files that covered the now-removed flag-off path. Co-Authored-By: Claude <noreply@anthropic.com>
Each toggle repeated a per-count comment explaining which buttons the reserved space was for. The button combinations differ per control and drift as buttons are added, so state the shared rule once instead: the actions are absolutely positioned, so the toggle reserves room on the right for as many of them as are rendered. Co-Authored-By: Claude <noreply@anthropic.com>
The reset button was the toggle's only trailing control, but the label's reserved right-hand space is now keyed off an `__actions` element and its child count, as in the background, shadow and duotone panels. Wrap the button in a `Stack` carrying that class so the sizing rule applies and further actions can join the same row. Co-Authored-By: Claude <noreply@anthropic.com>
The indicator exists only to host its tooltip, so rendering it as a Button meant suppressing the click it advertised. Render a `role="img"` span with `tabIndex` through `Tooltip.Trigger` instead: the tooltip stays reachable by keyboard, but the element carries no interactive semantics. Styles that came from Button (size, focus ring) move to the span. Co-Authored-By: Claude <noreply@anthropic.com>
…icator tooltip Follow-up to WordPress#80649. When a block-inspector control locally overrides a value inherited from Global Styles, the override indicator's tooltip now names where that value comes from, e.g. "Overrides inherited styles from Blocks › Group › Variations › Subtitle". Root/default-sourced overrides and the Global Styles screens keep the bare "Overrides inherited styles" label. Follows the approach settled on in WordPress#80150 (superseding the WordPress#79992 portal hack): breadcrumb part identifiers are recorded per source at resolve time and translated to titles in the block-editor layer, but rendered inside the existing diamond tooltip rather than a separate label tooltip. - global-styles-engine: resolve-style.ts source-map entries carry { breadcrumb, blockName, variation } (block-agnostic; no title resolution). - block-editor: inheritance/index.js adds the translation helpers and renders the breadcrumb in InheritanceOverrideIndicator; the source map is threaded through the hooks to every panel and bespoke control (Typography, Color, Dimensions, Border, Background, Filters, Shadow, Aspect ratio). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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?
Adds a Global Styles breadcrumb to the override-indicator tooltip in the block inspector. When a control locally overrides a value inherited from Global Styles, the tooltip now names where that inherited value comes from — e.g.:
Overrides inherited styles.Overrides inherited styles from multiple sources.Important
Builds on #80649 (the override-indicator iteration). Until that lands, this PR's diff includes #80649's commits; review the last commit (
Global Styles: Show the inherited-from breadcrumb…) for the breadcrumb change in isolation. Rebase once #80649 merges.Why?
#80649 marks that a control overrides an inherited value, but not what it overrides. The breadcrumb closes that gap without leaving the inspector, reviving the intent of the earlier (closed) explorations in #79992 / #80150.
How?
Follows the approach settled on in #80150 (which superseded the #79992
createPortalDOM hack): breadcrumb part identifiers are recorded per source at resolve time and translated to titles in the block-editor layer — but rendered inside the existing diamond tooltip rather than a separate label tooltip, so no component public APIs change.@wordpress/global-styles-engine(resolve-style.ts): each source-map entry now carries{ breadcrumb, blockName, variation }. Block-agnostic — it records generic part identifiers plus the slugs it already receives; no title resolution in the engine.@wordpress/block-editor(global-styles/inheritance/index.js): translation helpers (getTranslatedBreadcrumb,getOverrideTooltipText,getCommonOverrideTooltipText) resolve titles viagetBlockType/registered block styles and drop the redundant rootStylesnode;InheritanceOverrideIndicatorrenders the result. The source map is threaded through the block-supports hooks to every panel and bespoke control.Wired everywhere inherited styles surface: Typography (incl. Color), Color (link + per-element), Dimensions (incl. Aspect ratio), Border (incl. Shadow), Background (image, color, gradient), Filters (duotone).
Testing Instructions
Note: spacing/border/dimensions breadcrumbs only appear for values inherited from a block or variation layer (root-level ones don't cascade to blocks by design).
Tests
global-styles-engine:resolve-style.test.tsasserts the breadcrumb/blockName/variation metadata per layer.block-editor:inheritance/test/index.jscovers the translation helpers and indicator rendering.🤖 Generated with Claude Code