diff --git a/packages/block-editor/src/components/block-tools/index.js b/packages/block-editor/src/components/block-tools/index.js
index c07adb34e584f3..163c35b54e4381 100644
--- a/packages/block-editor/src/components/block-tools/index.js
+++ b/packages/block-editor/src/components/block-tools/index.js
@@ -251,12 +251,11 @@ export default function BlockTools( {
name="__unstable-block-tools-after"
ref={ blockToolbarAfterRef }
/>
- { window.__experimentalEnableZoomedOutPatternsTab &&
- isZoomOutMode && (
-
- ) }
+ { isZoomOutMode && (
+
+ ) }
);
diff --git a/packages/block-editor/src/components/iframe/index.js b/packages/block-editor/src/components/iframe/index.js
index 3b0bce6d56b403..e7af77920ea127 100644
--- a/packages/block-editor/src/components/iframe/index.js
+++ b/packages/block-editor/src/components/iframe/index.js
@@ -242,10 +242,8 @@ function Iframe( {
const isZoomedOut = scale !== 1;
useEffect( () => {
- if ( ! isZoomedOut ) {
- prevContainerWidth.current = containerWidth;
- }
- }, [ containerWidth, isZoomedOut ] );
+ prevContainerWidth.current = containerWidth;
+ }, [ containerWidth ] );
const disabledRef = useDisabled( { isDisabled: ! readonly } );
const bodyRef = useMergeRefs( [
diff --git a/packages/block-editor/src/hooks/use-zoom-out.js b/packages/block-editor/src/hooks/use-zoom-out.js
index 3ec701cfc4a14d..d0d7d0fd4d71c7 100644
--- a/packages/block-editor/src/hooks/use-zoom-out.js
+++ b/packages/block-editor/src/hooks/use-zoom-out.js
@@ -49,5 +49,5 @@ export function useZoomOut( zoomOut = true ) {
) {
__unstableSetEditorMode( originalEditingMode.current );
}
- }, [ __unstableSetEditorMode, zoomOut, mode ] );
+ }, [ __unstableGetEditorMode, __unstableSetEditorMode, zoomOut ] ); // Mode is deliberately excluded from the dependencies so that the effect does not run when mode changes.
}
diff --git a/packages/editor/src/components/header/index.js b/packages/editor/src/components/header/index.js
index 2a604229596005..b8eda30c721860 100644
--- a/packages/editor/src/components/header/index.js
+++ b/packages/editor/src/components/header/index.js
@@ -57,7 +57,6 @@ function Header( {
showIconLabels,
hasFixedToolbar,
isNestedEntity,
- isZoomedOutView,
} = useSelect( ( select ) => {
const { get: getPreference } = select( preferencesStore );
const {
@@ -136,7 +135,7 @@ function Header( {
) }
{
- const { getDeviceType, getCurrentPostType } = select( editorStore );
- const { getUnstableBase, getPostType } = select( coreStore );
- const { get } = select( preferencesStore );
- const _currentPostType = getCurrentPostType();
- return {
- deviceType: getDeviceType(),
- homeUrl: getUnstableBase()?.home,
- isTemplate: _currentPostType === 'wp_template',
- isViewable: getPostType( _currentPostType )?.viewable ?? false,
- showIconLabels: get( 'core', 'showIconLabels' ),
- };
- }, [] );
+ const {
+ deviceType,
+ editorMode,
+ homeUrl,
+ isTemplate,
+ isViewable,
+ showIconLabels,
+ } = useSelect( ( select ) => {
+ const { getDeviceType, getCurrentPostType } = select( editorStore );
+ const { getUnstableBase, getPostType } = select( coreStore );
+ const { get } = select( preferencesStore );
+ const { __unstableGetEditorMode } = select( blockEditorStore );
+ const _currentPostType = getCurrentPostType();
+ return {
+ deviceType: getDeviceType(),
+ editorMode: __unstableGetEditorMode(),
+ homeUrl: getUnstableBase()?.home,
+ isTemplate: _currentPostType === 'wp_template',
+ isViewable: getPostType( _currentPostType )?.viewable ?? false,
+ showIconLabels: get( 'core', 'showIconLabels' ),
+ };
+ }, [] );
const { setDeviceType } = useDispatch( editorStore );
+ const { __unstableSetEditorMode } = useDispatch( blockEditorStore );
+
+ /**
+ * Save the original editing mode in a ref to restore it when we exit zoom out.
+ */
+ const originalEditingMode = useRef( editorMode );
+ useEffect( () => {
+ if ( editorMode !== 'zoom-out' ) {
+ originalEditingMode.current = editorMode;
+ }
+
+ return () => {
+ if (
+ editorMode === 'zoom-out' &&
+ editorMode !== originalEditingMode.current
+ ) {
+ __unstableSetEditorMode( originalEditingMode.current );
+ }
+ };
+ }, [ editorMode, __unstableSetEditorMode ] );
+
const isMobile = useViewportMatch( 'medium', '<' );
if ( isMobile ) {
return null;
@@ -48,6 +84,7 @@ export default function PreviewDropdown( { forceIsAutosaveable, disabled } ) {
};
const toggleProps = {
className: 'editor-preview-dropdown__toggle',
+ iconPosition: 'right',
size: 'compact',
showTooltip: ! showIconLabels,
disabled,
@@ -58,9 +95,9 @@ export default function PreviewDropdown( { forceIsAutosaveable, disabled } ) {
};
const deviceIcons = {
+ desktop,
mobile,
tablet,
- desktop,
};
/**
@@ -74,6 +111,11 @@ export default function PreviewDropdown( { forceIsAutosaveable, disabled } ) {
label: __( 'Desktop' ),
icon: desktop,
},
+ {
+ value: 'ZoomOut',
+ label: __( 'Desktop (50%)' ),
+ icon: desktop,
+ },
{
value: 'Tablet',
label: __( 'Tablet' ),
@@ -86,29 +128,37 @@ export default function PreviewDropdown( { forceIsAutosaveable, disabled } ) {
},
];
+ const previewValue = editorMode === 'zoom-out' ? 'ZoomOut' : deviceType;
+
/**
- * The selected choice.
+ * Handles the selection of a device type.
*
- * @type {Object}
+ * @param {string} value The device type.
*/
- let selectedChoice = choices.find(
- ( choice ) => choice.value === deviceType
- );
+ const onSelect = ( value ) => {
+ let newEditorMode = originalEditingMode.current;
- /**
- * If no selected choice is found, default to the first
- */
- if ( ! selectedChoice ) {
- selectedChoice = choices[ 0 ];
- }
+ if ( value === 'ZoomOut' ) {
+ newEditorMode = 'zoom-out';
+ setDeviceType( 'Desktop' );
+ } else {
+ setDeviceType( value );
+ }
+
+ __unstableSetEditorMode( newEditorMode );
+ };
return (
@@ -117,8 +167,8 @@ export default function PreviewDropdown( { forceIsAutosaveable, disabled } ) {
{ isTemplate && (
diff --git a/packages/editor/src/components/preview-dropdown/style.scss b/packages/editor/src/components/preview-dropdown/style.scss
index 43fa7cdd8ecd97..c117a4239e9dfb 100644
--- a/packages/editor/src/components/preview-dropdown/style.scss
+++ b/packages/editor/src/components/preview-dropdown/style.scss
@@ -1,3 +1,8 @@
+.editor-preview-dropdown .editor-preview-dropdown__toggle.has-icon.has-text {
+ padding-right: 4px;
+ padding-left: 6px;
+}
+
.editor-preview-dropdown__button-external {
width: 100%;
display: flex;
diff --git a/packages/editor/src/components/visual-editor/index.js b/packages/editor/src/components/visual-editor/index.js
index 8b4877704f5f18..a67feb530e96a2 100644
--- a/packages/editor/src/components/visual-editor/index.js
+++ b/packages/editor/src/components/visual-editor/index.js
@@ -107,6 +107,7 @@ function VisualEditor( {
} ) {
const [ resizeObserver, sizes ] = useResizeObserver();
const isMobileViewport = useViewportMatch( 'small', '<' );
+ const isTabletViewport = useViewportMatch( 'medium', '<' );
const {
renderingMode,
postContentAttributes,
@@ -341,12 +342,13 @@ function VisualEditor( {
} ),
] );
- const zoomOutProps = isZoomOutMode
- ? {
- scale: 'default',
- frameSize: '48px',
- }
- : {};
+ const zoomOutProps =
+ isZoomOutMode && ! isTabletViewport
+ ? {
+ scale: 'default',
+ frameSize: '48px',
+ }
+ : {};
const forceFullHeight = postType === NAVIGATION_POST_TYPE;
const enableResizing =