Skip to content

Commit

Permalink
Block Popover: editor canvas as boundary (#19322)
Browse files Browse the repository at this point in the history
  • Loading branch information
ellatrix authored and Joen Asmussen committed Jan 14, 2020
1 parent 3abe71f commit 0449a2b
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -124,10 +124,14 @@ function BlockPopover( {
className="block-editor-block-list__block-popover"
__unstableSticky={ showEmptyBlockSideInserter ? false : popoverIsSticky }
__unstableSlotName="block-toolbar"
__unstableBoundaryParent
// Allow subpixel positioning for the block movement animation.
__unstableAllowVerticalSubpixelPosition={ moverDirection !== 'horizontal' && node }
__unstableAllowHorizontalSubpixelPosition={ moverDirection === 'horizontal' && node }
onBlur={ () => setIsToolbarForced( false ) }
// Popover calculates the width once. Trigger a reset by remounting
// the component.
key={ shouldShowContextualToolbar }
>
{ ( shouldShowContextualToolbar || isToolbarForced ) && (
<div
Expand Down
19 changes: 17 additions & 2 deletions packages/components/src/popover/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,7 @@ const Popover = ( {
__unstableSlotName = SLOT_NAME,
__unstableAllowVerticalSubpixelPosition,
__unstableAllowHorizontalSubpixelPosition,
__unstableBoundaryParent,
/* eslint-enable no-unused-vars */
...contentProps
} ) => {
Expand Down Expand Up @@ -273,14 +274,27 @@ const Popover = ( {
contentRect.current = contentRef.current.getBoundingClientRect();
}

let boundaryElement;

if ( __unstableBoundaryParent ) {
boundaryElement = containerRef.current.closest( '.popover-slot' ).parentNode;
}

const {
popoverTop,
popoverLeft,
xAxis,
yAxis,
contentHeight,
contentWidth,
} = computePopoverPosition( anchor, contentRect.current, position, __unstableSticky, anchorRef );
} = computePopoverPosition(
anchor,
contentRect.current,
position,
__unstableSticky,
anchorRef,
boundaryElement
);

if ( typeof popoverTop === 'number' && typeof popoverLeft === 'number' ) {
if ( subpixels && __unstableAllowVerticalSubpixelPosition ) {
Expand Down Expand Up @@ -374,6 +388,7 @@ const Popover = ( {
__unstableSticky,
__unstableAllowVerticalSubpixelPosition,
__unstableAllowHorizontalSubpixelPosition,
__unstableBoundaryParent,
] );

useFocusContentOnMount( focusOnMount, contentRef );
Expand Down Expand Up @@ -511,6 +526,6 @@ const Popover = ( {
const PopoverContainer = Popover;

PopoverContainer.Slot = ( { name = SLOT_NAME } ) =>
<Slot bubblesVirtually name={ name } />;
<Slot bubblesVirtually name={ name } className="popover-slot" />;

export default PopoverContainer;
20 changes: 17 additions & 3 deletions packages/components/src/popover/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,11 @@ const HEIGHT_OFFSET = 10; // used by the arrow and a bit of empty space
* scroll container edge when part of the anchor
* leaves view.
* @param {string} chosenYAxis yAxis to be used.
* @param {Element} boundaryElement
*
* @return {Object} Popover xAxis position and constraints.
*/
export function computePopoverXAxisPosition( anchorRect, contentSize, xAxis, corner, sticky, chosenYAxis ) {
export function computePopoverXAxisPosition( anchorRect, contentSize, xAxis, corner, sticky, chosenYAxis, boundaryElement ) {
const { width } = contentSize;
const isRTL = document.documentElement.dir === 'rtl';

Expand Down Expand Up @@ -101,6 +102,11 @@ export function computePopoverXAxisPosition( anchorRect, contentSize, xAxis, cor
popoverLeft = rightAlignment.popoverLeft;
}

if ( boundaryElement ) {
const boundaryRect = boundaryElement.getBoundingClientRect();
popoverLeft = Math.min( popoverLeft, boundaryRect.right - width );
}

return {
xAxis: chosenXAxis,
popoverLeft,
Expand Down Expand Up @@ -222,14 +228,22 @@ export function computePopoverYAxisPosition( anchorRect, contentSize, yAxis, cor
* scroll container edge when part of the anchor
* leaves view.
* @param {Element} anchorRef The anchor element.
* @param {Element} boundaryElement
*
* @return {Object} Popover position and constraints.
*/
export function computePopoverPosition( anchorRect, contentSize, position = 'top', sticky, anchorRef ) {
export function computePopoverPosition(
anchorRect,
contentSize,
position = 'top',
sticky,
anchorRef,
boundaryElement
) {
const [ yAxis, xAxis = 'center', corner ] = position.split( ' ' );

const yAxisPosition = computePopoverYAxisPosition( anchorRect, contentSize, yAxis, corner, sticky, anchorRef );
const xAxisPosition = computePopoverXAxisPosition( anchorRect, contentSize, xAxis, corner, sticky, yAxisPosition.yAxis );
const xAxisPosition = computePopoverXAxisPosition( anchorRect, contentSize, xAxis, corner, sticky, yAxisPosition.yAxis, boundaryElement );

return {
...xAxisPosition,
Expand Down

0 comments on commit 0449a2b

Please sign in to comment.