diff --git a/packages/block-editor/README.md b/packages/block-editor/README.md index a474d1df7e56d..75d7e8879572d 100644 --- a/packages/block-editor/README.md +++ b/packages/block-editor/README.md @@ -1027,11 +1027,11 @@ _Parameters_ ### useZoomOut -A hook used to set the editor mode to zoomed out mode, invoking the hook sets the mode. +A hook used to set the zoomed out view, invoking the hook sets the mode. _Parameters_ -- _zoomOut_ `boolean`: If we should enter into zoomOut mode or not +- _zoomOut_ `boolean`: If we should zoom out or not. ### Warning diff --git a/packages/block-editor/src/components/block-list/use-block-props/use-zoom-out-mode-exit.js b/packages/block-editor/src/components/block-list/use-block-props/use-zoom-out-mode-exit.js index d0001bd3b33c6..92c54bac9b806 100644 --- a/packages/block-editor/src/components/block-list/use-block-props/use-zoom-out-mode-exit.js +++ b/packages/block-editor/src/components/block-list/use-block-props/use-zoom-out-mode-exit.js @@ -16,14 +16,17 @@ import { unlock } from '../../../lock-unlock'; * @param {string} clientId Block client ID. */ export function useZoomOutModeExit( { editorMode } ) { - const { getSettings } = useSelect( blockEditorStore ); - const { __unstableSetEditorMode } = unlock( + const { getSettings, isZoomOut } = unlock( useSelect( blockEditorStore ) ); + const { __unstableSetEditorMode, resetZoomLevel } = unlock( useDispatch( blockEditorStore ) ); return useRefEffect( ( node ) => { - if ( editorMode !== 'zoom-out' ) { + // In "compose" mode. + const composeMode = editorMode === 'zoom-out' && isZoomOut(); + + if ( ! composeMode ) { return; } @@ -39,6 +42,7 @@ export function useZoomOutModeExit( { editorMode } ) { __experimentalSetIsInserterOpened( false ); } __unstableSetEditorMode( 'edit' ); + resetZoomLevel(); } } diff --git a/packages/block-editor/src/components/block-tools/zoom-out-toolbar.js b/packages/block-editor/src/components/block-tools/zoom-out-toolbar.js index a3c46c4b4c970..2c0ed6b26651f 100644 --- a/packages/block-editor/src/components/block-tools/zoom-out-toolbar.js +++ b/packages/block-editor/src/components/block-tools/zoom-out-toolbar.js @@ -20,6 +20,7 @@ import BlockDraggable from '../block-draggable'; import BlockMover from '../block-mover'; import Shuffle from '../block-toolbar/shuffle'; import NavigableToolbar from '../navigable-toolbar'; +import { unlock } from '../../lock-unlock'; export default function ZoomOutToolbar( { clientId, __unstableContentRef } ) { const selected = useSelect( @@ -84,8 +85,9 @@ export default function ZoomOutToolbar( { clientId, __unstableContentRef } ) { setIsInserterOpened, } = selected; - const { removeBlock, __unstableSetEditorMode } = - useDispatch( blockEditorStore ); + const { removeBlock, __unstableSetEditorMode, resetZoomLevel } = unlock( + useDispatch( blockEditorStore ) + ); const classNames = clsx( 'zoom-out-toolbar', { 'is-block-moving-mode': !! blockMovingMode, @@ -144,6 +146,7 @@ export default function ZoomOutToolbar( { clientId, __unstableContentRef } ) { setIsInserterOpened( false ); } __unstableSetEditorMode( 'edit' ); + resetZoomLevel(); __unstableContentRef.current?.focus(); } } /> diff --git a/packages/block-editor/src/components/tool-selector/index.js b/packages/block-editor/src/components/tool-selector/index.js index 4ec777a911cc7..6c70b3ac04285 100644 --- a/packages/block-editor/src/components/tool-selector/index.js +++ b/packages/block-editor/src/components/tool-selector/index.js @@ -18,6 +18,7 @@ import { Icon, edit as editIcon } from '@wordpress/icons'; * Internal dependencies */ import { store as blockEditorStore } from '../../store'; +import { unlock } from '../../lock-unlock'; const selectIcon = ( select( blockEditorStore ).__unstableGetEditorMode(), [] ); - const { __unstableSetEditorMode } = useDispatch( blockEditorStore ); + const { __unstableSetEditorMode } = unlock( + useDispatch( blockEditorStore ) + ); return ( { // Only set this on mount so we know what to return to when we unmount. - if ( ! originalEditingModeRef.current ) { - originalEditingModeRef.current = mode; + if ( ! originalIsZoomOutRef.current ) { + originalIsZoomOutRef.current = isZoomOut(); } - 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 ); - } - }; - }, [] ); - - // 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' ); + // The effect opens the zoom-out view if we want it open and the canvas is not currently zoomed-out. + if ( zoomOut && isZoomOut() === false ) { + setZoomLevel( 50 ); } else if ( ! zoomOut && - __unstableGetEditorMode() === 'zoom-out' && - originalEditingModeRef.current !== mode + isZoomOut() && + originalIsZoomOutRef.current !== isZoomOut() ) { - __unstableSetEditorMode( originalEditingModeRef.current ); + setZoomLevel( originalIsZoomOutRef.current ? 50 : 100 ); } - }, [ __unstableGetEditorMode, __unstableSetEditorMode, zoomOut ] ); // Mode is deliberately excluded from the dependencies so that the effect does not run when mode changes. + + return () => { + if ( isZoomOut() && isZoomOut() !== originalIsZoomOutRef.current ) { + setZoomLevel( originalIsZoomOutRef.current ? 50 : 100 ); + } + }; + }, [ isZoomOut, setZoomLevel, zoomOut ] ); } diff --git a/packages/block-editor/src/store/private-actions.js b/packages/block-editor/src/store/private-actions.js index dc57d61fd6b76..441a07202c42a 100644 --- a/packages/block-editor/src/store/private-actions.js +++ b/packages/block-editor/src/store/private-actions.js @@ -383,3 +383,26 @@ export const modifyContentLockBlock = focusModeToRevert ); }; + +/** + * Sets the zoom level. + * + * @param {number} zoom the new zoom level + * @return {Object} Action object. + */ +export function setZoomLevel( zoom = 100 ) { + return { + type: 'SET_ZOOM_LEVEL', + zoom, + }; +} + +/** + * Resets the Zoom state. + * @return {Object} Action object. + */ +export function resetZoomLevel() { + return { + type: 'RESET_ZOOM_LEVEL', + }; +} diff --git a/packages/block-editor/src/store/private-selectors.js b/packages/block-editor/src/store/private-selectors.js index 01ad8f69febc9..e24ae4abb4738 100644 --- a/packages/block-editor/src/store/private-selectors.js +++ b/packages/block-editor/src/store/private-selectors.js @@ -560,3 +560,23 @@ export function isZoomOutMode( state ) { export function getSectionRootClientId( state ) { return state.settings?.[ sectionRootClientIdKey ]; } + +/** + * Returns the zoom out state. + * + * @param {Object} state Global application state. + * @return {boolean} The zoom out state. + */ +export function getZoomLevel( state ) { + return state.zoomLevel; +} + +/** + * Returns whether the editor is considered zoomed out. + * + * @param {Object} state Global application state. + * @return {boolean} Whether the editor is zoomed. + */ +export function isZoomOut( state ) { + return getZoomLevel( state ) < 100; +} diff --git a/packages/block-editor/src/store/reducer.js b/packages/block-editor/src/store/reducer.js index cd4569c45e580..e80c90ffb41f2 100644 --- a/packages/block-editor/src/store/reducer.js +++ b/packages/block-editor/src/store/reducer.js @@ -2085,6 +2085,25 @@ export function hoveredBlockClientId( state = false, action ) { return state; } +/** + * Reducer setting zoom out state. + * + * @param {boolean} state Current state. + * @param {Object} action Dispatched action. + * + * @return {boolean} Updated state. + */ +export function zoomLevel( state = 100, action ) { + switch ( action.type ) { + case 'SET_ZOOM_LEVEL': + return action.zoom; + case 'RESET_ZOOM_LEVEL': + return 100; + } + + return state; +} + const combinedReducers = combineReducers( { blocks, isDragging, @@ -2118,6 +2137,7 @@ const combinedReducers = combineReducers( { openedBlockSettingsMenu, registeredInserterMediaCategories, hoveredBlockClientId, + zoomLevel, } ); function withAutomaticChangeReset( reducer ) { diff --git a/packages/editor/src/components/editor-interface/index.js b/packages/editor/src/components/editor-interface/index.js index 645e5fb6f53a2..0709b91175712 100644 --- a/packages/editor/src/components/editor-interface/index.js +++ b/packages/editor/src/components/editor-interface/index.js @@ -32,6 +32,8 @@ import TextEditor from '../text-editor'; import VisualEditor from '../visual-editor'; import EditorContentSlotFill from './content-slot-fill'; +import { unlock } from '../../lock-unlock'; + const interfaceLabels = { /* translators: accessibility text for the editor top bar landmark region. */ header: __( 'Editor top bar' ), @@ -71,12 +73,13 @@ export default function EditorInterface( { nextShortcut, showBlockBreadcrumbs, documentLabel, - blockEditorMode, + isZoomOut, } = useSelect( ( select ) => { const { get } = select( preferencesStore ); const { getEditorSettings, getPostTypeLabel } = select( editorStore ); const editorSettings = getEditorSettings(); const postTypeLabel = getPostTypeLabel(); + const { isZoomOut: _isZoomOut } = unlock( select( blockEditorStore ) ); return { mode: select( editorStore ).getEditorMode(), @@ -94,8 +97,7 @@ export default function EditorInterface( { showBlockBreadcrumbs: get( 'core', 'showBlockBreadcrumbs' ), // translators: Default label for the Document in the Block Breadcrumb. documentLabel: postTypeLabel || _x( 'Document', 'noun' ), - blockEditorMode: - select( blockEditorStore ).__unstableGetEditorMode(), + isZoomOut: _isZoomOut(), }; }, [] ); const isLargeViewport = useViewportMatch( 'medium' ); @@ -206,7 +208,7 @@ export default function EditorInterface( { isLargeViewport && showBlockBreadcrumbs && isRichEditingEnabled && - blockEditorMode !== 'zoom-out' && + ! isZoomOut && mode === 'visual' && ( ) diff --git a/packages/editor/src/components/visual-editor/index.js b/packages/editor/src/components/visual-editor/index.js index 2ff115272d614..88d2dac8ffd77 100644 --- a/packages/editor/src/components/visual-editor/index.js +++ b/packages/editor/src/components/visual-editor/index.js @@ -174,17 +174,19 @@ function VisualEditor( { hasRootPaddingAwareAlignments, themeHasDisabledLayoutStyles, themeSupportsLayout, - isZoomOutMode, + isZoomedOut, } = useSelect( ( select ) => { - const { getSettings, __unstableGetEditorMode } = - select( blockEditorStore ); + const { getSettings, isZoomOut: _isZoomOut } = unlock( + select( blockEditorStore ) + ); + const _settings = getSettings(); return { themeHasDisabledLayoutStyles: _settings.disableLayoutStyles, themeSupportsLayout: _settings.supportsLayout, hasRootPaddingAwareAlignments: _settings.__experimentalFeatures?.useRootPaddingAwareAlignments, - isZoomOutMode: __unstableGetEditorMode() === 'zoom-out', + isZoomedOut: _isZoomOut(), }; }, [] ); @@ -336,7 +338,7 @@ function VisualEditor( { ] ); const zoomOutProps = - isZoomOutMode && ! isTabletViewport + isZoomedOut && ! isTabletViewport ? { scale: 'default', frameSize: '48px', @@ -355,7 +357,7 @@ function VisualEditor( { // Disable resizing in mobile viewport. ! isMobileViewport && // Dsiable resizing in zoomed-out mode. - ! isZoomOutMode; + ! isZoomedOut; const shouldIframe = ! disableIframe || [ 'Tablet', 'Mobile' ].includes( deviceType ); diff --git a/packages/editor/src/components/zoom-out-toggle/index.js b/packages/editor/src/components/zoom-out-toggle/index.js index e8c7b1e50510a..214b1c51fd625 100644 --- a/packages/editor/src/components/zoom-out-toggle/index.js +++ b/packages/editor/src/components/zoom-out-toggle/index.js @@ -8,16 +8,27 @@ import { useDispatch, useSelect } from '@wordpress/data'; import { store as blockEditorStore } from '@wordpress/block-editor'; import { square as zoomOutIcon } from '@wordpress/icons'; +/** + * Internal dependencies + */ +import { unlock } from '../../lock-unlock'; + const ZoomOutToggle = () => { - const { isZoomOutMode } = useSelect( ( select ) => ( { - isZoomOutMode: - select( blockEditorStore ).__unstableGetEditorMode() === 'zoom-out', + const { isZoomOut } = useSelect( ( select ) => ( { + isZoomOut: unlock( select( blockEditorStore ) ).isZoomOut(), } ) ); - const { __unstableSetEditorMode } = useDispatch( blockEditorStore ); + const { resetZoomLevel, setZoomLevel, __unstableSetEditorMode } = unlock( + useDispatch( blockEditorStore ) + ); const handleZoomOut = () => { - __unstableSetEditorMode( isZoomOutMode ? 'edit' : 'zoom-out' ); + if ( isZoomOut ) { + resetZoomLevel(); + } else { + setZoomLevel( 50 ); + } + __unstableSetEditorMode( isZoomOut ? 'edit' : 'zoom-out' ); }; return ( @@ -25,7 +36,7 @@ const ZoomOutToggle = () => { onClick={ handleZoomOut } icon={ zoomOutIcon } label={ __( 'Toggle Zoom Out' ) } - isPressed={ isZoomOutMode } + isPressed={ isZoomOut } size="compact" /> );