Skip to content

Block Style States: Add -current custom state for Nav Link - #78769

Open
MaggieCabrera wants to merge 11 commits into
trunkfrom
add/nav-link-current-style-state
Open

MaggieCabrera wants to merge 11 commits into
trunkfrom
add/nav-link-current-style-state

Conversation

@MaggieCabrera

@MaggieCabrera MaggieCabrera commented May 28, 2026 •

Copy link
Copy Markdown
Contributor

What?

Closes #38277. Part of #79283.

You can now style the current menu item of a Navigation Link, in Global Styles and per block. Pick Current in the new Item group of the States dropdown, next to Viewport and Pseudo state.

Why?

Styling the current menu item meant writing theme.json or custom CSS by hand. theme.json already supports -current for Navigation Link, but there was no UI for it.

How?

  • Per-block styles scope the block's class to the selector the block declares for -current, wrapped in :is(): .wp-states-1a2b3c4d:is(.wp-block-navigation .current-menu-item). The block's selector and the theme.json output don't change.
  • Global Styles offers Current only at the default viewport and not for style variations, because theme.json doesn't accept -current inside either. Per-block styles can combine Current with a viewport.
  • Custom CSS isn't output for Current per block yet, so the block's Custom CSS panel is hidden while Current is selected.

Testing Instructions

  1. Create a page, and add a Navigation block to it with a link to the page itself and a link somewhere else.
  2. In the site editor, go to Styles > Blocks > Navigation Link. Open States and pick Current. Set a font size, such as Large, and save.
  3. View the page. The link to the page uses the new font size, and the other link doesn't.
  4. Back in the page, select the link to the page. Open the State menu in the block card, pick Current, set another font size and save.
  5. View the page again. The link uses the block's font size.

Testing Instructions for Keyboard

  1. Tab to the States button and press Enter.
  2. Use the arrow keys to reach Current and press Enter. A Current badge shows under the button.

Screenshots or screencast

Global Styles:

01-global-styles-states-menu 02-global-styles-current

Block inspector, with the Current state previewed on the canvas:

03-block-states-menu 04-block-current

Front end, where About is the current menu item:

05-front-end

Use of AI Tools

Ported to trunk with Claude Code (Opus 5.5). All output reviewed and validated by the author.

🤖 Generated with Claude Code

@github-actions github-actions Bot added [Package] Block library /packages/block-library [Package] Block editor /packages/block-editor labels May 28, 2026
@github-actions

github-actions Bot commented May 28, 2026 •

Copy link
Copy Markdown

Size Change: +801 B (+0.01%)

Total Size: 8.44 MB

📦 View Changed
Filename Size Change
build/scripts/block-editor/index.min.js 381 kB +680 B (+0.18%)
build/scripts/block-library/index.min.js 324 kB -4 B (0%)
build/scripts/edit-site/index.min.js 296 kB +47 B (+0.02%)
build/scripts/editor/index.min.js 466 kB +78 B (+0.02%)

compressed-size-action

@MaggieCabrera
MaggieCabrera force-pushed the add/nav-link-current-style-state branch from 9e53351 to 80ad5da Compare May 28, 2026 10:25
@github-actions github-actions Bot removed the [Package] Block library /packages/block-library label May 28, 2026
@github-actions

github-actions Bot commented May 28, 2026 •

Copy link
Copy Markdown

Flaky tests detected in 4223a4b.
Some 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.

🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/27193382063
📝 Reported issues:

@jasmussen

Copy link
Copy Markdown
Contributor

@MaggieCabrera not sure if it's this PR or not, but I'd love the ability to style the active menu item of a navigation. Is this mockup helpful, and can we do it?

image

Let me know if it's useful to attach to an issue instead.

@MaggieCabrera

MaggieCabrera commented Aug 12, 2026 •

Copy link
Copy Markdown
Contributor Author

@MaggieCabrera not sure if it's this PR or not, but I'd love the ability to style the active menu item of a navigation. Is this mockup helpful, and can we do it?

Let me know if it's useful to attach to an issue instead.

We probably need to have multiple PRs to also bring the pseudo states to the block too. It's in my plans, hopefully I can get to it for 7.2

@jasmussen

Copy link
Copy Markdown
Contributor

Fantastic. Please ping me if there's anything you need that I can help with.

MaggieCabrera added a commit that referenced this pull request Oct 14, 2026
Adds a custom state group, labeled "Item", between the Viewport and
Pseudo state groups of StateControl, and teaches StateControlBadges to
show and summarize the selected custom state. The three groups now share
one StateMenuGroup renderer.

Ported from #78769.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@MaggieCabrera
MaggieCabrera force-pushed the add/nav-link-current-style-state branch from 4223a4b to 965ce13 Compare October 14, 2026 23:09
MaggieCabrera added a commit that referenced this pull request Oct 14, 2026
Adds `custom` to the selected block style state, next to `viewport` and
`pseudo`, so the store and the style path helpers can address a custom
state such as Navigation Link's `-current`. The style path order is
viewport, custom, pseudo, so Mobile, Current and Hover are stored at
`style['@mobile']['-current'][':hover']`. `hasSelectedBlockStyleState`
now also returns true for a selected custom state.

Ported from #78769.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaggieCabrera added a commit that referenced this pull request Oct 14, 2026
Generates per-block CSS for a custom state such as Navigation Link's
`-current`, including its nested pseudo states and inside a viewport.
The rules scope the block-instance selector to the selector the block
declares in `selectors.states`, wrapped in `:is()`, so feature selectors
keep the state on the block's wrapper, as in
`.wp-elements-1:is(.wp-block-navigation .current-menu-item) > a`.

Custom state keys are no longer treated as root declarations, and the
canvas preview forces a selected custom state onto the block, layering
`-current` and `-current.:hover` when both are selected.

Ported from #78769.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaggieCabrera added a commit that referenced this pull request Oct 14, 2026
Renders per-block CSS for a custom state such as Navigation Link's
`-current`, including its nested pseudo states and inside a viewport,
mirroring the editor. The rules scope the block's `wp-states-*` class to
the selector the block declares in `selectors.states`, wrapped in
`:is()`, so a feature selector keeps the state on the block's wrapper.

Custom state keys are no longer treated as root declarations.

Ported from #78769.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaggieCabrera added a commit that referenced this pull request Oct 14, 2026
Adds `customState` to the private `resolveStyle` context and passes the
selected block style state's `custom` value through, so the block
inspector shows the Global Styles values a block inherits in a custom
state such as Navigation Link's `-current`. The state path order is
viewport, custom, pseudo, matching the block-editor state helpers.

Ported from #78769.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaggieCabrera added a commit that referenced this pull request Oct 14, 2026
Offers Navigation Link's `-current` state as "Current" in an Item group
of the block card's State dropdown, when the block declares a selector
for it, and shows it in the state badges.

A selected custom state counts as a style state being edited, can be
previewed on the canvas, and hides the layout and position controls the
same way a pseudo state does. The Custom CSS panel is hidden for custom
states because their custom CSS isn't output yet.

Ported from #78769.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaggieCabrera added a commit that referenced this pull request Oct 14, 2026
Offers Navigation Link's `-current` state as "Current" in an Item group
of the block screen's States dropdown, so the current menu item can be
styled in Global Styles. The state path order is viewport, custom,
pseudo, as in the block editor.

theme.json only accepts a custom state at the top level of a block's
styles, so Current isn't offered for a viewport or a block style
variation, or when the block declares no selector for it.

Ported from #78769.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions github-actions Bot removed the [Package] Block library /packages/block-library label Oct 14, 2026
@MaggieCabrera MaggieCabrera changed the title Block Style States: Add @current custom state for Nav Link Block Style States: Add -current custom state for Nav Link Oct 14, 2026
@github-actions

