Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a Submenu block for use in Navigation #33775

Merged
merged 40 commits into from
Sep 13, 2021
Merged

Conversation

tellthemachines
Copy link
Contributor

@tellthemachines tellthemachines commented Jul 30, 2021

Description

Follow-up from/alternative to #33351; fixes #18866. Might simplify #23745, at least on the UI level.

Adds a Submenu block to replace submenu functionality in Navigation Link blocks.

What's the difference between Submenu block and the current Navigation Link submenus?

  • Submenu dropdowns can now be created with either links or plain text as parent;
  • Plain text can be turned into links and vice-versa by adding or removing the link from the block toolbar.

How are we supporting the current workflow of creating a submenu from a Navigation Link?

  • The "add submenu" button is still there in Navigation Links, but now it transforms the block into a Submenu block.
  • Navigation Links can also be transformed in to Submenus from the menu that appears by clicking the block name in the block toolbar.

How are we ensuring Submenus are accessible?

  • We're moving to opening the submenus on click instead of focus, when navigating with keyboard and/or screen reader.
  • For text only parent items, that means the whole parent is a button.
  • For link parent items, a button is added next to the link, with the submenu icon inside it. This might need some design and styling adjustments, but currently it's the easiest way to support open on click for link parents.
  • The submenus currently open on hover as well as click, but we can adjust that behaviour to be optional. However, the choices should be hover and click, or click only. We shouldn't implement hover and focus because opening on focus is sub-optimal for accessibility.

How has this been tested?

Add a Navigation block to a post or template; add a Dropdown block inside it. Try to reproduce current functionality of Navigation Link submenus. Try creating a dropdown with a link or with a button as toggles, check both work as expected.

Screenshots

Types of changes

New feature (non-breaking change which adds functionality)

Checklist:

  • My code is tested.
  • My code follows the WordPress code style.
  • My code follows the accessibility standards.
  • I've tested my changes with keyboard and screen readers.
  • My code has proper inline documentation.
  • I've included developer documentation if appropriate.
  • I've updated all React Native files affected by any refactorings/renamings in this PR (please manually search all *.native.js files for terms that need renaming or removal).

@github-actions
Copy link

github-actions bot commented Jul 30, 2021

Size Change: +3.66 kB (0%)

Total Size: 1.05 MB

