Skip to content

Commit

Permalink
Make zoom out vertical toolbar consistent (#65627)
Browse files Browse the repository at this point in the history
* enable vertical toolbar for non full width elements, anchor based on parent

* Update packages/block-editor/src/components/block-popover/index.js

Co-authored-by: Dave Smith <[email protected]>

* Update packages/block-editor/src/components/block-popover/index.js

Co-authored-by: Dave Smith <[email protected]>

* make zoom out check a dependency of the memoization, improve code readability

* comment typos

* subscribe to state instead of calculating zoom out view state when calculating the anchor

* get the section wrapper for anchoring instead of the parent

* use a selector instead of computing on the fly the parent section

* check if the block element exists yet before computing the anchor

* check if the block element exists yet before computing the anchor

* differentiate between section toolbar and block toolbar for correct positioning when both are visible

* address some nits

* make the select in anchor setting rerun when block selection changes

* fix bug with anchor rect when zoom out not engaged

* fix typo

* Use root container element in post editor as popover anchor

* improve comment

* improve comment to max improvement possible

Co-authored-by: Dave Smith <[email protected]>

* mega nit commit

Co-authored-by: Dave Smith <[email protected]>

* Fix bug with Posts with no full width blocks

* give up on section root, always seek canvas element to position vertical toolbar, also fix typo

* introduce the concept of canvas via a 1st variable

* Use `__unstableContentRef` for zoomed out toolbar positioning instead of dom classname

---------
Co-authored-by: draganescu <[email protected]>
Co-authored-by: getdave <[email protected]>
Co-authored-by: talldan <[email protected]>
Co-authored-by: ciampo <[email protected]>
Co-authored-by: jsnajdr <[email protected]>
Co-authored-by: MaggieCabrera <[email protected]>
Co-authored-by: richtabor <[email protected]>
Co-authored-by: stokesman <[email protected]>
Co-authored-by: andrewserong <[email protected]>
  • Loading branch information
11 people committed Oct 15, 2024
1 parent 9bba721 commit a9af4b9
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 6 deletions.
66 changes: 64 additions & 2 deletions packages/block-editor/src/components/block-popover/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import clsx from 'clsx';
*/
import { useMergeRefs } from '@wordpress/compose';
import { Popover } from '@wordpress/components';
import { useSelect } from '@wordpress/data';
import {
forwardRef,
useMemo,
Expand All @@ -21,6 +22,8 @@ import {
import { useBlockElement } from '../block-list/use-block-props/use-block-refs';
import usePopoverScroll from './use-popover-scroll';
import { rectUnion, getVisibleElementBounds } from '../../utils/dom';
import { store as blockEditorStore } from '../../store';
import { unlock } from '../../lock-unlock';

const MAX_POPOVER_RECOMPUTE_COUNTER = Number.MAX_SAFE_INTEGER;

Expand Down Expand Up @@ -74,12 +77,38 @@ function BlockPopover(
};
}, [ selectedElement ] );

const { isZoomOut, parentSectionBlock, isSectionSelected } = useSelect(
( select ) => {
const {
isZoomOut: isZoomOutSelector,
getSectionRootClientId,
getParentSectionBlock,
getBlockOrder,
} = unlock( select( blockEditorStore ) );

return {
isZoomOut: isZoomOutSelector(),
parentSectionBlock:
getParentSectionBlock( clientId ) ?? clientId,
isSectionSelected: getBlockOrder(
getSectionRootClientId()
).includes( clientId ),
};
},
[ clientId ]
);

// This element is used to position the zoom out view vertical toolbar
// correctly, relative to the selected section.
const parentSectionElement = useBlockElement( parentSectionBlock );

const popoverAnchor = useMemo( () => {
if (
// popoverDimensionsRecomputeCounter is by definition always equal or greater
// than 0. This check is only there to satisfy the correctness of the
// exhaustive-deps rule for the `useMemo` hook.
popoverDimensionsRecomputeCounter < 0 ||
( isZoomOut && ! parentSectionElement ) ||
! selectedElement ||
( bottomClientId && ! lastSelectedElement )
) {
Expand All @@ -88,6 +117,35 @@ function BlockPopover(

return {
getBoundingClientRect() {
// The zoom out view has a vertical block toolbar that should always
// be on the edge of the canvas, aligned to the top of the currently
// selected section. This condition changes the anchor of the toolbar
// to the section instead of the block to handle blocks that are
// not full width and nested blocks to keep section height.
if ( isZoomOut && isSectionSelected ) {
// Compute the height based on the parent section of the
// selected block, because the selected block may be
// shorter than the section.
const canvasElementRect = getVisibleElementBounds(
__unstableContentRef.current
);
const parentSectionElementRect =
getVisibleElementBounds( parentSectionElement );
const anchorHeight =
parentSectionElementRect.bottom -
parentSectionElementRect.top;

// Always use the width of the section root element to make sure
// the toolbar is always on the edge of the canvas.
const anchorWidth = canvasElementRect.width;
return new window.DOMRectReadOnly(
canvasElementRect.left,
parentSectionElementRect.top,
anchorWidth,
anchorHeight
);
}

return lastSelectedElement
? rectUnion(
getVisibleElementBounds( selectedElement ),
Expand All @@ -98,10 +156,14 @@ function BlockPopover(
contextElement: selectedElement,
};
}, [
popoverDimensionsRecomputeCounter,
isZoomOut,
parentSectionElement,
selectedElement,
bottomClientId,
lastSelectedElement,
selectedElement,
popoverDimensionsRecomputeCounter,
isSectionSelected,
__unstableContentRef,
] );

if ( ! selectedElement || ( bottomClientId && ! lastSelectedElement ) ) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { isUnmodifiedDefaultBlock } from '@wordpress/blocks';
* Internal dependencies
*/
import { store as blockEditorStore } from '../../store';
import { unlock } from '../../lock-unlock';

/**
* Source of truth for which block tools are showing in the block editor.
Expand All @@ -25,7 +26,9 @@ export function useShowBlockTools() {
hasMultiSelection,
__unstableGetEditorMode,
isTyping,
} = select( blockEditorStore );
getBlockOrder,
getSectionRootClientId,
} = unlock( select( blockEditorStore ) );

const clientId =
getSelectedBlockClientId() || getFirstMultiSelectedBlockClientId();
Expand All @@ -48,11 +51,14 @@ export function useShowBlockTools() {
editorMode === 'navigation';

const isZoomOut = editorMode === 'zoom-out';
const isSectionSelected = getBlockOrder(
getSectionRootClientId()
).includes( clientId );
const _showZoomOutToolbar =
clientId &&
isZoomOut &&
block?.attributes?.align === 'full' &&
! _showEmptyBlockSideInserter &&
! maybeShowBreadcrumb;
isSectionSelected;
const _showBlockToolbarPopover =
! _showZoomOutToolbar &&
! getSettings().hasFixedToolbar &&
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import clsx from 'clsx';
/**
* Internal dependencies
*/
import BlockPopover from '../block-popover';
import { PrivateBlockPopover as BlockPopover } from '../block-popover';
import useBlockToolbarPopoverProps from './use-block-toolbar-popover-props';
import useSelectedBlockToolProps from './use-selected-block-tool-props';
import ZoomOutToolbar from './zoom-out-toolbar';
Expand All @@ -29,6 +29,7 @@ export default function ZoomOutPopover( { clientId, __unstableContentRef } ) {

return (
<BlockPopover
__unstableContentRef={ __unstableContentRef }
clientId={ capturingClientId || clientId }
bottomClientId={ lastClientId }
className={ clsx( 'zoom-out-toolbar-popover', {
Expand Down

0 comments on commit a9af4b9

Please sign in to comment.