Skip to content

Commit

Permalink
Block popover: allow scrolling over (#19769)
Browse files Browse the repository at this point in the history
* Block popover: allow scrolling over

* Clean up

* Fix overlapping inserter popover

* Better comment
  • Loading branch information
ellatrix authored Jan 22, 2020
1 parent 1f3ea11 commit 59ed771
Show file tree
Hide file tree
Showing 7 changed files with 67 additions and 25 deletions.
3 changes: 3 additions & 0 deletions packages/base-styles/_z-index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,9 @@ $z-layers: (
// Above the block list, under the header.
".block-editor-block-list__block-popover": 29,

// Under the block popover (block toolbar).
".block-editor-block-list__insertion-point-popover": 28,

// Show snackbars above everything (similar to popovers)
".components-snackbar-list": 100000,

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ export default function InsertionPoint( {
anchorRef={ inserterElement }
position="top right left"
focusOnMount={ false }
className="block-editor-block-list__block-popover"
className="block-editor-block-list__insertion-point-popover"
__unstableSlotName="block-toolbar"
>
<div className="block-editor-block-list__insertion-point" style={ { width: inserterElement.offsetWidth } }>
Expand Down
13 changes: 13 additions & 0 deletions packages/block-editor/src/components/block-list/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -537,8 +537,21 @@
}
}

.block-editor-block-list__insertion-point-popover {
z-index: z-index(".block-editor-block-list__insertion-point-popover");
position: absolute;

.components-popover__content {
background: none;
border: none;
box-shadow: none;
overflow-y: visible;
}
}

.components-popover.block-editor-block-list__block-popover {
z-index: z-index(".block-editor-block-list__block-popover");
position: absolute;

.components-popover__content {
margin: 0 !important;
Expand Down
25 changes: 23 additions & 2 deletions packages/components/src/popover/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,8 @@ const Popover = ( {
if ( ! containerRef.current || ! contentRef.current ) {
return;
}
const anchor = computeAnchorRect(

let anchor = computeAnchorRect(
anchorRefFallback,
anchorRect,
getAnchorRect,
Expand All @@ -273,14 +274,34 @@ const Popover = ( {
contentRect.current = contentRef.current.getBoundingClientRect();
}

const { offsetParent, ownerDocument } = containerRef.current;
let relativeOffsetTop = 0;

// If there is a positioned ancestor element that is not the body,
// subtract the position from the anchor rect. If the position of
// the popover is fixed, the offset parent is null or the body
// element, in which case the position is relative to the viewport.
// See https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetParent
if ( offsetParent && offsetParent !== ownerDocument.body ) {
const offsetParentRect = offsetParent.getBoundingClientRect();

relativeOffsetTop = offsetParentRect.top;
anchor = new window.DOMRect(
anchor.left - offsetParentRect.left,
anchor.top - offsetParentRect.top,
anchor.width,
anchor.height
);
}

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

if ( typeof popoverTop === 'number' && typeof popoverLeft === 'number' ) {
if ( subpixels && __unstableAllowVerticalSubpixelPosition ) {
Expand Down
46 changes: 25 additions & 21 deletions packages/components/src/popover/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,18 +111,20 @@ export function computePopoverXAxisPosition( anchorRect, contentSize, xAxis, cor
/**
* Utility used to compute the popover position over the yAxis
*
* @param {Object} anchorRect Anchor Rect.
* @param {Object} contentSize Content Size.
* @param {string} yAxis Desired yAxis.
* @param {string} corner Desired corner.
* @param {boolean} sticky Whether or not to stick the popover to the
* scroll container edge when part of the anchor
* leaves view.
* @param {Element} anchorRef The anchor element.
* @param {Object} anchorRect Anchor Rect.
* @param {Object} contentSize Content Size.
* @param {string} yAxis Desired yAxis.
* @param {string} corner Desired corner.
* @param {boolean} sticky Whether or not to stick the popover to the
* scroll container edge when part of the
* anchor leaves view.
* @param {Element} anchorRef The anchor element.
* @param {Element} relativeOffsetTop If applicable, top offset of the relative
* positioned parent container.
*
* @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, relativeOffsetTop ) {
const { height } = contentSize;

if ( sticky ) {
Expand All @@ -146,7 +148,7 @@ export function computePopoverYAxisPosition( anchorRect, contentSize, yAxis, cor
if ( topRect.top - height <= scrollRect.top ) {
return {
yAxis,
popoverTop: Math.min( bottomRect.bottom, scrollRect.top + height ),
popoverTop: Math.min( bottomRect.bottom - relativeOffsetTop, scrollRect.top + height - relativeOffsetTop ),
};
}
}
Expand Down Expand Up @@ -212,23 +214,25 @@ export function computePopoverYAxisPosition( anchorRect, contentSize, yAxis, cor
}

/**
* Utility used to compute the popover position and the content max width/height for a popover
* given its anchor rect and its content size.
* Utility used to compute the popover position and the content max width/height
* for a popover given its anchor rect and its content size.
*
* @param {Object} anchorRect Anchor Rect.
* @param {Object} contentSize Content Size.
* @param {string} position Position.
* @param {boolean} sticky Whether or not to stick the popover to the
* scroll container edge when part of the anchor
* leaves view.
* @param {Element} anchorRef The anchor element.
* @param {Object} anchorRect Anchor Rect.
* @param {Object} contentSize Content Size.
* @param {string} position Position.
* @param {boolean} sticky Whether or not to stick the popover to the
* scroll container edge when part of the
* anchor leaves view.
* @param {Element} anchorRef The anchor element.
* @param {number} relativeOffsetTop If applicable, top offset of the relative
* positioned parent container.
*
* @return {Object} Popover position and constraints.
*/
export function computePopoverPosition( anchorRect, contentSize, position = 'top', sticky, anchorRef ) {
export function computePopoverPosition( anchorRect, contentSize, position = 'top', sticky, anchorRef, relativeOffsetTop ) {
const [ yAxis, xAxis = 'center', corner ] = position.split( ' ' );

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

return {
Expand Down
1 change: 0 additions & 1 deletion packages/edit-post/src/components/layout/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,6 @@ function Layout() {
content={
<>
<EditorNotices />
<Popover.Slot name="block-toolbar" />
{ ( mode === 'text' || ! isRichEditingEnabled ) && <TextEditor /> }
{ isRichEditingEnabled && mode === 'visual' && <VisualEditor /> }
<div className="edit-post-layout__metaboxes">
Expand Down
2 changes: 2 additions & 0 deletions packages/edit-post/src/components/visual-editor/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
__experimentalBlockSettingsMenuFirstItem,
__experimentalBlockSettingsMenuPluginsExtension,
} from '@wordpress/block-editor';
import { Popover } from '@wordpress/components';

/**
* Internal dependencies
Expand All @@ -28,6 +29,7 @@ function VisualEditor() {
<BlockSelectionClearer className="edit-post-visual-editor editor-styles-wrapper">
<VisualEditorGlobalKeyboardShortcuts />
<MultiSelectScrollIntoView />
<Popover.Slot name="block-toolbar" />
<Typewriter>
<CopyHandler>
<WritingFlow>
Expand Down

0 comments on commit 59ed771

Please sign in to comment.