Skip to content

Menu: Clarify icon, label, and description usage guidelines - #84020

Open
ciampo wants to merge 7 commits into
trunkfrom
codex/menu-icon-usage-docs
Open

ciampo wants to merge 7 commits into
trunkfrom
codex/menu-icon-usage-docs

Conversation

@ciampo

@ciampo ciampo commented Oct 2, 2026 •

Copy link
Copy Markdown
Contributor

Follow-up to the icon guidance discussion in #83993, updated for the layout changes in #84028.

What?

Clarify when Menu items benefit from icons or descriptions, including useful prominence for key actions. Prefer icons on every item in a group or none, while documenting the supported mixed layout and suggesting regrouping when only one item needs an icon. Favor short labels that stand on their own and reserve descriptions for essential context.

Why?

Consistent icon usage helps users scan a menu, but it should not encourage unnecessary icons. Mixed icon usage no longer leaves an empty icon space.

How?

Keep the usage guide, component descriptions, and prop documentation focused on when icons and descriptions help. Revise stories to use meaningful icons and fewer descriptions, with separate examples for mixed icons and wrapping.

Testing Instructions

  1. Open Storybook → Components → @wordpress/ui → Menu → Usage Guidelines. Confirm Add prefix icons distinguishes the all-or-none recommendation from supported mixed usage, and Keep labels clear and descriptions rare explains when descriptions help.
  2. Open Item options. Both Actions items should have 16px icons, and both Navigation items should have none. Labels should align within each group. Open Mixed item options. Rename should start at the same position as the Duplicate and Archive icons, without an empty icon space.
  3. Open Rich Items. Only Delete… should have a description, with no prefix icon. Both Organize items should have meaningful icons and no descriptions. Check Default, Grouped Items, Checkbox Items, and Radio Items for consistent icon usage and concise labels.
  4. Open Wrapped Items. Labels and descriptions should wrap inside the popup. Suffixes and shortcuts should remain alongside the label, with descriptions below. The second item should use disabled styling. Its long text is deliberate layout coverage.
  5. Check the prefix, item label, and item description prop documentation, plus the Menu.PrefixIcon and Menu.ItemDescription component descriptions in Menu → Docs.

Testing Instructions for Keyboard

Open each menu with Enter or Space, navigate with the arrow keys, and close it with Escape. Focus should return to the trigger.

Use of AI Tools

Codex updated the documentation and Storybook examples, ran local verification, and performed an independent adversarial review.

@github-actions github-actions Bot added the [Package] UI /packages/ui label Oct 2, 2026
@github-actions

github-actions Bot commented Oct 2, 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: ciampo <mciampini@git.wordpress.org>
Co-authored-by: Mamaduka <mamaduka@git.wordpress.org>
Co-authored-by: jasmussen <joen@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: 0 B

Total Size: 8.38 MB

fdff929 Run

⚡ Performance

Show the results

Client side metrics exclude the server response time.

front-end-block-theme

Metric 3b44a52 trunk % Change
timeToFirstByte 57.05 ms +5.61% -2.98% 58.1 ms +11.27% -1.98% -1.81%
largestContentfulPaint 94 ms +6.38% -4.26% 102 ms +1.96% -9.8% -7.84%
lcpMinusTtfb 35.75 ms +13.85% -5.45% 40.3 ms +9.55% -14.64% -11.29%
wpBeforeTemplate 28.31 ms +11.06% -0.92% 28.88 ms +18.18% -1.49% -1.97%
wpTemplate 24.58 ms +3.05% -3.66% 25.15 ms +4.17% -2.31% -2.27%
wpTotal 53.33 ms +5.66% -2.87% 54.24 ms +11.87% -2.1% -1.68%
wpMemoryUsage 7.67 MB +0% -0% 7.64 MB +0% -0% 0.45%
wpDbQueries 17 +0% -0% 17 +0% -0% 0%

front-end-classic-theme

