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

Fix navigation link ui close focus management #59925

Merged
merged 16 commits into from
Mar 29, 2024

Conversation

jeryj
Copy link
Contributor

@jeryj jeryj commented Mar 15, 2024

Fixes #58820

What?

Focus when closing the link ui has not been managed. This PR fixes focus loss from:

  • New link (+ appender) -> Escape (doesn't create link) -> Focuses closest sibling (adjacent or parent or navigation block)
  • New link (+ appender) -> Create link -> Focuses the newly created navigation item
  • Edit link ( primary + k) -> Escape -> Focuses navigation link item
  • Editing link from toolbar -> Focus sent back to link toolbar item
  • Empty link click or primary + k -> Focuses navigation link item
  • All the same scenarios for submenus as well
  • Bonus: Fixes an issue where having a url-like menu item will always be selected when the popover closes, instead of only on create

It also adds an extensive e2e test that checks for focus management and being able to create, use the link control, and delete navigation items and submenu items.

Why?

Accessibility, focus management. There were severe focus loss issues across the navigation block, especially when using the link control popover.

How?

Adds openedBy state to navigation-link and submenu components and handles the various situations.

Testing Instructions for Keyboard

Check for focus loss when interacting with the navigation block link ui only using your keyboard

  • New link (+ appender) -> Escape (doesn't create link) -> Focuses closest sibling (adjacent or parent or navigation block)
  • New link (+ appender) -> Create link -> Focuses the newly created navigation item
  • Edit link ( primary + k) -> Escape -> Focuses navigation link item
  • Editing link from toolbar -> Focus sent back to link toolbar item
  • Empty link click (Add label) or primary + k -> Focuses navigation link item
  • All the same scenarios for submenu items as well as submenu parents

For the navigation label selection issue:

  • Create a link like "https//example.com"
  • example.com label should be selected when closing the popover using Escape
  • deselect the text
  • Open the link popover again
  • Escape to close it
  • example.com should not be selected

Screenshots or screencast

This video shows all the steps in the "navigation manages focus for creating, editing, and deleting items" test in slowMo mode:

Screen.Recording.2024-03-22.at.1.58.53.PM.mov

@jeryj jeryj requested a review from ajitbohra as a code owner March 15, 2024 19:27
Copy link

github-actions bot commented Mar 15, 2024

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

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: jeryj <[email protected]>
Co-authored-by: scruffian <[email protected]>
Co-authored-by: getdave <[email protected]>
Co-authored-by: youknowriad <[email protected]>

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

@jeryj jeryj self-assigned this Mar 15, 2024
@jeryj jeryj added [Type] Bug An existing feature does not function as intended [Block] Navigation Link Affects the Navigation Link Block [Block] Submenu Affects the Submenu Block - for submenus in navigation labels Mar 15, 2024
@jeryj jeryj changed the title Fix/navigation link close focus management Fix navigation link ui close focus management Mar 15, 2024
jeryj added 3 commits March 15, 2024 15:42
* Sets openedBy state based on what opened the link ui (toolbar link button or navigation link block text
* Returns focus to the item that opened it
* If the action is cancelled (no link is added), move focus to the previous block (sibling navigation link or parent navigation link or block)
* linting changes to let me save
* Removed a case where focus would no longer need to be handled
@jeryj jeryj force-pushed the fix/navigation-link-close-focus-management branch from 51b7df6 to 00be503 Compare March 15, 2024 20:44
Copy link

github-actions bot commented Mar 15, 2024

Size Change: +1.91 kB (0%)

Total Size: 1.72 MB

Filename Size Change
build/block-editor/index.min.js 253 kB +365 B (0%)
build/block-editor/style-rtl.css 15.6 kB +2 B (0%)
build/block-editor/style.css 15.6 kB -2 B (0%)
build/block-library/blocks/audio/theme-rtl.css 133 B +7 B (+6%) 🔍
build/block-library/blocks/audio/theme.css 133 B +7 B (+6%) 🔍
build/block-library/blocks/cover/style-rtl.css 1.7 kB +7 B (0%)
build/block-library/blocks/cover/style.css 1.69 kB +7 B (0%)
build/block-library/blocks/embed/theme-rtl.css 133 B +7 B (+6%) 🔍
build/block-library/blocks/embed/theme.css 133 B +7 B (+6%) 🔍
build/block-library/blocks/file/editor-rtl.css 326 B +10 B (+3%)
build/block-library/blocks/file/editor.css 327 B +11 B (+3%)
build/block-library/blocks/image/theme-rtl.css 133 B +7 B (+6%) 🔍
build/block-library/blocks/image/theme.css 133 B +7 B (+6%) 🔍
build/block-library/blocks/pullquote/theme-rtl.css 174 B +6 B (+4%)
build/block-library/blocks/pullquote/theme.css 174 B +6 B (+4%)
build/block-library/blocks/quote/theme-rtl.css 233 B +10 B (+4%)
build/block-library/blocks/quote/theme.css 235 B +9 B (+4%)
build/block-library/blocks/social-links/editor-rtl.css 678 B -4 B (-1%)
build/block-library/blocks/social-links/editor.css 678 B -3 B (0%)
build/block-library/blocks/table/theme-rtl.css 152 B +6 B (+4%)
build/block-library/blocks/table/theme.css 152 B +6 B (+4%)
build/block-library/blocks/template-part/editor-rtl.css 431 B +28 B (+7%) 🔍
build/block-library/blocks/template-part/editor.css 431 B +28 B (+7%) 🔍
build/block-library/blocks/template-part/theme-rtl.css 107 B +6 B (+6%) 🔍
build/block-library/blocks/template-part/theme.css 107 B +6 B (+6%) 🔍
build/block-library/blocks/video/theme-rtl.css 133 B +7 B (+6%) 🔍
build/block-library/blocks/video/theme.css 133 B +7 B (+6%) 🔍
build/block-library/editor-rtl.css 12.4 kB +33 B (0%)
build/block-library/editor.css 12.4 kB +34 B (0%)
build/block-library/index.min.js 218 kB +275 B (0%)
build/block-library/style-rtl.css 14.8 kB +9 B (0%)
build/block-library/style.css 14.8 kB +5 B (0%)
build/block-library/theme-rtl.css 707 B +19 B (+3%)
build/block-library/theme.css 713 B +20 B (+3%)
build/blocks/index.min.js 51.8 kB +18 B (0%)
build/components/index.min.js 223 kB -305 B (0%)
build/components/style-rtl.css 11.8 kB -17 B (0%)
build/components/style.css 11.8 kB -17 B (0%)
build/core-data/index.min.js 72.9 kB +151 B (0%)
build/customize-widgets/index.min.js 11.2 kB +22 B (0%)
build/data/index.min.js 8.98 kB +40 B (0%)
build/edit-post/index.min.js 24 kB -187 B (-1%)
build/edit-post/style-rtl.css 5.56 kB -15 B (0%)
build/edit-post/style.css 5.56 kB -14 B (0%)
build/edit-site/index.min.js 217 kB -273 B (0%)
build/edit-site/style-rtl.css 15.1 kB +128 B (+1%)
build/edit-site/style.css 15.1 kB +133 B (+1%)
build/edit-widgets/index.min.js 17.3 kB +24 B (0%)
build/edit-widgets/style-rtl.css 4.15 kB -13 B (0%)
build/edit-widgets/style.css 4.15 kB -13 B (0%)
build/editor/index.min.js 65.1 kB +1.11 kB (+2%)
build/editor/style-rtl.css 5.43 kB +78 B (+1%)
build/editor/style.css 5.43 kB +79 B (+1%)
build/format-library/index.min.js 8.1 kB +73 B (+1%)
build/style-engine/index.min.js 2.03 kB -68 B (-3%)
build/widgets/index.min.js 7.22 kB +12 B (0%)
ℹ️ View Unchanged
Filename Size
build/a11y/index.min.js 955 B
build/annotations/index.min.js 2.69 kB
build/api-fetch/index.min.js 2.32 kB
build/autop/index.min.js 2.1 kB
build/blob/index.min.js 578 B
build/block-directory/index.min.js 7.26 kB
build/block-directory/style-rtl.css 1.03 kB
build/block-directory/style.css 1.03 kB
build/block-editor/content-rtl.css 4.43 kB
build/block-editor/content.css 4.43 kB
build/block-editor/default-editor-styles-rtl.css 394 B
build/block-editor/default-editor-styles.css 394 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 90 B
build/block-library/blocks/archives/style.css 90 B
build/block-library/blocks/audio/editor-rtl.css 150 B
build/block-library/blocks/audio/editor.css 150 B
build/block-library/blocks/audio/style-rtl.css 122 B
build/block-library/blocks/audio/style.css 122 B
build/block-library/blocks/avatar/editor-rtl.css 116 B
build/block-library/blocks/avatar/editor.css 116 B
build/block-library/blocks/avatar/style-rtl.css 104 B
build/block-library/blocks/avatar/style.css 104 B
build/block-library/blocks/block/editor-rtl.css 305 B
build/block-library/blocks/block/editor.css 305 B
build/block-library/blocks/button/editor-rtl.css 415 B
build/block-library/blocks/button/editor.css 414 B
build/block-library/blocks/button/style-rtl.css 627 B
build/block-library/blocks/button/style.css 626 B
build/block-library/blocks/buttons/editor-rtl.css 337 B
build/block-library/blocks/buttons/editor.css 337 B
build/block-library/blocks/buttons/style-rtl.css 332 B
build/block-library/blocks/buttons/style.css 332 B
build/block-library/blocks/calendar/style-rtl.css 239 B
build/block-library/blocks/calendar/style.css 239 B
build/block-library/blocks/categories/editor-rtl.css 113 B
build/block-library/blocks/categories/editor.css 112 B
build/block-library/blocks/categories/style-rtl.css 124 B
build/block-library/blocks/categories/style.css 124 B
build/block-library/blocks/code/editor-rtl.css 53 B
build/block-library/blocks/code/editor.css 53 B
build/block-library/blocks/code/style-rtl.css 121 B
build/block-library/blocks/code/style.css 121 B
build/block-library/blocks/code/theme-rtl.css 124 B
build/block-library/blocks/code/theme.css 124 B
build/block-library/blocks/columns/editor-rtl.css 108 B
build/block-library/blocks/columns/editor.css 108 B
build/block-library/blocks/columns/style-rtl.css 421 B
build/block-library/blocks/columns/style.css 421 B
build/block-library/blocks/comment-author-avatar/editor-rtl.css 125 B
build/block-library/blocks/comment-author-avatar/editor.css 125 B
build/block-library/blocks/comment-content/style-rtl.css 92 B
build/block-library/blocks/comment-content/style.css 92 B
build/block-library/blocks/comment-template/style-rtl.css 199 B
build/block-library/blocks/comment-template/style.css 198 B
build/block-library/blocks/comments-pagination-numbers/editor-rtl.css 123 B
build/block-library/blocks/comments-pagination-numbers/editor.css 121 B
build/block-library/blocks/comments-pagination/editor-rtl.css 222 B
build/block-library/blocks/comments-pagination/editor.css 209 B
build/block-library/blocks/comments-pagination/style-rtl.css 235 B
build/block-library/blocks/comments-pagination/style.css 231 B
build/block-library/blocks/comments-title/editor-rtl.css 75 B
build/block-library/blocks/comments-title/editor.css 75 B
build/block-library/blocks/comments/editor-rtl.css 840 B
build/block-library/blocks/comments/editor.css 839 B
build/block-library/blocks/comments/style-rtl.css 637 B
build/block-library/blocks/comments/style.css 636 B
build/block-library/blocks/cover/editor-rtl.css 647 B
build/block-library/blocks/cover/editor.css 650 B
build/block-library/blocks/details/editor-rtl.css 65 B
build/block-library/blocks/details/editor.css 65 B
build/block-library/blocks/details/style-rtl.css 98 B
build/block-library/blocks/details/style.css 98 B
build/block-library/blocks/embed/editor-rtl.css 322 B
build/block-library/blocks/embed/editor.css 322 B
build/block-library/blocks/embed/style-rtl.css 410 B
build/block-library/blocks/embed/style.css 410 B
build/block-library/blocks/file/style-rtl.css 280 B
build/block-library/blocks/file/style.css 281 B
build/block-library/blocks/file/view.min.js 324 B
build/block-library/blocks/footnotes/style-rtl.css 201 B
build/block-library/blocks/footnotes/style.css 199 B
build/block-library/blocks/form-input/editor-rtl.css 227 B
build/block-library/blocks/form-input/editor.css 227 B
build/block-library/blocks/form-input/style-rtl.css 343 B
build/block-library/blocks/form-input/style.css 343 B
build/block-library/blocks/form-submission-notification/editor-rtl.css 340 B
build/block-library/blocks/form-submission-notification/editor.css 340 B
build/block-library/blocks/form-submit-button/style-rtl.css 69 B
build/block-library/blocks/form-submit-button/style.css 69 B
build/block-library/blocks/form/view.min.js 471 B
build/block-library/blocks/freeform/editor-rtl.css 2.61 kB
build/block-library/blocks/freeform/editor.css 2.61 kB
build/block-library/blocks/gallery/editor-rtl.css 947 B
build/block-library/blocks/gallery/editor.css 952 B
build/block-library/blocks/gallery/style-rtl.css 1.72 kB
build/block-library/blocks/gallery/style.css 1.72 kB
build/block-library/blocks/gallery/theme-rtl.css 108 B
build/block-library/blocks/gallery/theme.css 108 B
build/block-library/blocks/group/editor-rtl.css 647 B
build/block-library/blocks/group/editor.css 647 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 78 B
build/block-library/blocks/group/theme.css 78 B
build/block-library/blocks/heading/style-rtl.css 189 B
build/block-library/blocks/heading/style.css 189 B
build/block-library/blocks/html/editor-rtl.css 336 B
build/block-library/blocks/html/editor.css 337 B
build/block-library/blocks/image/editor-rtl.css 878 B
build/block-library/blocks/image/editor.css 878 B
build/block-library/blocks/image/style-rtl.css 1.6 kB
build/block-library/blocks/image/style.css 1.59 kB
build/block-library/blocks/image/view.min.js 1.54 kB
build/block-library/blocks/latest-comments/style-rtl.css 357 B
build/block-library/blocks/latest-comments/style.css 357 B
build/block-library/blocks/latest-posts/editor-rtl.css 213 B
build/block-library/blocks/latest-posts/editor.css 212 B
build/block-library/blocks/latest-posts/style-rtl.css 478 B
build/block-library/blocks/latest-posts/style.css 478 B
build/block-library/blocks/list/style-rtl.css 88 B
build/block-library/blocks/list/style.css 88 B
build/block-library/blocks/media-text/editor-rtl.css 306 B
build/block-library/blocks/media-text/editor.css 305 B
build/block-library/blocks/media-text/style-rtl.css 505 B
build/block-library/blocks/media-text/style.css 503 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 668 B
build/block-library/blocks/navigation-link/editor.css 669 B
build/block-library/blocks/navigation-link/style-rtl.css 259 B
build/block-library/blocks/navigation-link/style.css 257 B
build/block-library/blocks/navigation-submenu/editor-rtl.css 296 B
build/block-library/blocks/navigation-submenu/editor.css 295 B
build/block-library/blocks/navigation/editor-rtl.css 2.26 kB
build/block-library/blocks/navigation/editor.css 2.26 kB
build/block-library/blocks/navigation/style-rtl.css 2.26 kB
build/block-library/blocks/navigation/style.css 2.25 kB
build/block-library/blocks/navigation/view.min.js 1.02 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 377 B
build/block-library/blocks/page-list/editor.css 377 B
build/block-library/blocks/page-list/style-rtl.css 175 B
build/block-library/blocks/page-list/style.css 175 B
build/block-library/blocks/paragraph/editor-rtl.css 235 B
build/block-library/blocks/paragraph/editor.css 235 B
build/block-library/blocks/paragraph/style-rtl.css 335 B
build/block-library/blocks/paragraph/style.css 335 B
build/block-library/blocks/post-author/style-rtl.css 175 B
build/block-library/blocks/post-author/style.css 176 B
build/block-library/blocks/post-comments-form/editor-rtl.css 96 B
build/block-library/blocks/post-comments-form/editor.css 96 B
build/block-library/blocks/post-comments-form/style-rtl.css 508 B
build/block-library/blocks/post-comments-form/style.css 508 B
build/block-library/blocks/post-content/editor-rtl.css 74 B
build/block-library/blocks/post-content/editor.css 74 B
build/block-library/blocks/post-date/style-rtl.css 61 B
build/block-library/blocks/post-date/style.css 61 B
build/block-library/blocks/post-excerpt/editor-rtl.css 71 B
build/block-library/blocks/post-excerpt/editor.css 71 B
build/block-library/blocks/post-excerpt/style-rtl.css 141 B
build/block-library/blocks/post-excerpt/style.css 141 B
build/block-library/blocks/post-featured-image/editor-rtl.css 666 B
build/block-library/blocks/post-featured-image/editor.css 662 B
build/block-library/blocks/post-featured-image/style-rtl.css 342 B
build/block-library/blocks/post-featured-image/style.css 342 B
build/block-library/blocks/post-navigation-link/style-rtl.css 215 B
build/block-library/blocks/post-navigation-link/style.css 214 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 409 B
build/block-library/blocks/post-template/style.css 408 B
build/block-library/blocks/post-terms/style-rtl.css 96 B
build/block-library/blocks/post-terms/style.css 96 B
build/block-library/blocks/post-time-to-read/style-rtl.css 69 B
build/block-library/blocks/post-time-to-read/style.css 69 B
build/block-library/blocks/post-title/style-rtl.css 100 B
build/block-library/blocks/post-title/style.css 100 B
build/block-library/blocks/preformatted/style-rtl.css 125 B
build/block-library/blocks/preformatted/style.css 125 B
build/block-library/blocks/pullquote/editor-rtl.css 135 B
build/block-library/blocks/pullquote/editor.css 135 B
build/block-library/blocks/pullquote/style-rtl.css 354 B
build/block-library/blocks/pullquote/style.css 354 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-pagination/editor-rtl.css 221 B
build/block-library/blocks/query-pagination/editor.css 211 B
build/block-library/blocks/query-pagination/style-rtl.css 288 B
build/block-library/blocks/query-pagination/style.css 284 B
build/block-library/blocks/query-title/style-rtl.css 63 B
build/block-library/blocks/query-title/style.css 63 B
build/block-library/blocks/query/editor-rtl.css 486 B
build/block-library/blocks/query/editor.css 486 B
build/block-library/blocks/query/view.min.js 958 B
build/block-library/blocks/quote/style-rtl.css 237 B
build/block-library/blocks/quote/style.css 237 B
build/block-library/blocks/read-more/style-rtl.css 140 B
build/block-library/blocks/read-more/style.css 140 B
build/block-library/blocks/rss/editor-rtl.css 149 B
build/block-library/blocks/rss/editor.css 149 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 184 B
build/block-library/blocks/search/editor.css 184 B
build/block-library/blocks/search/style-rtl.css 629 B
build/block-library/blocks/search/style.css 628 B
build/block-library/blocks/search/theme-rtl.css 114 B
build/block-library/blocks/search/theme.css 114 B
build/block-library/blocks/search/view.min.js 478 B
build/block-library/blocks/separator/editor-rtl.css 146 B
build/block-library/blocks/separator/editor.css 146 B
build/block-library/blocks/separator/style-rtl.css 229 B
build/block-library/blocks/separator/style.css 229 B
build/block-library/blocks/separator/theme-rtl.css 194 B
build/block-library/blocks/separator/theme.css 194 B
build/block-library/blocks/shortcode/editor-rtl.css 323 B
build/block-library/blocks/shortcode/editor.css 323 B
build/block-library/blocks/site-logo/editor-rtl.css 754 B
build/block-library/blocks/site-logo/editor.css 754 B
build/block-library/blocks/site-logo/style-rtl.css 204 B
build/block-library/blocks/site-logo/style.css 204 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 116 B
build/block-library/blocks/site-title/editor.css 116 B
build/block-library/blocks/site-title/style-rtl.css 57 B
build/block-library/blocks/site-title/style.css 57 B
build/block-library/blocks/social-link/editor-rtl.css 184 B
build/block-library/blocks/social-link/editor.css 184 B
build/block-library/blocks/social-links/style-rtl.css 1.48 kB
build/block-library/blocks/social-links/style.css 1.48 kB
build/block-library/blocks/spacer/editor-rtl.css 350 B
build/block-library/blocks/spacer/editor.css 350 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 395 B
build/block-library/blocks/table/editor.css 395 B
build/block-library/blocks/table/style-rtl.css 639 B
build/block-library/blocks/table/style.css 639 B
build/block-library/blocks/tag-cloud/style-rtl.css 251 B
build/block-library/blocks/tag-cloud/style.css 253 B
build/block-library/blocks/term-description/style-rtl.css 111 B
build/block-library/blocks/term-description/style.css 111 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 99 B
build/block-library/blocks/verse/style.css 99 B
build/block-library/blocks/video/editor-rtl.css 552 B
build/block-library/blocks/video/editor.css 555 B
build/block-library/blocks/video/style-rtl.css 185 B
build/block-library/blocks/video/style.css 185 B
build/block-library/classic-rtl.css 179 B
build/block-library/classic.css 179 B
build/block-library/common-rtl.css 1.11 kB
build/block-library/common.css 1.11 kB
build/block-library/editor-elements-rtl.css 75 B
build/block-library/editor-elements.css 75 B
build/block-library/elements-rtl.css 54 B
build/block-library/elements.css 54 B
build/block-library/reset-rtl.css 472 B
build/block-library/reset.css 472 B
build/block-serialization-default-parser/index.min.js 1.12 kB
build/block-serialization-spec-parser/index.min.js 2.87 kB
build/commands/index.min.js 15.6 kB
build/commands/style-rtl.css 935 B
build/commands/style.css 930 B
build/compose/index.min.js 12.6 kB
build/core-commands/index.min.js 2.77 kB
build/customize-widgets/style-rtl.css 1.36 kB
build/customize-widgets/style.css 1.36 kB
build/data-controls/index.min.js 640 B
build/date/index.min.js 17.9 kB
build/deprecated/index.min.js 451 B
build/dom-ready/index.min.js 324 B
build/dom/index.min.js 4.65 kB
build/edit-post/classic-rtl.css 558 B
build/edit-post/classic.css 558 B
build/element/index.min.js 4.83 kB
build/escape-html/index.min.js 537 B
build/format-library/style-rtl.css 492 B
build/format-library/style.css 490 B
build/hooks/index.min.js 1.55 kB
build/html-entities/index.min.js 448 B
build/i18n/index.min.js 3.58 kB
build/interactivity/file.min.js 447 B
build/interactivity/image.min.js 1.67 kB
build/interactivity/index.min.js 13 kB
build/interactivity/navigation.min.js 1.15 kB
build/interactivity/query.min.js 740 B
build/interactivity/router.min.js 1.36 kB
build/interactivity/search.min.js 618 B
build/is-shallow-equal/index.min.js 527 B
build/keyboard-shortcuts/index.min.js 1.74 kB
build/keycodes/index.min.js 1.46 kB
build/list-reusable-blocks/index.min.js 2.11 kB
build/list-reusable-blocks/style-rtl.css 851 B
build/list-reusable-blocks/style.css 849 B
build/media-utils/index.min.js 2.92 kB
build/modules/importmap-polyfill.min.js 12.2 kB
build/notices/index.min.js 948 B
build/nux/index.min.js 2 kB
build/nux/style-rtl.css 747 B
build/nux/style.css 742 B
build/patterns/index.min.js 5.73 kB
build/patterns/style-rtl.css 553 B
build/patterns/style.css 552 B
build/plugins/index.min.js 1.8 kB
build/preferences-persistence/index.min.js 2.05 kB
build/preferences/index.min.js 2.81 kB
build/preferences/style-rtl.css 710 B
build/preferences/style.css 712 B
build/primitives/index.min.js 975 B
build/priority-queue/index.min.js 1.52 kB
build/private-apis/index.min.js 1 kB
build/react-i18n/index.min.js 623 B
build/react-refresh-entry/index.min.js 9.47 kB
build/react-refresh-runtime/index.min.js 6.78 kB
build/redux-routine/index.min.js 2.7 kB
build/reusable-blocks/index.min.js 2.73 kB
build/reusable-blocks/style-rtl.css 256 B
build/reusable-blocks/style.css 256 B
build/rich-text/index.min.js 10.5 kB
build/router/index.min.js 1.79 kB
build/server-side-render/index.min.js 1.96 kB
build/shortcode/index.min.js 1.39 kB
build/token-list/index.min.js 582 B
build/url/index.min.js 3.72 kB
build/vendors/inert-polyfill.min.js 2.48 kB
build/vendors/react-dom.min.js 41.7 kB
build/vendors/react.min.js 4.02 kB
build/viewport/index.min.js 957 B
build/warning/index.min.js 249 B
build/widgets/style-rtl.css 1.17 kB
build/widgets/style.css 1.17 kB
build/wordcount/index.min.js 1.02 kB

compressed-size-action

@@ -93,7 +90,7 @@ const useIsDraggingWithin = ( elementRef ) => {
ownerDocument.removeEventListener( 'dragend', handleDragEnd );
ownerDocument.removeEventListener( 'dragenter', handleDragEnter );
};
}, [] );
}, [ elementRef ] );
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Linting

@@ -226,7 +229,7 @@ export default function NavigationLinkEdit( {
/**
* Transform to submenu block.
*/
function transformToSubmenu() {
const transformToSubmenu = () => {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Linting

Comment on lines +277 to +281
! prevUrl &&
url &&
isLinkOpen &&
isURL( prependHTTP( label ) ) &&
/^.+\.[a-z]+/.test( label )
Copy link
Contributor Author

Choose a reason for hiding this comment

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

We only want the label text to be selected if we add a link with a custom url like https://www.example.com. Previously, this would select the label text every time the link popover closed, not just when the link was created. We only want this to happen when the link is created.

Comment on lines -281 to -282
// Focus it (but do not select).
placeCaretAtHorizontalEdge( ref.current, true );
Copy link
Contributor Author

Choose a reason for hiding this comment

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

We want the caret to go back to wherever it was. We shouldn't assume it to go to the start.

@@ -290,6 +313,220 @@ test.describe( 'Navigation block', () => {
await expect( warningMessage ).toBeVisible();
} );

test( 'creating navigation menus via keyboard without losing focus', async ( {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This test is huge, but it's better that it is:

  • Faster than running it in several smaller tests
  • We don't need to "redo" work in each test. For example, each test needs to build off the previous one, so there would either be repeating tests or lots of initial menus to start from.
  • Creating a navigation block using a keyboard should work. This is a more realistic example of creating a menu and is more likely to catch edge cases.

I tried to break it down into sensible smaller tests, and refactor reusable pieces but keep them readable. I wrote this with the idea that it will likely need to be debugged since I expect focus management bugs to happen. When we debug it or change the implementation, my intent is that this will be easier to understand and maintain.

Copy link
Contributor

@scruffian scruffian left a comment

Choose a reason for hiding this comment

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

I tested this and it works as described. The code makes sense too.

@jeryj jeryj merged commit 0cea924 into trunk Mar 29, 2024
58 checks passed
@jeryj jeryj deleted the fix/navigation-link-close-focus-management branch March 29, 2024 15:21
@github-actions github-actions bot added this to the Gutenberg 18.1 milestone Mar 29, 2024
cbravobernal pushed a commit to garridinsi/gutenberg that referenced this pull request Apr 9, 2024
@@ -565,10 +573,24 @@ export default function NavigationLinkEdit( {
// If there is no link then remove the auto-inserted block.
// This avoids empty blocks which can provided a poor UX.
if ( ! url ) {
// Need to handle refocusing the Nav block or the inserter?
// Select the previous block to keep focus nearby
selectPreviousBlock( clientId, true );
Copy link
Contributor

Choose a reason for hiding this comment

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

Perhaps this line is causing the main inserter to not open when you click the "Browse All" button (See #61361).

My guess is that this occurs for the following reasons:

  • The main inserter opens when "Browse All" is clicked (See).
  • onClose is called because the focus leaves the popover.
  • Since the URL does not exist, this part will be executed and the previous block will be selected.
  • The main inserter automatically closes because the block is selected.

I don't understand everything about this PR, but I would suggest not binding onSelectBlock directly to the popover component's onClose prop. It might be better to clearly separate onClose and onSelectBlock, and only move the focus to the previous block when onSelectBlock is called.

I haven't tested it thoroughly, but the code below works fine as far as I've tested it. I hope this helps.

diff --git a/packages/block-library/src/navigation-link/edit.js b/packages/block-library/src/navigation-link/edit.js
index 4902a6cb2b..cb89881f79 100644
--- a/packages/block-library/src/navigation-link/edit.js
+++ b/packages/block-library/src/navigation-link/edit.js
@@ -562,6 +562,15 @@ export default function NavigationLinkEdit( {
                                                        clientId={ clientId }
                                                        link={ attributes }
                                                        onClose={ () => {
+                                                               // When onClose is called, it means that the "Browse all" button
+                                                               // was clicked and the main inserter was opened. In this case,
+                                                               // remove the empty block and close the link UI. It does not return
+                                                               // focus to the previous block to prevent the main inserter from
+                                                               // closing.
+                                                               onReplace( [] );
+                                                               setIsLinkOpen( false );
+                                                       } }
+                                                       onSelectBlock={ () => {
                                                                // If there is no link then remove the auto-inserted block.
                                                                // This avoids empty blocks which can provided a poor UX.
                                                                if ( ! url ) {
diff --git a/packages/block-library/src/navigation-link/link-ui.js b/packages/block-library/src/navigation-link/link-ui.js
index ce79af40e4..64a742e776 100644
--- a/packages/block-library/src/navigation-link/link-ui.js
+++ b/packages/block-library/src/navigation-link/link-ui.js
@@ -208,10 +208,6 @@ export function LinkUI( props ) {
                `link-ui-link-control__description`
        );
 
-       // Selecting a block should close the popover and also remove the (previously) automatically inserted
-       // link block so that the newly selected block can be inserted in its place.
-       const { onClose: onSelectBlock } = props;
-
        return (
                <Popover
                        placement="bottom"
@@ -291,7 +287,7 @@ export function LinkUI( props ) {
                                                setAddingBlock( false );
                                                setFocusAddBlockButton( true );
                                        } }
-                                       onSelectBlock={ onSelectBlock }
+                                       onSelectBlock={ props.onSelectBlock }
                                />
                        ) }
                </Popover>

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for noticing and debugging this, @t-hamano! The onClose is all work-arounds for focus management, as we couldn't work out a cleaner way to return focus to the + inserter when closing it. This test covers a lot of scenarios to help show what the onClose code does. The diff you shared does make the inserter work again, but breaks the focus management. I'm not sure how to keep them both working consistently. Maybe there's a way to tell the onClose to return early if we're opening the all blocks inserter panel?

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, when I made this change locally and ran the E2E tests, some tests failed 😅 There may be a better approach.

// Now the appender should be visible and reachable with an arrow down
await pageUtils.pressKeys( 'ArrowDown' );
await expect( navBlockInserter ).toBeFocused();
} );
Copy link
Member

Choose a reason for hiding this comment

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

Does this have to be one big test? It's nice to split things into smaller tests if possible, it's quite overwhelming to debug.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think it can certainly be splitted. I submitted #64305.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Block] Navigation Link Affects the Navigation Link Block [Block] Submenu Affects the Submenu Block - for submenus in navigation [Type] Bug An existing feature does not function as intended
Projects
Development

Successfully merging this pull request may close these issues.

Navigation Link: Handle focus when removing the block
4 participants