Skip to content

Nav submenu: add support to style current submenu in theme.json - #76367

Open
MaggieCabrera wants to merge 7 commits into
trunkfrom
add-nav-submenu-state
Open

MaggieCabrera wants to merge 7 commits into
trunkfrom
add-nav-submenu-state

Conversation

@MaggieCabrera

@MaggieCabrera MaggieCabrera commented Mar 10, 2026 •

Copy link
Copy Markdown
Contributor

What?

Follow up to #75736

Following the discussion on the other PR, we are adding support for current state to the submenu block too

Why?

For consistency and to allow users more nunaced control over how they style their navigation blocks.

How?

We are adding support the same we did for the nav link, by adding it to the allowed blocks constant, adding a selector on block.json and modifying the schema andadding tests.

Testing Instructions

Add this to your theme.json, before this PR only the nav-link applied, now we can target submenus specifically.

"core/navigation-link": {
    "-current": { "color": { "text": "pink" } }
},
"core/navigation-submenu": {
    "-current": { "color": { "text": "green" } }
},

Screenshots or screencast

Before After
Screenshot 2026-03-10 at 17 20 40 Screenshot 2026-03-10 at 17 16 33

@github-actions github-actions Bot added the [Package] Block library /packages/block-library label Mar 10, 2026
@MaggieCabrera MaggieCabrera changed the title added support for the current submenu item Nav submenu: add support to style current submenu in theme.json Mar 10, 2026
Base automatically changed from add-nav-link-current-state to trunk March 10, 2026 16:27
@github-actions

github-actions Bot commented Mar 10, 2026 •

Copy link
Copy Markdown

Flaky tests detected in d352ea8.
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/29909695663
📝 Reported issues:

@MaggieCabrera
MaggieCabrera force-pushed the add-nav-submenu-state branch from c11d8b5 to 40b2cd6 Compare March 10, 2026 16:47
@MaggieCabrera
MaggieCabrera marked this pull request as ready for review March 10, 2026 16:55
@MaggieCabrera MaggieCabrera self-assigned this Mar 10, 2026
@github-actions

Copy link
Copy Markdown

Warning: Type of PR label mismatch

To merge this PR, it requires exactly 1 label indicating the type of PR. Other labels are optional and not being checked here.

  • Required label: Any label starting with [Type].
  • Labels found: [Package] Block library.

Read more about Type labels in Gutenberg. Don't worry if you don't have the required permissions to add labels; the PR reviewer should be able to help with the task.

Comment thread backport-changelog/7.1/11174.md Outdated
@scruffian

Copy link
Copy Markdown
Contributor

I'm a bit hesitant about this one. I think we should be moving in the direction of making navigation link and navigation submenu blocks simply variations of the same block. This will make that harder to do and moves us away from that direction. If this is a feature that we think themes will use then i might be a good compromise, however I'm struggling to think of a use case for it...

@getdave getdave left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

My main question is can you target the top level menu item represented by a submenu if it is current? I'm conscious it's a different block that core/navigation-link but you'd still want to be able to style the parent.

Styling menus within the submenu dropdown seems like a real edge case. Not sure if this is required but I'd defer to your theme expertise on that.

@MaggieCabrera

Copy link
Copy Markdown
Contributor Author

My main question is can you target the top level menu item represented by a submenu if it is current? I'm conscious it's a different block that core/navigation-link but you'd still want to be able to style the parent.

Styling menus within the submenu dropdown seems like a real edge case. Not sure if this is required but I'd defer to your theme expertise on that.

I've never personally needed to. That said, I don't think this PR is a must, but it certainly offers more flexibility at very little cost. I would love to hear what @WordPress/block-themers have to say about this.

@scruffian

Copy link
Copy Markdown
Contributor

My main question is can you target the top level menu item represented by a submenu if it is current? I'm conscious it's a different block that core/navigation-link but you'd still want to be able to style the parent.

Yes, the navigation-link selector also covers navigation-submenu links so it works in trunk already.

@t-hamano

t-hamano commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

I would like to check the status of this PR. Does this PR need to be shipped for 7.1?

It appears that this PR is not included in the core backport that has already been committed. Therefore, if we are to move forward with this PR, we will need to create a new core backport anyway.

@MaggieCabrera

Copy link
Copy Markdown
Contributor Author

I would like to check the status of this PR. Does this PR need to be shipped for 7.1?

It appears that this PR is not included in the core backport that has already been committed. Therefore, if we are to move forward with this PR, we will need to create a new core backport anyway.

I think we can remove it from 7.1, it's not clear that we even need/want it

@t-hamano t-hamano moved this from 🔎 Needs Review to 🦵 Punted to 7.2 in WordPress 7.1 Editor Tasks Jul 8, 2026
@jasmussen

Copy link
Copy Markdown
Contributor

7.2 or when it happens is fine. But wanted to comment on this:

it's not clear that we even need/want it

In case you're referring to the ability to style the current_menu_item visually in global styles, I personally really really want it ❤️ 🤞.

Then I could delete the following from my stylesheet:

.current-menu-item a {
	text-decoration: underline;
}

@luminuu

luminuu commented Jul 15, 2026

Copy link
Copy Markdown
Member

+1 for bringing this in, I've got this request multiple times in the past. It's just a small enhancement but I think it has a much bigger impact.

@getdave

getdave commented Jul 22, 2026 •

Copy link
Copy Markdown
Contributor

I'm a bit hesitant about this one. I think we should be moving in the direction of making navigation link and navigation submenu blocks simply variations of the same block. This will make that harder to do and moves us away from that direction.

I agree that it could make things harder. The otherside of the coin is that this is a feature that users/theme authors need now. Delaying it based on a hypothetical merging of the two blocks wouldn't feel right given the only opposition is a technical one. Let's deliver user value now.

I would prefer that we consider and design a migration path that allows any styles defined against Submenu to be migrated in the scenario that the Submenu block is normalized with the standard Nav Link block.

@MaggieCabrera do you think that is possible? Can you outline a potential migration route?

...however I'm struggling to think of a use case for it...

It seems a few folk think this is warranted. As the Submenu block can be a top level link item in it's own right I think it's important that we can achieve consistent styling whether the block is a standard link or a submenu.

Update: I realised that Submenu "current" styling is already handled. This PR is for the children of the submenu blocks.


I think we should bring this in.

@getdave
getdave force-pushed the add-nav-submenu-state branch from 8fd42d5 to c360e7b Compare July 22, 2026 09:24
@getdave getdave added the [Feature] Navigation Menus Any issue relating to Navigation Menus label Jul 22, 2026
@getdave

getdave commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

@MaggieCabrera I rebased and updated to match the new syntax for "currrent".

@github-actions

github-actions Bot commented Oct 14, 2026 •

Copy link
Copy Markdown

🤖 PR meta 🤖

🎉 Props

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

Co-authored-by: MaggieCabrera <onemaggie@git.wordpress.org>
Co-authored-by: getdave <get_dave@git.wordpress.org>
Co-authored-by: mikachan <mikachan@git.wordpress.org>
Co-authored-by: scruffian <scruffian@git.wordpress.org>
Co-authored-by: t-hamano <wildworks@git.wordpress.org>
Co-authored-by: jasmussen <joen@git.wordpress.org>
Co-authored-by: luminuu <luminuu@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: +35 B (0%)

Total Size: 8.96 MB

📦 View Changed
Filename Size Change
build/modules/lazy-editor/index.min.js 15.2 kB +10 B (+0.07%)
build/scripts/block-editor/index.min.js 599 kB +8 B (0%)
build/scripts/block-library/index.min.js 442 kB +5 B (0%)
build/scripts/edit-site/index.min.js 416 kB +5 B (0%)
build/scripts/editor/index.min.js 612 kB +7 B (0%)

ae99ef5 Run

⚡ Performance

Show the results

Client side metrics exclude the server response time.

front-end-block-theme

Metric 907d263 trunk % Change
timeToFirstByte 55.3 ms +18.81% -2.98% 60.6 ms +12.13% -7.01% -8.75%
largestContentfulPaint 96 ms +14.58% -4.17% 100 ms +4% -4% -4%
lcpMinusTtfb 40.4 ms +6.44% -13% 39.55 ms +7.59% -12.52% 2.15%
wpBeforeTemplate 28.68 ms +21.58% -1.26% 30.62 ms +17.64% -3.53% -6.34%
wpTemplate 22.25 ms +9.53% -4.49% 23.55 ms +7.64% -3.91% -5.52%
wpTotal 51.63 ms +17.06% -3.37% 56.35 ms +11.3% -7.1% -8.38%
wpMemoryUsage 7.65 MB +0% -0% 7.61 MB +0% -0% 0.47%
wpDbQueries 16 +0% -0% 16 +0% -0% 0%

front-end-classic-theme

Metric 907d263 trunk % Change
timeToFirstByte 46.15 ms +7.04% -1.08% 49.7 ms +7.24% -4.33% -7.14%
largestContentfulPaint 100 ms +8% -0% 104 ms +3.85% -1.92% -3.85%
lcpMinusTtfb 54.55 ms +3.76% -1.19% 53.85 ms +2.88% -1.11% 1.3%
wpBeforeTemplate 26.64 ms +1.31% -2.06% 28.25 ms +5.35% -4.67% -5.7%
wpTemplate 16.7 ms +4.07% -3.29% 17.95 ms +5.68% -4.57% -6.96%
wpTotal 43.29 ms +5.75% -1.87% 46.31 ms +7.75% -4.51% -6.52%
wpMemoryUsage 6.33 MB +0% -0% 6.30 MB +0% -0% 0.59%
wpDbQueries 13 +0% -0% 13 +0% -0% 0%

media-processing

Metric 907d263 trunk % Change
mediaProcessingJpeg 408.59 ms +0.74% -0.83% 407.93 ms +0.7% -1.25% 0.16%
mediaProcessingAvif 6144.96 ms +0.34% -0.12% 6140.07 ms +0.45% -0.03% 0.08%
mediaProcessingJpegToAvif 4276.69 ms +0.49% -0.76% 4255.9 ms +0.27% -0.09% 0.49%

media-upload

Metric 907d263 trunk % Change
jpegUploadProcessing 1948.37 ms +1.37% -0.54% 1965.43 ms +1.01% -0.76% -0.87%
pngUploadProcessing 216.36 ms +11.89% -9.95% 233.97 ms +7.68% -13.81% -7.53%
largeJpegUploadProcessing 1953.64 ms +0.46% -0.77% 1939 ms +0.69% -0.36% 0.76%
multipleImageUploadProcessing 2043.26 ms +0.84% -0.95% 2024.26 ms +2.84% -0.04% 0.94%

post-editor

Metric 907d263 trunk % Change
serverResponse 494.05 ms +1.94% -5.7% 481.41 ms +9.85% -4.15% 2.63%
firstPaint 334.62 ms +57.38% -5.13% 514.75 ms +0.88% -54.06% -34.99%
domContentLoaded 1210.44 ms +1.65% -1.75% 1191.88 ms +1.77% -1.96% 1.56%
loaded 1211.62 ms +1.66% -1.72% 1193.24 ms +1.76% -1.97% 1.54%
firstContentfulPaint 520.72 ms +4.14% -2.18% 515.61 ms +1.92% -2.44% 0.99%
firstBlock 3629.85 ms +0.64% -1.19% 3579.68 ms +0.65% -0.84% 1.4%
type 18.24 ms +4.28% -9.48% 17.75 ms +4.85% -1.86% 2.76%
typeWithoutInspector 17.92 ms +0.89% -1.79% 18.09 ms +3.32% -1.93% -0.94%
typeWithTopToolbar 23.05 ms +4.86% -3.25% 23.28 ms +3.91% -3.26% -0.99%
typeContainer 8.8 ms +8.86% -3.98% 9.06 ms +5.63% -13.02% -2.87%
focus 125.54 ms +4.03% -6.16% 123.57 ms +12.83% -2.92% 1.59%
firstFocus 230.06 ms +0% -0% 230.46 ms +0% -0% -0.17%
selectAll 562.88 ms +10.94% -1.43% 576.32 ms +8.89% -0.94% -2.33%
listViewOpen 79.67 ms +2.06% -4.57% 81.27 ms +16.38% -6.25% -1.97%
inserterOpen 42.92 ms +10.23% -11.81% 40.7 ms +6.68% -12.24% 5.45%
inserterHover 12 ms +9.58% -11.08% 12.03 ms +9.89% -5.74% -0.25%
inserterSearch 8.77 ms +8.32% -11.29% 8.55 ms +5.26% -9.94% 2.57%
loadPatterns 636.92 ms +4.43% -2.32% 667.44 ms +3.36% -0.54% -4.57%
wpTotal 483.36 ms +1.92% -5.71% 471.09 ms +9.72% -4.29% 2.6%
wpMemoryUsage 13.60 MB +0% -0% 13.56 MB +0% -0% 0.28%
wpDbQueries 55 +0% -1.82% 55 +0% -1.82% 0%

