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

Block editor: add a keyboard shortcut to create group from the selected blocks #46972

Merged
merged 12 commits into from
May 10, 2024

Conversation

t-hamano
Copy link
Contributor

@t-hamano t-hamano commented Jan 9, 2023

Closes #42227

What?

This PR adds a keyboard shortcut to create a group block from the selected blocks.

Why?

Many design tools provide shortcuts for grouping elements. It would make sense to add a similar shortcut, especially since the grouping of blocks should be done frequently in the site editing.

How?

To explore which key combinations were available, I tested all variations that included the letter G. The list can be found in this comment.

The results show that the following two modifiers are available:

  • primaryAlt: ⌘ command + ⌥ option + G on Mac / ctrl + alt + G on Window
  • secondary: ⌘ command + shift + ⌥ option + G on Mac / ctrl + shift + alt + G

I chose primaryAlt because the secondary modifier could be used for ungrouping (unwrapping) in the future.

However, as noted in this comment, it appears that Ctrl + Alt is usually used for Windows OS-level functions. I would appreciate your advice on whether it makes sense to add this shortcut and whether it will cause any confusion to the user.

Update: After some discussion, we adopted the simpler ⌘ command + G (ctrl + G) as a shortcut.

Also, this shortcut will not allow to create a group block if a single block is selected. This is consistent with the behavior of group block transformation.

Testing Instructions

  • Insert multiple blocks and select them all.
  • On Windows, press ctrl + alt + G. On Mac, press ⌘ command + ⌥ option + G.
  • Confirm that the selected block is wrapped in a group block.
  • The second shortcut should not be executed because the group block is selected.

Screenshots or screencast

83a8606c38f7f66351eb8b7854058146.mp4

@t-hamano t-hamano self-assigned this Jan 9, 2023
@t-hamano t-hamano added [Type] Enhancement A suggestion for improvement. [Package] Keyboard Shortcuts /packages/keyboard-shortcuts labels Jan 9, 2023
@github-actions
Copy link

github-actions bot commented Jan 9, 2023

Size Change: +214 B (+0.01%)

Total Size: 1.74 MB