Filename Size Change
build/block-editor/index.min.js 120 kB +583 B (0%)
build/block-editor/style-rtl.css 13.8 kB +16 B (0%)
build/block-editor/style.css 13.8 kB +17 B (0%)
build/block-library/blocks/gallery/editor-rtl.css 983 B +58 B (+6%) 🔍
build/block-library/blocks/gallery/editor.css 988 B +59 B (+6%) 🔍
build/block-library/blocks/html/editor-rtl.css 332 B +49 B (+17%) ⚠️
build/block-library/blocks/html/editor.css 333 B +49 B (+17%) ⚠️
build/block-library/blocks/navigation/style-rtl.css 1.44 kB +25 B (+2%)
build/block-library/blocks/navigation/style.css 1.44 kB +23 B (+2%)
build/block-library/blocks/query-pagination/editor-rtl.css 301 B +31 B (+11%) ⚠️
build/block-library/blocks/query-pagination/editor.css 292 B +30 B (+11%) ⚠️
build/block-library/blocks/query-pagination/style-rtl.css 259 B +20 B (+8%) 🔍
build/block-library/blocks/query-pagination/style.css 257 B +21 B (+9%) 🔍
build/block-library/editor-rtl.css 9.69 kB +152 B (+2%)
build/block-library/editor.css 9.68 kB +156 B (+2%)
build/block-library/index.min.js 153 kB +1.94 kB (+1%)
build/block-library/style-rtl.css 10.3 kB +125 B (+1%)
build/block-library/style.css 10.3 kB +124 B (+1%)
build/components/index.min.js 209 kB +136 B (0%)
build/core-data/index.min.js 12.3 kB -133 B (-1%)
build/edit-navigation/style-rtl.css 3.37 kB -3 B (0%)
build/edit-navigation/style.css 3.37 kB -2 B (0%)
build/edit-site/index.min.js 26.6 kB +198 B (+1%)
build/format-library/index.min.js 5.34 kB -21 B (0%)
build/format-library/style.css 670 B +1 B (0%)
ℹ️ View Unchanged
Filename Size
build/a11y/index.min.js 931 B
build/admin-manifest/index.min.js 1.09 kB
build/annotations/index.min.js 2.7 kB
build/api-fetch/index.min.js 2.19 kB
build/autop/index.min.js 2.08 kB
build/blob/index.min.js 459 B
build/block-directory/index.min.js 6.2 kB
build/block-directory/style-rtl.css 1.01 kB
build/block-directory/style.css 1.01 kB
build/block-editor/default-editor-styles-rtl.css 378 B
build/block-editor/default-editor-styles.css 378 B
build/block-library/blocks/archives/editor-rtl.css 61 B
build/block-library/blocks/archives/editor.css 60 B
build/block-library/blocks/archives/style-rtl.css 65 B
build/block-library/blocks/archives/style.css 65 B
build/block-library/blocks/audio/editor-rtl.css 58 B
build/block-library/blocks/audio/editor.css 58 B
build/block-library/blocks/audio/style-rtl.css 111 B
build/block-library/blocks/audio/style.css 111 B
build/block-library/blocks/audio/theme-rtl.css 125 B
build/block-library/blocks/audio/theme.css 125 B
build/block-library/blocks/block/editor-rtl.css 161 B
build/block-library/blocks/block/editor.css 161 B
build/block-library/blocks/button/editor-rtl.css 474 B
build/block-library/blocks/button/editor.css 474 B
build/block-library/blocks/button/style-rtl.css 600 B
build/block-library/blocks/button/style.css 600 B
build/block-library/blocks/buttons/editor-rtl.css 315 B
build/block-library/blocks/buttons/editor.css 315 B
build/block-library/blocks/buttons/style-rtl.css 370 B
build/block-library/blocks/buttons/style.css 370 B
build/block-library/blocks/calendar/style-rtl.css 207 B
build/block-library/blocks/calendar/style.css 207 B
build/block-library/blocks/categories/editor-rtl.css 84 B
build/block-library/blocks/categories/editor.css 83 B
build/block-library/blocks/categories/style-rtl.css 79 B
build/block-library/blocks/categories/style.css 79 B
build/block-library/blocks/code/style-rtl.css 90 B
build/block-library/blocks/code/style.css 90 B
build/block-library/blocks/code/theme-rtl.css 131 B
build/block-library/blocks/code/theme.css 131 B
build/block-library/blocks/columns/editor-rtl.css 206 B
build/block-library/blocks/columns/editor.css 205 B
build/block-library/blocks/columns/style-rtl.css 497 B
build/block-library/blocks/columns/style.css 496 B
build/block-library/blocks/cover/editor-rtl.css 666 B
build/block-library/blocks/cover/editor.css 670 B
build/block-library/blocks/cover/style-rtl.css 1.23 kB
build/block-library/blocks/cover/style.css 1.23 kB
build/block-library/blocks/embed/editor-rtl.css 488 B
build/block-library/blocks/embed/editor.css 488 B
build/block-library/blocks/embed/style-rtl.css 417 B
build/block-library/blocks/embed/style.css 417 B
build/block-library/blocks/embed/theme-rtl.css 124 B
build/block-library/blocks/embed/theme.css 124 B
build/block-library/blocks/file/editor-rtl.css 300 B
build/block-library/blocks/file/editor.css 300 B
build/block-library/blocks/file/style-rtl.css 255 B
build/block-library/blocks/file/style.css 255 B
build/block-library/blocks/file/view.min.js 322 B
build/block-library/blocks/freeform/editor-rtl.css 2.44 kB
build/block-library/blocks/freeform/editor.css 2.44 kB
build/block-library/blocks/gallery/style-rtl.css 1.6 kB
build/block-library/blocks/gallery/style.css 1.59 kB
build/block-library/blocks/gallery/theme-rtl.css 122 B
build/block-library/blocks/gallery/theme.css 122 B
build/block-library/blocks/group/editor-rtl.css 159 B
build/block-library/blocks/group/editor.css 159 B
build/block-library/blocks/group/style-rtl.css 57 B
build/block-library/blocks/group/style.css 57 B
build/block-library/blocks/group/theme-rtl.css 70 B
build/block-library/blocks/group/theme.css 70 B
build/block-library/blocks/heading/style-rtl.css 114 B
build/block-library/blocks/heading/style.css 114 B
build/block-library/blocks/home-link/style-rtl.css 247 B
build/block-library/blocks/home-link/style.css 247 B
build/block-library/blocks/image/editor-rtl.css 728 B
build/block-library/blocks/image/editor.css 728 B
build/block-library/blocks/image/style-rtl.css 482 B
build/block-library/blocks/image/style.css 487 B
build/block-library/blocks/image/theme-rtl.css 124 B
build/block-library/blocks/image/theme.css 124 B
build/block-library/blocks/latest-comments/style-rtl.css 284 B
build/block-library/blocks/latest-comments/style.css 284 B
build/block-library/blocks/latest-posts/editor-rtl.css 137 B
build/block-library/blocks/latest-posts/editor.css 137 B
build/block-library/blocks/latest-posts/style-rtl.css 528 B
build/block-library/blocks/latest-posts/style.css 527 B
build/block-library/blocks/list/style-rtl.css 94 B
build/block-library/blocks/list/style.css 94 B
build/block-library/blocks/media-text/editor-rtl.css 266 B
build/block-library/blocks/media-text/editor.css 263 B
build/block-library/blocks/media-text/style-rtl.css 488 B
build/block-library/blocks/media-text/style.css 485 B
build/block-library/blocks/more/editor-rtl.css 431 B
build/block-library/blocks/more/editor.css 431 B
build/block-library/blocks/navigation-link/editor-rtl.css 489 B
build/block-library/blocks/navigation-link/editor.css 488 B
build/block-library/blocks/navigation-link/style-rtl.css 94 B
build/block-library/blocks/navigation-link/style.css 94 B
build/block-library/blocks/navigation-submenu/editor-rtl.css 300 B
build/block-library/blocks/navigation-submenu/editor.css 299 B
build/block-library/blocks/navigation-submenu/style-rtl.css 298 B
build/block-library/blocks/navigation-submenu/style.css 298 B
build/block-library/blocks/navigation-submenu/view.min.js 343 B
build/block-library/blocks/navigation/editor-rtl.css 1.72 kB
build/block-library/blocks/navigation/editor.css 1.72 kB
build/block-library/blocks/navigation/view.min.js 2.52 kB
build/block-library/blocks/nextpage/editor-rtl.css 395 B
build/block-library/blocks/nextpage/editor.css 395 B
build/block-library/blocks/page-list/editor-rtl.css 310 B
build/block-library/blocks/page-list/editor.css 310 B
build/block-library/blocks/page-list/style-rtl.css 241 B
build/block-library/blocks/page-list/style.css 241 B
build/block-library/blocks/paragraph/editor-rtl.css 157 B
build/block-library/blocks/paragraph/editor.css 157 B
build/block-library/blocks/paragraph/style-rtl.css 261 B
build/block-library/blocks/paragraph/style.css 261 B
build/block-library/blocks/post-author/editor-rtl.css 210 B
build/block-library/blocks/post-author/editor.css 210 B
build/block-library/blocks/post-author/style-rtl.css 182 B
build/block-library/blocks/post-author/style.css 181 B
build/block-library/blocks/post-comments-form/style-rtl.css 140 B
build/block-library/blocks/post-comments-form/style.css 140 B
build/block-library/blocks/post-comments/style-rtl.css 360 B
build/block-library/blocks/post-comments/style.css 359 B
build/block-library/blocks/post-content/editor-rtl.css 138 B
build/block-library/blocks/post-content/editor.css 138 B
build/block-library/blocks/post-excerpt/editor-rtl.css 73 B
build/block-library/blocks/post-excerpt/editor.css 73 B
build/block-library/blocks/post-excerpt/style-rtl.css 69 B
build/block-library/blocks/post-excerpt/style.css 69 B
build/block-library/blocks/post-featured-image/editor-rtl.css 398 B
build/block-library/blocks/post-featured-image/editor.css 398 B
build/block-library/blocks/post-featured-image/style-rtl.css 143 B
build/block-library/blocks/post-featured-image/style.css 143 B
build/block-library/blocks/post-template/editor-rtl.css 99 B
build/block-library/blocks/post-template/editor.css 98 B
build/block-library/blocks/post-template/style-rtl.css 378 B
build/block-library/blocks/post-template/style.css 379 B
build/block-library/blocks/post-terms/style-rtl.css 73 B
build/block-library/blocks/post-terms/style.css 73 B
build/block-library/blocks/post-title/style-rtl.css 60 B
build/block-library/blocks/post-title/style.css 60 B
build/block-library/blocks/preformatted/style-rtl.css 103 B
build/block-library/blocks/preformatted/style.css 103 B
build/block-library/blocks/pullquote/editor-rtl.css 198 B
build/block-library/blocks/pullquote/editor.css 198 B
build/block-library/blocks/pullquote/style-rtl.css 378 B
build/block-library/blocks/pullquote/style.css 378 B
build/block-library/blocks/pullquote/theme-rtl.css 167 B
build/block-library/blocks/pullquote/theme.css 167 B
build/block-library/blocks/query-pagination-numbers/editor-rtl.css 122 B
build/block-library/blocks/query-pagination-numbers/editor.css 121 B
build/block-library/blocks/query-title/editor-rtl.css 85 B
build/block-library/blocks/query-title/editor.css 85 B
build/block-library/blocks/query/editor-rtl.css 131 B
build/block-library/blocks/query/editor.css 132 B
build/block-library/blocks/quote/style-rtl.css 187 B
build/block-library/blocks/quote/style.css 187 B
build/block-library/blocks/quote/theme-rtl.css 220 B
build/block-library/blocks/quote/theme.css 222 B
build/block-library/blocks/rss/editor-rtl.css 202 B
build/block-library/blocks/rss/editor.css 204 B
build/block-library/blocks/rss/style-rtl.css 289 B
build/block-library/blocks/rss/style.css 288 B
build/block-library/blocks/search/editor-rtl.css 165 B
build/block-library/blocks/search/editor.css 165 B
build/block-library/blocks/search/style-rtl.css 374 B
build/block-library/blocks/search/style.css 375 B
build/block-library/blocks/search/theme-rtl.css 64 B
build/block-library/blocks/search/theme.css 64 B
build/block-library/blocks/separator/editor-rtl.css 99 B
build/block-library/blocks/separator/editor.css 99 B
build/block-library/blocks/separator/style-rtl.css 250 B
build/block-library/blocks/separator/style.css 250 B
build/block-library/blocks/separator/theme-rtl.css 172 B
build/block-library/blocks/separator/theme.css 172 B
build/block-library/blocks/shortcode/editor-rtl.css 474 B
build/block-library/blocks/shortcode/editor.css 474 B
build/block-library/blocks/site-logo/editor-rtl.css 462 B
build/block-library/blocks/site-logo/editor.css 464 B
build/block-library/blocks/site-logo/style-rtl.css 153 B
build/block-library/blocks/site-logo/style.css 153 B
build/block-library/blocks/site-tagline/editor-rtl.css 86 B
build/block-library/blocks/site-tagline/editor.css 86 B
build/block-library/blocks/site-title/editor-rtl.css 84 B
build/block-library/blocks/site-title/editor.css 84 B
build/block-library/blocks/social-link/editor-rtl.css 165 B
build/block-library/blocks/social-link/editor.css 165 B
build/block-library/blocks/social-links/editor-rtl.css 812 B
build/block-library/blocks/social-links/editor.css 811 B
build/block-library/blocks/social-links/style-rtl.css 1.3 kB
build/block-library/blocks/social-links/style.css 1.3 kB
build/block-library/blocks/spacer/editor-rtl.css 307 B
build/block-library/blocks/spacer/editor.css 307 B
build/block-library/blocks/spacer/style-rtl.css 48 B
build/block-library/blocks/spacer/style.css 48 B
build/block-library/blocks/table/editor-rtl.css 471 B
build/block-library/blocks/table/editor.css 472 B
build/block-library/blocks/table/style-rtl.css 481 B
build/block-library/blocks/table/style.css 481 B
build/block-library/blocks/table/theme-rtl.css 188 B
build/block-library/blocks/table/theme.css 188 B
build/block-library/blocks/tag-cloud/style-rtl.css 146 B
build/block-library/blocks/tag-cloud/style.css 146 B
build/block-library/blocks/template-part/editor-rtl.css 636 B
build/block-library/blocks/template-part/editor.css 635 B
build/block-library/blocks/template-part/theme-rtl.css 101 B
build/block-library/blocks/template-part/theme.css 101 B
build/block-library/blocks/term-description/editor-rtl.css 90 B
build/block-library/blocks/term-description/editor.css 90 B
build/block-library/blocks/text-columns/editor-rtl.css 95 B
build/block-library/blocks/text-columns/editor.css 95 B
build/block-library/blocks/text-columns/style-rtl.css 166 B
build/block-library/blocks/text-columns/style.css 166 B
build/block-library/blocks/verse/style-rtl.css 87 B
build/block-library/blocks/verse/style.css 87 B
build/block-library/blocks/video/editor-rtl.css 571 B
build/block-library/blocks/video/editor.css 572 B
build/block-library/blocks/video/style-rtl.css 173 B
build/block-library/blocks/video/style.css 173 B
build/block-library/blocks/video/theme-rtl.css 124 B
build/block-library/blocks/video/theme.css 124 B
build/block-library/common-rtl.css 853 B
build/block-library/common.css 849 B
build/block-library/reset-rtl.css 527 B
build/block-library/reset.css 527 B
build/block-library/theme-rtl.css 658 B
build/block-library/theme.css 663 B
build/block-serialization-default-parser/index.min.js 1.09 kB
build/block-serialization-spec-parser/index.min.js 2.79 kB
build/blocks/index.min.js 46.9 kB
build/components/style-rtl.css 15.8 kB
build/components/style.css 15.8 kB
build/compose/index.min.js 10.2 kB
build/customize-widgets/index.min.js 11.1 kB
build/customize-widgets/style-rtl.css 1.5 kB
build/customize-widgets/style.css 1.49 kB
build/data-controls/index.min.js 614 B
build/data/index.min.js 7.1 kB
build/date/index.min.js 31.5 kB
build/deprecated/index.min.js 428 B
build/dom-ready/index.min.js 304 B
build/dom/index.min.js 4.53 kB
build/edit-navigation/index.min.js 14.9 kB
build/edit-post/classic-rtl.css 492 B
build/edit-post/classic.css 494 B
build/edit-post/index.min.js 29 kB
build/edit-post/style-rtl.css 7.2 kB
build/edit-post/style.css 7.2 kB
build/edit-site/style-rtl.css 5.07 kB
build/edit-site/style.css 5.07 kB
build/edit-widgets/index.min.js 16.1 kB
build/edit-widgets/style-rtl.css 4.06 kB
build/edit-widgets/style.css 4.06 kB
build/editor/index.min.js 37.7 kB
build/editor/style-rtl.css 3.74 kB
build/editor/style.css 3.73 kB
build/element/index.min.js 3.17 kB
build/escape-html/index.min.js 517 B
build/format-library/style-rtl.css 668 B
build/hooks/index.min.js 1.55 kB
build/html-entities/index.min.js 424 B
build/i18n/index.min.js 3.6 kB
build/is-shallow-equal/index.min.js 501 B
build/keyboard-shortcuts/index.min.js 1.49 kB
build/keycodes/index.min.js 1.25 kB
build/list-reusable-blocks/index.min.js 1.85 kB
build/list-reusable-blocks/style-rtl.css 838 B
build/list-reusable-blocks/style.css 838 B
build/media-utils/index.min.js 2.88 kB
build/notices/index.min.js 845 B
build/nux/index.min.js 2.03 kB
build/nux/style-rtl.css 747 B
build/nux/style.css 743 B
build/plugins/index.min.js 1.83 kB
build/primitives/index.min.js 921 B
build/priority-queue/index.min.js 582 B
build/react-i18n/index.min.js 671 B
build/redux-routine/index.min.js 2.63 kB
build/reusable-blocks/index.min.js 2.28 kB
build/reusable-blocks/style-rtl.css 256 B
build/reusable-blocks/style.css 256 B
build/rich-text/index.min.js 10.6 kB
build/server-side-render/index.min.js 1.32 kB
build/shortcode/index.min.js 1.48 kB
build/token-list/index.min.js 562 B
build/url/index.min.js 1.74 kB
build/viewport/index.min.js 1.02 kB
build/warning/index.min.js 248 B
build/widgets/index.min.js 7.27 kB
build/widgets/style-rtl.css 1.17 kB
build/widgets/style.css 1.18 kB
build/wordcount/index.min.js 1.04 kB

