Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Alternative zoom out trigger location #63913

Closed
wants to merge 20 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 5 additions & 6 deletions packages/block-editor/src/components/block-tools/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -251,12 +251,11 @@ export default function BlockTools( {
name="__unstable-block-tools-after"
ref={ blockToolbarAfterRef }
/>
{ window.__experimentalEnableZoomedOutPatternsTab &&
isZoomOutMode && (
<ZoomOutModeInserters
__unstableContentRef={ __unstableContentRef }
/>
) }
{ isZoomOutMode && (
<ZoomOutModeInserters
__unstableContentRef={ __unstableContentRef }
/>
) }
</InsertionPointOpenRef.Provider>
</div>
);
Expand Down
6 changes: 2 additions & 4 deletions packages/block-editor/src/components/iframe/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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( [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,13 @@ import { __ } from '@wordpress/i18n';
import {
__experimentalHStack as HStack,
__experimentalVStack as VStack,
__experimentalHeading as Heading,
__experimentalText as Text,
FlexBlock,
FormToggle,
VisuallyHidden,
Tooltip,
} from '@wordpress/components';
import { useDispatch, useSelect } from '@wordpress/data';
import { Icon, aspectRatio } from '@wordpress/icons';

/**
* Internal dependencies
Expand All @@ -32,6 +35,7 @@ import {
myPatternsCategory,
INSERTER_PATTERN_TYPES,
} from './utils';
import { store as blockEditorStore } from '../../../store';

const noop = () => {};

Expand All @@ -42,6 +46,12 @@ export function PatternCategoryPreviews( {
category,
showTitlesAsTooltip,
} ) {
const isZoomOut = useSelect( ( select ) => {
return (
select( blockEditorStore ).__unstableGetEditorMode() === 'zoom-out'
);
}, [] );

const [ allPatterns, , onClickPattern ] = usePatternsState(
onInsert,
rootClientId,
Expand Down Expand Up @@ -109,6 +119,8 @@ export function PatternCategoryPreviews( {
);
const { changePage } = pagingProps;

const { __unstableSetEditorMode } = useDispatch( blockEditorStore );

// Hide block pattern preview on unmount.
// eslint-disable-next-line react-hooks/exhaustive-deps
useEffect( () => () => onHover( null ), [] );
Expand All @@ -128,23 +140,32 @@ export function PatternCategoryPreviews( {
[ setPatternSourceFilter, changePage ]
);

const zoomOutLabel = __( 'Zoom out' );

return (
<>
<VStack
spacing={ 2 }
className="block-editor-inserter__patterns-category-panel-header"
>
<HStack>
<FlexBlock>
<Heading
className="block-editor-inserter__patterns-category-panel-title"
size={ 13 }
level={ 4 }
as="div"
>
{ category.label }
</Heading>
</FlexBlock>
<Tooltip text={ zoomOutLabel }>
<HStack as="label" expanded={ false }>
<FormToggle
onChange={ () => {
if ( isZoomOut ) {
// TODO: We should set it back to what it was, not to edit.
__unstableSetEditorMode( 'edit' );
} else {
__unstableSetEditorMode( 'zoom-out' );
}
} }
checked={ isZoomOut }
/>
<VisuallyHidden>{ zoomOutLabel }</VisuallyHidden>
<Icon icon={ aspectRatio } size="24" />
</HStack>
</Tooltip>
<PatternsFilter
patternSyncFilter={ patternSyncFilter }
patternSourceFilter={ patternSourceFilter }
Expand Down
2 changes: 1 addition & 1 deletion packages/block-editor/src/hooks/use-zoom-out.js
Original file line number Diff line number Diff line change
Expand Up @@ -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.
}
3 changes: 1 addition & 2 deletions packages/editor/src/components/header/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ function Header( {
showIconLabels,
hasFixedToolbar,
isNestedEntity,
isZoomedOutView,
} = useSelect( ( select ) => {
const { get: getPreference } = select( preferencesStore );
const {
Expand Down Expand Up @@ -136,7 +135,7 @@ function Header( {
) }
<PreviewDropdown
forceIsAutosaveable={ forceIsDirty }
disabled={ isNestedEntity || isZoomedOutView }
disabled={ isNestedEntity }
/>
<PostPreviewButton
className="editor-header__post-preview-button"
Expand Down
127 changes: 94 additions & 33 deletions packages/editor/src/components/preview-dropdown/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
/**
* External dependencies
*/
import clsx from 'clsx';

/**
* WordPress dependencies
*/
Expand All @@ -11,10 +16,12 @@ import {
Icon,
} from '@wordpress/components';
import { __ } from '@wordpress/i18n';
import { desktop, mobile, tablet, external } from '@wordpress/icons';
import { mobile, tablet, external, chevronDownSmall } from '@wordpress/icons';
import { useSelect, useDispatch } from '@wordpress/data';
import { store as coreStore } from '@wordpress/core-data';
import { useEffect, useRef } from '@wordpress/element';
import { store as preferencesStore } from '@wordpress/preferences';
import { store as blockEditorStore } from '@wordpress/block-editor';

/**
* Internal dependencies
Expand All @@ -23,21 +30,50 @@ import { store as editorStore } from '../../store';
import PostPreviewButton from '../post-preview-button';

export default function PreviewDropdown( { forceIsAutosaveable, disabled } ) {
const { deviceType, homeUrl, isTemplate, isViewable, showIconLabels } =
useSelect( ( select ) => {
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;
Expand All @@ -48,6 +84,7 @@ export default function PreviewDropdown( { forceIsAutosaveable, disabled } ) {
};
const toggleProps = {
className: 'editor-preview-dropdown__toggle',
iconPosition: 'right',
size: 'compact',
showTooltip: ! showIconLabels,
disabled,
Expand All @@ -60,7 +97,6 @@ export default function PreviewDropdown( { forceIsAutosaveable, disabled } ) {
const deviceIcons = {
mobile,
tablet,
desktop,
};

/**
Expand All @@ -71,8 +107,13 @@ export default function PreviewDropdown( { forceIsAutosaveable, disabled } ) {
const choices = [
{
value: 'Desktop',
label: __( 'Desktop' ),
icon: desktop,
label: __( 'Zoom to 100%' ),
icon: <>{ __( '100%' ) }</>,
},
{
value: 'ZoomOut',
label: __( 'Zoom to 50%' ),
icon: <>{ __( '50%' ) }</>,
},
{
value: 'Tablet',
Expand All @@ -86,29 +127,49 @@ 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 );
};

const getText = () => {
if ( editorMode === 'zoom-out' ) {
return __( '50%' );
}

if ( deviceType === 'Desktop' ) {
return __( '100%' );
}

return <Icon icon={ deviceIcons[ deviceType.toLowerCase() ] } />;
};

return (
<DropdownMenu
className="editor-preview-dropdown"
className={ clsx(
'editor-preview-dropdown',
`editor-preview-dropdown--${ deviceType.toLowerCase() }`
) }
popoverProps={ popoverProps }
toggleProps={ toggleProps }
menuProps={ menuProps }
icon={ deviceIcons[ deviceType.toLowerCase() ] }
icon={ chevronDownSmall }
text={ getText() }
label={ __( 'View' ) }
disableOpenOnArrowDown={ disabled }
>
Expand All @@ -117,8 +178,8 @@ export default function PreviewDropdown( { forceIsAutosaveable, disabled } ) {
<MenuGroup>
<MenuItemsChoice
choices={ choices }
value={ selectedChoice.value }
onSelect={ setDeviceType }
value={ previewValue }
onSelect={ onSelect }
/>
</MenuGroup>
{ isTemplate && (
Expand Down
13 changes: 13 additions & 0 deletions packages/editor/src/components/preview-dropdown/style.scss
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
.editor-preview-dropdown .editor-preview-dropdown__toggle.has-icon.has-text {
padding-right: $grid-unit-05 * 0.5;
gap: 0;
}

.editor-preview-dropdown--mobile,
.editor-preview-dropdown--tablet {
.editor-preview-dropdown__toggle.has-icon.has-text {
gap: 0;
padding-left: $grid-unit-05;
}
}

.editor-preview-dropdown__button-external {
width: 100%;
display: flex;
Expand Down
14 changes: 8 additions & 6 deletions packages/editor/src/components/visual-editor/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ function VisualEditor( {
} ) {
const [ resizeObserver, sizes ] = useResizeObserver();
const isMobileViewport = useViewportMatch( 'small', '<' );
const isTabletViewport = useViewportMatch( 'medium', '<' );
const {
renderingMode,
postContentAttributes,
Expand Down Expand Up @@ -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 =
Expand Down
Loading