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

Decouple "zoom/scaling the canvas" from zoom out mode (without mode rename) #65482

Merged
merged 11 commits into from
Sep 20, 2024
4 changes: 2 additions & 2 deletions packages/block-editor/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What are we exiting, the view or the selection mode? I guess view, so it doesn't matter the mode, only if isZoomOut. Right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is one where I didn't know the answer. I kept the current behaviour on trunk which is that double click is connected to the mode.

As you say, let's merge and iterate 👍


if ( ! composeMode ) {
return;
}

Expand All @@ -39,6 +42,7 @@ export function useZoomOutModeExit( { editorMode } ) {
__experimentalSetIsInserterOpened( false );
}
__unstableSetEditorMode( 'edit' );
resetZoomLevel();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -144,6 +146,7 @@ export default function ZoomOutToolbar( { clientId, __unstableContentRef } ) {
setIsInserterOpened( false );
}
__unstableSetEditorMode( 'edit' );
resetZoomLevel();
__unstableContentRef.current?.focus();
} }
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 = (
<SVG
Expand All @@ -35,7 +36,9 @@ function ToolSelector( props, ref ) {
( select ) => select( blockEditorStore ).__unstableGetEditorMode(),
[]
);
const { __unstableSetEditorMode } = useDispatch( blockEditorStore );
const { __unstableSetEditorMode } = unlock(
useDispatch( blockEditorStore )
);

return (
<Dropdown
Expand Down
48 changes: 21 additions & 27 deletions packages/block-editor/src/hooks/use-zoom-out.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,46 +8,40 @@ import { useEffect, useRef } from '@wordpress/element';
* Internal dependencies
*/
import { store as blockEditorStore } from '../store';
import { unlock } from '../lock-unlock';

/**
* 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.
Comment on lines -13 to +14
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This hook used to set the mode to zoom-out. Now it just sets the zoom level. Is that what we want? It's only used in a single location in Core.

Personally I think it should be deprecated as an API.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't we need the hook for all the effect management it does?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess it could be useful for "zooming the canvas". But note how it's usage has already changed from managing "modes" to managing "scale". It's just a premature API in my opinion.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file likely needs to be reverted to also handle the mode. It's being used to set the patterns tab to zoom out mode. By removing the mode handling, we're not setting the mode along with it, meaning you zoom out but aren't really in zoom out mode. This is causing some really odd states.

  • Open Inserter
  • Open Patterns Tab
  • Select something on canvas
  • Bug one: (it will be in the normal editing mode, not zoom out)
  • Unset Zoom Out via header button
  • Click Zoom Out button in header again
  • Enters Zoom out for real
  • Close Inserter
  • Bug 2: In zoom out mode while on full canvas
Screen.Recording.2024-10-09.at.3.57.44.PM.mov

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Started a PR here to address it. Please take it over because I'm unsure what all the purpose was of your refactorings afterwards: #65999

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think I understand why we needed this refactor at the moment. I agree that if we ever allow zooming to be separate from the mode or allow a slider to adjust zoom out, this would be necessary. But at the moment I'm not sure what we gain from this. Did it fix any specific bugs? I'm not trying to push back on the decision or be argumentative here -- I'm trying to understand what it gets us now vs a future potential.

Copy link
Contributor

@draganescu draganescu Oct 10, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't this fix the fact that we wanted global styles preview to only scale and keep the normal mode?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't know that was a requirement -- that's helpful info for sure!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Screen.Recording.2024-10-10.at.9.11.53.AM.mov

Is this what we want to happen on the styles tab though? I would assume not? It seems like it shouldn't have any editing mode attached to it? And if there is one, then zoom out would be more appropriate anyways?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that if we ever allow zooming to be separate from the mode or allow a slider to adjust zoom out,

Unfortunately in Gutenberg "next" (i.e. trunk) thats precisely what is being aimed for. So it felt correct to decouple the hook also.

This was my concern about having a "fork" of the Zoom Out experience in 6.7 vs Gutenberg Plugin.

I totally get where you're coming from @jeryj.

Questions:

  • is the hook a public API
  • when was the hook introduced (which release)
  • should the refactor be a "regression"?
  • if so should we revert it entirely

*
* @param {boolean} zoomOut If we should enter into zoomOut mode or not
* @param {boolean} zoomOut If we should zoom out or not.
*/
export function useZoomOut( zoomOut = true ) {
const { __unstableSetEditorMode } = useDispatch( blockEditorStore );
const { __unstableGetEditorMode } = useSelect( blockEditorStore );
const { setZoomLevel } = unlock( useDispatch( blockEditorStore ) );
const { isZoomOut } = unlock( useSelect( blockEditorStore ) );

const originalEditingModeRef = useRef( null );
const mode = __unstableGetEditorMode();
const originalIsZoomOutRef = useRef( null );

useEffect( () => {
// 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 ] );
}
23 changes: 23 additions & 0 deletions packages/block-editor/src/store/private-actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -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',
};
}
20 changes: 20 additions & 0 deletions packages/block-editor/src/store/private-selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Comment on lines +570 to +582
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's make the nomenclature consistent. Is it "zoom-out" or "zoom-level"? type and naming need to be consistent.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is all right, zoom out is any zoom level less than 1.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

20 changes: 20 additions & 0 deletions packages/block-editor/src/store/reducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -2118,6 +2137,7 @@ const combinedReducers = combineReducers( {
openedBlockSettingsMenu,
registeredInserterMediaCategories,
hoveredBlockClientId,
zoomLevel,
} );

function withAutomaticChangeReset( reducer ) {
Expand Down
10 changes: 6 additions & 4 deletions packages/editor/src/components/editor-interface/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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' ),
Expand Down Expand Up @@ -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(),
Expand All @@ -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' );
Expand Down Expand Up @@ -206,7 +208,7 @@ export default function EditorInterface( {
isLargeViewport &&
showBlockBreadcrumbs &&
isRichEditingEnabled &&
blockEditorMode !== 'zoom-out' &&
! isZoomOut &&
mode === 'visual' && (
<BlockBreadcrumb rootLabelText={ documentLabel } />
)
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 @@ -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(),
};
}, [] );

Expand Down Expand Up @@ -336,7 +338,7 @@ function VisualEditor( {
] );

const zoomOutProps =
isZoomOutMode && ! isTabletViewport
isZoomedOut && ! isTabletViewport
? {
scale: 'default',
frameSize: '48px',
Expand All @@ -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 );

Expand Down
23 changes: 17 additions & 6 deletions packages/editor/src/components/zoom-out-toggle/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,35 @@ 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 (
<Button
onClick={ handleZoomOut }
icon={ zoomOutIcon }
label={ __( 'Toggle Zoom Out' ) }
isPressed={ isZoomOutMode }
isPressed={ isZoomOut }
size="compact"
/>
);
Expand Down
Loading