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

Block API: Add block styles variations API #7362

Merged
merged 32 commits into from
Jun 27, 2018
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
f972ed8
Block API: Add block styles variation API
youknowriad Jun 19, 2018
b239ceb
Adding some unit tests
youknowriad Jun 19, 2018
df5ac6d
Fix unit tests
youknowriad Jun 19, 2018
0354f96
Fix e2e tests
youknowriad Jun 19, 2018
f6ccf0c
Update the block switcher UI to show style variations and previews
youknowriad Jun 21, 2018
7bc5ad7
Always open the block transforms panel and avoid leaking the text-align
youknowriad Jun 21, 2018
f498532
Use the same inserterg grid view for block transforms
youknowriad Jun 22, 2018
4453d7d
Fix unit tests
youknowriad Jun 22, 2018
91c85d4
Add style variations e2e test
youknowriad Jun 22, 2018
25822af
Use block icon with colors in main block toolbar.
mtias Jun 22, 2018
3023b50
Adjust padding of block switcher chip to avoid toolbar clipping.
mtias Jun 22, 2018
5ceb5da
Center preview for block styles.
mtias Jun 22, 2018
e5bd680
Use button to ensure valid HTML
youknowriad Jun 22, 2018
50cbfd0
Fix lint
youknowriad Jun 22, 2018
07f1b24
Add alternate styles for separator.
mtias Jun 25, 2018
e4d56da
Show style variations when the block type doesn't have any block tran…
youknowriad Jun 25, 2018
904eb3b
Improve a11y of the style switcher
youknowriad Jun 25, 2018
da71ec9
Add Button block style variants and fix line height.
mtias Jun 25, 2018
99a27a8
Polish the visuals a bit.
jasmussen Jun 26, 2018
409e28d
Fix tabs/spaces.
jasmussen Jun 26, 2018
1b9a9fc
Fix keyboard navigation into the styles preview buttons
youknowriad Jun 26, 2018
5449188
Polish preview container, fix focus, separator
jasmussen Jun 26, 2018
20e460e
Adding the is-active className to the block-styles component
youknowriad Jun 26, 2018
ac3ab56
Move the styles BlockAPI to the root level (out of the transforms)
youknowriad Jun 26, 2018
91c8900
Rename CSS class to utilize is-active.
jasmussen Jun 26, 2018
616731d
Showing style variation labels
youknowriad Jun 27, 2018
295b608
Polish the separator styles
Jun 27, 2018
052922c
Fix grid items width
youknowriad Jun 27, 2018
252a3fc
Use proper label names for quote styles.
mtias Jun 27, 2018
837295a
Polish separator styles for frontend
Jun 27, 2018
8c0db3a
Add button outline style.
mtias Jun 27, 2018
d720cab
Fix unit tests (Block Switcher without blocks)
youknowriad Jun 27, 2018
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
Update the block switcher UI to show style variations and previews
  • Loading branch information
youknowriad committed Jun 27, 2018
commit f6ccf0cf3c10b958bb11db8670f936fab6c25c5e
4 changes: 2 additions & 2 deletions core-blocks/quote/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ export const settings = {

transforms: {
styles: [
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a very expected API 👍

{ name: 'default', label: '1', isDefault: true, icon: 'format-quote' },
{ name: 'large', label: '2', icon: 'testimonial' },
{ name: 'default', label: '1', isDefault: true },
{ name: 'large', label: '2' },
],
from: [
{
Expand Down
3 changes: 1 addition & 2 deletions edit-post/assets/stylesheets/_z-index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ $z-layers: (
'.edit-post-meta-boxes-area.is-loading:before': 1,
'.edit-post-meta-boxes-area .spinner': 5,
'.editor-block-contextual-toolbar': 21,
'.editor-block-switcher__menu': 5,
'.components-popover__close': 5,
'.editor-block-list__insertion-point': 5,
'.core-blocks-gallery-item__inline-menu': 20,
Expand All @@ -30,7 +29,7 @@ $z-layers: (
// Side UI active buttons
'.editor-block-settings-remove': 1,
'.editor-block-mover__control': 1,

// Should have lower index than anything else positioned inside the block containers
'.editor-block-list__block-draggable': 0,

Expand Down
23 changes: 14 additions & 9 deletions editor/components/block-preview/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,27 @@ import './style.scss';
*
* @return {WPElement} Rendered element.
*/
function BlockPreview( { name, attributes } ) {
const block = createBlock( name, attributes );

function BlockPreview( props ) {
return (
<div className="editor-block-preview">
<div className="editor-block-preview__title">{ __( 'Preview' ) }</div>
<div className="editor-block-preview__content">
<BlockEdit
name={ name }
focus={ false }
attributes={ block.attributes }
setAttributes={ noop }
/>
<BlockPreviewContent { ...props } />
</div>
</div>
);
}

export function BlockPreviewContent( { name, attributes } ) {
const block = createBlock( name, attributes );
return (
<BlockEdit
name={ name }
focus={ false }
attributes={ block.attributes }
setAttributes={ noop }
/>
);
}

export default BlockPreview;
51 changes: 40 additions & 11 deletions editor/components/block-styles/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,15 @@ import { find, compact, get } from 'lodash';
/**
* WordPress dependencies
*/
import { __, sprintf } from '@wordpress/i18n';
import { Toolbar } from '@wordpress/components';
import { compose } from '@wordpress/element';
import { withSelect, withDispatch } from '@wordpress/data';
import { getBlockType } from '@wordpress/blocks';
import { Button } from '@wordpress/components';

/**
* Internal dependencies
*/
import { BlockPreviewContent } from '../block-preview';

/**
* Returns the active style from the given className.
Expand Down Expand Up @@ -68,7 +72,15 @@ export function replaceActiveStyle( className, activeStyle, newStyle ) {
return updatedClassName;
}

function BlockStyles( { styles, className, onChangeClassName } ) {
function BlockStyles( {
styles,
className,
onChangeClassName,
name,
attributes,
onSwitch,
onHoverClassName,
} ) {
if ( ! styles ) {
return null;
}
Expand All @@ -77,17 +89,32 @@ function BlockStyles( { styles, className, onChangeClassName } ) {
function updateClassName( style ) {
const updatedClassName = replaceActiveStyle( className, activeStyle, style );
onChangeClassName( updatedClassName );
onSwitch();
}

return (
<Toolbar controls={ styles.map( ( variation ) => ( {
icon: variation.icon,
title: sprintf( __( 'Style %s' ), variation.label || variation.name ),
isActive: activeStyle === variation,
onClick() {
updateClassName( variation );
},
} ) ) } />
<div className="editor-block-styles">
{ styles.map( ( style ) => {
const styleClassName = replaceActiveStyle( className, activeStyle, style );
return (
<Button
key={ style.name }
className="editor-block-styles__item"
onClick={ () => updateClassName( style ) }
onMouseEnter={ () => onHoverClassName( styleClassName ) }
onMouseLeave={ () => onHoverClassName( null ) }
>
<BlockPreviewContent
name={ name }
attributes={ {
...attributes,
className: styleClassName,
} }
/>
</Button>
);
} ) }
</div>
);
}

Expand All @@ -96,6 +123,8 @@ export default compose( [
const block = select( 'core/editor' ).getBlock( uid );

return {
name: block.name,
attributes: block.attributes,
className: block.attributes.className || '',
styles: get( getBlockType( block.name ), [ 'transforms', 'styles' ] ),
};
Expand Down
172 changes: 103 additions & 69 deletions editor/components/block-switcher/index.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
/**
* External dependencies
*/
import { get } from 'lodash';

/**
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';
import { Dropdown, Dashicon, IconButton, Toolbar, NavigableMenu } from '@wordpress/components';
import { Dropdown, Dashicon, IconButton, Toolbar, PanelBody } from '@wordpress/components';
import { getBlockType, getPossibleBlockTransformations, switchToBlockType } from '@wordpress/blocks';
import { compose } from '@wordpress/element';
import { compose, Component, Fragment } from '@wordpress/element';
import { keycodes } from '@wordpress/utils';
import { withSelect, withDispatch } from '@wordpress/data';

Expand All @@ -13,87 +18,116 @@ import { withSelect, withDispatch } from '@wordpress/data';
*/
import './style.scss';
import BlockIcon from '../block-icon';
import BlockStyles from '../block-styles';
import BlockPreview from '../block-preview';

/**
* Module Constants
*/
const { DOWN } = keycodes;

export function BlockSwitcher( { blocks, onTransform, isLocked } ) {
const allowedBlocks = getPossibleBlockTransformations( blocks );
export class BlockSwitcher extends Component {
constructor() {
super( ...arguments );
this.state = {
hoveredClassName: null,
};
this.onHoverClassName = this.onHoverClassName.bind( this );
}

if ( isLocked || ! allowedBlocks.length ) {
return null;
onHoverClassName( className ) {
this.setState( { hoveredClassName: className } );
}

const sourceBlockName = blocks[ 0 ].name;
const blockType = getBlockType( sourceBlockName );
render() {
const { blocks, onTransform, isLocked } = this.props;
const { hoveredClassName } = this.state;
const allowedBlocks = getPossibleBlockTransformations( blocks );

return (
<Dropdown
className="editor-block-switcher"
contentClassName="editor-block-switcher__popover"
renderToggle={ ( { onToggle, isOpen } ) => {
const openOnArrowDown = ( event ) => {
if ( ! isOpen && event.keyCode === DOWN ) {
event.preventDefault();
event.stopPropagation();
onToggle();
}
};
const label = __( 'Change block type' );
if ( isLocked || ! allowedBlocks.length ) {
return null;
}

return (
<Toolbar>
<IconButton
className="editor-block-switcher__toggle"
icon={ <BlockIcon icon={ blockType.icon && blockType.icon.src } /> }
onClick={ onToggle }
aria-haspopup="true"
aria-expanded={ isOpen }
label={ label }
tooltip={ label }
onKeyDown={ openOnArrowDown }
>
<Dashicon icon="arrow-down" />
</IconButton>
</Toolbar>
);
} }
renderContent={ ( { onClose } ) => (
<div>
<span
className="editor-block-switcher__menu-title"
>
{ __( 'Transform into:' ) }
</span>
<NavigableMenu
role="menu"
aria-label={ __( 'Block types' ) }
>
{ allowedBlocks.map( ( { name, title, icon } ) => (
const sourceBlockName = blocks[ 0 ].name;
const blockType = getBlockType( sourceBlockName );
const hasStyles = blocks.length === 1 && get( blockType, [ 'transforms', 'styles' ], [] ).length !== 0;

return (
<Dropdown
position="bottom right"
className="editor-block-switcher"
contentClassName="editor-block-switcher__popover"
renderToggle={ ( { onToggle, isOpen } ) => {
const openOnArrowDown = ( event ) => {
if ( ! isOpen && event.keyCode === DOWN ) {
event.preventDefault();
event.stopPropagation();
onToggle();
}
};
const label = __( 'Change block type' );

return (
<Toolbar>
<IconButton
key={ name }
onClick={ () => {
onTransform( blocks, name );
onClose();
} }
className="editor-block-switcher__menu-item"
icon={ (
<span className="editor-block-switcher__block-icon">
<BlockIcon icon={ icon && icon.src } />
</span>
) }
role="menuitem"
className="editor-block-switcher__toggle"
icon={ <BlockIcon icon={ blockType.icon && blockType.icon.src } /> }
onClick={ onToggle }
aria-haspopup="true"
aria-expanded={ isOpen }
label={ label }
tooltip={ label }
onKeyDown={ openOnArrowDown }
>
{ title }
<Dashicon icon="arrow-down" />
</IconButton>
) ) }
</NavigableMenu>
</div>
) }
/>
);
</Toolbar>
);
} }
renderContent={ ( { onClose } ) => (
<Fragment>
{ hasStyles &&
<PanelBody
title={ __( 'Block Styles' ) }
initialOpen
>
<BlockStyles uid={ blocks[ 0 ].uid } onSwitch={ onClose } onHoverClassName={ this.onHoverClassName } />
</PanelBody>
}
<PanelBody
title={ __( 'Block transforms' ) }
initialOpen={ ! hasStyles }
>
{ allowedBlocks.map( ( { name, title, icon } ) => (
<IconButton
key={ name }
onClick={ () => {
onTransform( blocks, name );
onClose();
} }
className="editor-block-switcher__transform"
icon={ (
<span className="editor-block-switcher__block-icon">
<BlockIcon icon={ icon && icon.src } />
</span>
) }
>
{ title }
</IconButton>
) ) }
</PanelBody>

{ ( hoveredClassName !== null ) &&
<BlockPreview
name={ blocks[ 0 ].name }
attributes={ { ...blocks[ 0 ].attributes, className: hoveredClassName } }
/>
}
</Fragment>
) }
/>
);
}
}

export default compose(
Expand Down
Loading