From 45558f4d2a9b693d3c4d2182a40ea9b78b4b6d0a Mon Sep 17 00:00:00 2001 From: Jerry Jones Date: Wed, 8 May 2024 12:26:45 +0900 Subject: [PATCH 1/3] Fix scenario where blocks have been inserted but focus has not left the canvas Now that the inserter stays open when focus leaves it, an edge case can occur where blocks are inserted before the canvas has ever been focused. When that happens, focus is trying to get sent to the previously focused block, but no block has been focused. This focuses the currently selected block when entering the canvas. --- .../block-editor/src/components/writing-flow/use-tab-nav.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/block-editor/src/components/writing-flow/use-tab-nav.js b/packages/block-editor/src/components/writing-flow/use-tab-nav.js index 818a2cdbbda029..d563a09e970687 100644 --- a/packages/block-editor/src/components/writing-flow/use-tab-nav.js +++ b/packages/block-editor/src/components/writing-flow/use-tab-nav.js @@ -45,7 +45,11 @@ export default function useTabNav() { } else if ( hasMultiSelection() ) { container.current.focus(); } else if ( getSelectedBlockClientId() ) { - getLastFocus()?.current.focus(); + container.current + .querySelector( + `[data-block="${ getSelectedBlockClientId() }"]` + ) + .focus(); } else { setNavigationMode( true ); From 29df449fdcae8e58bd1cf08d8d59fb599cef6089 Mon Sep 17 00:00:00 2001 From: Jerry Jones Date: Thu, 9 May 2024 11:10:36 +0900 Subject: [PATCH 2/3] Clear last focused block when inserting new blocks When inserting a new block from the inserter, focus should go to this block when focus is moved to the canvas via the Tab keypress. To do this, we need to clear where focus previously was when a new block is inserted, otherwise it tries to place focus where it was before. --- .../inserter/hooks/use-insertion-point.js | 9 ++++++++- .../src/components/writing-flow/use-tab-nav.js | 15 ++++++++++----- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/packages/block-editor/src/components/inserter/hooks/use-insertion-point.js b/packages/block-editor/src/components/inserter/hooks/use-insertion-point.js index 8252de58b49d51..41f1bb92a7050e 100644 --- a/packages/block-editor/src/components/inserter/hooks/use-insertion-point.js +++ b/packages/block-editor/src/components/inserter/hooks/use-insertion-point.js @@ -11,6 +11,7 @@ import { useCallback } from '@wordpress/element'; * Internal dependencies */ import { store as blockEditorStore } from '../../../store'; +import { unlock } from '../../../lock-unlock'; /** * @typedef WPInserterConfig @@ -86,10 +87,16 @@ function useInsertionPoint( { insertBlocks, showInsertionPoint, hideInsertionPoint, - } = useDispatch( blockEditorStore ); + setLastFocus, + } = unlock( useDispatch( blockEditorStore ) ); const onInsertBlocks = useCallback( ( blocks, meta, shouldForceFocusBlock = false ) => { + // Clear the last focused block and let writing flow handle + // focusing the new block when focus returns to the canvas, + // such as when inserting from the sidebar. + setLastFocus( null ); + const selectedBlock = getSelectedBlock(); if ( diff --git a/packages/block-editor/src/components/writing-flow/use-tab-nav.js b/packages/block-editor/src/components/writing-flow/use-tab-nav.js index d563a09e970687..1394fbbd37e258 100644 --- a/packages/block-editor/src/components/writing-flow/use-tab-nav.js +++ b/packages/block-editor/src/components/writing-flow/use-tab-nav.js @@ -45,11 +45,16 @@ export default function useTabNav() { } else if ( hasMultiSelection() ) { container.current.focus(); } else if ( getSelectedBlockClientId() ) { - container.current - .querySelector( - `[data-block="${ getSelectedBlockClientId() }"]` - ) - .focus(); + if ( getLastFocus()?.current ) { + getLastFocus().current.focus(); + } else { + // Handles when the last focus has not been set yet, or has been cleared by new blocks being added via the inserter. + container.current + .querySelector( + `[data-block="${ getSelectedBlockClientId() }"]` + ) + .focus(); + } } else { setNavigationMode( true ); From dc7a62f4c9a64c82a9faae01f4f469386700f0a6 Mon Sep 17 00:00:00 2001 From: Jerry Jones Date: Thu, 9 May 2024 11:24:55 +0900 Subject: [PATCH 3/3] Only clear last focus if we're selecting the block or focusing it on insert --- .../inserter/hooks/use-insertion-point.js | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/packages/block-editor/src/components/inserter/hooks/use-insertion-point.js b/packages/block-editor/src/components/inserter/hooks/use-insertion-point.js index 41f1bb92a7050e..0dae090578ab4f 100644 --- a/packages/block-editor/src/components/inserter/hooks/use-insertion-point.js +++ b/packages/block-editor/src/components/inserter/hooks/use-insertion-point.js @@ -92,10 +92,17 @@ function useInsertionPoint( { const onInsertBlocks = useCallback( ( blocks, meta, shouldForceFocusBlock = false ) => { - // Clear the last focused block and let writing flow handle - // focusing the new block when focus returns to the canvas, - // such as when inserting from the sidebar. - setLastFocus( null ); + // When we are trying to move focus or select a new block on insert, we also + // need to clear the last focus to avoid the focus being set to the wrong block + // when tabbing back into the canvas if the block was added from outside the + // editor canvas. + if ( + shouldForceFocusBlock || + shouldFocusBlock || + selectBlockOnInsert + ) { + setLastFocus( null ); + } const selectedBlock = getSelectedBlock();