Filename Size Change
build/block-editor/index.min.js 258 kB +214 B (+0.08%)
ℹ️ View Unchanged
Filename Size
build/a11y/index.min.js 955 B
build/annotations/index.min.js 2.27 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.5 kB
build/block-editor/content.css 4.49 kB
build/block-editor/default-editor-styles-rtl.css 395 B
build/block-editor/default-editor-styles.css 395 B
build/block-editor/style-rtl.css 15.5 kB
build/block-editor/style.css 15.5 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 133 B
build/block-library/blocks/audio/theme.css 133 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 277 B
build/block-library/blocks/block/editor.css 277 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 671 B
build/block-library/blocks/cover/editor.css 674 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 86 B
build/block-library/blocks/details/style.css 86 B
build/block-library/blocks/embed/editor-rtl.css 312 B
build/block-library/blocks/embed/editor.css 312 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 133 B
build/block-library/blocks/embed/theme.css 133 B
build/block-library/blocks/file/editor-rtl.css 326 B
build/block-library/blocks/file/editor.css 327 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 956 B
build/block-library/blocks/gallery/editor.css 960 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 394 B
build/block-library/blocks/group/editor.css 394 B
build/block-library/blocks/group/style-rtl.css 103 B
build/block-library/blocks/group/style.css 103 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 891 B
build/block-library/blocks/image/editor.css 891 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/theme-rtl.css 133 B
build/block-library/blocks/image/theme.css 133 B
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 193 B
build/block-library/blocks/navigation-link/style.css 192 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.03 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 734 B
build/block-library/blocks/post-featured-image/editor.css 732 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 397 B
build/block-library/blocks/post-template/style.css 396 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 353 B
build/block-library/blocks/pullquote/theme-rtl.css 174 B
build/block-library/blocks/pullquote/theme.css 174 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/quote/theme-rtl.css 233 B
build/block-library/blocks/quote/theme.css 235 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 690 B
build/block-library/blocks/search/style.css 689 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 239 B
build/block-library/blocks/separator/style.css 239 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 805 B
build/block-library/blocks/site-logo/editor.css 805 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 324 B
build/block-library/blocks/social-link/editor.css 324 B
build/block-library/blocks/social-links/editor-rtl.css 676 B
build/block-library/blocks/social-links/editor.css 675 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/table/theme-rtl.css 152 B
build/block-library/blocks/table/theme.css 152 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 393 B
build/block-library/blocks/template-part/editor.css 393 B
build/block-library/blocks/template-part/theme-rtl.css 107 B
build/block-library/blocks/template-part/theme.css 107 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/blocks/video/theme-rtl.css 133 B
build/block-library/blocks/video/theme.css 133 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.3 kB
build/block-library/editor.css 12.2 kB
build/block-library/elements-rtl.css 54 B
build/block-library/elements.css 54 B
build/block-library/index.min.js 218 kB
build/block-library/reset-rtl.css 472 B
build/block-library/reset.css 472 B
build/block-library/style-rtl.css 14.8 kB
build/block-library/style.css 14.8 kB
build/block-library/theme-rtl.css 707 B
build/block-library/theme.css 713 B
build/block-serialization-default-parser/index.min.js 1.12 kB
build/block-serialization-spec-parser/index.min.js 2.87 kB
build/blocks/index.min.js 51.7 kB
build/commands/index.min.js 15.1 kB
build/commands/style-rtl.css 953 B
build/commands/style.css 951 B
build/components/index.min.js 220 kB
build/components/style-rtl.css 11.9 kB
build/components/style.css 11.9 kB
build/compose/index.min.js 12.8 kB
build/core-commands/index.min.js 2.81 kB
build/core-data/index.min.js 72.5 kB
build/customize-widgets/index.min.js 10.9 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/data/index.min.js 9 kB
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 578 B
build/edit-post/classic.css 578 B
build/edit-post/index.min.js 14.4 kB
build/edit-post/style-rtl.css 2.68 kB
build/edit-post/style.css 2.68 kB
build/edit-site/index.min.js 223 kB
build/edit-site/style-rtl.css 12.9 kB
build/edit-site/style.css 12.9 kB
build/edit-widgets/index.min.js 17.5 kB
build/edit-widgets/style-rtl.css 4.18 kB
build/edit-widgets/style.css 4.18 kB
build/editor/index.min.js 83.3 kB
build/editor/style-rtl.css 8.27 kB
build/editor/style.css 8.28 kB
build/element/index.min.js 4.83 kB
build/escape-html/index.min.js 537 B
build/format-library/index.min.js 8.07 kB
build/format-library/style-rtl.css 493 B
build/format-library/style.css 492 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/debug.min.js 16.2 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.17 kB
build/interactivity/query.min.js 740 B
build/interactivity/router.min.js 2.79 kB
build/interactivity/search.min.js 618 B
build/is-shallow-equal/index.min.js 527 B
build/keyboard-shortcuts/index.min.js 1.3 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 851 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 1.57 kB
build/nux/style-rtl.css 748 B
build/nux/style.css 744 B
build/patterns/index.min.js 6.45 kB
build/patterns/style-rtl.css 595 B
build/patterns/style.css 595 B
build/plugins/index.min.js 1.8 kB
build/preferences-persistence/index.min.js 2.06 kB
build/preferences/index.min.js 2.85 kB
build/preferences/style-rtl.css 710 B
build/preferences/style.css 712 B
build/primitives/index.min.js 809 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.7 kB
build/reusable-blocks/style-rtl.css 256 B
build/reusable-blocks/style.css 256 B
build/rich-text/index.min.js 10.1 kB
build/router/index.min.js 1.93 kB
build/server-side-render/index.min.js 1.96 kB
build/shortcode/index.min.js 1.39 kB
build/style-engine/index.min.js 2.02 kB
build/token-list/index.min.js 582 B
build/url/index.min.js 3.74 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.03 kB
build/viewport/index.min.js 957 B
build/warning/index.min.js 249 B
build/widgets/index.min.js 7.11 kB
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

@github-actions
Copy link

github-actions bot commented Jan 9, 2023

Flaky tests detected in 4b69935.
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/8938077208
📝 Reported issues:

@t-hamano t-hamano force-pushed the enhancement/shorcut-selected-blocks-to-group branch from af7a71d to f329fa4 Compare March 2, 2024 11:21
Copy link

github-actions bot commented Mar 2, 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: t-hamano <wildworks@git.wordpress.org>
Co-authored-by: jasmussen <joen@git.wordpress.org>
Co-authored-by: talldan <talldanwp@git.wordpress.org>
Co-authored-by: andrewserong <andrewserong@git.wordpress.org>
Co-authored-by: jameskoster <jameskoster@git.wordpress.org>
Co-authored-by: bacoords <bacoords@git.wordpress.org>
Co-authored-by: alexstine <alexstine@git.wordpress.org>
Co-authored-by: pagelab <pagelab@git.wordpress.org>
Co-authored-by: bissy <bissy@git.wordpress.org>

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

@jameskoster
Copy link
Contributor

@t-hamano any reason this never got added? 🤔

@t-hamano
Copy link
Contributor Author

t-hamano commented May 1, 2024

I think this PR makes sense, but maybe it got buried because there are so many open PRs out there 😅 There is a conflict going on and I would like to resolve this and also add an E2E test(Already added!).

Copy link
Contributor

@talldan talldan left a comment

Choose a reason for hiding this comment

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

Looks great - one suggestion, but I think you can address it and then merge, or get feedback from a more experienced a11y contributor first if you want to.

Comment on lines 169 to 179
const clientIds = getSelectedBlockClientIds();
if ( clientIds.length > 1 && isGroupable( clientIds ) ) {
event.preventDefault();
const blocks = getBlocksByClientId( clientIds );
const groupingBlockName = getGroupingBlockName();
const newBlocks = switchToBlockType(
blocks,
groupingBlockName
);
replaceBlocks( clientIds, newBlocks );
}
Copy link
Contributor

Choose a reason for hiding this comment

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

A spoken message when grouping is successful might be a good affordance. I tested with voiceover and there's not any indication that anything happens.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Updated by 8cf7f34

When you run the shortcut, you should hear "Selected blocks are grouped.".

Video tested with NVDA:

7274217df9cd891d1cc3d9bcedd95b7d.mp4

Copy link
Contributor Author

Choose a reason for hiding this comment

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

By the way, we may need to add a spoken message to other shortcuts as well. See #61168.

@t-hamano
Copy link
Contributor Author

t-hamano commented May 2, 2024

but I think you can address it and then merge, or get feedback from a more experienced a11y contributor first if you want to.

Let's get feedback before merging this PR. @afercia, @alexstine, if you have any feedback regarding this PR, please let us know.

Summary

  • This PR adds a shortcut to wrap selected blocks with a Group block.
  • At first, I considered using ⌘ command + ⌥ option + G (ctrl + alt + G), but after some discussion we decided to use ⌘ command + G (ctrl + G).
  • This shortcut conflicts with the browser's search shortcut, so it only performs grouping when multiple blocks are selected.

@t-hamano t-hamano added the Needs Accessibility Feedback Need input from accessibility label May 2, 2024
@bacoords
Copy link
Contributor

bacoords commented May 2, 2024

A few notes from my testing (MacOS)

  • The keyboard shortcut shows up next to "Group" in the dropdown when you have multiple blocks selected but not when you have only one block selected, even though the option to "Group" still exists. This could be related to another issue with the fact that grouping/transforming have sort of a blurred lines approach and can work in different ways for unclear reasons: (Grouping a single Quote block transforms it (instead of grouping it) #58042)
  • The shortcut does not seem to work for me when selecting items in the list view, only when selecting blocks on the canvas.

I would also second the idea that if we're adding a shortcut for Group it makes sense to do Ungroup as well (with the shift modifier).

But overall great work and this is going to be a very popular enhancement.

@jameskoster
Copy link
Contributor

but it also serves to prevent multi-level group blocks from being created when shortcuts are executed consecutively.

To be honest I don't feel this guardrail is necessary. In most design software, repetition of the shortcut creates additional groups. In not allowing this, I worry it might be frustrating in situations you want nested groups, rare as it may be. Ultimately it feels like something we could add later based on feedback.

@t-hamano
Copy link
Contributor Author

t-hamano commented May 3, 2024

The shortcut does not seem to work for me when selecting items in the list view, only when selecting blocks on the canvas.

Nice catch! Added shortcut to work in the list view as well.

but it also serves to prevent multi-level group blocks from being created when shortcuts are executed consecutively.

To be honest I don't feel this guardrail is necessary.

If we remove this guardrail, in most cases you will override the browser's search shortcut (Find Next / Find Previous). If a user wants to use the browser's search shortcut, they are forced to move focus away from the editor canvas or list view.

This is my only concern, but I'd love to hear what the accessibility team has to say.

@jasmussen
Copy link
Contributor

It could be reasonable to start with the current PR behavior, and then remove the guardrail as a separate discussion at a later time, if the grouping behavior feels unintuitive.

@alexstine
Copy link
Contributor

@t-hamano Thanks for waiting on feedback, much appreciated. Hoping I can start reviewing faster soon.

Do not have time to do a code review at this point but the accessibility is good. The announcement is working as expected.

Let's not remove the guardrail in this PR because we need to figure out how to communicate to non-sighted users that multiple nested groups could be created depending on how many times they use the shortcut. Honestly, I would have a hard time understanding why someone would want a group inside a group.

The only issue I could find is when grouping blocks from the list view, the editor canvas steals focus. I think this has come up in other PRs and if you don't have an easy way to fix it, let's figure out how to solve the actual problem in a follow-up.

Thanks.

Copy link
Contributor

@andrewserong andrewserong left a comment

Choose a reason for hiding this comment

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

This is such a nice enhancement! I've just left a couple of comments about the list view behaviour, which I think will help address the notes that Alex raised regarding the focus shift when using the shortcut in the list view.

@@ -324,6 +332,19 @@ function ListViewBlock( {
collapseAll();
// Expand all parents of the current block.
expand( blockParents );
} else if ( isMatch( 'core/block-editor/group', event ) ) {
const clientIds = getSelectedBlockClientIds();
Copy link
Contributor

@andrewserong andrewserong May 8, 2024

Choose a reason for hiding this comment

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

In the List View, rather than using the selected block client ids, I think it's generally better to use const { blocksToUpdate } = getBlocksToUpdate(); as used in the insert before and after keyboard shortcuts above. This will ensure that if the user is focused on a block that isn't part of the selection, then the action is performed on the currently focused block. If the focused block is part of the selection, then the whole selection is used.

Copy link
Contributor

Choose a reason for hiding this comment

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

I just realised this might not be particularly clear as to why it matters. Here's a quick example video of the behaviour as it is currently, where if I move up the list view to outside the selection, the keyboard shortcut acts on the selected blocks instead of the focused one:

2024-05-08.16.12.33.mp4

blocks,
groupingBlockName
);
replaceBlocks( clientIds, newBlocks );
Copy link
Contributor

Choose a reason for hiding this comment

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

To fix the issue of the canvas stealing focus that Alex mentioned, we might be able to use a similar approach as in the insert before and after keyboard shortcuts above, where we grab the selected blocks after calling replaceBlocks and then call the following to shift focus back to the list view again:

			const newlySelectedBlocks = getSelectedBlockClientIds();
			// Focus the first block of the newly inserted blocks, to keep focus within the list view.
			updateFocusAndSelection( newlySelectedBlocks[ 0 ], false );

@t-hamano
Copy link
Contributor Author

t-hamano commented May 8, 2024

@alexstine @andrewserong Thanks for the review!

Let's not remove the guardrail in this PR because we need to figure out how to communicate to non-sighted users that multiple nested groups could be created depending on how many times they use the shortcut. Honestly, I would have a hard time understanding why someone would want a group inside a group.

I see, let's keep the current specs.

In the List View, rather than using the selected block client ids, I think it's generally better to use const { blocksToUpdate } = getBlocksToUpdate();
where we grab the selected blocks after calling replaceBlocks and then call the following to shift focus back to the list view again:

I have also addressed this approach. This part of the E2E test should ensure that the focus remains on the list view when you run the shortcut in the list view.

@jameskoster
Copy link
Contributor

we need to figure out how to communicate to non-sighted users that multiple nested groups could be created depending on how many times they use the shortcut

Could a Snackbar work, similar to the 'Copy all blocks' action?

Copy link
Contributor

@andrewserong andrewserong left a comment

Choose a reason for hiding this comment

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

Thanks for the update, this feels very close to me! Just noticed something when focusing over a single item in the list view, so I've left a comment.

@@ -324,6 +332,23 @@ function ListViewBlock( {
collapseAll();
// Expand all parents of the current block.
expand( blockParents );
} else if ( isMatch( 'core/block-editor/group', event ) ) {
const { blocksToUpdate } = getBlocksToUpdate();
if ( blocksToUpdate.length > 1 && isGroupable( blocksToUpdate ) ) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Why is the check that the length is greater than one? If a single block is selected or focused, should we still be able to group it? In the editor canvas, I think it's good to only allow it in a multi-selection, but it could still be useful to allow it in the list view, otherwise this is what happens when using the shortcut over a focused item that isn't part of the selection:

2024-05-09.11.10.36.mp4

The above video demoes grouping two blocks, then moving up to a block outside the selection and pressing the keyboard shortcut.

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 reason for checking that the length is greater than 1 is to be consistent with the editor canvas. When I run the shortcut on a single item that has focus and is not in a selection, the browser's search window opens. I think this is the expected behavior for now, but is the same behavior happening in your environment?

browser-search

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, that's what's happening for me, too. All good to leave it as-is for now, and we can always revisit in follow-ups if folks run into any issues. The main value is to group multiple items together so I doubt that in practice anyone will really struggle with the current behaviour.

Copy link
Contributor

@andrewserong andrewserong left a comment

Choose a reason for hiding this comment

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

Thanks for all the back and forth and discussion! I think this is in a good place to land, and we can always continue to iterate based on feedback.

LGTM! 🚀

@t-hamano
Copy link
Contributor Author

Thank you everyone for your reviews! I think everything is ready, so let's merge this PR. If we have any accessibility issues or spec concerns, I will be happy to follow up and address them.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Needs Accessibility Feedback Need input from accessibility [Package] Keyboard Shortcuts /packages/keyboard-shortcuts [Type] Enhancement A suggestion for improvement.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add a keyboard shortcut to create group
7 participants