From f6c90edfd99c697aa172c8b51f93021659e803a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ella=20van=C2=A0Durpe?= Date: Tue, 21 Jan 2020 09:30:17 +0100 Subject: [PATCH] Multi-select: don't focus first selected block (#19762) * Multi-select: don't focus first selected block * Move CopyHandler outside WritingFlow * Fix click appender * Remove useless line --- .../src/components/block-list/block.js | 15 ++----- .../components/writing-flow/focus-capture.js | 6 +++ .../src/components/writing-flow/index.js | 39 ++++++++++++++----- .../src/components/visual-editor/index.js | 18 +++++---- .../src/components/visual-editor/style.scss | 5 ++- 5 files changed, 53 insertions(+), 30 deletions(-) diff --git a/packages/block-editor/src/components/block-list/block.js b/packages/block-editor/src/components/block-list/block.js index 19958b7ae884b..8902227bbd561 100644 --- a/packages/block-editor/src/components/block-list/block.js +++ b/packages/block-editor/src/components/block-list/block.js @@ -103,10 +103,8 @@ function BlockListBlock( { const onBlockError = () => setErrorState( true ); const blockType = getBlockType( name ); - const blockLabel = isFirstMultiSelected ? - __( 'Multiple selected blocks' ) : - // translators: %s: Type of block (i.e. Text, Image etc) - sprintf( __( 'Block: %s' ), blockType.title ); + // translators: %s: Type of block (i.e. Text, Image etc) + const blockLabel = sprintf( __( 'Block: %s' ), blockType.title ); // Handing the focus of the block on creation and update @@ -148,18 +146,13 @@ function BlockListBlock( { const isMounting = useRef( true ); useEffect( () => { - if ( ! isMultiSelecting && ! isNavigationMode ) { - if ( isSelected ) { - focusTabbable( ! isMounting.current ); - } else if ( isFirstMultiSelected ) { - wrapper.current.focus(); - } + if ( ! isMultiSelecting && ! isNavigationMode && isSelected ) { + focusTabbable( ! isMounting.current ); } isMounting.current = false; }, [ isSelected, - isFirstMultiSelected, isMultiSelecting, isNavigationMode, ] ); diff --git a/packages/block-editor/src/components/writing-flow/focus-capture.js b/packages/block-editor/src/components/writing-flow/focus-capture.js index b1753c6ea7b15..50e7fa9009f01 100644 --- a/packages/block-editor/src/components/writing-flow/focus-capture.js +++ b/packages/block-editor/src/components/writing-flow/focus-capture.js @@ -35,6 +35,7 @@ const FocusCapture = forwardRef( ( { isReverse, containerRef, noCapture, + hasMultiSelection, }, ref ) => { const isNavigationMode = useSelect( ( select ) => select( 'core/block-editor' ).isNavigationMode() @@ -52,6 +53,11 @@ const FocusCapture = forwardRef( ( { // selected, enable Navigation mode and select the first or last block // depending on the direction. if ( ! selectedClientId ) { + if ( hasMultiSelection ) { + containerRef.current.focus(); + return; + } + setNavigationMode( true ); const tabbables = focus.tabbable.find( containerRef.current ); diff --git a/packages/block-editor/src/components/writing-flow/index.js b/packages/block-editor/src/components/writing-flow/index.js index 9248931df8196..170199a8f679f 100644 --- a/packages/block-editor/src/components/writing-flow/index.js +++ b/packages/block-editor/src/components/writing-flow/index.js @@ -6,7 +6,7 @@ import { overEvery, find, findLast, reverse, first, last } from 'lodash'; /** * WordPress dependencies */ -import { useRef } from '@wordpress/element'; +import { useRef, useEffect } from '@wordpress/element'; import { computeCaretRect, focus, @@ -19,6 +19,7 @@ import { } from '@wordpress/dom'; import { UP, DOWN, LEFT, RIGHT, TAB, isKeyboardEvent, ESCAPE } from '@wordpress/keycodes'; import { useSelect, useDispatch } from '@wordpress/data'; +import { __ } from '@wordpress/i18n'; /** * Internal dependencies @@ -164,6 +165,7 @@ function selector( select ) { isNavigationMode, isSelectionEnabled, getBlockSelectionStart, + isMultiSelecting, } = select( 'core/block-editor' ); const selectedBlockClientId = getSelectedBlockClientId(); @@ -182,6 +184,7 @@ function selector( select ) { isNavigationMode: isNavigationMode(), isSelectionEnabled: isSelectionEnabled(), blockSelectionStart: getBlockSelectionStart(), + isMultiSelecting: isMultiSelecting(), }; } @@ -217,6 +220,7 @@ export default function WritingFlow( { children } ) { isNavigationMode, isSelectionEnabled, blockSelectionStart, + isMultiSelecting, } = useSelect( selector, [] ); const { multiSelect, @@ -348,18 +352,16 @@ export default function WritingFlow( { children } ) { return; } - const clientId = selectedBlockClientId || selectedFirstClientId; - // In Edit mode, Tab should focus the first tabbable element after the // content, which is normally the sidebar (with block controls) and // Shift+Tab should focus the first tabbable element before the content, // which is normally the block toolbar. // Arrow keys can be used, and Tab and arrow keys can be used in // Navigation mode (press Esc), to navigate through blocks. - if ( clientId ) { - const wrapper = getBlockDOMNode( clientId ); - + if ( selectedBlockClientId ) { if ( isTab ) { + const wrapper = getBlockDOMNode( selectedBlockClientId ); + if ( isShift ) { if ( target === wrapper ) { // Disable focus capturing on the focus capture element, so @@ -383,6 +385,17 @@ export default function WritingFlow( { children } ) { } else if ( isEscape ) { setNavigationMode( true ); } + } else if ( hasMultiSelection && isTab && target === container.current ) { + // See comment above. + noCapture.current = true; + + if ( isShift ) { + focusCaptureBeforeRef.current.focus(); + } else { + focusCaptureAfterRef.current.focus(); + } + + return; } // When presing any key other than up or down, the initial vertical @@ -486,7 +499,11 @@ export default function WritingFlow( { children } ) { } } - const selectedClientId = selectedBlockClientId || selectedFirstClientId; + useEffect( () => { + if ( hasMultiSelection && ! isMultiSelecting ) { + container.current.focus(); + } + }, [ hasMultiSelection, isMultiSelecting ] ); // Disable reason: Wrapper itself is non-interactive, but must capture // bubbling events from children to determine focus transition intents. @@ -495,22 +512,26 @@ export default function WritingFlow( { children } ) {
{ children }
- - - - - - - - + + + + + + + + + + <__experimentalBlockSettingsMenuFirstItem> { ( { onClose } ) => } diff --git a/packages/edit-post/src/components/visual-editor/style.scss b/packages/edit-post/src/components/visual-editor/style.scss index f61ea75108f44..7dd1f86dab879 100644 --- a/packages/edit-post/src/components/visual-editor/style.scss +++ b/packages/edit-post/src/components/visual-editor/style.scss @@ -17,8 +17,9 @@ } .edit-post-visual-editor > .block-editor__typewriter, -.edit-post-visual-editor > .block-editor__typewriter > .block-editor-writing-flow, -.edit-post-visual-editor > .block-editor__typewriter > .block-editor-writing-flow > .block-editor-writing-flow__click-redirect { +.edit-post-visual-editor > .block-editor__typewriter > div, +.edit-post-visual-editor > .block-editor__typewriter > div > .block-editor-writing-flow, +.edit-post-visual-editor > .block-editor__typewriter > div > .block-editor-writing-flow > .block-editor-writing-flow__click-redirect { height: 100%; }