compressed-size-action

@talldan
Copy link
Contributor

talldan commented Aug 4, 2021

It's nice having the dropdown block in the inserter. For me it feels like it would be a clearer way to create a submenu compared to the current flow (particularly if the navigation block's quick inserter could be cleaned up to prioritise particular blocks). This makes it clear from the start what kind of an item I'm going to create, whereas adding a link and then converting to a submenu always felt like it took a bit of discovery and wasn't quite so direct.

I'd imagine navigation links could still retain the toolbar button for creating a submenu, but it'd result in a transform from the navigation link to a dropdown.

Not the most important part of this PR right now, but the name of this block is an interesting one. Dropdown implies a very specific style type of submenu. In the future, the navigation block might support other types of submenu (like an accordion), and I'm not sure whether that'd be the same block with a different style, or variation, or a different block entirely.

@jasmussen
Copy link
Contributor

Coming back to this after a bit of AFK, thanks so much for the PR. Here's what I see:

nav

Some of the rough edges aside (it's a draft PR), there are some interesting revelations in trying this, and forgive me for mostly echoing Dan above:

  • While there would need to be a way to "convert" an existing menu item into a dropdown menu, the ability to explicitly insert a dropdown item like this seems like it has potential. It might even be great for patterns that are meant to suggest dropdown menu navigation.
  • One potentially important benefit of this approach is that you can create truly click-only dropdown menus, which would be a big benefit for some particular designs, well explained in this post.
  • The approach does challenge the menu item setup state as it exists, and the state would need to be tweaked in order to accommodate this item type. Blocks that link: Provide a split label/URL control and placeholder state #30170 might benefit here, as might Menu Item placeholder: Show page label in setup state #33091.
  • On a more general level, as we add more menu item types, Navigation: use generic css class names for navigation items #33048 is becoming increasingly important so themes won't have to refactor their CSS to target new CSS classes whenever a menu item type is added.
  • It's possibly muscle memory and not necessarily the most ideal solution, but I find myself missing the "Add submenu item" button in the block toolbar, for creating dropdowns. It might be interesting to not only keep that button, but make it available even when the main navigation block is selected, and if clicked there, it just inserts the dropdown menu item.

As far as next steps, what are the smallest tweaks we need to make in order to find out if this is the best path forward?

@tellthemachines
Copy link
Contributor Author

Thanks for the feedback, folks!

I'd imagine navigation links could still retain the toolbar button for creating a submenu, but it'd result in a transform from the navigation link to a dropdown.

Oooh nice! That would be in addition to the transform option in the block name dropdown, right?

Dropdown implies a very specific style type of submenu. In the future, the navigation block might support other types of submenu (like an accordion), and I'm not sure whether that'd be the same block with a different style, or variation, or a different block entirely

Good question, I think that depends on whether we can use the same markup for both patterns, in which case it would make sense to have the same block with two styling options or variations, and call it Submenu. Or perhaps the block should be context-aware, as an accordion only makes sense within a certain layout. You'd expect it to be a slideout menu, or at least vertically oriented. It wouldn't make sense to have an accordion sitting next to a dropdown in a horizontal nav.

I think I went with Dropdown because at first I was considering if we'd want to use it outside the Nav block, but there's so much nav-specific behaviour in here that it's probably best to forget that 😅

The approach does challenge the menu item setup state as it exists, and the state would need to be tweaked in order to accommodate this item type

@jasmussen could you elaborate a bit more on this? I'm thinking the Navigation Link block could be just a menu item with no additional functionality apart from perhaps the ability to be transformed into a Dropdown.

#33048 is becoming increasingly important so themes won't have to refactor their CSS

Absolutely, and I'm now wondering if we should tackle that before moving on with this work. I'm happy to do a PR but we'll probably want to agree on the appropriate classnames beforehand 😄

As far as next steps, what are the smallest tweaks we need to make in order to find out if this is the best path forward?

I'm working on the open on click functionality, as that was a general requirement for submenus from the a11y feedback on the Navigation Heading PR. Then there's a bunch of styling issues that need to be fixed, but perhaps we should get #33048 done beforehand, as it will avoid some code duplication in this PR.

Really, the choice is between this PR and #33351 in terms of how we allow users to create submenus. I'm inclining towards this PR from a code perspective, and I like how obvious it is to have Dropdown as an option in the block inserter, but welcome more opinions on both fronts!

@jasmussen
Copy link
Contributor

Oooh nice! That would be in addition to the transform option in the block name dropdown, right?

I'm missing a beat. In my testing this branch and trunk, I don't see any transform options for any menu items at the moment.

As I wrote the initial suggestion, I was thinking of the need for us to still support the existing use case of all the existing dropdown menus that only open on hover, and where the main opening item also links to its own page. But I'm now reminded of a conversation on the initial issue, #18395 (comment) about potentially avoiding this "mix and match". My comment there assumes that a JS-based click-only menu is ideally a progressive enhancement on the existing dropdown structure, but I'm happy to be corrected there.

could you elaborate a bit more on this? I'm thinking the Navigation Link block could be just a menu item with no additional functionality apart from perhaps the ability to be transformed into a Dropdown.

Currently when you insert a menu item, but don't choose a destination, it looks like this:

Screenshot 2021-08-05 at 09 16 37

That state serves to indicate both that the menu item is in a draft state (and won't show up on the front-end), but also to indicate, just like grammar underlines, that you can click it to correct it:

Screenshot 2021-08-05 at 09 16 44

The behavior exists also in part to accommodate highly opinionated patterns. That means unless the menu item has both a label and a URL, it will show up in this draft state. So if it needs to be able to transform into a destination-less click-only dropdown, the flow will probably not feel great as is.

Absolutely, and I'm now wondering if we should tackle that before moving on with this work. I'm happy to do a PR but we'll probably want to agree on the appropriate classnames beforehand 😄

The current classes targeted in the Navigation block structural CSS are these, as copied from #31879:

Menu item container:

  • Page list: .wp-block-pages-list__item
  • Menu items: .wp-block-navigation-link

Menu item link:

  • Page list: .wp-block-pages-list__item__link
  • Menu items: .wp-block-navigation-link__content

Submenu indicator:

  • Page list: .wp-block-page-list__submenu-icon
  • Menu items: .wp-block-navigation-link__submenu-icon

Submenu container:

  • Page list: .submenu-container
  • Menu items: .wp-block-navigation-link__container

The submenu indicators and submenu containers are specific to the Page List block and therefore mostly a separate issue that's less important. But both the menu item container and link containers are both used and targetted by all menu items. So, how about:

  • Menu item container: .wp-block-navigation-item
  • Menu item link: .wp-block-navigation-item__content

There's also a little conversation about it in #32677 (comment).

Really, the choice is between this PR and #33351 in terms of how we allow users to create submenus. I'm inclining towards this PR from a code perspective, and I like how obvious it is to have Dropdown as an option in the block inserter, but welcome more opinions on both fronts!

Thanks for that summary, makes a ton of sense. When approaching it from that angle, there's the added angle of "do we allow mix and match", and what does that mean for any JS we might need to output to ensure click-only behaviors?

To be fair, I have seen a number of mega-menu sites that do mix and match, and have click or even hover-only menu items where the opener itself doesn't link anywhere. But at the same time I could also see it being useful to have a single navigation-block-level toggle to choose whether dropdowns opened on click or on hover. There's some mostly out of date work in #18445 that explores the latter.

@tellthemachines
Copy link
Contributor Author

I'm missing a beat. In my testing this branch and trunk, I don't see any transform options for any menu items at the moment.

I haven't added them yet 😅 but am assuming we'd want to add them in the default location for block transforms.

there's the added angle of "do we allow mix and match", and what does that mean for any JS we might need to output to ensure click-only behaviors?

The accessibility feedback is that we should avoid having the dropdowns open on focus, and should instead open them on click when using the keyboard (and this solution also avoids having to tab through endless submenu items to reach the next top-level item). It's fine to have them open on both click and hover, like Twenty Twenty One does. Potentially we could flip the question in #18395 and allow hover to be the configurable behaviour: have open on click be the default, and an option to also open on hover.

That would mean the JS for open on click would always be output. I've just added that functionality in my latest commit, btw, and I left the open on hover working too, so we can have a play with this and see how it feels.

@jasmussen
Copy link
Contributor

Cool, click is great. But it does come with some design challenges that are perhaps best explained in this post I can highly recommend, so we kind of have to decide where we land on that.

Potentially we could flip the question in #18395 and allow hover to be the configurable behaviour: have open on click be the default, and an option to also open on hover.

That makes a lot of sense to me, considering we probably have to keep the hover mechanism around, even just for cases where the JS fails or is blocked from loading, or as back compat for existing hover only themes. We can even add a yellow warning notice like we do for low contrast, when you choose the hover only option.

The challenge is, TwentyTwentyOne is designed around handling both hover and click, with a little "plus" icon being output for the click-only behavior. While I find it works well for that theme because it's designed around it, I'm skeptical it's a pattern we can roll out for every menu out there. Menus where the primary item links to its destination but also opens a submenu is like having the cake and eating it too — and it's not as obvious as the primary item performing only the single duty of opening the submenu. This is the part that needs the most flow-thought, I think.

Picture this structure:

Products [links to /products/]
	Jorts [links to /products/jorts/]
	Jeggings [links to /products/jeggings/]
	Jeans [links to /products/jeans]

If the entire menu, or just the menu item, was toggled to be click only, how would we handle the /products/ link? Doing double-duty with the split button feels like a plan B to me. Another option might be to move the products link inside the menu, and keep only the label. It would need to duplicate the label, but a design could potentialy work:

Frame 506

The other alternative, outside of the split menu, would be the Dropdown item approach, where the main item doesn't link anywhere:

Products [doesn't link anywhere]
	Jorts
	Jeggings
	Jeans

While a fine approach, it would allow the potentially confusing mix and match of hover-only menus and click-only menus, and it would also require the menu to be built in this way.

@tellthemachines
Copy link
Contributor Author

The challenge is, TwentyTwentyOne is designed around handling both hover and click, with a little "plus" icon being output for the click-only behavior. While I find it works well for that theme because it's designed around it, I'm skeptical it's a pattern we can roll out for every menu out there.

I'm thinking Twenty Twenty One is the best pattern to implement here, because it works just like a classic hover menu, and we only notice the open-on-click interaction when navigating with the keyboard. And when using the keyboard, it's frankly a relief not to have the submenus open as soon as we focus the parent element. The only obvious thing that we'd have to change in the Navigation block in order to implement that pattern is the submenu indicator could no longer be optional, as the click behaviour would need its own button whenever the parent element is a link, and we'd need the submenu indicator to signal the button's presence. But perhaps the indicator itself could be configurable, if a theme wanted to use a different icon.

What other issues do you anticipate with using the Twenty Twenty One pattern, @jasmussen ?

We can even add a yellow warning notice like we do for low contrast, when you choose the hover only option.

I meant having hover as optional in addition to click, not instead of it, otherwise the menu will be inaccessible. Unless the option is to have hover + open on focus instead of open on click only. But the accessibility folks seemed pretty keen on not using focus to open submenus at all.

@tellthemachines
Copy link
Contributor Author

The submenu indicators and submenu containers are specific to the Page List block and therefore mostly a separate issue that's less important. But both the menu item container and link containers are both used and targetted by all menu items. So, how about:

  • Menu item container: .wp-block-navigation-item
  • Menu item link: .wp-block-navigation-item__content

I've just made #33918 to address this issue. I'm thinking we'd better also add a classname for submenu containers, and perhaps for the indicators as well? That would help reduce (or even eliminate) the custom styles in this PR.

@jasmussen
Copy link
Contributor

jasmussen commented Aug 6, 2021

I'm thinking Twenty Twenty One is the best pattern to implement here, because it works just like a classic hover menu, and we only notice the open-on-click interaction when navigating with the keyboard.

Here's what I see in TT1:

TT1

  • When using the mouse, the mixture of hover and click makes it tricky to select submenu items. I click the plus to open the submenu, but when hovering outside of the plus, that closes it.
  • When using the keyboard alone, tab sets focus on the "opening" menu item, making it easy to follow that link. The next tab sets focus on the plus which then opens the submenu. However now I have to press tab again to enter the submenu, which doesn't match the visual order since the actual dropdown menu sits before the plus. My first instinct was shift-tab, or to use roving arrow-keys to navigate.

Moreover, the dropdown menu doesn't act as a modal in that it captures tab and closes on Escape, so it feels like it only adds limited value over the keyboard interaction compared to how the hover-only menu works with the keyboard:

TT1-hover

Click is great, though, but click and hover I'm less sure about: it's an extra tab-stop, and it requires a very delicate design in order for the visual order to match the tab-order. I'm also worried about what this means for the existing WordPress themes that are designed assuming a hover-only design; if we were to enforce click by default, we'd have to output a split-button indicator like a plus or a chevron, I don't think we can be sure existing themes are ready for that.

Approaching this fresh, on the other hand, I think we have a great opportunity to make an excellent click-only experience by default, one which works out of the box, is carefully designed, and perhaps uses Micromodal like the burger menu for keyboard interactions (which could be extra useful in mega-menu cases). If combined with leaving the existing hover/basic tabbing behavior as an optional fallback, it might thread the needle.

Because this feels important to get right, I would hope we could get some wider input from some of our themers on this: @MaggieCabrera @melchoyce @critterverse @javierarce @kellychoffman — if you have time, thank you!

@jasmussen
Copy link
Contributor

I've just made #33918 to address this issue. I'm thinking we'd better also add a classname for submenu containers, and perhaps for the indicators as well? That would help reduce (or even eliminate) the custom styles in this PR.

👏

A unification of all those classes sounds useful, absolutely, especially if it isn't too much work. One option might be to just let the existing classes for navigation items be intact (.wp-block-navigation-link__submenu-icon and .wp-block-navigation-link__container), and then copy those over to the Page List (which currently has .wp-block-page-list__submenu-icon, .submenu-container equivalents).

@tellthemachines
Copy link
Contributor Author

Here's what I see in TT1:

I agree the experience isn't great when clicking with a mouse, because we get a weird mix of click and hover behaviours, but both hover-only and click-only (using keyboard) is pretty nice:

 hover
click

Compared to the sub-optimal experience of opening on focus when there are large or multiple submenus:
focus

So I wouldn't give up straightaway on a hover/click combination, but we can definitely work to improve the points you mentioned. Perhaps we could try:

  • Aligning the submenus with the click button, so the focus order is visually obvious;
  • Ignoring hover events if the submenu was opened with a click, and only closing it when focus is moved outside of it.

I was thinking that if we allow interaction on hover, the button icon could be positioned closer to the top-level element text, so that they don't seem to be separate elements? But that kind of makes open on click functionality less obvious for mouse users. I don't know, it's a complicated problem 😅

I'm not completely sold on the idea of moving the top-level link into the submenu, mainly because I suspect users may take exception to not being allowed to make that decision themselves, but generally I agree that having top-level items just be buttons that open submenus, instead of links, is nicer. But WP has had the top-level item be a link for such a long time that springing a completely new pattern on our users might be quite jarring. On the other hand, the Navigation block is completely new (and it's not released yet! So we still have room to change stuff around) so it might be a good place to make that change.

@kjellr
Copy link
Contributor

kjellr commented Aug 11, 2021

👋

When using the mouse, the mixture of hover and click makes it tricky to select submenu items. I click the plus to open the submenu, but when hovering outside of the plus, that closes it.

Oof. That seems like something that should be fixed in TT1.

In case you're curious, this is the thread where we discussed the current TT1 implementation: WordPress/twentytwentyone#263

The separate, click-to-expand submenu was put in place for two reasons: for more intuitive keyboard navigation, and to reinforce the "hover is not necessarily a reflection of intent" concept. We added hover back in after testing, since folks (like me 😄) really expect it these days.

So I wouldn't give up straightaway on a hover/click combination, but we can definitely work to improve the points you mentioned. Perhaps we could try:
...
• Ignoring hover events if the submenu was opened with a click, and only closing it when focus is moved outside of it.

This suggestion from @tellthemachines seems reasonable to me, and I think is worth a try.

@shaunandrews
Copy link
Contributor

Ideally, the nav menu would be able to support all three options from the w3 docs (https://www.w3.org/WAI/tutorials/menus/flyout/). I can then see the hover+click pattern being the default, as it is the most accessible. Another option to to have the nav block support only one of the w3 options, but is extensible in a way that a plugin could easily provide those options.

https://codepen.io/okia/pen/jXWrYL

I think that codepen above is a great example of how it should work. It combines keyboard navigation with hover in a really nice way. You can still have the parent item trigger a link but also use the spacebar or down arrow to navigate to it's children. Mouse interaction works on hover and feel natural.

@jasmussen
Copy link
Contributor

Thanks for the added context. To be clear, my primary concern is with backwards compatibility with existing menus that rely on hover: the "plus" as a click affordance might mess with their layouts.

While the hover-only menu only provides basic accessibility, it is accessible, so I don't think there's any harm in existing menus retaining this behavior. Furthermore it's an opportunity to educate and warn in the interface, by providing a strong new default and warnings when choosing the legacy interface. Something like this, perhaps:

click

hover

@talldan
Copy link
Contributor

talldan commented Sep 8, 2021

@getdave I've been keeping a PR up-to-date here that adds support for submenu in the nav editor - #34281

@tellthemachines
Copy link
Contributor Author

The key is to not have two different ways to accomplish the same, that will often cause confusion as to which way is the right/best way. In other words, if we bring back the submenu block, we should consider removing the button in the toolbar.

There's nothing wrong with having two ways of accomplishing something. This is a very similar situation to the Image to Cover transform: Cover is available as a block in the inserter, and it's possible to transform Image into Cover via the usual transforms menu, but the transform is additionally exposed in the Image toolbar as "Add text over image".

There doesn't have to be a single best way; if having two or more ways to do something makes it easier for users to accomplish what they want, I can't see any downsides 🙂

Thinking specifically of this case, due to the differences between hover and click, different flows are better suited to each option: transforming from a Link is more intuitive for the hover menu, but adding the Submenu directly makes more sense for the click menu.

Ultimately, some usability testing on this would help us confirm what is best.

The option not showing in the inserter would only be an issue when using the inline inserter; for the sidebar one the social links etc. are under a different section, so won't interfere with the visibility of the Submenu block. I'm not sure which inserter gets most use, but I doubt it would be a huge issue even for the inline one.

I wonder whether we ought to include the link text here if it's available rather than just Submenu. The block icon is enough to denote it's a submenu.

When adding dropdowns within dropdowns I found the teriary level sometimes appeared on top of the secondary level dropdown instead of to the side.

Thanks, fixed!

Nit: I noticed that when you expand / collapse the Submenu item in the list view the dropdown doesn't match in the Editor. I expected when I collapsed in the List View that the dropdown would disappear in the Editor.

Hmm, this also happens on trunk so it's either intended behaviour, or a bug that can be fixed separately 😅

Hover intent is a great idea! Again, it's not on trunk so we can do it separately.

@talldan
Copy link
Contributor

talldan commented Sep 8, 2021

Did some testing and I noticed in TT1 Blocks empty submenus are transparent (theme styles disabled):
Screenshot 2021-09-08 at 1 15 55 pm

The block behind also seems to be selectable so maybe it's more of a z-index thing. The same happens in standard Twenty Twenty One, but is harder to reproduce because there are bigger gaps between blocks, so it's harder to get a dropdown over the top of a trailing block.

Also, side note, #34281 should be ready for review now.

@talldan
Copy link
Contributor

talldan commented Sep 8, 2021

The way these options jump around doesn't feel good. It makes it really easy to click the wrong one.

Kapture.2021-09-08.at.13.40.42.mp4

@tellthemachines
Copy link
Contributor Author

The block behind also seems to be selectable so maybe it's more of a z-index thing.

It was; fixed now.

The way these options jump around doesn't feel good. It makes it really easy to click the wrong one.

I've moved them around so the disappearing one is at the bottom. In any case, there are plans to change some of these to buttons soon.

Copy link
Contributor

@talldan talldan left a comment

Choose a reason for hiding this comment

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

LGTM, I only found very minor things!

@@ -326,11 +327,16 @@ export default function NavigationLinkEdit( {
.length;

return {
innerBlocks: getBlocks( clientId ),
isAtMaxNesting:
getBlockParentsByBlockName( clientId, name ).length >=
Copy link
Contributor

Choose a reason for hiding this comment

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

Should name be expanded to take into account the submenu block the same way isTopLevelLink does?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes! Thanks, totally missed that 😅

Comment on lines 334 to 339
// Temporary fix until navigation link submenus are properly deprecated.
isTopLevelLink:
getBlockParentsByBlockName( clientId, name ).length === 0,
getBlockParentsByBlockName( clientId, [
name,
'core/navigation-submenu',
] ).length === 0,
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't know that it's possible to deprecate from one block type to another. 🤔

It might also be more flexible to make this check if the parent is a core/navigation block. something like getBlockName( getRootClientId( clientId ) ) === 'core/navigation'.

}

// Show submenus on click.
.wp-block-navigation-submenu__toggle[aria-expanded="true"] + .wp-block-navigation__submenu-container {
Copy link
Contributor

Choose a reason for hiding this comment

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

Something I noticed in usage. I think the button could use cursor: pointer

// Add the navigation block.
await insertBlock( 'Navigation' );

await selectDropDownOption( 'Test Menu 2' );
Copy link
Contributor

Choose a reason for hiding this comment

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

Not added here, but my OCD was triggered by 'DropDown' 😆

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ugh yeah, would be good to rename that if possible.

* @param array $attributes Block attributes.
* @return array Colors CSS classes and inline styles.
*/
function block_core_navigation_submenu_build_css_colors( $context, $attributes ) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe it's fine for it live in the nav block's PHP file, given this is using the colors from that block.

@talldan talldan added the New Block Suggestion for a new block label Sep 8, 2021
@getdave getdave mentioned this pull request Sep 8, 2021
62 tasks
@tellthemachines
Copy link
Contributor Author

Thanks for the reviews, folks! I've fixed the pending issues.

In the meantime, there's the navigation editor update PR, #34281, that I'm going to review and test in a bit. Should that one be merged together with this one, or is it not a blocker for merging this?

There's also #34675 to update Page List block, but I think that one can be merged later.

We haven't formally reached an agreement on whether to show Submenu in the inserter or not 😄 but I'm inclined to show it, and then gather data on how it's being used.

The remaining thing is to investigate how/if we can deprecate submenus in Navigation Link. I'll look at that separately.

@talldan
Copy link
Contributor

talldan commented Sep 10, 2021

@tellthemachines All still looks good. I say go ahead and merge, and then it'd be good also merge #34281 straight after. I've addressed the feedback on that one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Block] Navigation Affects the Navigation Block [Focus] Accessibility (a11y) Changes that impact accessibility and need corresponding review (e.g. markup changes). Needs Accessibility Feedback Need input from accessibility New Block Suggestion for a new block
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Navigation block: can't unlink items
9 participants