-
Notifications
You must be signed in to change notification settings - Fork 4.6k
Make zoom out vertical toolbar consistent #65627
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
Changes from all commits
598d612
ced9cbd
31f69eb
0d91f44
2bb5176
bb2b790
216f472
64b48d6
457db03
6c3aa91
605e660
cc9ec16
086fe16
1fb06f5
7589c5d
22286ac
ee585e4
97836d3
dfa04be
b95d7ef
9fadd33
0afb084
f5a632e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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, | ||
|
|
@@ -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; | ||
|
|
||
|
|
@@ -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 ) | ||
| ) { | ||
|
|
@@ -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 ), | ||
|
|
@@ -98,10 +156,14 @@ function BlockPopover( | |
| contextElement: selectedElement, | ||
| }; | ||
| }, [ | ||
| popoverDimensionsRecomputeCounter, | ||
| isZoomOut, | ||
| parentSectionElement, | ||
| selectedElement, | ||
| bottomClientId, | ||
| lastSelectedElement, | ||
| selectedElement, | ||
| popoverDimensionsRecomputeCounter, | ||
| isSectionSelected, | ||
| __unstableContentRef, | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't really understand the change here. Can you explain why the block popover component needs to be aware of zoom-out...
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The reason I'm confused is because for me the "BlockPopover" is just a component that gives you the "position" of the block. So I don't see how zoom-out is related. It's not about giving the position of the toolbar, it's about giving the position of the block. It just happens that toolbar is adjacent to the block (in most cases). I think if we need to adapt the position differently in zoom-out, we should either have clear props in this component to change the behavior (for instance a prop that clearly indicates how we want to change the behavior) or do this computation elsewhere.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I don't know what to say about that, since this does render a whole popover, it's not some utility called to get the position. I do get the concern though.
That is a good alternative sure. But at some point someone will have to "know" about zoom out. Let's wait on the faith of this toolbar and if it sticks around return to reflect in code the idea that toolbars "just happen" to be adjacent to blocks. This was intended as a bug fix and it does not introduce a big glaring problem IMO just some minor tech debt reflecting the issue with multiple toolbar types. Do you agree?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes :) |
||
| ] ); | ||
|
|
||
| if ( ! selectedElement || ( bottomClientId && ! lastSelectedElement ) ) { | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.