Skip to content

Commit

Permalink
UI Components: Refactor BlockSettingsMenu and MoreMenu as DropdownMenu (
Browse files Browse the repository at this point in the history
#14843)

* Components: Document missing menuLabel, position, className Dropdown props

* Components: Add render prop support to DropdownMenu

* Block Editor: Refactor BlockSettingsMenu as DropdownMenu

* CHANGELOG 7a54cec

* CHANGELOG 743e4da

* CHANGELOG ea82658

* Components: Remove unintended tabs from DropdownMenu tests

* Refactor MoreMenu component to use DropdownMenu component

* Use single label for DrowdownMenu components

* Fix all failing e2e tests

* Add all class names for backward compatibility

* Fix unit tests by refreshing saved snapshots

* Update packages/components/src/menu-group/index.js

Co-Authored-By: gziolo <grzegorz@gziolo.pl>

* Add back removed changelog update for components during rebase

* Mark all props used with DropdownMenu for backward compatibility as unstable

* Remove obsolete DropdownMenuSepararator component

* Apply changes after rebase to align CSS styles with master

* Display dropdown menu indicator only when icon set expliclity to false
  • Loading branch information
aduth authored and gziolo committed Jun 3, 2019
1 parent dbc155c commit c2768ec
Show file tree
Hide file tree
Showing 25 changed files with 391 additions and 332 deletions.
6 changes: 6 additions & 0 deletions packages/block-editor/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## Master

### Internal

- Refactored `BlockSettingsMenu` to use `DropdownMenu` from `@wordpress/components`.

## 2.0.0 (2019-04-16)

### New Features
Expand Down
191 changes: 90 additions & 101 deletions packages/block-editor/src/components/block-settings-menu/index.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
/**
* External dependencies
*/
import classnames from 'classnames';
import { castArray, flow } from 'lodash';

/**
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';
import { Toolbar, Dropdown, NavigableMenu, MenuItem } from '@wordpress/components';
import { withDispatch } from '@wordpress/data';
import {
Toolbar,
DropdownMenu,
MenuGroup,
MenuItem,
} from '@wordpress/components';

/**
* Internal dependencies
Expand All @@ -22,113 +25,99 @@ import BlockUnknownConvertButton from './block-unknown-convert-button';
import __experimentalBlockSettingsMenuFirstItem from './block-settings-menu-first-item';
import __experimentalBlockSettingsMenuPluginsExtension from './block-settings-menu-plugins-extension';

export function BlockSettingsMenu( { clientIds, onSelect } ) {
export function BlockSettingsMenu( { clientIds } ) {
const blockClientIds = castArray( clientIds );
const count = blockClientIds.length;
const firstBlockClientId = blockClientIds[ 0 ];

return (
<BlockActions clientIds={ clientIds }>
{ ( { onDuplicate, onRemove, onInsertAfter, onInsertBefore, canDuplicate, isLocked } ) => (
<Dropdown
contentClassName="editor-block-settings-menu__popover block-editor-block-settings-menu__popover"
position="bottom right"
renderToggle={ ( { onToggle, isOpen } ) => {
const toggleClassname = classnames( 'editor-block-settings-menu__toggle block-editor-block-settings-menu__toggle', {
'is-opened': isOpen,
} );
const label = isOpen ? __( 'Hide options' ) : __( 'More options' );

return (
<Toolbar controls={ [ {
icon: 'ellipsis',
title: label,
onClick: () => {
if ( count === 1 ) {
onSelect( firstBlockClientId );
}
onToggle();
},
className: toggleClassname,
extraProps: { 'aria-expanded': isOpen },
} ] } />
);
} }
renderContent={ ( { onClose } ) => (
<NavigableMenu className="editor-block-settings-menu__content block-editor-block-settings-menu__content">
<__experimentalBlockSettingsMenuFirstItem.Slot fillProps={ { onClose } } />
{ count === 1 && (
<BlockUnknownConvertButton
clientId={ firstBlockClientId }
/>
) }
{ count === 1 && (
<BlockHTMLConvertButton
clientId={ firstBlockClientId }
/>
) }
{ ! isLocked && canDuplicate && (
<MenuItem
className="editor-block-settings-menu__control block-editor-block-settings-menu__control"
onClick={ flow( onClose, onDuplicate ) }
icon="admin-page"
shortcut={ shortcuts.duplicate.display }
>
{ __( 'Duplicate' ) }
</MenuItem>
) }
{ ! isLocked && (
<>
<MenuItem
className="editor-block-settings-menu__control block-editor-block-settings-menu__control"
onClick={ flow( onClose, onInsertBefore ) }
icon="insert-before"
shortcut={ shortcuts.insertBefore.display }
>
{ __( 'Insert Before' ) }
</MenuItem>
<MenuItem
className="editor-block-settings-menu__control block-editor-block-settings-menu__control"
onClick={ flow( onClose, onInsertAfter ) }
icon="insert-after"
shortcut={ shortcuts.insertAfter.display }
>
{ __( 'Insert After' ) }
</MenuItem>
</>
) }
{ count === 1 && (
<BlockModeToggle
clientId={ firstBlockClientId }
onToggle={ onClose }
/>
) }
<__experimentalBlockSettingsMenuPluginsExtension.Slot fillProps={ { clientIds, onClose } } />
<div className="editor-block-settings-menu__separator block-editor-block-settings-menu__separator" />
{ ! isLocked && (
<MenuItem
className="editor-block-settings-menu__control block-editor-block-settings-menu__control"
onClick={ flow( onClose, onRemove ) }
icon="trash"
shortcut={ shortcuts.removeBlock.display }
>
{ __( 'Remove Block' ) }
</MenuItem>
) }
</NavigableMenu>
) }
/>
<Toolbar>
<DropdownMenu
icon="ellipsis"
label={ __( 'More options' ) }
position="bottom right"
className="block-editor-block-settings-menu"
__unstableToggleClassName="block-editor-block-settings-menu__toggle editor-block-settings-menu__toggle"
__unstableMenuClassName="block-editor-block-settings-menu__content editor-block-settings-menu__content"
__unstablePopoverClassName="block-editor-block-settings-menu__popover editor-block-settings-menu__popover"
>
{ ( { onClose } ) => (
<>
<MenuGroup>
<__experimentalBlockSettingsMenuFirstItem.Slot
fillProps={ { onClose } }
/>
{ count === 1 && (
<BlockUnknownConvertButton
clientId={ firstBlockClientId }
/>
) }
{ count === 1 && (
<BlockHTMLConvertButton
clientId={ firstBlockClientId }
/>
) }
{ ! isLocked && canDuplicate && (
<MenuItem
className="editor-block-settings-menu__control block-editor-block-settings-menu__control"
onClick={ flow( onClose, onDuplicate ) }
icon="admin-page"
shortcut={ shortcuts.duplicate.display }
>
{ __( 'Duplicate' ) }
</MenuItem>
) }
{ ! isLocked && (
<>
<MenuItem
className="editor-block-settings-menu__control block-editor-block-settings-menu__control"
onClick={ flow( onClose, onInsertBefore ) }
icon="insert-before"
shortcut={ shortcuts.insertBefore.display }
>
{ __( 'Insert Before' ) }
</MenuItem>
<MenuItem
className="editor-block-settings-menu__control block-editor-block-settings-menu__control"
onClick={ flow( onClose, onInsertAfter ) }
icon="insert-after"
shortcut={ shortcuts.insertAfter.display }
>
{ __( 'Insert After' ) }
</MenuItem>
</>
) }
{ count === 1 && (
<BlockModeToggle
clientId={ firstBlockClientId }
onToggle={ onClose }
/>
) }
<__experimentalBlockSettingsMenuPluginsExtension.Slot
fillProps={ { clientIds, onClose } }
/>
</MenuGroup>
<MenuGroup>
{ ! isLocked && (
<MenuItem
className="editor-block-settings-menu__control block-editor-block-settings-menu__control"
onClick={ flow( onClose, onRemove ) }
icon="trash"
shortcut={ shortcuts.removeBlock.display }
>
{ __( 'Remove Block' ) }
</MenuItem>
) }
</MenuGroup>
</>
) }
</DropdownMenu>
</Toolbar>
) }
</BlockActions>
);
}

export default withDispatch( ( dispatch ) => {
const { selectBlock } = dispatch( 'core/block-editor' );

return {
onSelect( clientId ) {
selectBlock( clientId );
},
};
} )( BlockSettingsMenu );
export default BlockSettingsMenu;
Original file line number Diff line number Diff line change
@@ -1,59 +1,7 @@
.block-editor-block-settings-menu__toggle .dashicon {
transform: rotate(90deg);
.block-editor-block-settings-menu__content {
padding: 0;
}

// Popout menu
.block-editor-block-settings-menu__popover {
&::before,
&::after {
margin-left: 2px;
}

.block-editor-block-settings-menu__content {
padding: ($grid-size - $border-width) 0;
}

.block-editor-block-settings-menu__separator {
margin-top: $grid-size;
margin-bottom: $grid-size;
margin-left: 0;
margin-right: 0;
border-top: $border-width solid $light-gray-500;

// Check if the separator is the last child in the node and if so, hide itself
&:last-child {
display: none;
}
}

.block-editor-block-settings-menu__title {
display: block;
padding: 6px;
color: $dark-gray-300;
}

// Menu items
.block-editor-block-settings-menu__control {
width: 100%;
justify-content: flex-start;
background: none;
outline: none;
border-radius: 0;
text-align: left;
cursor: pointer;
color: $dark-gray-600;
@include menu-style__neutral;

&:hover:not(:disabled):not([aria-disabled="true"]) {
@include menu-style__hover;
}

&:focus:not(:disabled):not([aria-disabled="true"]) {
@include menu-style__focus;
}

.dashicon {
margin-right: 5px;
}
}
.block-editor-block-settings-menu__toggle .dashicon {
transform: rotate(90deg);
}
10 changes: 10 additions & 0 deletions packages/components/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,16 @@
### New Feature

- Add new `BlockQuotation` block to the primitives folder to support blockquote in a multiplatform way. [#15482](https://github.com/WordPress/gutenberg/pull/15482).
- `DropdownMenu` now supports passing a [render prop](https://reactjs.org/docs/render-props.html#using-props-other-than-render) as children for more advanced customization.

### Internal

- `MenuGroup` no longer uses `NavigableMenu` internally. It needs to be explicitly wrapped with `NavigableMenu` to bring back the same behavior.

### Documentation

- Added missing documentation for `DropdownMenu` props `menuLabel`, `position`, `className`.


## 7.4.0 (2019-05-21)

Expand Down
Loading

0 comments on commit c2768ec

Please sign in to comment.