github-actions Bot commented Oct 14, 2026 •

Copy link
Copy Markdown

🤖 PR meta 🤖

🎉 Props

Unlinked Accounts

The following contributors have not linked their GitHub and WordPress.org accounts: @itsdavidmorgan, @le-sgs.

Contributors, please read how to link your accounts to ensure your work is properly credited in WordPress releases.

If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.

Unlinked contributors: itsdavidmorgan, le-sgs.

Co-authored-by: MaggieCabrera <onemaggie@git.wordpress.org>
Co-authored-by: mikachan <mikachan@git.wordpress.org>
Co-authored-by: jasmussen <joen@git.wordpress.org>
Co-authored-by: jorgefilipecosta <jorgefilipecosta@git.wordpress.org>
Co-authored-by: andrewserong <andrewserong@git.wordpress.org>
Co-authored-by: scruffian <scruffian@git.wordpress.org>
Co-authored-by: paaljoachim <paaljoachim@git.wordpress.org>
Co-authored-by: HILAYTRIVEDI <hilayt24@git.wordpress.org>
Co-authored-by: javierarce <javiarce@git.wordpress.org>
Co-authored-by: fabiankaegy <fabiankaegy@git.wordpress.org>
Co-authored-by: mtias <matveb@git.wordpress.org>
Co-authored-by: carolinan <poena@git.wordpress.org>
Co-authored-by: eric-michel <ytfeldrawkcab@git.wordpress.org>
Co-authored-by: cbirdsong <cbirdsong@git.wordpress.org>
Co-authored-by: jameskoster <jameskoster@git.wordpress.org>
Co-authored-by: shaunandrews <shaunandrews@git.wordpress.org>
Co-authored-by: nathanrodrigues2111 <nathanrbsf@git.wordpress.org>
Co-authored-by: masteradhoc <masteradhoc@git.wordpress.org>
Co-authored-by: deryckoe <deryck@git.wordpress.org>
Co-authored-by: draganescu <andraganescu@git.wordpress.org>
Co-authored-by: onetrev <onetrev@git.wordpress.org>
Co-authored-by: jarekmorawski <jarekmorawski@git.wordpress.org>
Co-authored-by: simonwammerfors <simonwammerfors@git.wordpress.org>
Co-authored-by: mateuswetah <wetah@git.wordpress.org>
Co-authored-by: t-hamano <wildworks@git.wordpress.org>
Co-authored-by: colinduwe <colind@git.wordpress.org>
Co-authored-by: matiasbenedetto <mmaattiiaass@git.wordpress.org>
Co-authored-by: davewhitley <drw158@git.wordpress.org>
Co-authored-by: hanneslsm <hanneslsm@git.wordpress.org>
Co-authored-by: JiveDig <jivedig@git.wordpress.org>
Co-authored-by: Bovelett <annebovelett@git.wordpress.org>
Co-authored-by: hadamlenz <adrock42@git.wordpress.org>
Co-authored-by: ethanclevenger91 <eclev91@git.wordpress.org>
Co-authored-by: getdave <get_dave@git.wordpress.org>

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 props-bot label to refresh.

📦 Bundle size

Size Change: +728 B (+0.01%)

Total Size: 8.96 MB

📦 View Changed
Filename Size Change
build/scripts/block-editor/index.min.js 600 kB +846 B (+0.14%)
build/scripts/block-library/index.min.js 442 kB +87 B (+0.02%)
build/scripts/components/index.min.js 370 kB -509 B (-0.14%)
build/scripts/edit-site/index.min.js 417 kB +88 B (+0.02%)
build/scripts/editor/index.min.js 612 kB +216 B (+0.04%)

13d3197 Run

⚡ Performance

Show the results

Client side metrics exclude the server response time.

front-end-block-theme

