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

Writing flow: A11Y enhancements for useTabNav #41645

Open
wants to merge 22 commits into
base: trunk
Choose a base branch
from

Conversation

alexstine
Copy link
Contributor

@alexstine alexstine commented Jun 9, 2022

What?

This is a fairly complex refactor of writing flow for accessibility. Specifically the tabbing functionality in useTabNav.

Why?

See the following discussion for details. Essentially, Shift+Tab/Tab keys should be reserved for navigating a blocks content, not triggering actions such as toolbar focus or sidebar jump (to be addressed in another PR).

#38311

How?

  1. Modified isFormField() function to finally be compatible with contenteditable.
  2. Refactored useTabNav() in writing flow to do the following.
  3. Fixed one of the if conditionals to ensure elements exist in the same block before allowing focus to move. E.g., You should be able to press Tab to get from Upload to Media Library buttons for the image block, but not pressing Tab to get from paragraph to heading blocks.
  4. The Tab key with the Shift+Tab key should navigate block content reliably.

Testing Instructions

  1. Open a post or page.
  2. Insert an image block.
  3. Tab to the different buttons and even in to the sidebar.
  4. Now use Shift+Tab back to the block and through the available focus candidates. Once you run out of previous focus candidates, you should land safely in the block toolbar.
  5. This can also be tested with the table block as it has multiple text input fields after the table is created.

Screenshots or screencast

@alexstine alexstine requested a review from ellatrix as a code owner June 9, 2022 22:20
@alexstine alexstine self-assigned this Jun 9, 2022
@alexstine alexstine added [Type] Bug An existing feature does not function as intended [Focus] Accessibility (a11y) Changes that impact accessibility and need corresponding review (e.g. markup changes). [Feature] Writing Flow Block selection, navigation, splitting, merging, deletion... Needs Accessibility Feedback Need input from accessibility [Package] Block editor /packages/block-editor [a11y] Keyboard & Focus labels Jun 9, 2022
@github-actions
Copy link

github-actions bot commented Jun 9, 2022

Size Change: +994 B (0%)

Total Size: 1.24 MB

Filename Size Change
build/block-editor/index.min.js 159 kB +674 B (0%)
build/block-editor/style-rtl.css 15 kB -22 B (0%)
build/block-editor/style.css 15 kB -19 B (0%)
build/block-library/blocks/media-text/style-rtl.css 507 B +14 B (+3%)
build/block-library/blocks/media-text/style.css 505 B +15 B (+3%)
build/block-library/blocks/navigation/editor-rtl.css 2.05 kB +23 B (+1%)
build/block-library/blocks/navigation/editor.css 2.06 kB +18 B (+1%)
build/block-library/blocks/post-title/style-rtl.css 100 B +20 B (+25%) 🚨
build/block-library/blocks/post-title/style.css 100 B +20 B (+25%) 🚨
build/block-library/editor-rtl.css 11 kB +31 B (0%)
build/block-library/editor.css 11 kB +31 B (0%)
build/block-library/index.min.js 186 kB +627 B (0%)
build/block-library/style-rtl.css 11.9 kB +20 B (0%)
build/block-library/style.css 11.9 kB +20 B (0%)
build/blocks/index.min.js 49.5 kB +5 B (0%)
build/components/index.min.js 198 kB -785 B (0%)
build/core-data/index.min.js 15.5 kB +63 B (0%)
build/customize-widgets/style-rtl.css 1.38 kB -24 B (-2%)
build/customize-widgets/style.css 1.38 kB -24 B (-2%)
build/data/index.min.js 8.05 kB +24 B (0%)
build/dom/index.min.js 4.72 kB +34 B (+1%)
build/edit-navigation/index.min.js 16 kB +8 B (0%)
build/edit-post/index.min.js 30.5 kB +14 B (0%)
build/edit-site/index.min.js 57.4 kB +136 B (0%)
build/element/index.min.js 4.68 kB +6 B (0%)
build/redux-routine/index.min.js 2.74 kB -1 B (0%)
build/widgets/index.min.js 7.2 kB +11 B (0%)
build/widgets/style-rtl.css 1.18 kB +27 B (+2%)
build/widgets/style.css 1.19 kB +28 B (+2%)
ℹ️ View Unchanged
Filename Size
build/a11y/index.min.js 982 B
build/annotations/index.min.js 2.76 kB
build/api-fetch/index.min.js 2.26 kB
build/autop/index.min.js 2.14 kB
build/blob/index.min.js 475 B
build/block-directory/index.min.js 7.06 kB
build/block-directory/style-rtl.css 990 B
build/block-directory/style.css 991 B
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 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/audio/theme-rtl.css 110 B
build/block-library/blocks/audio/theme.css 110 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 59 B
build/block-library/blocks/avatar/style.css 59 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 441 B
build/block-library/blocks/button/editor.css 441 B
build/block-library/blocks/button/style-rtl.css 539 B
build/block-library/blocks/button/style.css 539 B
build/block-library/blocks/buttons/editor-rtl.css 292 B
build/block-library/blocks/buttons/editor.css 292 B
build/block-library/blocks/buttons/style-rtl.css 275 B
build/block-library/blocks/buttons/style.css 275 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 103 B
build/block-library/blocks/code/style.css 103 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 406 B
build/block-library/blocks/columns/style.css 406 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 187 B
build/block-library/blocks/comment-template/style.css 185 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 834 B
build/block-library/blocks/comments/editor.css 832 B
build/block-library/blocks/comments/style-rtl.css 632 B
build/block-library/blocks/comments/style.css 630 B
build/block-library/blocks/cover/editor-rtl.css 615 B
build/block-library/blocks/cover/editor.css 616 B
build/block-library/blocks/cover/style-rtl.css 1.55 kB
build/block-library/blocks/cover/style.css 1.55 kB
build/block-library/blocks/embed/editor-rtl.css 293 B
build/block-library/blocks/embed/editor.css 293 B
build/block-library/blocks/embed/style-rtl.css 410 B
build/block-library/blocks/embed/style.css 410 B
build/block-library/blocks/embed/theme-rtl.css 110 B
build/block-library/blocks/embed/theme.css 110 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 253 B
build/block-library/blocks/file/style.css 254 B
build/block-library/blocks/file/view.min.js 346 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/editor-rtl.css 948 B
build/block-library/blocks/gallery/editor.css 950 B
build/block-library/blocks/gallery/style-rtl.css 1.53 kB
build/block-library/blocks/gallery/style.css 1.53 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 412 B
build/block-library/blocks/group/editor.css 412 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 76 B
build/block-library/blocks/heading/style.css 76 B
build/block-library/blocks/html/editor-rtl.css 327 B
build/block-library/blocks/html/editor.css 329 B
build/block-library/blocks/image/editor-rtl.css 876 B
build/block-library/blocks/image/editor.css 873 B
build/block-library/blocks/image/style-rtl.css 627 B
build/block-library/blocks/image/style.css 630 B
build/block-library/blocks/image/theme-rtl.css 110 B
build/block-library/blocks/image/theme.css 110 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 213 B
build/block-library/blocks/latest-posts/editor.css 212 B
build/block-library/blocks/latest-posts/style-rtl.css 463 B
build/block-library/blocks/latest-posts/style.css 462 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 266 B
build/block-library/blocks/media-text/editor.css 263 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 705 B
build/block-library/blocks/navigation-link/editor.css 703 B
build/block-library/blocks/navigation-link/style-rtl.css 115 B
build/block-library/blocks/navigation-link/style.css 115 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-submenu/view.min.js 423 B
build/block-library/blocks/navigation/style-rtl.css 1.98 kB
build/block-library/blocks/navigation/style.css 1.97 kB
build/block-library/blocks/navigation/view-modal.min.js 2.78 kB
build/block-library/blocks/navigation/view.min.js 443 B
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 363 B
build/block-library/blocks/page-list/editor.css 363 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 174 B
build/block-library/blocks/paragraph/editor.css 174 B
build/block-library/blocks/paragraph/style-rtl.css 260 B
build/block-library/blocks/paragraph/style.css 260 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 493 B
build/block-library/blocks/post-comments-form/style.css 493 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 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 507 B
build/block-library/blocks/post-featured-image/editor.css 505 B
build/block-library/blocks/post-featured-image/style-rtl.css 166 B
build/block-library/blocks/post-featured-image/style.css 166 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 282 B
build/block-library/blocks/post-template/style.css 282 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/preformatted/style-rtl.css 103 B
build/block-library/blocks/preformatted/style.css 103 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 326 B
build/block-library/blocks/pullquote/style.css 325 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-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 282 B
build/block-library/blocks/query-pagination/style.css 278 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 439 B
build/block-library/blocks/query/editor.css 439 B
build/block-library/blocks/quote/style-rtl.css 213 B
build/block-library/blocks/quote/style.css 213 B
build/block-library/blocks/quote/theme-rtl.css 223 B
build/block-library/blocks/quote/theme.css 226 B
build/block-library/blocks/read-more/style-rtl.css 132 B
build/block-library/blocks/read-more/style.css 132 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 396 B
build/block-library/blocks/search/style.css 393 B
build/block-library/blocks/search/theme-rtl.css 114 B
build/block-library/blocks/search/theme.css 114 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 233 B
build/block-library/blocks/separator/style.css 233 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 464 B
build/block-library/blocks/shortcode/editor.css 464 B
build/block-library/blocks/site-logo/editor-rtl.css 455 B
build/block-library/blocks/site-logo/editor.css 455 B
build/block-library/blocks/site-logo/style-rtl.css 192 B
build/block-library/blocks/site-logo/style.css 192 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 184 B
build/block-library/blocks/social-link/editor.css 184 B
build/block-library/blocks/social-links/editor-rtl.css 674 B
build/block-library/blocks/social-links/editor.css 673 B
build/block-library/blocks/social-links/style-rtl.css 1.39 kB
build/block-library/blocks/social-links/style.css 1.38 kB
build/block-library/blocks/spacer/editor-rtl.css 322 B
build/block-library/blocks/spacer/editor.css 322 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 494 B
build/block-library/blocks/table/editor.css 494 B
build/block-library/blocks/table/style-rtl.css 611 B
build/block-library/blocks/table/style.css 609 B
build/block-library/blocks/table/theme-rtl.css 175 B
build/block-library/blocks/table/theme.css 175 B
build/block-library/blocks/tag-cloud/style-rtl.css 239 B
build/block-library/blocks/tag-cloud/style.css 239 B
build/block-library/blocks/template-part/editor-rtl.css 235 B
build/block-library/blocks/template-part/editor.css 235 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/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 561 B
build/block-library/blocks/video/editor.css 563 B
build/block-library/blocks/video/style-rtl.css 174 B
build/block-library/blocks/video/style.css 174 B
build/block-library/blocks/video/theme-rtl.css 110 B
build/block-library/blocks/video/theme.css 110 B
build/block-library/common-rtl.css 1.01 kB
build/block-library/common.css 1 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 478 B
build/block-library/reset.css 478 B
build/block-library/theme-rtl.css 695 B
build/block-library/theme.css 700 B
build/block-serialization-default-parser/index.min.js 1.11 kB
build/block-serialization-spec-parser/index.min.js 2.83 kB
build/components/style-rtl.css 11.6 kB
build/components/style.css 11.6 kB
build/compose/index.min.js 12 kB
build/customize-widgets/index.min.js 11.3 kB
build/data-controls/index.min.js 653 B
build/date/index.min.js 32 kB
build/deprecated/index.min.js 507 B
build/dom-ready/index.min.js 324 B
build/edit-navigation/style-rtl.css 4 kB
build/edit-navigation/style.css 4.01 kB
build/edit-post/classic-rtl.css 546 B
build/edit-post/classic.css 547 B
build/edit-post/style-rtl.css 6.94 kB
build/edit-post/style.css 6.94 kB
build/edit-site/style-rtl.css 8.22 kB
build/edit-site/style.css 8.2 kB
build/edit-widgets/index.min.js 16.5 kB
build/edit-widgets/style-rtl.css 4.35 kB
build/edit-widgets/style.css 4.35 kB
build/editor/index.min.js 41.5 kB
build/editor/style-rtl.css 3.66 kB
build/editor/style.css 3.65 kB
build/escape-html/index.min.js 537 B
build/format-library/index.min.js 6.75 kB
build/format-library/style-rtl.css 571 B
build/format-library/style.css 571 B
build/hooks/index.min.js 1.64 kB
build/html-entities/index.min.js 448 B
build/i18n/index.min.js 3.77 kB
build/is-shallow-equal/index.min.js 527 B
build/keyboard-shortcuts/index.min.js 1.78 kB
build/keycodes/index.min.js 1.81 kB
build/list-reusable-blocks/index.min.js 1.74 kB
build/list-reusable-blocks/style-rtl.css 835 B
build/list-reusable-blocks/style.css 835 B
build/media-utils/index.min.js 2.93 kB
build/notices/index.min.js 953 B
build/nux/index.min.js 2.05 kB
build/nux/style-rtl.css 732 B
build/nux/style.css 728 B
build/plugins/index.min.js 1.94 kB
build/preferences-persistence/index.min.js 2.22 kB
build/preferences/index.min.js 1.3 kB
build/primitives/index.min.js 933 B
build/priority-queue/index.min.js 612 B
build/react-i18n/index.min.js 696 B
build/react-refresh-entry/index.min.js 8.44 kB
build/react-refresh-runtime/index.min.js 7.31 kB
build/reusable-blocks/index.min.js 2.21 kB
build/reusable-blocks/style-rtl.css 256 B
build/reusable-blocks/style.css 256 B
build/rich-text/index.min.js 11.2 kB
build/server-side-render/index.min.js 1.61 kB
build/shortcode/index.min.js 1.53 kB
build/token-list/index.min.js 644 B
build/url/index.min.js 3.61 kB
build/vendors/react-dom.min.js 38.5 kB
build/vendors/react.min.js 4.34 kB
build/viewport/index.min.js 1.08 kB
build/warning/index.min.js 268 B
build/wordcount/index.min.js 1.06 kB

compressed-size-action

@alexstine
Copy link
Contributor Author

I am sure there will be tons of failed E2E tests and maybe even some unit tests. I will start working on those slowly but wanted to get some technical feedback. I know Alt+F10 is a harder shortcut but Shift+Tab is too crucial for navigating dynamic blocks.

Copy link
Contributor Author

@alexstine alexstine left a comment

Choose a reason for hiding this comment

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

I've done a considerable amount of work on this now. It is working much better. The logic is a lot simpler and my next focus will be updating code comments.

packages/block-editor/src/components/writing-flow/index.js Outdated Show resolved Hide resolved
@@ -10,11 +10,11 @@ import { useRef } from '@wordpress/element';
/**
* Internal dependencies
*/
import { isInSameBlock } from '../../utils/dom';
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 is needed to ensure a successful check later. More info shortly.

const { tagName } = element;
const checkForInputTextarea = isInputOrTextArea( element );
const checkContentEditable =
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The default value of checking contenteditable="true" is false for this function but I needed this extended to handle tabbing in blocks such as the table block.

Copy link
Member

Choose a reason for hiding this comment

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

Do we need this option? Can't we just make it the default? This function was added to check form elements in placeholders. Not sure why it was ever moved to the dom package as an API.

I think we're also missing links here.

Why can't we just use check the tabbable API (findNext) and skip over blocks?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@ellatrix I moved it because this was being used in multiple places.

#39461

I will try to remove this and see if E2E catches bugs.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh yes, I do not think we will be able to do this. Seems like this backfires because focus.tabbable will always have somewhere to go since blocks have tabindex of 0. Need to ensure it is a form field or something we want to move to. Unless you see another way around this...

@@ -200,7 +200,7 @@ describe( 'Order of block keyboard navigation', () => {
'Multiple selected blocks'
);

await pressKeyWithModifier( 'shift', 'Tab' );
await pressKeyWithModifier( 'alt', 'F10' );
Copy link
Contributor Author

Choose a reason for hiding this comment

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

New shortcut to focus the toolbar.

@@ -35,7 +35,7 @@ async function testBlockToolbarKeyboardNavigation(
await expectLabelToHaveFocus( 'Move up' );
await page.keyboard.press( 'Tab' );
await expectLabelToHaveFocus( currentBlockLabel );
await pressKeyWithModifier( 'shift', 'Tab' );
await focusBlockToolbar();
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 just executes Alt+F10 for us.

Copy link
Member

Choose a reason for hiding this comment

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

Shift+Tab now works again, right? So we can revert these lines?

await pageUtils.pressKeyWithModifier( 'shift', 'Tab' );
// and finally Bold.
await pageUtils.pressKeyWithModifier( 'shift', 'Tab' );
// Navigate to Image.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm not honestly sure how this ever worked. This needs bad accessibility help. Had no idea a double toolbar could exist.

@alexstine alexstine added the [Package] DOM /packages/dom label Jun 10, 2022
@alexstine alexstine changed the title Writing flow: Try removing Shift+Tab in to block toolbar Writing flow: A11Y enhancements for useTabNav Jun 10, 2022
@alexstine alexstine requested a review from mtias June 10, 2022 18:51
… instead without needing to worry about moving back to the block.
Copy link
Contributor Author

@alexstine alexstine left a comment

Choose a reason for hiding this comment

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

New E2E tests to ensure this doesn't break in the future.

@@ -753,4 +753,42 @@ describe( 'Writing Flow', () => {
);
expect( paragraphs ).toEqual( [ 'first', 'second' ] );
} );

it( 'Allows block wrapper focus when there are no previous focus elements', 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 ensures Shift+Tab can focus the block wrapper if there are no previous elements. Then Shift+Tab will not work for anything before the block wrapper. Tab can move back in to the block.

await expect( getAriaLabel ).toEqual( 'Block: Image' );
} );

it( 'Allows block settings sidebar focus when there are no next focus elements', 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 ensures you can use Tab key to access the sidebar. However, you must tab through the block first until there are no more tabbable elements.

@ellatrix
Copy link
Member

I've left a comment on the parent PR. I'm not convinced we should allow tabbing in between blocks. #38311 (comment)

@alexstine
Copy link
Contributor Author

Okay @ellatrix . This seems stable enough for testing. I restored the ability to Shift+Tab to the block toolbar. However, in blocks that still have wrappers, you will land on the wrapper first. Do you anticipate that being a problem? Up Arrow can always get you to a block wrapper, thought I should logically allow Shift+Tab to do the same. In the future, could add descriptions saying what to do in this wrapper area. Something like this I think.

You are currently in the block wrapper for X. Press Backspace to remove.

Anyway, that was kind of the idea but I do not want to distract from this PR's goal.

@ellatrix
Copy link
Member

However, in blocks that still have wrappers, you will land on the wrapper first. Do you anticipate that being a problem?

That's fine!

I'll test the PR today.

@ellatrix
Copy link
Member

Some case I'll want to be testing:

  • FSE with a selected block and many deep nested blocks.
  • Inline rich text toolbar and other toolbar configs.

@ellatrix
Copy link
Member

Ok, so one accessibility problem I'm experiencing is that there's no way to access the inline toolbar anymore for blocks that define that (caption in an image block, cite in a quote).

Other than that, it's working well. It's just a little weird that tab doesn't navigate through the direct inner blocks. I'm not sure how that would even work though. I understand that you can access them through navigation mode, but it's not really clear.

@alexstine
Copy link
Contributor Author

@ellatrix

Other than that, it's working well. It's just a little weird that tab doesn't navigate through the direct inner blocks. I'm not sure how that would even work though. I understand that you can access them through navigation mode, but it's not really clear.

Yeah, not sure how to work around that right now. We'll need to revisit this down the line. My biggest hope is to get rid of the block selection button and replace it with opening the list view. Seems like that could be a better experience long term and screen readers will not need to manually change modes since list view has better ARIA spec currently.

@tellthemachines
Copy link
Contributor

Thanks for all the work you've put in here @alexstine !

Testing this branch, the issue Ella mentioned above with tabbing into the caption toolbar seems to be fixed. I'll try to do some more testing across other blocks in the next couple of days. This is a big change so best make sure everything is working as expected. So far it looks good though!

I pushed a tentative fix for an e2e test failure that seems to be due to flakiness (I can't consistently reproduce it locally). Hopefully that improves matters on CI.

I also opened #43564 to report keyboard navigation inconsistency across toolbars.

@ellatrix
Copy link
Member

Thanks for all the work on this.

While reverse tabbing into the formatting toolbar from a caption now works, we're introducing some inconsistency: you can tab into the caption from the image wrapper, but when reverse tabbing you tab into the toolbar.

I'm also still wondering how you can select inner blocks from a parent block, if this is supposed to be an alternative to navigating by arrow keys. Maybe we should allow the block list element to be tabbed into with instructions to enter navigation mode to select inner blocks as a label?

@ellatrix
Copy link
Member

I think we should try this under the existing option that disables arrow key navigation across elements.
Why not enable tab for the whole editor in that case, instead of containing it to the block?

@alexstine
Copy link
Contributor Author

@ellatrix

Why not enable tab for the whole editor in that case, instead of containing it to the block?

You cannot do that because the editor does not follow semantic code layout. That would be super nice, but I doubt it happens any time soon.

If accessibility was introduced from the start instead of this late in the game, this is what I would have done.

  1. Main toolbar which is one tab stop.
  2. Title field which is a second tab stop.
  3. Heading 2 to mark each block.
  4. Heading 3 to mark child blocks/inner blocks.
  5. Complementary landmark for each block sidebar.

The problem is there is too much dynamic movement in Gutenberg. The problem really begins with block selecting and sidebar/formatting toolbars constantly dynamically updating. There would not be a need for this whole big focus discussion if the editor just followed basic flows of a website.

I'm also still wondering how you can select inner blocks from a parent block, if this is supposed to be an alternative to navigating by arrow keys. Maybe we should allow the block list element to be tabbed into with instructions to enter navigation mode to select inner blocks as a label?

I really want navigation mode gone because it has caused a lot of bugs between NVDA and JAWS on Windows. However, this PR is something I have worked on but still cannot get it in due to a delay in upgrading React versions. I'd like to land it, but again, it does not appear it will happen soon. Unless it already has and I just did not know/no one revisited the PR.

#39558

I do agree with you on the tab/shift+tab issue with the image caption field. That must be why I disabled that toolbar in the first place. This whole PR seems to be quite a nightmare now. 😞

I think I was trying to fix a structural problem with more hacking. However, I just do not have time to contribute at this level anymore.

@ellatrix
Copy link
Member

  • Heading 2 to mark each block.
  • Heading 3 to mark child blocks/inner blocks.

What do you mean with headings to mark blocks?

I'm fine with moving forward with this PR if we enable this only for the option that blocks arrow key navigation for now.

If you don't have time to continue work on this, shall I take it over and tweak some things? Would you still be able to test and review?

@alexstine
Copy link
Contributor Author

@ellatrix

If you don't have time to continue work on this, shall I take it over and tweak some things? Would you still be able to test and review?

That would be awesome. Yes, I can still review, I just do not have much time for code writing these days now that I am not working with WordPress.

I think the point I am trying to get across is the fact Gutenberg relies on a lot of custom keyboard support. When you use a screen reader on Windows, there are two different modes. One mode allows you to send all keyboard input to the application. This is called edit/focus mode. The other mode uses a virtual cursor to allow screen readers to follow the natural order of the DOM. The problem is, React/VUE are frameworks that can dynamically change the DOM and screen readers just have not caught up. We are now left with two very big problems.

  1. The majority of users are going to stay in browse mode, not edit/focus mode because this allows quick navigation by jumping by headings, landmarks, etc.
  2. Even if Gutenberg did force users to stay in edit/focus mode, now we have to take on the issue of teaching users our custom keyboard interactions for one app.

My problem with number 2 is WordPress used to be so easy. Now, editing in WordPress is like learning to use Slack or Teams. A completely new interaction model with tons of keyboard shortcuts to remember. When really, it would be a huge investment, but better off to just allow Gutenberg to act like a normal website.

This all sounds quite foreign to you I am sure because Voiceover does a much better job as it does not have to switch between modes constantly. However, Voiceover is not liked due to the amount of keyboard gymnastics required to do basic functions compared to Windows. I dug up this older video by @diegohaz who explains this really well.
https://www.youtube.com/watch?v=DKnkoHdbW68

Here is the related issue where all of this stuff started coming to light.
#30620 (comment)

I am not saying to stop using JS completely, but JS is meant to make certain parts dynamic. Not whole apps. I mean, you may be able to use JS this way, but the end result is an inaccessible mess that is highly depend it on which OS you use.

@ellatrix
Copy link
Member

@alexstine I modified your PR so that Tab is only enabled in blocks when the keep caret in block is set to true. Could you review the changes? Then we can merge this.

@alexstine
Copy link
Contributor Author

@ellatrix I'll review later today, thanks!

Do you think we should hold off on this until #45157 gets closer? It will fix our problem with shift+tab landing on the inline toolbar and region shortcut could be used for this. Then we could have dedicated navigation keys. I do enjoy your idea there regardless of my thoughts of the keyboard shortcuts chosen.

Might be good to get this one in as a good enhancement until the other PR lands.

Thoughts?

Thanks.

@ellatrix
Copy link
Member

That sounds good if you prefer that!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Feature] Writing Flow Block selection, navigation, splitting, merging, deletion... [Focus] Accessibility (a11y) Changes that impact accessibility and need corresponding review (e.g. markup changes). Needs Accessibility Feedback Need input from accessibility [Package] Block editor /packages/block-editor [Package] DOM /packages/dom [Package] E2E Tests /packages/e2e-tests [Type] Bug An existing feature does not function as intended
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants