Skip to content

Commit

Permalink
Have Post Editor’s notices obstruct the block toolbars
Browse files Browse the repository at this point in the history
- Add props for sticky top of block toolbars and popovers
- Add onResize prop to EditorNotices
- Use height of notices as sticky top for block toolbars
- Restore styles for sticky notices
- Set z-index of notices to higher than block toolbars
  • Loading branch information
stokesman committed Jun 2, 2021
1 parent 0940cec commit 296530e
Show file tree
Hide file tree
Showing 11 changed files with 82 additions and 27 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 @@ -114,6 +114,9 @@ $z-layers: (
// Show the FSE template previews above the editor and any open block toolbars
".edit-site-navigation-panel__preview": 32,

// Show notices above block toolbars
".components-notice-list": 32,

// Above the block list and the header.
".block-editor-block-list__block-popover": 31,

Expand Down
1 change: 1 addition & 0 deletions packages/block-editor/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,7 @@ _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.

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,13 @@ import NavigableToolbar from '../navigable-toolbar';
import BlockToolbar from '../block-toolbar';
import { store as blockEditorStore } from '../../store';

function BlockContextualToolbar( { focusOnMount, isFixed, ...props } ) {
function BlockContextualToolbar( {
focusOnMount,
isFixed,
__experimentalStickyTop,
style = {},
...props
} ) {
const { blockType, hasParents, showParentSelector } = useSelect(
( select ) => {
const {
Expand Down Expand Up @@ -59,12 +65,17 @@ function BlockContextualToolbar( { focusOnMount, isFixed, ...props } ) {
'is-fixed': isFixed,
} );

if ( __experimentalStickyTop ) {
style.top = __experimentalStickyTop;
}

return (
<NavigableToolbar
focusOnMount={ focusOnMount }
className={ classes }
/* translators: accessibility text for the block toolbar */
aria-label={ __( 'Block tools' ) }
style={ style }
{ ...props }
>
<BlockToolbar hideDragHandle={ isFixed } />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ function BlockPopover( {
capturingClientId,
__unstablePopoverSlot,
__unstableContentRef,
__experimentalStickyTop,
} ) {
const {
isNavigationMode,
Expand Down Expand Up @@ -193,6 +194,7 @@ function BlockPopover( {
// Observe movement for block animations (especially horizontal).
__unstableObserveElement={ node }
shouldAnchorIncludePadding
__experimentalStickyTop={ __experimentalStickyTop }
>
{ ( shouldShowContextualToolbar || isToolbarForced ) && (
<div
Expand Down Expand Up @@ -304,6 +306,7 @@ function wrapperSelector( select ) {
export default function WrappedBlockPopover( {
__unstablePopoverSlot,
__unstableContentRef,
__experimentalStickyTop,
} ) {
const selected = useSelect( wrapperSelector, [] );

Expand Down Expand Up @@ -333,6 +336,7 @@ export default function WrappedBlockPopover( {
capturingClientId={ capturingClientId }
__unstablePopoverSlot={ __unstablePopoverSlot }
__unstableContentRef={ __unstableContentRef }
__experimentalStickyTop={ __experimentalStickyTop }
/>
);
}
23 changes: 17 additions & 6 deletions packages/block-editor/src/components/block-tools/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,16 @@ 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 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.
*/
export default function BlockTools( { children, __unstableContentRef } ) {
export default function BlockTools( {
children,
__unstableContentRef,
__experimentalStickyTop,
} ) {
const isLargeViewport = useViewportMatch( 'medium' );
const hasFixedToolbar = useSelect(
( select ) => select( blockEditorStore ).getSettings().hasFixedToolbar,
Expand All @@ -33,11 +38,17 @@ export default function BlockTools( { children, __unstableContentRef } ) {
return (
<InsertionPoint __unstableContentRef={ __unstableContentRef }>
{ ( hasFixedToolbar || ! isLargeViewport ) && (
<BlockContextualToolbar isFixed />
<BlockContextualToolbar
isFixed
__experimentalStickyTop={ __experimentalStickyTop }
/>
) }
{ /* Even if the toolbar is fixed, the block popover is still
needed for navigation mode. */ }
<BlockPopover __unstableContentRef={ __unstableContentRef } />
<BlockPopover
__unstableContentRef={ __unstableContentRef }
__experimentalStickyTop={ __experimentalStickyTop }
/>
{ /* Used for the inline rich text toolbar. */ }
<Popover.Slot
name="block-toolbar"
Expand Down
1 change: 1 addition & 0 deletions packages/components/src/notice/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@
// The notice should never be wider than the viewport, or the close button might be hidden. Especially relevant at high zoom levels. Related to https://core.trac.wordpress.org/ticket/47603#ticket.
max-width: 100vw;
box-sizing: border-box;
z-index: z-index(".components-notice-list");

.components-notice__content {
margin-top: $grid-unit-15;
Expand Down
6 changes: 4 additions & 2 deletions packages/components/src/popover/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,7 @@ const Popover = (
__unstableBoundaryParent,
__unstableForcePosition,
__unstableForceXAlignment,
__experimentalStickyTop: stickyTop = 0,
/* eslint-enable no-unused-vars */
...contentProps
},
Expand Down Expand Up @@ -310,7 +311,7 @@ const Popover = (

const { offsetParent, ownerDocument } = containerRef.current;

let relativeOffsetTop = 0;
let relativeOffsetTop = -stickyTop;

// 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 @@ -320,7 +321,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 @@ -481,6 +482,7 @@ const Popover = (
position,
contentSize,
__unstableStickyBoundaryElement,
stickyTop,
__unstableObserveElement,
__unstableBoundaryParent,
] );
Expand Down
10 changes: 8 additions & 2 deletions packages/edit-post/src/components/layout/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,9 @@ function Layout( { styles } ) {
return null;
};

const [ contentStickyTop, setContentStickyTop ] = useState( 0 );
const onNoticesResize = ( { height } ) => setContentStickyTop( height );

return (
<>
<FullscreenMode isActive={ isFullscreenActive } />
Expand Down Expand Up @@ -222,12 +225,15 @@ function Layout( { styles } ) {
}
content={
<>
<EditorNotices />
<EditorNotices onResize={ onNoticesResize } />
{ ( mode === 'text' || ! isRichEditingEnabled ) && (
<TextEditor />
) }
{ isRichEditingEnabled && mode === 'visual' && (
<VisualEditor styles={ styles } />
<VisualEditor
styles={ styles }
__experimentalStickyTop={ contentStickyTop }
/>
) }
{ ! isTemplateMode && (
<div className="edit-post-layout__metaboxes">
Expand Down
7 changes: 5 additions & 2 deletions packages/edit-post/src/components/visual-editor/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ function MaybeIframe( {
);
}

export default function VisualEditor( { styles } ) {
export default function VisualEditor( { styles, __experimentalStickyTop } ) {
const {
deviceType,
isTemplateMode,
Expand Down Expand Up @@ -192,7 +192,10 @@ export default function VisualEditor( { styles } ) {
} ) }
>
<VisualEditorGlobalKeyboardShortcuts />
<BlockTools __unstableContentRef={ ref }>
<BlockTools
__experimentalStickyTop={ __experimentalStickyTop }
__unstableContentRef={ ref }
>
<motion.div
className="edit-post-visual-editor__content-area"
animate={ {
Expand Down
27 changes: 15 additions & 12 deletions packages/editor/src/components/editor-notices/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,27 @@ import { filter } from 'lodash';
* WordPress dependencies
*/
import { NoticeList, SnackbarList } from '@wordpress/components';
import { withSelect, withDispatch } from '@wordpress/data';
import { compose } from '@wordpress/compose';
import { useResizeObserver } from '@wordpress/compose';
import { useSelect, useDispatch } from '@wordpress/data';
import { useEffect } from '@wordpress/element';
import { store as noticesStore } from '@wordpress/notices';

/**
* Internal dependencies
*/
import TemplateValidationNotice from '../template-validation-notice';

export function EditorNotices( { notices, onRemove } ) {
export default function EditorNotices( { onResize } ) {
const notices = useSelect( ( select ) => {
return select( noticesStore ).getNotices();
}, [] );
const { removeNotice: onRemove } = useDispatch( noticesStore );

const [ resizeListener, size ] = useResizeObserver();
useEffect( () => {
onResize?.( size );
}, [ size.width, size.height ] );

const dismissibleNotices = filter( notices, {
isDismissible: true,
type: 'default',
Expand All @@ -40,6 +51,7 @@ export function EditorNotices( { notices, onRemove } ) {
className="components-editor-notices__dismissible"
onRemove={ onRemove }
>
{ resizeListener }
<TemplateValidationNotice />
</NoticeList>
<SnackbarList
Expand All @@ -50,12 +62,3 @@ export function EditorNotices( { notices, onRemove } ) {
</>
);
}

export default compose( [
withSelect( ( select ) => ( {
notices: select( noticesStore ).getNotices(),
} ) ),
withDispatch( ( dispatch ) => ( {
onRemove: dispatch( noticesStore ).removeNotice,
} ) ),
] )( EditorNotices );
14 changes: 12 additions & 2 deletions packages/editor/src/components/editor-notices/style.scss
Original file line number Diff line number Diff line change
@@ -1,12 +1,22 @@
// Dismissible & non-dismissible notices.
.components-editor-notices__dismissible,
// Dismissible notices.
.components-editor-notices__dismissible {
position: sticky;
top: 0;
right: 0;
color: $gray-900;
}

// Non-dismissible notices.
.components-editor-notices__pinned {
position: relative;
left: 0;
top: 0;
right: 0;
color: $gray-900;
}

.components-editor-notices__dismissible,
.components-editor-notices__pinned {
.components-notice {
box-sizing: border-box;
margin: 0;
Expand Down

0 comments on commit 296530e

Please sign in to comment.