Skip to content

Commit

Permalink
Have floating block toolbar remain in view when block is out of view
Browse files Browse the repository at this point in the history
- Add props to BlockTools and Popover to support expanded sticky
  area and sticky position off the bottom
- Add logic for sticking the popover as its anchorRect overflows the
  bottom of its boundary
- Remove now extraneous z-index rules and map entry
  • Loading branch information
stokesman committed Jun 7, 2021
1 parent 276e287 commit 02678d0
Show file tree
Hide file tree
Showing 8 changed files with 73 additions and 22 deletions.
3 changes: 0 additions & 3 deletions packages/base-styles/_z-index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -181,9 +181,6 @@ $z-layers: (

// Appear under the customizer heading UI, but over anything else.
".customize-widgets__topbar": 8,

// Appear over the topbar of both editor and customizer.
".customize-widgets__block-toolbar": 10,
);

@function z-index( $key ) {
Expand Down
5 changes: 4 additions & 1 deletion packages/block-editor/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,10 @@ _Parameters_
- _$0_ `Object`: Props.
- _$0.children_ `Object`: The block content and style container.
- _$0.\_\_unstableContentRef_ `Object`: Ref holding the content scroll container.
- _$0.\_\_experimentalStickyTop_ `Object`: Offset for the top position of toolbars.
- _$0.\_\_experimentalStickyBottom_ `number`: Bottom sticky position of floating toolbar.
- _$0.\_\_experimentalStickyTop_ `number`: Top sticky position of floating and top toolbar.
- _$0.\_\_experimentalStickyAreaBottom_ `number`: Offset of bottom side of sticky area.
- _$0.\_\_experimentalStickyAreaTop_ `number`: Offset of top side of sticky area.

<a name="BlockVerticalAlignmentControl" href="#BlockVerticalAlignmentControl">#</a> **BlockVerticalAlignmentControl**

Expand Down
12 changes: 12 additions & 0 deletions packages/block-editor/src/components/block-tools/block-popover.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,10 @@ function BlockPopover( {
capturingClientId,
__unstablePopoverSlot,
__unstableContentRef,
__experimentalStickyBottom,
__experimentalStickyTop,
__experimentalStickyAreaBottom,
__experimentalStickyAreaTop,
} ) {
const {
isNavigationMode,
Expand Down Expand Up @@ -194,7 +197,10 @@ function BlockPopover( {
// Observe movement for block animations (especially horizontal).
__unstableObserveElement={ node }
shouldAnchorIncludePadding
__experimentalStickyBottom={ __experimentalStickyBottom }
__experimentalStickyTop={ __experimentalStickyTop }
__experimentalStickyAreaBottom={ __experimentalStickyAreaBottom }
__experimentalStickyAreaTop={ __experimentalStickyAreaTop }
>
{ ( shouldShowContextualToolbar || isToolbarForced ) && (
<div
Expand Down Expand Up @@ -306,7 +312,10 @@ function wrapperSelector( select ) {
export default function WrappedBlockPopover( {
__unstablePopoverSlot,
__unstableContentRef,
__experimentalStickyBottom,
__experimentalStickyTop,
__experimentalStickyAreaBottom,
__experimentalStickyAreaTop,
} ) {
const selected = useSelect( wrapperSelector, [] );

Expand Down Expand Up @@ -336,7 +345,10 @@ export default function WrappedBlockPopover( {
capturingClientId={ capturingClientId }
__unstablePopoverSlot={ __unstablePopoverSlot }
__unstableContentRef={ __unstableContentRef }
__experimentalStickyBottom={ __experimentalStickyBottom }
__experimentalStickyTop={ __experimentalStickyTop }
__experimentalStickyAreaBottom={ __experimentalStickyAreaBottom }
__experimentalStickyAreaTop={ __experimentalStickyAreaTop }
/>
);
}
17 changes: 13 additions & 4 deletions packages/block-editor/src/components/block-tools/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,21 @@ import { usePopoverScroll } from './use-popover-scroll';
* insertion point and a slot for the inline rich text toolbar). Must be wrapped
* around the block content and editor styles wrapper or iframe.
*
* @param {Object} $0 Props.
* @param {Object} $0.children The block content and style container.
* @param {Object} $0.__unstableContentRef Ref holding the content scroll container.
* @param {Object} $0.__experimentalStickyTop Offset for the top position of toolbars.
* @param {Object} $0 Props.
* @param {Object} $0.children The block content and style container.
* @param {Object} $0.__unstableContentRef Ref holding the content scroll container.
* @param {number} $0.__experimentalStickyBottom Bottom sticky position of floating toolbar.
* @param {number} $0.__experimentalStickyTop Top sticky position of floating and top toolbar.
* @param {number} $0.__experimentalStickyAreaBottom Offset of bottom side of sticky area.
* @param {number} $0.__experimentalStickyAreaTop Offset of top side of sticky area.
*/
export default function BlockTools( {
children,
__unstableContentRef,
__experimentalStickyBottom,
__experimentalStickyTop,
__experimentalStickyAreaBottom: stickyAreaBottom,
__experimentalStickyAreaTop: stickyAreaTop,
} ) {
const isLargeViewport = useViewportMatch( 'medium' );
const hasFixedToolbar = useSelect(
Expand All @@ -47,7 +53,10 @@ export default function BlockTools( {
needed for navigation mode. */ }
<BlockPopover
__unstableContentRef={ __unstableContentRef }
__experimentalStickyBottom={ __experimentalStickyBottom }
__experimentalStickyTop={ __experimentalStickyTop }
__experimentalStickyAreaBottom={ stickyAreaBottom }
__experimentalStickyAreaTop={ stickyAreaTop }
/>
{ /* Used for the inline rich text toolbar. */ }
<Popover.Slot
Expand Down
14 changes: 11 additions & 3 deletions packages/components/src/popover/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,10 @@ const Popover = (
__unstableBoundaryParent,
__unstableForcePosition,
__unstableForceXAlignment,
__experimentalStickyBottom: stickyBottom = 0,
__experimentalStickyTop: stickyTop = 0,
__experimentalStickyAreaBottom: stickyAreaBottom = 0,
__experimentalStickyAreaTop: stickyAreaTop = 0,
/* eslint-enable no-unused-vars */
...contentProps
},
Expand Down Expand Up @@ -311,7 +314,7 @@ const Popover = (

const { offsetParent, ownerDocument } = containerRef.current;

let relativeOffsetTop = -stickyTop;
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
Expand All @@ -321,7 +324,7 @@ const Popover = (
if ( offsetParent && offsetParent !== ownerDocument.body ) {
const offsetParentRect = offsetParent.getBoundingClientRect();

relativeOffsetTop += offsetParentRect.top;
relativeOffsetTop = offsetParentRect.top;
anchor = new window.DOMRect(
anchor.left - offsetParentRect.left,
anchor.top - offsetParentRect.top,
Expand Down Expand Up @@ -357,7 +360,9 @@ const Popover = (
relativeOffsetTop,
boundaryElement,
__unstableForcePosition,
__unstableForceXAlignment
__unstableForceXAlignment,
{ top: stickyTop, bottom: stickyBottom },
{ top: stickyAreaTop, bottom: stickyAreaBottom }
);

if (
Expand Down Expand Up @@ -482,7 +487,10 @@ const Popover = (
position,
contentSize,
__unstableStickyBoundaryElement,
stickyBottom,
stickyTop,
stickyAreaBottom,
stickyAreaTop,
__unstableObserveElement,
__unstableBoundaryParent,
] );
Expand Down
39 changes: 30 additions & 9 deletions packages/components/src/popover/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -166,9 +166,15 @@ export function computePopoverXAxisPosition(
* switching between sticky and normal
* position.
* @param {Element} anchorRef The anchor element.
* @param {Element} relativeOffsetTop If applicable, top offset of the
* @param {number} relativeOffsetTop If applicable, top offset of the
* relative positioned parent container.
* @param {boolean} forcePosition Don't adjust position based on anchor.
* @param {Object} sticky Sticky positions per side.
* @param {number} sticky.top Top sticky position.
* @param {number} sticky.bottom Bottom sticky position.
* @param {Object} stickyArea Offsets relative to anchorRect.
* @param {number} stickyArea.top Offset from top.
* @param {number} stickyArea.bottom Offset from bottom.
*
* @return {Object} Popover xAxis position and constraints.
*/
Expand All @@ -180,18 +186,27 @@ export function computePopoverYAxisPosition(
stickyBoundaryElement,
anchorRef,
relativeOffsetTop,
forcePosition
forcePosition,
{ top, bottom },
{ top: start, bottom: end }
) {
const { height } = contentSize;

if ( stickyBoundaryElement ) {
const stickyRect = stickyBoundaryElement.getBoundingClientRect();
const stickyPosition = stickyRect.top + height - relativeOffsetTop;

if ( anchorRect.top <= stickyPosition ) {
top += stickyRect.top + height - relativeOffsetTop;
bottom = -bottom + stickyRect.bottom - relativeOffsetTop;
if ( anchorRect.top < top ) {
end += anchorRect.bottom;
return {
yAxis,
popoverTop: Math.min( end, top ),
};
} else if ( anchorRect.top > bottom ) {
start += anchorRect.top;
return {
yAxis,
popoverTop: Math.min( anchorRect.bottom, stickyPosition ),
popoverTop: Math.max( start, bottom ),
};
}
}
Expand Down Expand Up @@ -287,7 +302,9 @@ export function computePopoverYAxisPosition(
* relative positioned parent container.
* @param {Element} boundaryElement Boundary element.
* @param {boolean} forcePosition Don't adjust position based on anchor.
* @param {boolean} forceXAlignment Don't adjust alignment based on YAxis
* @param {boolean} forceXAlignment Don't adjust alignment based on YAxis.
* @param {Object} sticky Sticky positions per side.
* @param {Object} stickyBounds Boundary offsets relative to anchorRect.
*
* @return {Object} Popover position and constraints.
*/
Expand All @@ -300,7 +317,9 @@ export function computePopoverPosition(
relativeOffsetTop,
boundaryElement,
forcePosition,
forceXAlignment
forceXAlignment,
sticky,
stickyBounds
) {
const [ yAxis, xAxis = 'center', corner ] = position.split( ' ' );

Expand All @@ -312,7 +331,9 @@ export function computePopoverPosition(
stickyBoundaryElement,
anchorRef,
relativeOffsetTop,
forcePosition
forcePosition,
sticky,
stickyBounds
);
const xAxisPosition = computePopoverXAxisPosition(
anchorRect,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,9 @@ export default function SidebarBlockEditor( {

<BlockTools
__experimentalStickyTop={ headerToolbarHeight + scrollback }
__experimentalStickyAreaBottom={ Infinity }
__experimentalStickyBottom={ 0 }
__experimentalStickyAreaTop={ -Infinity }
>
<BlockSelectionClearer>
<WritingFlow>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,8 @@

// Scroll sideways.
overflow-y: auto;
z-index: z-index(".customize-widgets__block-toolbar");
}

.customize-control-sidebar_block_editor .block-editor-block-list__block-popover {
position: fixed;
z-index: z-index(".customize-widgets__block-toolbar");
}

0 comments on commit 02678d0

Please sign in to comment.