Metric ae7942b trunk % Change
timeToFirstByte 50.1 ms +10.68% -3.39% 50.4 ms +12.1% -5.75% -0.6%
largestContentfulPaint 86 ms +6.98% -2.33% 92 ms +0% -10.87% -6.52%
lcpMinusTtfb 34.2 ms +20.76% -2.92% 33.8 ms +25.3% -1.92% 1.18%
wpBeforeTemplate 25.4 ms +10.87% -4.45% 24.89 ms +11.13% -3.25% 2.05%
wpTemplate 20.54 ms +5.7% -5.16% 20.8 ms +5.14% -5.87% -1.25%
wpTotal 46.23 ms +9.47% -3.85% 46.41 ms +11.55% -6.1% -0.39%
wpMemoryUsage 7.65 MB +0% -0% 7.62 MB +0% -0% 0.46%
wpDbQueries 16 +0% -0% 16 +0% -0% 0%

front-end-classic-theme

Metric ae7942b trunk % Change
timeToFirstByte 42.15 ms +5.93% -4.27% 42.3 ms +4.73% -2.01% -0.35%
largestContentfulPaint 96 ms +6.25% -0% 96 ms +0% -0% 0%
lcpMinusTtfb 54.95 ms +4% -2.18% 53.7 ms +1.58% -3.17% 2.33%
wpBeforeTemplate 22.18 ms +7.98% -2.52% 22.39 ms +9.2% -0.98% -0.94%
wpTemplate 16.09 ms +5.03% -4.04% 16.24 ms +2.65% -3.51% -0.92%
wpTotal 38.82 ms +5.56% -4.59% 39.06 ms +5.07% -2.28% -0.61%
wpMemoryUsage 6.33 MB +0% -0% 6.30 MB +0% -0% 0.57%
wpDbQueries 13 +0% -0% 13 +0% -0% 0%

media-processing

Metric ae7942b trunk % Change
mediaProcessingJpeg 400.34 ms +1.32% -1.06% 397.1 ms +0.56% -1.62% 0.82%
mediaProcessingAvif 5802.87 ms +0.64% -0.07% 5797.56 ms +0.13% -0.07% 0.09%
mediaProcessingJpegToAvif 3967.55 ms +0.48% -0.09% 3965.97 ms +0.25% -0.13% 0.04%

media-upload

Metric ae7942b trunk % Change
jpegUploadProcessing 1486.53 ms +32.03% -3.52% 1436.18 ms +1.13% -0.84% 3.51%
pngUploadProcessing 216.72 ms +9.12% -3.98% 215.3 ms +5.77% -5.43% 0.66%
largeJpegUploadProcessing 1431.13 ms +0.27% -0.99% 1418.69 ms +0.73% -0.4% 0.88%
multipleImageUploadProcessing 1606.82 ms +7.65% -1.54% 1576.04 ms +30.96% -1.02% 1.95%

post-editor

Metric ae7942b trunk % Change
serverResponse 502.44 ms +4.4% -5.29% 524.34 ms +3.35% -2.53% -4.18%
firstPaint 307.2 ms +48.45% -22.48% 295.18 ms +67.47% -10.96% 4.07%
domContentLoaded 1283.55 ms +2.11% -1.32% 1272.56 ms +0.56% -2.44% 0.86%
loaded 1284.98 ms +2.1% -1.32% 1274 ms +0.58% -2.42% 0.86%
firstContentfulPaint 573.56 ms +3.13% -6.44% 557.98 ms +1.29% -1.53% 2.79%
firstBlock 3670.78 ms +2.07% -0.39% 3732.7 ms +3.05% -1.35% -1.66%
type 20.69 ms +1.84% -4.35% 19.15 ms +4.86% -8.98% 8.04%
typeWithoutInspector 20.22 ms +3.31% -1.19% 19.29 ms +2.13% -1.71% 4.82%
typeWithTopToolbar 27.99 ms +4.29% -3.54% 25.34 ms +1.93% -4.5% 10.46%
typeContainer 9.69 ms +10.11% -7.95% 9.44 ms +2.33% -6.46% 2.65%
focus 127.19 ms +8.07% -3.96% 133.56 ms +8.18% -9.48% -4.77%
firstFocus 245.67 ms +0% -0% 239.49 ms +0% -0% 2.58%
selectAll 616.88 ms +4.6% -0.46% 616.68 ms +1.62% -3.72% 0.03%
listViewOpen 85.93 ms +14.64% -9.18% 85.11 ms +3.01% -12.91% 0.96%
inserterOpen 43.75 ms +7.11% -6.61% 43.83 ms +5.54% -5.13% -0.18%
inserterHover 12.89 ms +14.12% -4.65% 12.5 ms +12.48% -3.84% 3.12%
inserterSearch 9.65 ms +5.49% -4.35% 9.34 ms +5.57% -9.53% 3.32%
loadPatterns 694.71 ms +1.67% -3.17% 697.66 ms +4.91% -2.86% -0.42%
wpTotal 492.12 ms +4.62% -5.43% 512.96 ms +3.66% -2.25% -4.06%
wpMemoryUsage 13.59 MB +0% -0% 13.56 MB +0% -0% 0.25%
wpDbQueries 55 +0% -1.82% 55 +0% -1.82% 0%

site-editor

Metric ae7942b trunk % Change
serverResponse 485.79 ms +2.82% -4.11% 479.37 ms +3.17% -3.17% 1.34%
firstPaint 282.24 ms +12.07% -11.15% 249.77 ms +16.02% -6.68% 13%
domContentLoaded 1283.89 ms +3.66% -1.1% 1293.95 ms +0.73% -2.12% -0.78%
loaded 1285.1 ms +3.65% -1.09% 1295.23 ms +0.72% -2.11% -0.78%
firstContentfulPaint 538.64 ms +6.06% -1.65% 539.11 ms +2.46% -3.24% -0.09%
firstBlock 4802.3 ms +0.93% -1.71% 4823.25 ms +0.46% -1.97% -0.43%
type 19.98 ms +3.25% -4.05% 18.77 ms +4.58% -5.22% 6.45%
navigate 121.74 ms +16.44% -0.75% 112.35 ms +16.56% -2.65% 8.36%
loadPatterns 1320.84 ms +5.11% -3.26% 1365.43 ms +6.41% -5.67% -3.27%
loadPages 1050.79 ms +0.62% -2.02% 1023.39 ms +3.31% -1.06% 2.68%
wpTotal 476.11 ms +2.79% -4.18% 469.58 ms +3.23% -3.25% 1.39%
wpMemoryUsage 12.63 MB +0% -0% 12.60 MB +0% -0% 0.29%
wpDbQueries 44 +2.27% -0% 44 +2.27% -0% 0%

13d3197 Run

🏁 Flaky tests

Some 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 /test/e2e/specs/editor/various/core-settings.spec.js, passed after 1 failed attempt.
Error: expect(received).toStrictEqual(expected) // deep equality

- Expected  - 1
+ Received  + 1

  Array [
    "rewrite_rules",
-   "SERIALIZED DATA",
+   "",
  ]
    at forEach (/home/runner/work/gutenberg/gutenberg/test/e2e/specs/editor/various/core-settings.spec.js:46:26)
    at /home/runner/work/gutenberg/gutenberg/test/e2e/specs/editor/various/core-settings.spec.js:43:35

13d3197 Run

MaggieCabrera added a commit that referenced this pull request Oct 14, 2026
Offers Navigation Link's `-current` state as "Current" in an Item group
of the block card's State dropdown, when the block declares a selector
for it, and shows it in the state badges.

A selected custom state counts as a style state being edited, can be
previewed on the canvas, and hides the layout and position controls the
same way a pseudo state does. The Custom CSS panel is hidden for custom
states because their custom CSS isn't output yet.

