From 802519e6e89926d6be4f5a63c979773744291c71 Mon Sep 17 00:00:00 2001 From: Jerry Jones Date: Thu, 9 May 2024 11:59:27 +0900 Subject: [PATCH] Fix scenario where blocks have been inserted but focus has not left the canvas (#61472) 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. Co-authored-by: jeryj Co-authored-by: mikachan Co-authored-by: priethor --- .../inserter/hooks/use-insertion-point.js | 16 +++++++++++++++- .../src/components/writing-flow/use-tab-nav.js | 11 ++++++++++- 2 files changed, 25 insertions(+), 2 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..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 @@ -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,23 @@ function useInsertionPoint( { insertBlocks, showInsertionPoint, hideInsertionPoint, - } = useDispatch( blockEditorStore ); + setLastFocus, + } = unlock( useDispatch( blockEditorStore ) ); const onInsertBlocks = useCallback( ( blocks, meta, shouldForceFocusBlock = false ) => { + // 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(); 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 818a2cdbbda029..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,7 +45,16 @@ export default function useTabNav() { } else if ( hasMultiSelection() ) { container.current.focus(); } else if ( getSelectedBlockClientId() ) { - getLastFocus()?.current.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 );