Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make the inserter behave as a popover #24429

Merged
merged 5 commits into from
Aug 10, 2020
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -196,8 +196,12 @@ function QuickInserter( {
const onBrowseAll = () => {
// We have to select the previous block because the menu inserter
// inserts the new block after the selected one.
// Ideally, this selection shouldn't focus the block to avoid the setTimeout.
selectBlock( previousBlockClientId );
setInserterIsOpened( true );
// eslint-disable-next-line @wordpress/react-no-unsafe-timeout
setTimeout( () => {
setInserterIsOpened( true );
} );
};

// Disable reason (no-autofocus): The inserter menu is a modal display, not one which
Expand Down
7 changes: 3 additions & 4 deletions packages/e2e-tests/specs/editor/various/adding-blocks.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -248,13 +248,12 @@ describe( 'adding blocks', () => {
);
await browseAll.click();
const inserterMenuInputSelector =
'.block-editor-inserter__menu .block-editor-inserter__search-input';
await page.waitForSelector( inserterMenuInputSelector );
const inserterMenuSearchInput = await page.$(
'.edit-post-layout__inserter-panel .block-editor-inserter__search-input';
const inserterMenuSearchInput = await page.waitForSelector(
inserterMenuInputSelector
);
inserterMenuSearchInput.type( 'cover' );
const coverBlock = await page.$(
const coverBlock = await page.waitForSelector(
'.block-editor-block-types-list .editor-block-list-item-cover'
);
await coverBlock.click();
Expand Down
15 changes: 14 additions & 1 deletion packages/edit-post/src/components/header/header-toolbar/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@ import {
__experimentalToolbarItem as ToolbarItem,
} from '@wordpress/components';
import { plus } from '@wordpress/icons';
import { useRef } from '@wordpress/element';

function HeaderToolbar() {
const inserterButton = useRef();
const { setIsInserterOpened } = useDispatch( 'core/edit-post' );
const {
hasFixedToolbar,
Expand Down Expand Up @@ -72,11 +74,22 @@ function HeaderToolbar() {
aria-label={ toolbarAriaLabel }
>
<ToolbarItem
ref={ inserterButton }
as={ Button }
className="edit-post-header-toolbar__inserter-toggle"
isPrimary
isPressed={ isInserterOpened }
onClick={ () => setIsInserterOpened( ! isInserterOpened ) }
onMouseDown={ ( event ) => {
event.preventDefault();
} }
onClick={ () => {
if ( isInserterOpened ) {
// Focusing the inserter button closes the inserter popover
inserterButton.current.focus();
} else {
setIsInserterOpened( true );
}
} }
disabled={ ! isInserterEnabled }
icon={ plus }
label={ _x(
Expand Down
50 changes: 29 additions & 21 deletions packages/edit-post/src/components/layout/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ import SettingsSidebar from '../sidebar/settings-sidebar';
import MetaBoxes from '../meta-boxes';
import WelcomeGuide from '../welcome-guide';
import ActionsPanel from './actions-panel';
import PopoverWrapper from './popover-wrapper';

const interfaceLabels = {
leftSidebar: __( 'Block library' ),
Expand Down Expand Up @@ -178,29 +179,36 @@ function Layout() {
leftSidebar={
mode === 'visual' &&
isInserterOpened && (
<div className="edit-post-layout__inserter-panel">
<div className="edit-post-layout__inserter-panel-header">
<Button
icon={ close }
onClick={ () =>
setIsInserterOpened( false )
}
/>
</div>
<div className="edit-post-layout__inserter-panel-content">
<Library
showMostUsedBlocks={
showMostUsedBlocks
}
showInserterHelpPanel
onSelect={ () => {
if ( isMobileViewport ) {
setIsInserterOpened( false );
<PopoverWrapper
className="edit-post-layout__inserter-panel-popover-wrapper"
onClose={ () => setIsInserterOpened( false ) }
>
<div className="edit-post-layout__inserter-panel">
<div className="edit-post-layout__inserter-panel-header">
<Button
icon={ close }
onClick={ () =>
setIsInserterOpened( false )
}
/>
</div>
<div className="edit-post-layout__inserter-panel-content">
<Library
showMostUsedBlocks={
showMostUsedBlocks
}
} }
/>
showInserterHelpPanel
onSelect={ () => {
if ( isMobileViewport ) {
setIsInserterOpened(
false
);
}
} }
/>
</div>
</div>
</div>
</PopoverWrapper>
)
}
sidebar={
Expand Down
57 changes: 57 additions & 0 deletions packages/edit-post/src/components/layout/popover-wrapper.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/**
* WordPress dependencies
*/
import {
withConstrainedTabbing,
withFocusReturn,
withFocusOutside,
} from '@wordpress/components';
import { Component } from '@wordpress/element';
import { ESCAPE } from '@wordpress/keycodes';

function stopPropagation( event ) {
event.stopPropagation();
}

const DetectOutside = withFocusOutside(
class extends Component {
handleFocusOutside( event ) {
this.props.onFocusOutside( event );
}

render() {
return this.props.children;
}
}
);

const FocusManaged = withConstrainedTabbing(
withFocusReturn( ( { children } ) => children )
);

export default function PopoverWrapper( { onClose, children, className } ) {
// Event handlers
const maybeClose = ( event ) => {
// Close on escape
if ( event.keyCode === ESCAPE && onClose ) {
event.stopPropagation();
onClose();
}
};

// Disable reason: this stops certain events from propagating outside of the component.
// - onMouseDown is disabled as this can cause interactions with other DOM elements
/* eslint-disable jsx-a11y/no-static-element-interactions */
return (
<div
className={ className }
onKeyDown={ maybeClose }
onMouseDown={ stopPropagation }
>
<DetectOutside onFocusOutside={ onClose }>
<FocusManaged>{ children }</FocusManaged>
</DetectOutside>
</div>
);
/* eslint-enable jsx-a11y/no-static-element-interactions */
}
11 changes: 11 additions & 0 deletions packages/edit-post/src/components/layout/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,17 @@
background-color: $light-gray-700;
}

// Ideally we don't need all these nested divs.
// Removing these requires a refactoring of the different a11y HoCs.
.edit-post-layout__inserter-panel-popover-wrapper {
&
& > div,
& > div > div,
& > div > div > div {
height: 100%;
}
}

.edit-post-layout__inserter-panel {
height: 100%;
display: flex;
Expand Down