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

Indent/outdent on tab (list, code) #56474

Closed
wants to merge 5 commits into from
Closed

Indent/outdent on tab (list, code) #56474

wants to merge 5 commits into from

Conversation

ellatrix
Copy link
Member

@ellatrix ellatrix commented Nov 23, 2023

What?

Allows indenting/outdenting list items through tab/shift+tab.

Why?

See #45404.

How?

This PR removes tabbing from the editor when in writing mode.

  • Note that tabbing still working in Navigation mode (press Esc to get to it)
  • You can still focus the block toolbar with the shortcut (Alt+F10)
  • You can still navigate regions (Ctrl+`)
  • Additionally, tab follows normal DOM order when keepCaretInsideBlock is on and disables custom tab behaviour in blocks.

Testing Instructions

Testing Instructions for Keyboard

Screenshots or screencast

@ellatrix ellatrix added the [Type] Enhancement A suggestion for improvement. label Nov 23, 2023
Copy link

github-actions bot commented Nov 23, 2023

Size Change: +631 B (0%)

Total Size: 1.7 MB

Filename Size Change
build/block-editor/index.min.js 248 kB +6 B (0%)
build/block-library/index.min.js 212 kB +255 B (0%)
build/components/index.min.js 256 kB +38 B (0%)
build/edit-site/index.min.js 208 kB +214 B (0%)
build/edit-site/style-rtl.css 14.3 kB +59 B (0%)
build/edit-site/style.css 14.3 kB +59 B (0%)
ℹ️ View Unchanged
Filename Size
build/a11y/index.min.js 964 B
build/annotations/index.min.js 2.71 kB
build/api-fetch/index.min.js 2.29 kB
build/autop/index.min.js 2.11 kB
build/blob/index.min.js 590 B
build/block-directory/index.min.js 7.25 kB
build/block-directory/style-rtl.css 1.04 kB
build/block-directory/style.css 1.04 kB
build/block-editor/content-rtl.css 4.29 kB
build/block-editor/content.css 4.28 kB
build/block-editor/default-editor-styles-rtl.css 403 B
build/block-editor/default-editor-styles.css 403 B
build/block-editor/style-rtl.css 15.7 kB
build/block-editor/style.css 15.7 kB
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/audio/theme-rtl.css 138 B
build/block-library/blocks/audio/theme.css 138 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 587 B
build/block-library/blocks/button/editor.css 587 B
build/block-library/blocks/button/style-rtl.css 633 B
build/block-library/blocks/button/style.css 632 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/cover/style-rtl.css 1.7 kB
build/block-library/blocks/cover/style.css 1.69 kB
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 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 138 B
build/block-library/blocks/embed/theme.css 138 B
build/block-library/blocks/file/editor-rtl.css 316 B
build/block-library/blocks/file/editor.css 316 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 320 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 229 B
build/block-library/blocks/form-input/editor.css 228 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 343 B
build/block-library/blocks/form-submission-notification/editor.css 342 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 452 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 957 B
build/block-library/blocks/gallery/editor.css 962 B
build/block-library/blocks/gallery/style-rtl.css 1.55 kB
build/block-library/blocks/gallery/style.css 1.55 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 654 B
build/block-library/blocks/group/editor.css 654 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 340 B
build/block-library/blocks/html/editor.css 341 B
build/block-library/blocks/image/editor-rtl.css 834 B
build/block-library/blocks/image/editor.css 833 B
build/block-library/blocks/image/style-rtl.css 1.61 kB
build/block-library/blocks/image/style.css 1.6 kB
build/block-library/blocks/image/theme-rtl.css 137 B
build/block-library/blocks/image/theme.css 137 B
build/block-library/blocks/image/view.min.js 2.05 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 266 B
build/block-library/blocks/media-text/editor.css 263 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 671 B
build/block-library/blocks/navigation-link/editor.css 672 B
build/block-library/blocks/navigation-link/style-rtl.css 103 B
build/block-library/blocks/navigation-link/style.css 103 B
build/block-library/blocks/navigation-submenu/editor-rtl.css 299 B
build/block-library/blocks/navigation-submenu/editor.css 299 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.27 kB
build/block-library/blocks/navigation/style.css 2.26 kB
build/block-library/blocks/navigation/view.min.js 1.07 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 401 B
build/block-library/blocks/page-list/editor.css 401 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-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 345 B
build/block-library/blocks/post-featured-image/style.css 345 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 335 B
build/block-library/blocks/pullquote/style.css 335 B
build/block-library/blocks/pullquote/theme-rtl.css 168 B
build/block-library/blocks/pullquote/theme.css 168 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/style-rtl.css 312 B
build/block-library/blocks/query/style.css 308 B
build/block-library/blocks/query/view.min.js 637 B
build/block-library/blocks/quote/style-rtl.css 237 B
build/block-library/blocks/quote/style.css 237 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 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 613 B
build/block-library/blocks/search/style.css 613 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 471 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 234 B
build/block-library/blocks/separator/style.css 234 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 329 B
build/block-library/blocks/shortcode/editor.css 329 B
build/block-library/blocks/site-logo/editor-rtl.css 760 B
build/block-library/blocks/site-logo/editor.css 760 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/editor-rtl.css 682 B
build/block-library/blocks/social-links/editor.css 681 B
build/block-library/blocks/social-links/style-rtl.css 1.45 kB
build/block-library/blocks/social-links/style.css 1.45 kB
build/block-library/blocks/spacer/editor-rtl.css 359 B
build/block-library/blocks/spacer/editor.css 359 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 432 B
build/block-library/blocks/table/editor.css 432 B
build/block-library/blocks/table/style-rtl.css 646 B
build/block-library/blocks/table/style.css 645 B
build/block-library/blocks/table/theme-rtl.css 157 B
build/block-library/blocks/table/theme.css 157 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/template-part/editor-rtl.css 403 B
build/block-library/blocks/template-part/editor.css 403 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/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 191 B
build/block-library/blocks/video/style.css 191 B
build/block-library/blocks/video/theme-rtl.css 139 B
build/block-library/blocks/video/theme.css 139 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/editor-rtl.css 12.5 kB
build/block-library/editor.css 12.4 kB
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-library/style-rtl.css 14.5 kB
build/block-library/style.css 14.5 kB
build/block-library/theme-rtl.css 700 B
build/block-library/theme.css 705 B
build/block-serialization-default-parser/index.min.js 1.13 kB
build/block-serialization-spec-parser/index.min.js 2.87 kB
build/blocks/index.min.js 51.5 kB
build/commands/index.min.js 15.5 kB
build/commands/style-rtl.css 947 B
build/commands/style.css 942 B
build/components/style-rtl.css 12 kB
build/components/style.css 12 kB
build/compose/index.min.js 12.7 kB
build/core-commands/index.min.js 2.72 kB
build/core-data/index.min.js 72.5 kB
build/customize-widgets/index.min.js 12.1 kB
build/customize-widgets/style-rtl.css 1.43 kB
build/customize-widgets/style.css 1.43 kB
build/data-controls/index.min.js 651 B
build/data/index.min.js 8.87 kB
build/date/index.min.js 17.9 kB
build/deprecated/index.min.js 462 B
build/dom-ready/index.min.js 336 B
build/dom/index.min.js 4.68 kB
build/edit-post/classic-rtl.css 571 B
build/edit-post/classic.css 571 B
build/edit-post/index.min.js 35.7 kB
build/edit-post/style-rtl.css 7.58 kB
build/edit-post/style.css 7.57 kB
build/edit-widgets/index.min.js 17.2 kB
build/edit-widgets/style-rtl.css 4.65 kB
build/edit-widgets/style.css 4.65 kB
build/editor/index.min.js 47.1 kB
build/editor/style-rtl.css 3.72 kB
build/editor/style.css 3.71 kB
build/element/index.min.js 4.87 kB
build/escape-html/index.min.js 548 B
build/format-library/index.min.js 7.76 kB
build/format-library/style-rtl.css 577 B
build/format-library/style.css 577 B
build/hooks/index.min.js 1.57 kB
build/html-entities/index.min.js 454 B
build/i18n/index.min.js 3.61 kB
build/interactivity/index.min.js 11.4 kB
build/is-shallow-equal/index.min.js 535 B
build/keyboard-shortcuts/index.min.js 1.76 kB
build/keycodes/index.min.js 1.9 kB
build/list-reusable-blocks/index.min.js 2.11 kB
build/list-reusable-blocks/style-rtl.css 865 B
build/list-reusable-blocks/style.css 865 B
build/media-utils/index.min.js 2.92 kB
build/notices/index.min.js 964 B
build/nux/index.min.js 2.01 kB
build/nux/style-rtl.css 775 B
build/nux/style.css 771 B
build/patterns/index.min.js 4.82 kB
build/patterns/style-rtl.css 567 B
build/patterns/style.css 566 B
build/plugins/index.min.js 1.81 kB
build/preferences-persistence/index.min.js 1.85 kB
build/preferences/index.min.js 1.26 kB
build/primitives/index.min.js 994 B
build/priority-queue/index.min.js 1.52 kB
build/private-apis/index.min.js 988 B
build/react-i18n/index.min.js 631 B
build/react-refresh-entry/index.min.js 9.46 kB
build/react-refresh-runtime/index.min.js 6.78 kB
build/redux-routine/index.min.js 2.71 kB
build/reusable-blocks/index.min.js 2.75 kB
build/reusable-blocks/style-rtl.css 265 B
build/reusable-blocks/style.css 265 B
build/rich-text/index.min.js 9.96 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.4 kB
build/style-engine/index.min.js 1.98 kB
build/token-list/index.min.js 587 B
build/url/index.min.js 3.83 kB
build/vendors/inert-polyfill.min.js 2.48 kB
build/vendors/react-dom.min.js 41.8 kB
build/vendors/react.min.js 4.02 kB
build/viewport/index.min.js 967 B
build/warning/index.min.js 259 B
build/widgets/index.min.js 7.18 kB
build/widgets/style-rtl.css 1.18 kB
build/widgets/style.css 1.18 kB
build/wordcount/index.min.js 1.03 kB

compressed-size-action

Copy link

Flaky tests detected in df81bbf.
Some tests passed with failed attempts. The failures may not be related to this commit but are still reported for visibility. See the documentation for more information.

🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/6969602242
📝 Reported issues:

@draganescu
Copy link
Contributor

With the current developments on editor DOM form @jeryj 's work on block top toolbar shift tab has been considered a still needed way to navigate from content to editor UI - particularly when the toolbar is floating because of visual proximity.

Considering the deep discussions in previous PRs about shift tab it may be good to decouple tab to indent from shift tab to outdent in separate PRs because one of them (tab to indent) is probable to land easier.

@ellatrix
Copy link
Member Author

@draganescu I don't get why it's still needed? It's the same problem as trunk? Can you share links?

@draganescu draganescu added Needs Accessibility Feedback Need input from accessibility [Focus] Accessibility (a11y) Changes that impact accessibility and need corresponding review (e.g. markup changes). labels Nov 23, 2023
@draganescu
Copy link
Contributor

In previous discussions such as this one the shift tab shortcut to block toolbar was meant to be removed but it was persisted because of various arguments the most powerful one being that floating UI is the closest to the current selection so shift tab would intuitively move focus to the closest previous UI.

However, this PR - a thing which I missed on my previous comment - removes the entire tab based navigation of the block editor UI unless the navigation mode is on or the keepCaretInsideBlock preference is on.

This direction is "releasing" tab and shift tab to act as they normally do in text editing contexts and there is no need for 2 PRs like I previously suggested.

@alexstine
Copy link
Contributor

Let's not rush into this please. This is going to receive A11Y pushback because of the following.

  1. F10 on a Mac translates to Alt+Function+F10. I worry about the keyboard gymnastics for jumping to the toolbar. I've always wanted to use F10 as it makes sense on Windows OS but maybe not so much for Mac.
  2. As already noted, Shift+Tab must be kept for visual parity with the previous element being the floating toolbar. Navigation mode does not allow you to access the toolbar.
  3. Will this only apply to the list block? What will Tab/Shift+Tab do in all other blocks?
  4. There is a plan to maybe do away with navigation and edit mode in favor of the list view as navigation mode on Windows can be quite buggy with the dynamic button. It was discussed in the last hallway hangout.
    https://make.wordpress.org/core/2023/11/15/hallway-hangout-recap-of-working-session-on-consolidating-navigation-modes/

I really do want to achieve this goal at some point but people just need to be patient. We're trying to unravel editor accessibility from the beginning of Gutenberg so we need to be smart about how we go about it. A compromise for now could be adding it to the command pallet.

CC: @afercia @joedolson @jeryj.

For now, this might be worth discovering with the top toolbar setting but otherwise, I think this is the wrong time to introduce this across all modes. I can only imagine how many E2E edits were also required.

@ellatrix This actually might be a perfect time to revisit region navigation. Both you and I tried but never were able to land a complete solution. You added more regions so that way you could jump to the block toolbar and I suggested a PR that would add some code to find the first tabbable in a region and focus it. Simply placing focus on a region makes a Windows screen reader read the entire region which is why I attempted my fix and did not want to move forward with yours. The reason why my fix was ultimately rejected is because the focus indicators broke around the regions as focus was placed on the first item inside the region, not the region itself. That might be a way forward.

  1. Revive your PR that would make the block floating toolbar a region. I think you also figured out how to do this for the selected block.
  2. Open a PR to place focus on the first focusable element inside a region but somehow keep the region highlighted with CSS.

My point, there's still a lot to think through. 😞

@ellatrix
Copy link
Member Author

F10 on a Mac translates to Alt+Function+F10. I worry about the keyboard gymnastics for jumping to the toolbar. I've always wanted to use F10 as it makes sense on Windows OS but maybe not so much for Mac.

I've gotten used to it now, even though I don't use it often, I do remember it in muscle memory. That said, I'd love it if Escaping to navigation move would preserve the toolbar so that shortcut can be used additionally. Probably for a separate PR though.

As already noted, Shift+Tab must be kept for visual parity with the previous element being the floating toolbar. Navigation mode does not allow you to access the toolbar.

I'm not following here. Since Tab is not used for navigation, why should Shift+Tab be? We're in a different content here.

Will this only apply to the list block? What will Tab/Shift+Tab do in all other blocks?

This applies to all blocks. Tab is not used of navigation for consistency, and used for input if relevant.

There is a plan to maybe do away with navigation and edit mode in favor of the list view as navigation mode on Windows can be quite buggy with the dynamic button. It was discussed in the last hallway hangout.

Ok, so Esc will open the List View? If not, maybe we could use Esc then to exit the canvas and focus the toolbar. Maybe the toolbar (or a button inside) could be used to Enter the canvas. Just thinking out loud here.

I can only imagine how many E2E edits were also required.

Not too many actually. There were just 11 cases where I had to replace Shift+Tab with Alt+F10.

This actually might be a perfect time to revisit region navigation.

I can try that. So include the toolbar as a region, change focus to first item, while keeping the highlighting of the region? That should be possible.

@ellatrix
Copy link
Member Author

I included the block toolbar as a region in #56560. We can look at focusing the first element in a follow-up?

@draganescu
Copy link
Contributor

@ellatrix while testing this I noticed that tab indents list items indifferent of where the cursor is in the text. Is this intentional? Shouldn't the indent happen only when the cursor is at the start of the line?

@ellatrix
Copy link
Member Author

@draganescu That's intentional and how it works in most editors. :)

@draganescu
Copy link
Contributor

@ellatrix I recorded this comparison of Google Docs, MS Word, Textedit and Gutenberg on this branch.

tab-indent-comparison.mp4

The common thread on most editors is that pressing tab in the middle of a list item inserts a TAB char, it does not indent.

As a separate note, in text editors pressing tab again after indent, indents again, but that would require us to create empty LI elements I guess and it doesn't look useful.

@jeryj
Copy link
Contributor

jeryj commented Nov 27, 2023

Note: I spent the day using this and thinking about it. Here's my essay 🙈 Don't feel like everything needs responded to. This is more of a public thinking-out-loud.

That said, I'd love it if Escaping to navigation move would preserve the toolbar so that shortcut can be used additionally. Probably for a separate PR though.

I think this would be possible with how the Block Toolbar and Breadcrumbs (Navigation Mode Block Popover) are being split out at #56335.

Since Tab is not used for navigation, why should Shift+Tab be? We're in a different content here.

This is a really big mental model shift for me. I love how simple of an idea it is as well. I am concerned about educating people that you can't Tab out of the editor, since it has been a way of navigating before. Could we detect if someone is pressing Tab repeatedly with no editing effect, and offer an educational popup to teach them about Alt + F10, region navigation, or pressing Escape to use Tab to navigate?

Some thinking out loud/Notes from trying this out

If I can enter into the content using Tab, I expect to be able to exit the content using Tab. It feels like a focus trap if I can't exit using Tab. This is where an educational alert would be useful to tell me what to do, since it's diverging from the norm I'd expect on the web.

To address that, we could turn on Navigation mode when tabbing into the editor so you have to choose to enter editing mode. Then I have to escape to leave editing mode since I chose to enter it, but, in practice that feels clunky. I'd rather get dropped back to the editor in the same place I was. I don't want to have to Tab through all the blocks, then press enter, then arrow over to my previous location.

Can we leave Tab navigation as is, but if Shift + Tab is useful in editing context, then you need to Arrow up to block selection, then use Shift + Tab? After playing with this for awhile, I think I prefer having Shift + Tab in place for being able to enter/leave the editor in one tab stop more than the inconsistency of Shift + Tab being removed for Code and List blocks. As in, it's less disruptive to the mental model of how Tab keypresses typically work on a website and in an editor. Any block where Shift+Tab is in use to have editing action, you would need to arrow up and then Shift + Tab to reach the toolbar. I feel like this is an acceptable compromise without impacting the Tab navigation.

The above idea won't work, since an arrow up on a paragraph block moves the cursor to the next paragraph in the same location. As it should. Maybe we can codify it as, "If Tab/Shift+Tab is not in use by the block, then allow it to function natively." I'm not sure if I'm hesitant to remove it because I'm so used to using Tab in this way, or if it's because it is a better experience to preserve it. If Tab and Shift + Tab are still useful in many instances of the editor to navigate, do we need to remove it entirely to have indent/outdent on list and code blocks? Or is the inconsistency in Tab usage OK? If I had to decide right now, I'd say that keys useful to the editor in editing context should "win" over all else. After all, it is an editor. So, I feel comfortable with the inconsistency of, "If Tab/Shift+Tab is not in use by the block, then allow it to function natively." This would impact:

  • List blocks (disrupts tab navigation when at the first character space in the list item)
  • Code blocks (disrupts tab navigation but not shift+tab)
  • Future: Any writing block that Tab could insert a tab space (disrupts tab navigation but not shift+tab)

Well… That's starting to be a lot of blocks, and as paragraph is the most common, it's going to be the default for Tab to not function. At that point, maybe it is better to remove Tab in editing mode entirely to encourage people towards learning a more consistent keyboard navigation... I'm concerned by the learning curve though, but a nudge to educate when tab or shift tab is pressed repeatedly would be really helpful.

I'm going to keep using this and thinking through it. I'm very undecided on how I feel about it at the moment. I'm excited about the possibility of opening up shift + tab and tab to be used in the editor. I think that's a really important thing that needs to happen. So far, this idea to remove Tab as a navigation for the editing context does feel like the best way forwards.

@afercia
Copy link
Contributor

afercia commented Nov 28, 2023

This was already discussed at length years ago at the time of the first implementation of the List block. It received a 'no-go' for accessibility reasons. Tab and Shift+Tab should be reserved for navigation, as the WordPress Editor is not Google Docs.

Why this gets repurposed now? It's still a no-go for accessibility, as also noted in the related issue.

@afercia
Copy link
Contributor

afercia commented Nov 28, 2023

Aside:

Revive your PR that would make the block floating...
Open a PR to place focus on the first focusable element inside a region but somehow keep the region highlighted with CSS

I'm not sure I'd agree on these two points. Will comment on the related PRs.

@ellatrix
Copy link
Member Author

@draganescu It does indent from anywhere for TinyMCE (and thus the classic editor), CKEditor, Draftjs, Apple Notes and Pages. I'd say it's the common behaviour whenever inserting a literal tab character is not allowed.

@ellatrix
Copy link
Member Author

If I can enter into the content using Tab, I expect to be able to exit the content using Tab. It feels like a focus trap if I can't exit using Tab. This is where an educational alert would be useful to tell me what to do, since it's diverging from the norm I'd expect on the web.

Yes, that's a good point. To me, ideally, it behaves like a modal or dialog where you explicitly Enter editing mode, and then naturally can press Escape to exit.

The above idea won't work, since an arrow up on a paragraph block moves the cursor to the next paragraph in the same location.

This could work in navigation mode: arrow keys navigate blocks in 2d, and tab goes outside the editor.

@ellatrix
Copy link
Member Author

@afercia Tab has always worked to indent in the classic editor. Why can't we just see the canvas as an area that you enter and exit where tab behaves differently? What's the problem with that? That fixed the tab being reserved issue to me. If you had a code editor on the web, you'd need a similar thing since you really do need tab.

@mtias
Copy link
Member

mtias commented Nov 28, 2023

@afercia it's resurfaced because what we have clearly is not working. We cannot be the odd one out that refrains to implement what is an expected experience across virtually all rich text editors for indenting lists. The current shortcuts with space and backspace are not growing familiar—and they won't be—since people are constantly trained by other experiences on the web and apps. It doesn't really matter that the editor is not Google Docs.

So we are back at figuring out how to bring this in the best possible way.

Given the top toolbar situation, it might be time to look at adding a preference for a user-configurable shortcut to access the toolbar given it's proven hard to come up with something that works for everyone under all circumstances. It might also be a way to get rolling on allowing customization of other keyboard shortcuts, which has not caught traction before.

@jeryj
Copy link
Contributor

jeryj commented Nov 28, 2023

Yes, that's a good point. To me, ideally, it behaves like a modal or dialog where you explicitly Enter editing mode, and then naturally can press Escape to exit.

That's what I was thinking too when I was testing it out. That part does feel nice to explicitly Enter into editing then escape to exit. To make that a consistent pattern, I think it would end up being a worse experience though. For example, on a new post we couldn't place focus on the title in editing mode since it would break the explicit enter/exit model. Also, we can exit the editor region shortcuts, alt + f10, etc.

To make it consistent, we might have to switch to navigation mode anytime focus is outside the editor. It's really nice being able to return the text caret to the same spot in the editor when focus is sent to it rather than focusing the block in navigation mode, having to press enter, move the caret back in place, etc... So, while I 100% agree that the enter to edit and escape to exit idea feels like a good technically accessible solution, I'm worried about the overall UX impacts it that would make it worse for everyone.

I'd prefer leaving it as inconsistent in terms of entering/exiting so we can keep the UX improvements, but have the educational popup when we suspect someone needs help navigating via keyboard.

This could work in navigation mode: arrow keys navigate blocks in 2d, and tab goes outside the editor.

Ah, so Navigation mode becomes one tabstop and arrow keys to navigate. That sounds like a good change!

Potential way forwards?

I do still like the idea of in the editor canvas Tab/Shift+Tab being an editor-first level key and navigation secondary. So, if the Tab keypress can be used for editing (indent/outdent/insert tab space) then it is. If it can't be, then it functions for navigation.

It's when my tab keypresses don't do anything that it feels broken. If I'm pressing Tab within a paragraph and I see it insert a Tab character, I understand it's doing something, even if it's not doing what I want. If that was the case, I'd try to navigate a different way or move to a different mode. If we detect the keypresses aren't doing anything, such as when trying to repeatedly indent a list that is already indented as far as it can go, we show the navigation helper notification.

@ellatrix
Copy link
Member Author

It's really nice being able to return the text caret to the same spot in the editor when focus is sent to it rather than focusing the block in navigation mode, having to press enter, move the caret back in place, etc... So, while I 100% agree that the enter to edit and escape to exit idea feels like a good technically accessible solution, I'm worried about the overall UX impacts it that would make it worse for everyone.

Right, if you use Alt+F10 to access the toolbar, you shouldn't leave the editing mode.

I do still like the idea of in the editor canvas Tab/Shift+Tab being an editor-first level key and navigation secondary. So, if the Tab keypress can be used for editing (indent/outdent/insert tab space) then it is. If it can't be, then it functions for navigation.

There's a risk of getting trapped in a block that uses Tab completely, like Code and probably List as well. If people only use Tab and there's no other obvious solution, you're stuck. I also really don't like the inconsistency. You can press Shift+Tab to access the toolbar in a paragraph and not in a list? That's strange and feels broken.

We can for sure log a notice or something when you try pressing Tab elsewhere. And maybe also if you press tab, and then undo it (high chance it wasn't what's intended).

@jeryj
Copy link
Contributor

jeryj commented Nov 28, 2023

You can press Shift+Tab to access the toolbar in a paragraph and not in a list? That's strange and feels broken.

Yeah, I totally agree. I was hoping it would feel less broken since Shift+Tab at least operates for navigation in most scenarios and Tab would be functional, even if it doesn't do what you want it to. For me, pressing Tab and seeing it do something feels less broken than if I press Tab and don't have any indication it was pressed. Having something happen allows my brain to skip the thoughts of, "Is my Tab key broken or is my keypress being registered?"

The Tab + Undo or Tab + Backspace to show a notice is a great idea. Admittedly not ideal, but the times where Shift + Tab it is an issue is pretty limited and has a few fallbacks/hopefully easily discoverable ways out? I'm not sure though. It might feel totally broken in practice.

Alternative DOM restructure idea

Possibly a bad idea and sweeping a larger issue under the rug... but what if we moved the editor to be the last spot in the DOM? Tab to move past it would be less necessary, and shift + tab could always move you backwards. I know Tab should cycle you back to the beginning of the page though, so you would have to enter into navigation mode to move to the beginning of the page again.

This would mean shift+tab would always be reserved for navigation, so list interactions would be Tab indent and Delete to outdent.

The default DOM structure would look like:

  • Header
  • Sidebar (which brings the sidebar tools closer to the button that opens it, which is a win)
  • Floating Block toolbar (Top toolbar mode would render it in the header)
  • Editor Canvas

Again, not committed to this DOM restructure idea because it feels quite hacky. Maybe it would make the lack of Tab forwards in edit mode less of a problem? Trying to throw out some ideas. Maybe it'll lead to a better one 😅

@alexstine
Copy link
Contributor

Thanks for all the feedback and discussion. I'm at AWS re:Invent this week so thoughts may be delayed.

This would mean shift+tab would always be reserved for navigation, so list interactions would be Tab indent and Delete to outdent.

No, don't do this. I'm not sure we should change native keyboard behavior. Delete key should delete forwards text.

Tab/Shift+Tab make sense for indenting and outdenting.

Problems to solve:

  1. Alt+F10 might not be so discoverable or user friendly to move to the toolbar. A possible solution is the toolbar in a region but that PR will likely get shut down I suppose from opposing feedback.
  2. I do not want Tab/Shift+Tab to do different things in different blocks. It either needs to be indent/outdent or navigation. I agree with popping up a navigation message if Tab/Shift+Tab are used.
  3. I don't want to see us create 3 modes. Edit, navigation, and list view. For example, if I'm in edit mode but have to switch to navigation mode to focus the toolbar and then I have to open the list view to switch blocks, the UX here would be terrible.

I agree Tab/Shift+Tab need to be freed up keys, I'm just not sure how to accomplish it.

Region navigation is not good enough because you could move to the sidebar and then back to editor content, but how would we communicate moving focus back to the block?

For apps like Slack and Microsoft Teams both desktop client and web, the F6 shortcut key is used to move focus around different regions but focus actually gets placed inside the region, not just placing focus on a tabindex="-1" wrapper.

One thing is for sure, we all need to be open to exploring other ideas because I too would like to see Tab/Shift+Tab for the code block and other blocks that could benefit.

@jeryj
Copy link
Contributor

jeryj commented Nov 28, 2023

If it's a given that Tab/Shift + Tab need to be freed up for use in Edit mode, and Tab/Shift + Tab not have mixed usage, then this PR accomplishes that. I'll stop throwing out ideas around mixed usage :)

The issue with removing the Tab for navigation is that it's a keyboard trap in edit mode since you can navigate in with Tab, but not navigate out with Tab. This is a keyboard trap, but it looks like a notification is an acceptable alternative in a situation like this.

If keyboard focus can be moved to a component of the page using a keyboard interface, then focus can be moved away from that component using only a keyboard interface, and, if it requires more than unmodified arrow or tab keys or other standard exit methods, the user is advised of the method for moving focus away.
https://www.w3.org/WAI/WCAG21/Understanding/no-keyboard-trap.html

So, would providing the notification on how to navigate away should allow us to meet this criteria of "user is advised of a method for moving focus away? We can surface notifications for:

  • Tab + Undo
  • Tab + Backspace
  • Two tab or Shift + Tab keypresses that have no action
  • …?

This interaction will probably feel broken to all of us who commonly use a keyboard for Gutenberg, but I imagine it'll get better as we modify our workflows. I don't see any alternative, and I'd rather change my keyboard habit and have a tab keypress function as an editor key.

@afercia
Copy link
Contributor

afercia commented Dec 5, 2023

@afercia Tab has always worked to indent in the classic editor.

@ellatrix

We can't because those are two very different cases.

  • Classic editor (TinyMCE) is more similar to a document text editor. It has a role=application. It's one single contenteditable. It does provide scripting to exit the canvas and focus the next focusable element (there is even a setting to choose what element to move focus to).
  • The Gutenberg editor is not a document text editor. It has multiple contenteditable. Each block has its own UI that users need to access. We established long time ago that Shift+Tab must be an affordance for users to navigate from the block to its toolbar.

What I expect in the editor is to just be able to use the Tab key for its native purpose: navigating the UI.

This was already discussed at length years ago. Honestly, I'm not sure I understand why we're discussing again these points.

I'd agree with almost everything @alexstine said above, with one difference:

  • I want Shift+Tab to always be used exclusively to navigate from the block to the block toolbar. No exceptions, no notifications please.

@mtias

it's resurfaced because what we have clearly is not working. We cannot be the odd one out that refrains to implement what is an expected experience

I think your idea of 'expected experience' is a little biased and actually depends on the fact your keeping into consideration only a group of users. Instead, we need to design user interfaces that work for everyone. Keyboard users would be highly impacted by the change in this PR. Things would get worse for a group of users and I wouldn't call this the 'expected experience'.

That said, since I don't want to block exploration of a better solution, I'd like to propose an option that could work for everyone. Similarly to what Google Docs does:

  • Tab and Shift+Tab are reserved for navigation.
  • Shift+Tab always moves focus from the block to its toolbar, for any block with no exceptions.
  • In a List (and Code?) block Tab and Shift+Tab indent and outdent but only when:
    • The caret is at the beginning of a list item.
    • A list item text is selected.
  • Instead, when the caret is in the middle or at the end of a list item, Tab and Shift+Tab navigate the content as expected.

I'd like to invite you to test this behavior on Google Docs. Animated GIF to illustrate:

indent

@afercia
Copy link
Contributor

afercia commented Dec 5, 2023

On this point:

Given the top toolbar situation, it might be time to look at adding a preference for a user-configurable shortcut to access the toolbar given it's proven hard to come up with something that works for everyone under all circumstances. It might also be a way to get rolling on allowing customization of other keyboard shortcuts, which has not caught traction before.

@mtias I would like to remind you that the WordPress accessibility team asked for this feature long time ago and created a dedicated issue on October 28, 2017, see #3218. That was never prioritized.
I would also like to remind everyone that there are pending issues with keyboard shortcuts that can't work for all operating systems and software due to conflicts, see for example #11154 (5 years ago).

I'm glad to see that after more than 6 years allowing keyboard shortcuts customization will maybe get more attention.

@alexstine
Copy link
Contributor

@afercia I agree, the selection and then Tab/Shift+Tab to indent outdent seems perfectly reasonable.

One question. If you want Tab/Shift+Tab to become navigation keys, how does Shift+Tab move backwards if it always had to focus the block toolbar? For example, in a table block where each cell is editable, Shift+Tab could only go to the toolbar, not navigate cells. It makes total sense why you want to keep Shift+Tab to navigate to the toolbar but I keep trying to get around other keyboard impacts and it isn't easy. Arrow keys should not navigate fields, Tab/Shift+Tab should.

We're kind of at a cross-roads in SPA accessibility as a whole. Sites like Google Gmail are forcing users to not use screen reader virtual mode and remember all their shortcuts so that JS can customize the experience around their site. In Gutenberg, we're almost doing this with the acception of still having some fairly semantic layouts. I've always long said that keyboard users are going to be in a world of hurt if each website requires very different shortcuts and it seems like we're hurtling towards that direction, not slowing down.

For this PR, I think it is totally reasonable to require highlighting for the indent/outdent. We'll continue to try to figure the rest out as we go.

Thanks.

@ellatrix
Copy link
Member Author

ellatrix commented Dec 5, 2023

We can't because those are two very different cases.

  • Classic editor (TinyMCE) is more similar to a document text editor. It has a role=application. It's one single contenteditable. It does provide scripting to exit the canvas and focus the next focusable element (there is even a setting to choose what element to move focus to).
  • The Gutenberg editor is not a document text editor. It has multiple contenteditable. Each block has its own UI that users need to access. We established long time ago that Shift+Tab must be an affordance for users to navigate from the block to its toolbar.

I disagree. The multiple contenteditable thing is just an implementation detail. Doesn't have anything to do with this. In TinyMCE each "block" also has its own buttons, while just like TinyMCE we have buttons that are shared between similar content.

@ellatrix
Copy link
Member Author

ellatrix commented Dec 5, 2023

For this PR, I think it is totally reasonable to require highlighting for the indent/outdent. We'll continue to try to figure the rest out as we go.

I don't think it's a good solution. People are used to be able to use Tab to indent in a list without selecting anything. That's the point of this PR: to restore that what people are used to.

It's also again making things inconsistent. If I happen to be at the start of a list item or I have some text selected, Tab will indent the list and if I happen to be elsewhere it will navigate away? It doesn't make sense to me.

@alexstine
Copy link
Contributor

I disagree. The multiple contenteditable thing is just an implementation detail. Doesn't have anything to do with this. In TinyMCE each "block" also has its own buttons, while just like TinyMCE we have buttons that are shared between similar content.

Thing is, when you have one large content editable the semantics really disappear. So yeah, it is much different. Each block has a totally different interaction model from a keyboard perspective and this is why you can't compare it to a single editing canvas like TinyMCE. It may look the same visually but the technical happenings behind the scenes are different enough.

I agree this isn't the best solution but until the larger problems are fixed, highlight is as good as we're going to get.

I don't see us all coming to agreement in this PR about how to remove Shift+Tab/Tab functionality for navigation. It will be required one of these days because eventually we're going to run out of work-arounds.

@ellatrix
Copy link
Member Author

Let's close this since we have #59199.

@ellatrix ellatrix closed this Mar 28, 2024
@ellatrix ellatrix deleted the try/tab-as-input branch March 28, 2024 16:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Focus] Accessibility (a11y) Changes that impact accessibility and need corresponding review (e.g. markup changes). Needs Accessibility Feedback Need input from accessibility [Type] Enhancement A suggestion for improvement.
6 participants