site-editor

Metric 907d263 trunk % Change
serverResponse 480.2 ms +6.9% -6.92% 481.13 ms +5.31% -8.12% -0.19%
firstPaint 273.38 ms +77.33% -5.94% 252.45 ms +22.76% -6.1% 8.29%
domContentLoaded 1250.03 ms +1.19% -3.04% 1258.21 ms +0.71% -0.72% -0.65%
loaded 1251.37 ms +1.2% -3.06% 1259.3 ms +0.71% -0.7% -0.63%
firstContentfulPaint 525.1 ms +1.87% -1.97% 518.57 ms +3.64% -0.88% 1.26%
firstBlock 4666.45 ms +0.57% -0.87% 4674.35 ms +0.3% -0.74% -0.17%
type 18.22 ms +1.98% -5.16% 18 ms +8.06% -2.56% 1.22%
navigate 114.34 ms +7.32% -1.57% 118.74 ms +3.28% -2.95% -3.71%
loadPatterns 1229.77 ms +2.96% -3.47% 1289.38 ms +3.28% -5.21% -4.62%
loadPages 1015.72 ms +2.23% -1.69% 1009.86 ms +2.59% -1.9% 0.58%
wpTotal 469.9 ms +7.14% -6.99% 471.52 ms +5.34% -8.35% -0.34%
wpMemoryUsage 12.64 MB +0% -0% 12.60 MB +0% -0% 0.3%
wpDbQueries 44 +2.27% -0% 44 +2.27% -0% 0%