Ported from #78769.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaggieCabrera added a commit that referenced this pull request Oct 14, 2026
Offers Navigation Link's `-current` state as "Current" in an Item group
of the block screen's States dropdown, so the current menu item can be
styled in Global Styles. The state path order is viewport, custom,
pseudo, as in the block editor.

theme.json only accepts a custom state at the top level of a block's
styles, so Current isn't offered for a viewport or a block style
variation, or when the block declares no selector for it.

Ported from #78769.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@MaggieCabrera
MaggieCabrera force-pushed the add/nav-link-current-style-state branch from 965ce13 to f24e802 Compare October 14, 2026 23:22
MaggieCabrera added a commit that referenced this pull request Oct 14, 2026
Links WordPress/wordpress-develop#14285, which backports the custom
state output in `lib/block-supports/states.php`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@MaggieCabrera MaggieCabrera added the [Type] Enhancement A suggestion for improvement. label Oct 14, 2026
@MaggieCabrera MaggieCabrera added the [Feature] Style States Related to block style states (currently viewport and pseudo-states) label Oct 14, 2026
@MaggieCabrera
MaggieCabrera marked this pull request as ready for review October 14, 2026 23:29

@mikachan mikachan left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this! Scoping the instance class with :is() is a nice approach. The block's selector and the theme.json output are staying the same, the PHP and JS sides build the scoped selector the same way, and the scope goes into the wp-states-* hash. Also, limiting Global Styles to the default viewport and no style variations makes sense based on what theme.json accepts.

Most of my inline comments are about how styles stack when Current is combined with Hover, I don't think there's anything major here.

* @param {Object} selectedState Selected block style state.
* @return {Object|undefined} Style value for the canvas preview.
*/
export function getCanvasStateStyleValue( style, selectedState ) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On the frontend, a current link being hovered matches three rules:

Rule Specificity
.wp-states-x:hover (Hover) 0,2,0
.wp-states-x:is(.wp-block-navigation .current-menu-item) (Current) 0,3,0
.wp-states-x:is(…):hover (Current + Hover) 0,4,0

For Current + Hover, this preview merges only -current and -current.:hover. A plain :hover is left out, so the canvas and the frontend can be different. For example, if the following is set:

  • Hover: underline
  • Current: red text
  • Current + Hover: bold

Hovering the current link on the frontend gives underline, red and bold. The Current + Hover preview shows red and bold, with no underline.

Could the plain pseudo state go in at the bottom, so the merge follows the frontend's specificity (Hover, then Current, then Current + Hover)? Something like:

 states = [
     { ...selectedState, custom: DEFAULT_BLOCK_STYLE_STATE.custom },
     { ...selectedState, pseudo: DEFAULT_BLOCK_STYLE_STATE.pseudo },
     ...states,
 ];

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for the suggestion! I did this on fad31bb

];

// For a non-default state (pseudo and/or viewport), layer each layer's
// For a non-default state (viewport, custom and/or pseudo), layer each layer's

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With Current + Hover selected, each layer adds only its ['-current'][':hover'] slice on top of the base, because getStateSlice() (line 300) reads the exact path. The -current and plain :hover slices are never added. So if Global Styles sets a Current font size, the panel won't show it as inherited under Current + Hover, even though the frontend applies it.

This should probably follow the same order as the canvas preview in getCanvasStateStyleValue(): Hover, then Current, then Current + Hover, each above the base layers.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed on 1b49627. Also added a unit test for the new helper function

await expect( currentItem ).toHaveClass( /wp-states-/ );
// The default "Large" font size preset is 36px.
await expect( currentItem ).toHaveCSS( 'font-size', '36px' );
await expect( otherItem ).not.toHaveCSS( 'font-size', '36px' );

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This negative assertion can't fail. otherItem has no block styles, so it would fail the 36px check even without the :is() scope. We would need to test that the styled link loses the style when it isn't current.

Could you add a check that visits another page that shows the same menu (or the front page) and asserts that "Current Link" isn't 36px there?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Solved on 13d3197

MaggieCabrera and others added 11 commits October 19, 2026 18:58
Adds a custom state group, labeled "Item", between the Viewport and
Pseudo state groups of StateControl, and teaches StateControlBadges to
show and summarize the selected custom state. The three groups now share
one StateMenuGroup renderer.

Ported from #78769.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Adds `custom` to the selected block style state, next to `viewport` and
`pseudo`, so the store and the style path helpers can address a custom
state such as Navigation Link's `-current`. The style path order is
viewport, custom, pseudo, so Mobile, Current and Hover are stored at
`style['@mobile']['-current'][':hover']`. `hasSelectedBlockStyleState`
now also returns true for a selected custom state.

Ported from #78769.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Generates per-block CSS for a custom state such as Navigation Link's
`-current`, including its nested pseudo states and inside a viewport.
The rules scope the block-instance selector to the selector the block
declares in `selectors.states`, wrapped in `:is()`, so feature selectors
keep the state on the block's wrapper, as in
`.wp-elements-1:is(.wp-block-navigation .current-menu-item) > a`.

Custom state keys are no longer treated as root declarations, and the
canvas preview forces a selected custom state onto the block, layering
`-current` and `-current.:hover` when both are selected.

Ported from #78769.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Renders per-block CSS for a custom state such as Navigation Link's
`-current`, including its nested pseudo states and inside a viewport,
mirroring the editor. The rules scope the block's `wp-states-*` class to
the selector the block declares in `selectors.states`, wrapped in
`:is()`, so a feature selector keeps the state on the block's wrapper.

Custom state keys are no longer treated as root declarations.

Ported from #78769.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Adds `customState` to the private `resolveStyle` context and passes the
selected block style state's `custom` value through, so the block
inspector shows the Global Styles values a block inherits in a custom
state such as Navigation Link's `-current`. The state path order is
viewport, custom, pseudo, matching the block-editor state helpers.

Ported from #78769.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Offers Navigation Link's `-current` state as "Current" in an Item group
of the block card's State dropdown, when the block declares a selector
for it, and shows it in the state badges.

A selected custom state counts as a style state being edited, can be
previewed on the canvas, and hides the layout and position controls the
same way a pseudo state does. The Custom CSS panel is hidden for custom
states because their custom CSS isn't output yet.

Ported from #78769.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Offers Navigation Link's `-current` state as "Current" in an Item group
of the block screen's States dropdown, so the current menu item can be
styled in Global Styles. The state path order is viewport, custom,
pseudo, as in the block editor.

theme.json only accepts a custom state at the top level of a block's
styles, so Current isn't offered for a viewport or a block style
variation, or when the block declares no selector for it.

Ported from #78769.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Links WordPress/wordpress-develop#14285, which backports the custom
state output in `lib/block-supports/states.php`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
When Current and Hover are both selected, the canvas preview now merges
the plain `:hover` styles first, then `-current`, then `-current.:hover`.
This follows the front end's specificity, so a hovered current link looks
the same on the canvas as it does on the site.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
With Current and Hover both selected, each layer now adds its `:hover`,
`-current` and `-current.:hover` slices in that order, instead of only
`-current.:hover`. A Current font size set in Global Styles now shows as
inherited under Current + Hover, as it applies on the front end.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The previous negative check used a link without block styles, so it
couldn't fail. The test now visits the post that shows the same menu,
where the styled link isn't the current menu item, and checks its
Current font size doesn't apply there.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

[Feature] Style States Related to block style states (currently viewport and pseudo-states) [Package] Block editor /packages/block-editor [Type] Enhancement A suggestion for improvement.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Standardized way to modify interactive states (:hover, :focus .etc) for blocks

3 participants