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

Show transforms as a vertical list #23028

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
19374c2
Move Styles below transform options.
ntsekouras Jun 8, 2020
0aab098
revert preview in BlockStyles as they are reused
ntsekouras Jun 8, 2020
d6b93ab
Hide BlockStyles preview only from BlockTypes list.
ntsekouras Jun 8, 2020
577cfd2
Change BlockStyles position next to style options
ntsekouras Jun 9, 2020
8af59ea
Show Preview styles properly and on smaller viewports.
ntsekouras Jun 9, 2020
298275b
Add line break
ntsekouras Jun 9, 2020
8f11e28
Revert changes from other blocks and override in Block Switcher
ntsekouras Jun 9, 2020
baa6541
Add arrow navigation to blocks and BlockStyles
ntsekouras Jun 10, 2020
2a64cfe
Push a little polish.
jasmussen Jun 10, 2020
c9339fe
Fix scrolling window on arrow navigation
ntsekouras Jun 10, 2020
fc42b4b
Destructure items' properties
ntsekouras Jun 10, 2020
08e3b22
Fix aria role related e2e tests
ntsekouras Jun 11, 2020
a958a9e
reverse destructuring
ntsekouras Jun 11, 2020
6e092ff
Use DropdownMenu instead of Dropdown.
ntsekouras Jun 15, 2020
92fa685
Add class property to support the override styles with DropdownMenu
ntsekouras Jun 15, 2020
37ac84e
Add role attribute support for BlockStyleItem
ntsekouras Jun 15, 2020
a195fee
Add Preview to a Popover component.
ntsekouras Jun 15, 2020
2b44bf9
Added container elements to change Preview Popover position.
ntsekouras Jun 16, 2020
189b35a
Introduce 'skipchildrenfocus' attribute to Focusable.
ntsekouras Jun 16, 2020
938e1ef
Add filter for tabindex -1 in focusable
ntsekouras Jun 16, 2020
22f4141
revert BlockTypesList and remove extra role attribute
ntsekouras Jun 16, 2020
3101ccd
add the Styles Preview popover
ntsekouras Jun 16, 2020
7d7e864
Hide popover on mobile + move styles on top
ntsekouras Jun 18, 2020
adb4ed2
Add labels to MenuGroups
ntsekouras Jun 18, 2020
8273999
Wrap icon with BlockIcon
ntsekouras Jun 18, 2020
83045c3
minor Firefox style fix
ntsekouras Jun 18, 2020
c8ac83c
Rename BlockStyles role to itemRole
ntsekouras Jun 18, 2020
af166a7
turn PreviewBlockPopover to function component
ntsekouras Jun 19, 2020
b56c05d
Fix BlockSwitcher tests
ntsekouras Jun 19, 2020
0da2829
Adjust outer block with new Popover functionality
ntsekouras Jun 19, 2020
a64b44e
make skipFocus function more specific to our use case.
ntsekouras Jun 19, 2020
0cbba47
use toLowerCase fn
ntsekouras Jun 20, 2020
50cf323
fix BlockSwitcher e2e tests
ntsekouras Jun 20, 2020
2a2b2c8
add block menu default class + fix toolbar roving tabindex e2e tests
ntsekouras Jun 20, 2020
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
Prev Previous commit
Next Next commit
Use DropdownMenu instead of Dropdown.
Create seperate BlockTransformationsMenu component
  • Loading branch information
ntsekouras committed Jun 20, 2020
commit 6e092ffa6af22e528686612103c5664fb69b3620
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/**
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';
import { MenuGroup, MenuItem } from '@wordpress/components';

const BlockTransformationsMenu = ( {
possibleBlockTransformations,
onSelect,
} ) => {
return (
<MenuGroup>
<div className="block-editor-block-switcher__label">
{ __( 'Transform to' ) }
</div>
{ possibleBlockTransformations.map( ( item ) => {
const { name, icon: { src: iconSrc } = {}, title } = item;
return (
<MenuItem
key={ name }
icon={ iconSrc }
onClick={ ( event ) => {
event.preventDefault();
onSelect( name );
} }
>
{ title }
</MenuItem>
);
} ) }
</MenuGroup>
);
};

export default BlockTransformationsMenu;
262 changes: 111 additions & 151 deletions packages/block-editor/src/components/block-switcher/index.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
/**
* External dependencies
*/
import { castArray, filter, first, mapKeys, orderBy, uniq, map } from 'lodash';
import { castArray, filter, mapKeys, orderBy, uniq, map } from 'lodash';

/**
* WordPress dependencies
*/
import { __, _n, sprintf } from '@wordpress/i18n';
import {
Dropdown,
DropdownMenu,
ToolbarButton,
ToolbarGroup,
__experimentalToolbarItem as ToolbarItem,
MenuGroup,
} from '@wordpress/components';
import {
Expand All @@ -21,7 +22,6 @@ import {
getBlockFromExample,
} from '@wordpress/blocks';
import { Component } from '@wordpress/element';
import { DOWN } from '@wordpress/keycodes';
import { withSelect, withDispatch } from '@wordpress/data';
import { compose } from '@wordpress/compose';
import { layout } from '@wordpress/icons';
Expand All @@ -32,8 +32,7 @@ import { layout } from '@wordpress/icons';
import BlockIcon from '../block-icon';
import BlockStyles from '../block-styles';
import BlockPreview from '../block-preview';
import BlockTypesList from '../block-types-list';
import NavigableToolbar from '../navigable-toolbar';
import BlockTransformationsMenu from './block-switcher-block-transformations-menu';

const POPOVER_PROPS = {
position: 'bottom right',
Expand Down Expand Up @@ -62,11 +61,11 @@ export class BlockSwitcher extends Component {
} = this.props;
const { hoveredClassName } = this.state;

if ( ! blocks || ! blocks.length ) {
if ( ! Array.isArray( blocks ) || ! blocks.length ) {
return null;
}

const hoveredBlock = blocks[ 0 ];
const [ hoveredBlock ] = blocks;
const hoveredBlockType = getBlockType( hoveredBlock.name );

const itemsByName = mapKeys( inserterItems, ( { name } ) => name );
Expand All @@ -86,14 +85,16 @@ export class BlockSwitcher extends Component {

let icon;
if ( isSelectionOfSameType ) {
const sourceBlockName = blocks[ 0 ].name;
const sourceBlockName = hoveredBlock.name;
const blockType = getBlockType( sourceBlockName );
icon = blockType.icon;
} else {
icon = layout;
}

if ( ! hasBlockStyles && ! possibleBlockTransformations.length ) {
const hasPossibleBlockTransformations = !! possibleBlockTransformations.length;

if ( ! hasBlockStyles && ! hasPossibleBlockTransformations ) {
return (
<ToolbarGroup>
<ToolbarButton
Expand All @@ -106,152 +107,111 @@ export class BlockSwitcher extends Component {
);
}

return (
<Dropdown
popoverProps={ POPOVER_PROPS }
className="block-editor-block-switcher"
contentClassName="block-editor-block-switcher__popover"
renderToggle={ ( { onToggle, isOpen } ) => {
const openOnArrowDown = ( event ) => {
if ( ! isOpen && event.keyCode === DOWN ) {
event.preventDefault();
event.stopPropagation();
onToggle();
}
};
const label =
1 === blocks.length
? __( 'Change block type or style' )
: sprintf(
/* translators: %s: number of blocks. */
_n(
'Change type of %d block',
'Change type of %d blocks',
blocks.length
),
blocks.length
);
// todo check if move/rename elsewhere
const PreviewBlock = (
<div className="block-editor-block-switcher__preview">
<div className="block-editor-block-switcher__preview-title">
{ __( 'Preview' ) }
</div>
<BlockPreview
viewportWidth={ 500 }
blocks={
hoveredBlockType.example
? getBlockFromExample( hoveredBlock.name, {
attributes: {
...hoveredBlockType.example.attributes,
className: hoveredClassName,
},
innerBlocks:
hoveredBlockType.example.innerBlocks,
} )
: cloneBlock( hoveredBlock, {
className: hoveredClassName,
} )
}
/>
</div>
);

const blockSwitcherLabel =
1 === blocks.length
? __( 'Change block type or style' )
: sprintf(
/* translators: %s: number of blocks. */
_n(
'Change type of %d block',
'Change type of %d blocks',
blocks.length
),
blocks.length
);

return (
<ToolbarGroup>
<ToolbarButton
className="block-editor-block-switcher__toggle"
onClick={ onToggle }
aria-haspopup="true"
aria-expanded={ isOpen }
title={ label }
onKeyDown={ openOnArrowDown }
showTooltip
icon={ <BlockIcon icon={ icon } showColors /> }
/>
</ToolbarGroup>
);
} }
renderContent={ ( { onClose } ) => (
<>
{ ( hasBlockStyles ||
possibleBlockTransformations.length !== 0 ) && (
<div className="block-editor-block-switcher__container">
{ possibleBlockTransformations.length !== 0 && (
<NavigableToolbar
orientation="vertical"
className="block-editor-block-switcher-toolbar"
role="menu"
/* translators: accessibility text for the block toolbar */
aria-label={ __( 'Block switcher' ) }
>
<MenuGroup>
<div className="block-editor-block-switcher__label">
{ __( 'Transform to' ) }
</div>
<BlockTypesList
items={ possibleBlockTransformations.map(
( {
name,
icon: destinationBlockTypeIcon,
title,
} ) => ( {
id: name,
icon: destinationBlockTypeIcon,
title,
role: 'menuitem', // this is to prevent scroll containers from scrolling (NavigableContainer internal check).
} )
) }
onSelect={ ( item ) => {
onTransform(
blocks,
item.id
);
onClose();
} }
/>
</MenuGroup>
</NavigableToolbar>
) }
{ hasBlockStyles && (
<NavigableToolbar
orientation="vertical"
className="block-editor-block-switcher-toolbar"
/* translators: accessibility text for the block toolbar */
aria-label={ __(
'Block Styles switcher'
) }
>
<MenuGroup>
<div className="block-editor-block-switcher__label">
{ __( 'Styles' ) }
</div>
<BlockStyles
clientId={
blocks[ 0 ].clientId
}
onSwitch={ onClose }
onHoverClassName={
this.onHoverClassName
}
/>
{ hoveredClassName !== null && (
<div className="block-editor-block-switcher__preview">
<div className="block-editor-block-switcher__preview-title">
{ __( 'Preview' ) }
return (
<ToolbarGroup>
<ToolbarItem>
{ ( toggleProps ) => (
<DropdownMenu
popoverProps={ POPOVER_PROPS }
className="block-editor-block-switcher"
// contentClassName="block-editor-block-switcher__popover"
label={ blockSwitcherLabel }
icon={
<BlockIcon
icon={ icon }
className="block-editor-block-switcher__toggle"
showColors
/>
}
toggleProps={ toggleProps }
menuProps={ { orientation: 'both' } }
>
{ ( { onClose } ) => (
<>
{ ( hasBlockStyles ||
hasPossibleBlockTransformations ) && (
<div className="block-editor-block-switcher__container">
{ hasPossibleBlockTransformations && (
<BlockTransformationsMenu
possibleBlockTransformations={
possibleBlockTransformations
}
onSelect={ ( name ) => {
onTransform(
blocks,
name
);
onClose();
} }
/>
) }
{ hasBlockStyles && (
<MenuGroup>
<div className="block-editor-block-switcher__label">
{ __( 'Styles' ) }
</div>
<BlockPreview
viewportWidth={ 500 }
blocks={
hoveredBlockType.example
? getBlockFromExample(
hoveredBlock.name,
{
attributes: {
...hoveredBlockType
.example
.attributes,
className: hoveredClassName,
},
innerBlocks:
hoveredBlockType
.example
.innerBlocks,
}
)
: cloneBlock(
hoveredBlock,
{
className: hoveredClassName,
}
)
<BlockStyles
clientId={
hoveredBlock.clientId
}
onSwitch={ onClose }
onHoverClassName={
this
.onHoverClassName
}
role="menuitem"
/>
</div>
{ hoveredClassName !==
null && PreviewBlock }
</MenuGroup>
) }
</MenuGroup>
</NavigableToolbar>
) }
</div>
) }
</>
) }
/>
</div>
) }
</>
) }
</DropdownMenu>
) }
</ToolbarItem>
</ToolbarGroup>
);
}
}
Expand All @@ -265,7 +225,7 @@ export default compose(
} = select( 'core/block-editor' );
const { getBlockStyles } = select( 'core/blocks' );
const rootClientId = getBlockRootClientId(
first( castArray( clientIds ) )
castArray( clientIds )[ 0 ]
);
const blocks = getBlocksByClientId( clientIds );
const firstBlock = blocks && blocks.length === 1 ? blocks[ 0 ] : null;
Expand Down