Skip to content

Commit

Permalink
Popover: different boundary element
Browse files Browse the repository at this point in the history
  • Loading branch information
ellatrix committed Dec 24, 2019
1 parent fb836a4 commit ffff29d
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 11 deletions.
1 change: 1 addition & 0 deletions packages/block-editor/src/components/block-list/block.js
Original file line number Diff line number Diff line change
Expand Up @@ -573,6 +573,7 @@ function BlockListBlock( {
// Allow subpixel positioning for the block movement animation.
__unstableAllowVerticalSubpixelPosition={ moverDirection !== 'horizontal' && wrapper.current }
__unstableAllowHorizontalSubpixelPosition={ moverDirection === 'horizontal' && wrapper.current }
__unstableBoundaryParent
>
{ ! hasAncestorCapturingToolbars && ( shouldShowContextualToolbar || isForcingContextualToolbar.current ) && renderBlockContextualToolbar() }
{ hasAncestorCapturingToolbars && ( shouldShowContextualToolbar || isForcingContextualToolbar.current ) && (
Expand Down
12 changes: 11 additions & 1 deletion 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 @@ -280,7 +281,15 @@ const Popover = ( {
yAxis,
contentHeight,
contentWidth,
} = computePopoverPosition( anchor, contentRect.current, position, __unstableSticky, anchorRef );
} = computePopoverPosition(
anchor,
contentRect.current,
position,
__unstableSticky,
anchorRef,
// To do: get slot parent instead.
__unstableBoundaryParent ? document.querySelector( '.edit-post-editor-regions__content' ) : undefined
);

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

useFocusContentOnMount( focusOnMount, contentRef );
Expand Down
32 changes: 22 additions & 10 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 = document.body ) {
const { width } = contentSize;
const isRTL = document.documentElement.dir === 'rtl';

Expand All @@ -45,7 +46,7 @@ export function computePopoverXAxisPosition( anchorRect, contentSize, xAxis, cor
popoverLeft: anchorMidPoint,
contentWidth: (
( anchorMidPoint - ( width / 2 ) > 0 ? ( width / 2 ) : anchorMidPoint ) +
( anchorMidPoint + ( width / 2 ) > window.innerWidth ? window.innerWidth - anchorMidPoint : ( width / 2 ) )
( anchorMidPoint + ( width / 2 ) > boundaryElement.clientWidth ? boundaryElement.clientWidth - anchorMidPoint : ( width / 2 ) )
),
};

Expand All @@ -71,7 +72,7 @@ export function computePopoverXAxisPosition( anchorRect, contentSize, xAxis, cor
};
const rightAlignment = {
popoverLeft: rightAlignmentX,
contentWidth: rightAlignmentX + width > window.innerWidth ? window.innerWidth - rightAlignmentX : width,
contentWidth: rightAlignmentX + width > boundaryElement.clientWidth ? boundaryElement.clientWidth - rightAlignmentX : width,
};

// Choosing the x axis
Expand Down Expand Up @@ -101,9 +102,11 @@ export function computePopoverXAxisPosition( anchorRect, contentSize, xAxis, cor
popoverLeft = rightAlignment.popoverLeft;
}

const boundaryRect = boundaryElement.getBoundingClientRect();

return {
xAxis: chosenXAxis,
popoverLeft,
popoverLeft: Math.min( popoverLeft, boundaryRect.right - width ),
contentWidth,
};
}
Expand All @@ -119,10 +122,11 @@ export function computePopoverXAxisPosition( anchorRect, contentSize, xAxis, cor
* scroll container edge when part of the anchor
* leaves view.
* @param {Element} anchorRef The anchor element.
* @param {Element} boundaryElement
*
* @return {Object} Popover xAxis position and constraints.
*/
export function computePopoverYAxisPosition( anchorRect, contentSize, yAxis, corner, sticky, anchorRef ) {
export function computePopoverYAxisPosition( anchorRect, contentSize, yAxis, corner, sticky, anchorRef, boundaryElement = document.body ) {
const { height } = contentSize;

if ( sticky ) {
Expand Down Expand Up @@ -164,7 +168,7 @@ export function computePopoverYAxisPosition( anchorRect, contentSize, yAxis, cor
popoverTop: anchorMidPoint,
contentHeight: (
( anchorMidPoint - ( height / 2 ) > 0 ? ( height / 2 ) : anchorMidPoint ) +
( anchorMidPoint + ( height / 2 ) > window.innerHeight ? window.innerHeight - anchorMidPoint : ( height / 2 ) )
( anchorMidPoint + ( height / 2 ) > boundaryElement.clientHeight ? boundaryElement.clientHeight - anchorMidPoint : ( height / 2 ) )
),
};

Expand All @@ -174,7 +178,7 @@ export function computePopoverYAxisPosition( anchorRect, contentSize, yAxis, cor
};
const bottomAlignment = {
popoverTop: anchorRect.bottom,
contentHeight: anchorRect.bottom + HEIGHT_OFFSET + height > window.innerHeight ? window.innerHeight - HEIGHT_OFFSET - anchorRect.bottom : height,
contentHeight: anchorRect.bottom + HEIGHT_OFFSET + height > boundaryElement.clientHeight ? boundaryElement.clientHeight - HEIGHT_OFFSET - anchorRect.bottom : height,
};

// Choosing the y axis
Expand Down Expand Up @@ -222,14 +226,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 yAxisPosition = computePopoverYAxisPosition( anchorRect, contentSize, yAxis, corner, sticky, anchorRef, boundaryElement );
const xAxisPosition = computePopoverXAxisPosition( anchorRect, contentSize, xAxis, corner, sticky, yAxisPosition.yAxis, boundaryElement );

return {
...xAxisPosition,
Expand Down

0 comments on commit ffff29d

Please sign in to comment.