Metric 3b44a52 trunk % Change
timeToFirstByte 48.25 ms +8.6% -1.55% 47.45 ms +4.11% -2% 1.69%
largestContentfulPaint 104 ms +5.77% -0% 100 ms +4% -0% 4%
lcpMinusTtfb 56.05 ms +1.25% -3.03% 53.9 ms +3.71% -0.83% 3.99%
wpBeforeTemplate 26.86 ms +6.63% -1.27% 26.32 ms +1.82% -2.36% 2.05%
wpTemplate 18.19 ms +5.94% -1.43% 17.94 ms +2.84% -1.34% 1.39%
wpTotal 45.25 ms +8.18% -1.26% 44.41 ms +4.28% -1.76% 1.89%
wpMemoryUsage 6.30 MB +0% -0% 6.25 MB +0% -0% 0.7%
wpDbQueries 14 +0% -0% 14 +0% -0% 0%

media-processing

Metric 3b44a52 trunk % Change
mediaProcessingJpeg 405.42 ms +0.49% -0.74% 400.34 ms +1.63% -0.65% 1.27%
mediaProcessingAvif 6053.84 ms +0.3% -0.21% 6045.14 ms +0.57% -0.16% 0.14%
mediaProcessingJpegToAvif 4181.68 ms +0.21% -0.46% 4177.16 ms +0.15% -0.22% 0.11%

media-upload

Metric 3b44a52 trunk % Change
jpegUploadProcessing 1460.27 ms +32.28% -2.89% 1425.86 ms +0.47% -0.45% 2.41%
pngUploadProcessing 181.9 ms +11.83% -6.17% 175.74 ms +5.42% -2.63% 3.51%
largeJpegUploadProcessing 1406.13 ms +0.2% -0.31% 1410.92 ms +0.13% -0.37% -0.34%
multipleImageUploadProcessing 1570.7 ms +1.49% -1.16% 1578.78 ms +1.39% -2.31% -0.51%

post-editor

Metric 3b44a52 trunk % Change
serverResponse 504.2 ms +7.4% -6.25% 516.11 ms +4.11% -9.72% -2.31%
firstPaint 264.37 ms +38.82% -10.79% 257.15 ms +12.71% -14.07% 2.81%
domContentLoaded 1109.16 ms +2.29% -2.28% 1125.87 ms +4.66% -1.35% -1.48%
loaded 1110.26 ms +2.33% -2.24% 1127.25 ms +4.65% -1.36% -1.51%
firstContentfulPaint 464.67 ms +2.15% -3.51% 476.84 ms +5.4% -2.56% -2.55%
firstBlock 3390.2 ms +0.41% -2.23% 3355.37 ms +1.98% -0.93% 1.04%
type 18.99 ms +1.63% -5.11% 19.47 ms +3.34% -6.68% -2.47%
typeWithoutInspector 19.2 ms +2.08% -3.54% 17.91 ms +4.8% -1.56% 7.2%
typeWithTopToolbar 23.79 ms +5.17% -3.11% 23.77 ms +2.65% -9.05% 0.08%
typeContainer 8.65 ms +5.43% -4.62% 8.59 ms +6.98% -4.19% 0.7%
focus 107 ms +9.47% -6.13% 111.77 ms +5.9% -3.1% -4.27%
firstFocus 221.47 ms +0% -0% 227.58 ms +0% -0% -2.68%
selectAll 574.16 ms +3.92% -0.22% 546.53 ms +4.66% -2.42% 5.06%
listViewOpen 80.66 ms +4.5% -4.17% 79.01 ms +16.16% -7.52% 2.09%
inserterOpen 42.92 ms +2.45% -10.53% 42.45 ms +8.06% -11.99% 1.11%
inserterHover 12.67 ms +4.66% -12.47% 12.8 ms +7.73% -11.56% -1.02%
inserterSearch 8.74 ms +3.43% -2.17% 8.52 ms +5.52% -9.15% 2.58%
loadPatterns 631.47 ms +4.9% -7.73% 637.46 ms +3.07% -3.11% -0.94%
wpTotal 493.45 ms +7.75% -6.26% 505.04 ms +4.38% -9.74% -2.29%
wpMemoryUsage 13.23 MB +0% -0% 13.20 MB +0% -0% 0.28%
wpDbQueries 54 +0% -1.85% 53.5 +0.93% -0.93% 0.93%

site-editor

Metric 3b44a52 trunk % Change
serverResponse 274.16 ms +3% -4.11% 257.53 ms +4.87% -7.33% 6.46%
firstPaint 195.76 ms +15.17% -12.85% 225.32 ms +56.85% -26.89% -13.12%
domContentLoaded 764.86 ms +5.76% -0.39% 769.39 ms +0.8% -1.79% -0.59%
loaded 766 ms +5.75% -0.4% 770.46 ms +0.8% -1.8% -0.58%
firstContentfulPaint 335.4 ms +2.36% -3.36% 350.96 ms +1.64% -5.47% -4.43%
firstBlock 2849.85 ms +2.78% -2.28% 2790.51 ms +1.85% -0.63% 2.13%
type 15.72 ms +5.28% -5.92% 14.74 ms +4.34% -2.85% 6.65%
navigate 106.04 ms +1.81% -2.06% 87.79 ms +2.64% -5.4% 20.79%
loadPatterns 1072.16 ms +13.68% -9.53% 1124.88 ms +9.42% -18.2% -4.69%
loadPages 979.16 ms +3.51% -2.97% 1004.98 ms +5.19% -5.28% -2.57%
wpTotal 267.42 ms +2.92% -4.08% 251.17 ms +4.75% -7.61% 6.47%
wpMemoryUsage 12.27 MB +0% -0% 12.22 MB +0% -0% 0.4%
wpDbQueries 43 +2.33% -0% 43.5 +1.15% -1.15% -1.15%

fdff929 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.

refuses the drop and uploads nothing in /test/e2e/specs/editor/various/single-file-placeholder-drop.spec.js, passed after 1 failed attempt.
Error: expect(received).toHaveLength(expected)

Expected length: 0
Received length: 2
Received array:  [{"_links": {"about": [{"href": "http://localhost:8889/wp-json/wp/v2/types/attachment"}], "author": [{"embeddable": true, "href": "http://localhost:8889/wp-json/wp/v2/users/1"}], "collection": [{"href": "http://localhost:8889/wp-json/wp/v2/media"}], "curies": [{"href": "https://api.w.org/{rel}", "name": "wp", "templated": true}], "replies": [{"embeddable": true, "href": "http://localhost:8889/wp-json/wp/v2/comments?post=264"}], "self": [{"href": "http://localhost:8889/wp-json/wp/v2/media/264", "targetHints": {"allow": ["GET", "POST", "PUT", "PATCH", "DELETE"]}}], "wp:attached-to": [{"embeddable": true, "href": "http://localhost:8889/wp-json/wp/v2/posts/262", "id": 262, "post_type": "post"}]}, "alt_text": "", "author": 1, "caption": {"rendered": ""}, "class_list": ["post-264", "attachment", "type-attachment", "status-inherit", "hentry", "entry"], "comment_status": "open", "date": "2026-10-08T16:07:16", "date_gmt": "2026-10-08T16:07:16", "description": {"rendered": "<p class=\"attachment\"><a href='http://localhost:8889/wp-content/uploads/2026/10/10x10_e2e_test_image_z9T8jK-1.png'><img loading=\"lazy\" decoding=\"async\" width=\"10\" height=\"10\" src=\"http://localhost:8889/wp-content/uploads/2026/10/10x10_e2e_test_image_z9T8jK-1.png\" class=\"attachment-medium size-medium\" alt=\"\" style=\"width:100%;height:100%;max-width:10px;\" /></a></p>
"}, "featured_media": 0, "filename": "10x10_e2e_test_image_z9T8jK-1.png", "filesize": 80, "guid": {"rendered": "http://localhost:8889/wp-content/uploads/2026/10/10x10_e2e_test_image_z9T8jK-1.png"}, "id": 264, "link": "http://localhost:8889/?attachment_id=264", "media_details": {"file": "2026/10/10x10_e2e_test_image_z9T8jK-1.png", "filesize": 80, "height": 10, "image_meta": {"alt": "", "aperture": "0", "camera": "", "caption": "", "copyright": "", "created_timestamp": "0", "credit": "", "focal_length": "0", "iso": "0", "keywords": [], "orientation": "0", "shutter_speed": "0", "title": ""}, "sizes": {}, "width": 10}, "media_type": "image", "meta": [], "mime_type": "image/png", "modified": "2026-10-08T16:07:16", "modified_gmt": "2026-10-08T16:07:16", "ping_status": "closed", "post": 262, "slug": "10x10_e2e_test_image_z9t8jk-2", "source_url": "http://localhost:8889/wp-content/uploads/2026/10/10x10_e2e_test_image_z9T8jK-1.png", "status": "inherit", "template": "", "title": {"rendered": "10x10_e2e_test_image_z9T8jK"}, "type": "attachment"}, {"_links": {"about": [{"href": "http://localhost:8889/wp-json/wp/v2/types/attachment"}], "author": [{"embeddable": true, "href": "http://localhost:8889/wp-json/wp/v2/users/1"}], "collection": [{"href": "http://localhost:8889/wp-json/wp/v2/media"}], "curies": [{"href": "https://api.w.org/{rel}", "name": "wp", "templated": true}], "replies": [{"embeddable": true, "href": "http://localhost:8889/wp-json/wp/v2/comments?post=263"}], "self": [{"href": "http://localhost:8889/wp-json/wp/v2/media/263", "targetHints": {"allow": ["GET", "POST", "PUT", "PATCH", "DELETE"]}}], "wp:attached-to": [{"embeddable": true, "href": "http://localhost:8889/wp-json/wp/v2/posts/262", "id": 262, "post_type": "post"}]}, "alt_text": "", "author": 1, "caption": {"rendered": ""}, "class_list": ["post-263", "attachment", "type-attachment", "status-inherit", "hentry", "entry"], "comment_status": "open", "date": "2026-10-08T16:07:16", "date_gmt": "2026-10-08T16:07:16", "description": {"rendered": "<p class=\"attachment\"><a href='http://localhost:8889/wp-content/uploads/2026/10/10x10_e2e_test_image_z9T8jK.png'><img loading=\"lazy\" decoding=\"async\" width=\"10\" height=\"10\" src=\"http://localhost:8889/wp-content/uploads/2026/10/10x10_e2e_test_image_z9T8jK.png\" class=\"attachment-medium size-medium\" alt=\"\" style=\"width:100%;height:100%;max-width:10px;\" /></a></p>
"}, "featured_media": 0, "filename": "10x10_e2e_test_image_z9T8jK.png", "filesize": 80, "guid": {"rendered": "http://localhost:8889/wp-content/uploads/2026/10/10x10_e2e_test_image_z9T8jK.png"}, "id": 263, "link": "http://localhost:8889/?attachment_id=263", "media_details": {"file": "2026/10/10x10_e2e_test_image_z9T8jK.png", "filesize": 80, "height": 10, "image_meta": {"alt": "", "aperture": "0", "camera": "", "caption": "", "copyright": "", "created_timestamp": "0", "credit": "", "focal_length": "0", "iso": "0", "keywords": [], "orientation": "0", "shutter_speed": "0", "title": ""}, "sizes": {}, "width": 10}, "media_type": "image", "meta": [], "mime_type": "image/png", "modified": "2026-10-08T16:07:16", "modified_gmt": "2026-10-08T16:07:16", "ping_status": "closed", "post": 262, "slug": "10x10_e2e_test_image_z9t8jk", "source_url": "http://localhost:8889/wp-content/uploads/2026/10/10x10_e2e_test_image_z9T8jK.png", "status": "inherit", "template": "", "title": {"rendered": "10x10_e2e_test_image_z9T8jK"}, "type": "attachment"}]
    at /home/runner/work/gutenberg/gutenberg/test/e2e/specs/editor/various/single-file-placeholder-drop.spec.js:71:45

fdff929 Run

@ciampo ciampo added the [Type] Developer Documentation Documentation for developers label Oct 2, 2026
@ciampo
ciampo marked this pull request as ready for review October 2, 2026 09:58
@ciampo
ciampo requested a review from a team as a code owner October 2, 2026 09:58
@ciampo
ciampo requested review from a team and Mamaduka October 2, 2026 09:58

## Add prefix icons

> For the best visual results, use prefix icons on every item in a group, or use no prefix icons in that group. If one item needs a prefix icon, prefer adding meaningful icons to all the other items too. Avoid using an icon to highlight just one item in a group.

@Mamaduka Mamaduka Oct 2, 2026 •

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.

If one item needs a prefix icon, prefer adding meaningful icons to all the other items too.

It could be me, but this reads like encouragement to fill the group with icons, even if they aren't needed for other items. However, it may be more effective to omit the icon for a single item, rather than overwhelming the group with unnecessary icons.

What do you think?

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.

Agreed. I think a lot of the present critique centres around vertical alignment, where if some menu items in a group have icons and others don't, it creates whitespace and visual rivers. In that sense, perhaps there could be a guideline along the lines of: every icon in a group should either have, or not have icons, with no mixing in the same group.

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.

Agreed. The guidance now favors omitting a single icon rather than adding unnecessary icons to the group

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.

Indeed. Let's unpack this.

In the previous menu, we were able to items with and without icons, because icons were on the right side of the menu. The downside was that any menu item that had a suffix, e.g. shortcut, would get very noisy if it also had an icon. Designwise, you either had an icon, or a suffix.

That's solved with the new menu which keeps the suffix on the right, but moves the icon on the left. The tradeoff is that now if we mix icon items with iconless items, you get visual rivers of whitespace from the indentation of iconless icons.

Absent reverting to the old behaviour (which I don't think we should), or a way to make iconless items work non-indented next to items with icons, the net effect is, to be reductive: either all items in a group should have icons, or none of them should. This is the MacOS model, and can look through a variety of MacOS items to see this behavior in effect. The key benefit: things line up across.

Based on the above, we could go this direction:

Prefix icons

Don't mix iconless menu items with icon menu items. Either all items in a group should have prefix icons, or none of them should have.
This is to avoid visual rivers of iconless and icon menu items and create strong scannable vertical alignment lines to benefit legibility.
When should you use an icon menu item? When it is a key menu item that needs an additional visual affordance or prominence. If it sits in a large group of other items, consider whether it sits in the correct group, or needs its own.
Groups don't have to have headings, they can also be implied by separators.

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.

Updated the guidance to allow useful prominence for a key action and suggest reconsidering its grouping when it is the only item that needs an icon. It still discourages adding unnecessary icons to make a group match.

@ciampo
ciampo requested a review from jasmussen October 2, 2026 15:50
@ciampo ciampo changed the title Menu: Document consistent prefix icon usage within groups Menu: Clarify icon, label, and description usage guidelines Oct 2, 2026
@ciampo
ciampo requested a review from Mamaduka October 2, 2026 16:11
@ciampo

ciampo commented Oct 5, 2026

Copy link
Copy Markdown
Contributor Author

I'll pause work on this PR while we experiment with a different layout behaviour in #84028, where adding an icon doesn't cause all other items in the group to shift.

Once we settle on an approach, I'll resume the work here.

@ciampo ciampo self-assigned this Oct 5, 2026
@ciampo
ciampo force-pushed the codex/menu-icon-usage-docs branch from b710246 to 3d0f118 Compare October 8, 2026 15:23
@ciampo

ciampo commented Oct 8, 2026

Copy link
Copy Markdown
Contributor Author

Updated after the new direction taken with #84028, and ready for a new round of review

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

[Package] UI /packages/ui [Type] Developer Documentation Documentation for developers

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants