diff --git a/packages/block-editor/README.md b/packages/block-editor/README.md index 36f3dc0ba73fa1..7fc44c2ead9439 100644 --- a/packages/block-editor/README.md +++ b/packages/block-editor/README.md @@ -1077,11 +1077,11 @@ _Parameters_ ### useZoomOut -A hook used to set the zoomed out view, invoking the hook sets the mode. +A hook used to set the editor mode to zoomed out mode, invoking the hook sets the mode. _Parameters_ -- _zoomOut_ `boolean`: If we should zoom out or not. +- _zoomOut_ `boolean`: If we should enter into zoomOut mode or not ### Warning diff --git a/packages/block-editor/src/hooks/use-zoom-out.js b/packages/block-editor/src/hooks/use-zoom-out.js index 2a1b43060c00a9..23511487a54bf7 100644 --- a/packages/block-editor/src/hooks/use-zoom-out.js +++ b/packages/block-editor/src/hooks/use-zoom-out.js @@ -9,39 +9,55 @@ import { useEffect, useRef } from '@wordpress/element'; */ import { store as blockEditorStore } from '../store'; import { unlock } from '../lock-unlock'; - /** - * A hook used to set the zoomed out view, invoking the hook sets the mode. + * A hook used to set the editor mode to zoomed out mode, invoking the hook sets the mode. * - * @param {boolean} zoomOut If we should zoom out or not. + * @param {boolean} zoomOut If we should enter into zoomOut mode or not */ export function useZoomOut( zoomOut = true ) { - const { setZoomLevel } = unlock( useDispatch( blockEditorStore ) ); - const { isZoomOut } = unlock( useSelect( blockEditorStore ) ); + const { __unstableSetEditorMode, setZoomLevel } = unlock( + useDispatch( blockEditorStore ) + ); + const { __unstableGetEditorMode } = unlock( useSelect( blockEditorStore ) ); - const originalIsZoomOutRef = useRef( null ); + const originalEditingModeRef = useRef( null ); + const mode = __unstableGetEditorMode(); useEffect( () => { // Only set this on mount so we know what to return to when we unmount. - if ( ! originalIsZoomOutRef.current ) { - originalIsZoomOutRef.current = isZoomOut(); + if ( ! originalEditingModeRef.current ) { + originalEditingModeRef.current = mode; } - // The effect opens the zoom-out view if we want it open and the canvas is not currently zoomed-out. - if ( zoomOut && isZoomOut() === false ) { + return () => { + // We need to use __unstableGetEditorMode() here and not `mode`, as mode may not update on unmount + if ( + __unstableGetEditorMode() === 'zoom-out' && + __unstableGetEditorMode() !== originalEditingModeRef.current + ) { + __unstableSetEditorMode( originalEditingModeRef.current ); + setZoomLevel( 100 ); + } + }; + }, [] ); + + // The effect opens the zoom-out view if we want it open and it's not currently in zoom-out mode. + useEffect( () => { + if ( zoomOut && mode !== 'zoom-out' ) { + __unstableSetEditorMode( 'zoom-out' ); setZoomLevel( 50 ); } else if ( ! zoomOut && - isZoomOut() && - originalIsZoomOutRef.current !== isZoomOut() + __unstableGetEditorMode() === 'zoom-out' && + originalEditingModeRef.current !== mode ) { - setZoomLevel( originalIsZoomOutRef.current ? 50 : 100 ); + __unstableSetEditorMode( originalEditingModeRef.current ); + setZoomLevel( 100 ); } - - return () => { - if ( isZoomOut() && isZoomOut() !== originalIsZoomOutRef.current ) { - setZoomLevel( originalIsZoomOutRef.current ? 50 : 100 ); - } - }; - }, [ isZoomOut, setZoomLevel, zoomOut ] ); + }, [ + __unstableGetEditorMode, + __unstableSetEditorMode, + zoomOut, + setZoomLevel, + ] ); // Mode is deliberately excluded from the dependencies so that the effect does not run when mode changes. } diff --git a/test/e2e/specs/editor/various/parsing-patterns.spec.js b/test/e2e/specs/editor/various/parsing-patterns.spec.js index 62c8ba2de24104..fd9305d0db786f 100644 --- a/test/e2e/specs/editor/various/parsing-patterns.spec.js +++ b/test/e2e/specs/editor/various/parsing-patterns.spec.js @@ -36,6 +36,14 @@ test.describe( 'Parsing patterns', () => { ], } ); } ); + + // Exit zoom out mode and select the inner buttons block to ensure + // the correct insertion point is selected. + await page.getByRole( 'button', { name: 'Zoom Out' } ).click(); + await editor.selectBlocks( + editor.canvas.locator( 'role=document[name="Block: Button"i]' ) + ); + await page.fill( 'role=region[name="Block Library"i] >> role=searchbox[name="Search"i]', 'whitespace' @@ -43,7 +51,7 @@ test.describe( 'Parsing patterns', () => { await page .locator( 'role=option[name="Pattern with top-level whitespace"i]' ) .click(); - expect( await editor.getBlocks() ).toMatchObject( [ + await expect.poll( editor.getBlocks ).toMatchObject( [ { name: 'core/buttons', innerBlocks: [