ae99ef5 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
preserves content in the Custom HTML block in /test/e2e/specs/widgets/customizing-widgets.spec.js, passed after 1 failed attempt.
Error: apiRequestContext.fetch: socket hang up
Call log:
  - → POST http://localhost:8889/wp-json/wp/v2/sidebars/sidebar-2
    - user-agent: Playwright/1.63.0 (x64; ubuntu 24.04) node/24.20 CI/1
    - accept: */*
    - accept-encoding: gzip,deflate,br
    - X-WP-Nonce: fcd3278025
    - content-type: application/json
    - content-length: 31
    - cookie: wordpress_test_cookie=WP%20Cookie%20check; wordpress_logged_in_23778236db82f19306f247e20a353a99=admin%7C1792600431%7CbJ4jjT4sL55Vxn2IMM9iaUd45h8EBuwNisOCvHiAwdM%7Caa3f32250ba575fcefff5ff92a1617e7a7d9403f147a5a408c38c185cbaeb868; wp-settings-time-1=1792428374

    at RequestUtils.rest (/home/runner/work/gutenberg/gutenberg/packages/e2e-test-utils-playwright/src/request-utils/rest.ts:112:39)
    at map (/home/runner/work/gutenberg/gutenberg/packages/e2e-test-utils-playwright/src/request-utils/widgets.js:22:9)
    at RequestUtils.deleteAllWidgets (/home/runner/work/gutenberg/gutenberg/packages/e2e-test-utils-playwright/src/request-utils/widgets.js:21:12)
    at /home/runner/work/gutenberg/gutenberg/test/e2e/specs/widgets/customizing-widgets.spec.js:34:3

ae99ef5 Run

Keep VALID_BLOCK_PSEUDO_SELECTORS in sync with the PHP constant, so
`:hover`, `:focus`, `:focus-visible` and `:active` styles on
core/navigation-submenu show in the editor as well as on the front end.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The 7.1 backport (wordpress-develop#11174) was committed without this
change, so it now has its own 7.2 Core PR, wordpress-develop#14284.

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

Copy link
Copy Markdown
Contributor

Would love reviews on this one, @WordPress/gutenberg-core

@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! Left a few inline comments with a couple of things that I think need fixing before we bring this in.

"shadow": ".wp-block-navigation-submenu > .wp-block-navigation__submenu-container"
"shadow": ".wp-block-navigation-submenu > .wp-block-navigation__submenu-container",
"states": {
"-current": ".wp-block-navigation .wp-block-navigation-submenu .current-menu-item"

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.

I think this selector matches the wrong element. When a submenu is the current page, navigation-submenu/index.php (~L131) puts current-menu-item on the submenu's own wrapper <li>, next to wp-block-navigation-submenu. Because there's a space between .wp-block-navigation-submenu and .current-menu-item, this selector only matches current items inside a submenu. In practice that means a current Navigation Link nested in a dropdown, not the current submenu itself.

So with the theme.json from the testing instructions, the green -current submenu style would override the pink -current link style for any current link inside a dropdown. A current top-level submenu would stay pink, because it still matches the link selector .wp-block-navigation .current-menu-item.

Should this be a compound selector instead?

"-current": ".wp-block-navigation .wp-block-navigation-submenu.current-menu-item"

The README line and the expected CSS in the test would need the same change.

Comment thread schemas/json/theme.json
Comment on lines 2758 to +2769
"core/navigation-submenu": {
"$ref": "#/definitions/stylesPropertiesAndElementsComplete"
"allOf": [
{
"$ref": "#/definitions/stylesPropertiesAndElementsComplete"
},
{
"$ref": "#/definitions/stylesBlocksPseudoSelectorsProperties"
},
{
"$ref": "#/definitions/stylesBlocksCustomStatesProperties"
}
]

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.

I don't think this allOf can validate -current or :hover. stylesPropertiesAndElementsComplete has a propertyNames constraint that only allows style property names, elements, variations and breakpoint keys. Every branch of an allOf has to pass, so that constraint will reject the new keys even though the other two $refs define them.

This means the testing instructions snippet would get flagged in editors that use the schema. Could this copy the core/navigation-link definition just above? That one builds from stylesProperties plus the pseudo, custom-state and responsive-with-pseudo definitions, and its own propertyNames anyOf includes stylesBlocksPseudoSelectorsPropertyNames and stylesBlocksCustomStatesPropertyNames.

"shadow": ".wp-block-navigation-submenu > .wp-block-navigation__submenu-container"
"shadow": ".wp-block-navigation-submenu > .wp-block-navigation__submenu-container",
"states": {
"-current": ".wp-block-navigation .wp-block-navigation-submenu .current-menu-item"

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.

Related to the pseudo-selector question: once the selector targets the submenu <li>, -current → color.text will also be inherited by every link in that submenu's dropdown. Navigation Link avoids this because it has no children. Is that acceptable? Or should -current target the submenu's own > .wp-block-navigation-item__content instead?

@MaggieCabrera

Copy link
Copy Markdown
Contributor Author

Moving this out of 7.2, it needs more work

wporg-sync pushed a commit to WordPress/wordpress-develop that referenced this pull request Oct 20, 2026
…on`.

This changeset backports the `WP_Theme_JSON` changes from GB76367, and is a follow-up to #64806.

Themes can style the current link inside a Navigation Submenu dropdown with `-current` on `core/navigation-submenu` in `theme.json`, including its `:hover`, `:focus`, `:focus-visible` and `:active states`.

The block's `selectors.states` selector arrives with the Gutenberg package sync, so the new test uses `get_styles_for_block()` with explicit style nodes, like the existing custom state tests.

Developed in: 
- #14284
- WordPress/gutenberg#76367

Follow-up to #62641.

Props onemaggie.
Fixes #66312.
See #64806.



git-svn-id: https://develop.svn.wordpress.org/trunk@64600 602fd350-edb4-49c9-b593-d223f7449a82
wporg-sync pushed a commit to WordPress/WordPress that referenced this pull request Oct 20, 2026
…on`.

This changeset backports the `WP_Theme_JSON` changes from GB76367, and is a follow-up to #64806.

Themes can style the current link inside a Navigation Submenu dropdown with `-current` on `core/navigation-submenu` in `theme.json`, including its `:hover`, `:focus`, `:focus-visible` and `:active states`.

The block's `selectors.states` selector arrives with the Gutenberg package sync, so the new test uses `get_styles_for_block()` with explicit style nodes, like the existing custom state tests.

Developed in: 
- WordPress/wordpress-develop#14284
- WordPress/gutenberg#76367

Follow-up to #62641.

Props onemaggie.
Fixes #66312.
See #64806.


Built from https://develop.svn.wordpress.org/trunk@64600


git-svn-id: http://core.svn.wordpress.org/trunk@63750 1a063a9b-81f0-0310-95a4-ce76da25c4cd

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

[Block] Submenu Affects the Submenu Block - for submenus in navigation [Feature] Navigation Menus Any issue relating to Navigation Menus [Package] Block library /packages/block-library [Type] Enhancement A suggestion for improvement.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants