Skip to content

Commit

Permalink
Blocks: Extract and factorize block alignment controls
Browse files Browse the repository at this point in the history
  • Loading branch information
youknowriad committed Jun 14, 2017
1 parent e8f984f commit 705da6c
Show file tree
Hide file tree
Showing 5 changed files with 128 additions and 193 deletions.
50 changes: 50 additions & 0 deletions blocks/block-alignment-toolbar/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/**
* WordPress dependencies
*/
import { __ } from 'i18n';
import { Toolbar } from 'components';

const BLOCK_ALIGNMENTS_CONTROLS = {
left: {
icon: 'align-left',
title: __( 'Align left' ),
},
center: {
icon: 'align-center',
title: __( 'Align center' ),
},
right: {
icon: 'align-right',
title: __( 'Align right' ),
},
wide: {
icon: 'align-wide',
title: __( 'Wide width' ),
},
full: {
icon: 'align-full-width',
title: __( 'Full width' ),
},
};

const DEFAULT_CONTROLS = [ 'left', 'center', 'right' ];

export default function BlockAlignmentToolbar( { value, onChange, controls = DEFAULT_CONTROLS } ) {
function applyOrUnset( align ) {
return () => onChange( value === align ? undefined : align );
}

return (
<Toolbar
controls={
controls.map( control => {
return {
...BLOCK_ALIGNMENTS_CONTROLS[ control ],
isActive: value === control,
onClick: applyOrUnset( control ),
};
} )
}
/>
);
}
53 changes: 13 additions & 40 deletions blocks/library/button/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,11 @@ import { IconButton } from 'components';
import './style.scss';
import { registerBlockType, query } from '../../api';
import Editable from '../../editable';
import BlockControls from '../../block-controls';
import BlockAlignmentToolbar from '../../block-alignment-toolbar';

const { attr, children } = query;

/**
* Returns an attribute setter with behavior that if the target value is
* already the assigned attribute value, it will be set to undefined.
*
* @param {string} align Alignment value
* @return {Function} Attribute setter
*/
function applyOrUnset( align ) {
return ( attributes, setAttributes ) => {
const nextAlign = attributes.align === align ? undefined : align;
setAttributes( { align: nextAlign } );
};
}

registerBlockType( 'core/button', {
title: wp.i18n.__( 'Button' ),

Expand All @@ -39,27 +27,6 @@ registerBlockType( 'core/button', {
text: children( 'a' ),
},

controls: [
{
icon: 'align-left',
title: wp.i18n.__( 'Align left' ),
isActive: ( { align } ) => 'left' === align,
onClick: applyOrUnset( 'left' ),
},
{
icon: 'align-center',
title: wp.i18n.__( 'Align center' ),
isActive: ( { align } ) => 'center' === align,
onClick: applyOrUnset( 'center' ),
},
{
icon: 'align-right',
title: wp.i18n.__( 'Align right' ),
isActive: ( { align } ) => 'right' === align,
onClick: applyOrUnset( 'right' ),
},
],

getEditWrapperProps( attributes ) {
const { align } = attributes;
if ( 'left' === align || 'right' === align || 'center' === align ) {
Expand All @@ -68,10 +35,16 @@ registerBlockType( 'core/button', {
},

edit( { attributes, setAttributes, focus, setFocus } ) {
const { text, url, title } = attributes;
const { text, url, title, align } = attributes;
const updateAlignment = ( nextAlign ) => setAttributes( { align: nextAlign } );

return (
<span className="blocks-button" title={ title }>
return [
focus && (
<BlockControls key="controls">
<BlockAlignmentToolbar value={ align } onChange={ updateAlignment } />
</BlockControls>
),
<span key="button" className="blocks-button" title={ title }>
<Editable
tagName="span"
placeholder={ wp.i18n.__( 'Write label…' ) }
Expand All @@ -98,8 +71,8 @@ registerBlockType( 'core/button', {
<IconButton icon="editor-break" type="submit" />
</form>
}
</span>
);
</span>,
];
},

save( { attributes } ) {
Expand Down
91 changes: 31 additions & 60 deletions blocks/library/embed/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,25 +15,13 @@ import { Button, Placeholder, HtmlEmbed, Spinner } from 'components';
import './style.scss';
import { registerBlockType, query } from '../../api';
import Editable from '../../editable';
import BlockControls from '../../block-controls';
import BlockAlignmentToolbar from '../../block-alignment-toolbar';

const { attr, children } = query;

const HOSTS_NO_PREVIEWS = [ 'facebook.com' ];

/**
* Returns an attribute setter with behavior that if the target value is
* already the assigned attribute value, it will be set to undefined.
*
* @param {string} align Alignment value
* @return {Function} Attribute setter
*/
function toggleAlignment( align ) {
return ( attributes, setAttributes ) => {
const nextAlign = attributes.align === align ? undefined : align;
setAttributes( { align: nextAlign } );
};
}

function getEmbedBlockSettings( { title, icon, category = 'embed' } ) {
return {
title: wp.i18n.__( title ),
Expand All @@ -47,39 +35,6 @@ function getEmbedBlockSettings( { title, icon, category = 'embed' } ) {
caption: children( 'figcaption' ),
},

controls: [
{
icon: 'align-left',
title: wp.i18n.__( 'Align left' ),
isActive: ( { align } ) => 'left' === align,
onClick: toggleAlignment( 'left' ),
},
{
icon: 'align-center',
title: wp.i18n.__( 'Align center' ),
isActive: ( { align } ) => ! align || 'center' === align,
onClick: toggleAlignment( 'center' ),
},
{
icon: 'align-right',
title: wp.i18n.__( 'Align right' ),
isActive: ( { align } ) => 'right' === align,
onClick: toggleAlignment( 'right' ),
},
{
icon: 'align-full-width',
title: wp.i18n.__( 'Wide width' ),
isActive: ( { align } ) => 'wide' === align,
onClick: toggleAlignment( 'wide' ),
},
{
icon: 'align-full-width',
title: wp.i18n.__( 'Full width' ),
isActive: ( { align } ) => 'full' === align,
onClick: toggleAlignment( 'full' ),
},
],

getEditWrapperProps( attributes ) {
const { align } = attributes;
if ( 'left' === align || 'right' === align || 'wide' === align || 'full' === align ) {
Expand Down Expand Up @@ -144,21 +99,36 @@ function getEmbedBlockSettings( { title, icon, category = 'embed' } ) {

render() {
const { html, type, error, fetching } = this.state;
const { url, caption } = this.props.attributes;
const { align, url, caption } = this.props.attributes;
const { setAttributes, focus, setFocus } = this.props;
const updateAlignment = ( nextAlign ) => setAttributes( { align: nextAlign } );

const controls = (
focus && (
<BlockControls key="controls">
<BlockAlignmentToolbar
value={ align }
onChange={ updateAlignment }
controls={ [ 'left', 'center', 'right', 'wide', 'full' ] }
/>
</BlockControls>
)
);

if ( fetching ) {
return (
<div className="blocks-embed is-loading">
return [
controls,
<div key="loading" className="blocks-embed is-loading">
<Spinner />
<p>{ wp.i18n.__( 'Embedding…' ) }</p>
</div>
);
</div>,
];
}

if ( ! html ) {
return (
<Placeholder icon={ icon } label={ wp.i18n.sprintf( wp.i18n.__( '%s URL' ), title ) } className="blocks-embed">
return [
controls,
<Placeholder key="placeholder" icon={ icon } label={ wp.i18n.sprintf( wp.i18n.__( '%s URL' ), title ) } className="blocks-embed">
<form onSubmit={ this.doServerSideRender }>
<input
type="url"
Expand All @@ -173,8 +143,8 @@ function getEmbedBlockSettings( { title, icon, category = 'embed' } ) {
</Button>
{ error && <p className="components-placeholder__error">{ wp.i18n.__( 'Sorry, we could not embed that content.' ) }</p> }
</form>
</Placeholder>
);
</Placeholder>,
];
}

const parsedUrl = parse( url );
Expand All @@ -185,8 +155,9 @@ function getEmbedBlockSettings( { title, icon, category = 'embed' } ) {
typeClassName = 'blocks-embed-video';
}

return (
<figure className={ typeClassName }>
return [
controls,
<figure key="embed" className={ typeClassName }>
{ ( cannotPreview ) ? (
<Placeholder icon={ icon } label={ wp.i18n.__( 'Embed URL' ) }>
<p className="components-placeholder__error"><a href={ url }>{ url }</a></p>
Expand All @@ -207,8 +178,8 @@ function getEmbedBlockSettings( { title, icon, category = 'embed' } ) {
inlineToolbar
/>
) : null }
</figure>
);
</figure>,
];
}
},

Expand Down
66 changes: 18 additions & 48 deletions blocks/library/image/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,23 +13,11 @@ import Editable from '../../editable';
import MediaUploadButton from '../../media-upload-button';
import InspectorControls from '../../inspector-controls';
import TextControl from '../../inspector-controls/text-control';
import BlockControls from '../../block-controls';
import BlockAlignmentToolbar from '../../block-alignment-toolbar';

const { attr, children } = query;

/**
* Returns an attribute setter with behavior that if the target value is
* already the assigned attribute value, it will be set to undefined.
*
* @param {string} align Alignment value
* @return {Function} Attribute setter
*/
function toggleAlignment( align ) {
return ( attributes, setAttributes ) => {
const nextAlign = attributes.align === align ? undefined : align;
setAttributes( { align: nextAlign } );
};
}

registerBlockType( 'core/image', {
title: __( 'Image' ),

Expand All @@ -43,39 +31,6 @@ registerBlockType( 'core/image', {
caption: children( 'figcaption' ),
},

controls: [
{
icon: 'align-left',
title: __( 'Align left' ),
isActive: ( { align } ) => 'left' === align,
onClick: toggleAlignment( 'left' ),
},
{
icon: 'align-center',
title: __( 'Align center' ),
isActive: ( { align } ) => ! align || 'center' === align,
onClick: toggleAlignment( 'center' ),
},
{
icon: 'align-right',
title: __( 'Align right' ),
isActive: ( { align } ) => 'right' === align,
onClick: toggleAlignment( 'right' ),
},
{
icon: 'align-wide',
title: __( 'Wide width' ),
isActive: ( { align } ) => 'wide' === align,
onClick: toggleAlignment( 'wide' ),
},
{
icon: 'align-full-width',
title: __( 'Full width' ),
isActive: ( { align } ) => 'full' === align,
onClick: toggleAlignment( 'full' ),
},
],

getEditWrapperProps( attributes ) {
const { align } = attributes;
if ( 'left' === align || 'right' === align || 'wide' === align || 'full' === align ) {
Expand All @@ -84,13 +39,27 @@ registerBlockType( 'core/image', {
},

edit( { attributes, setAttributes, focus, setFocus } ) {
const { url, alt, caption } = attributes;
const { url, alt, caption, align } = attributes;
const updateAlt = ( newAlt ) => setAttributes( { alt: newAlt } );
const updateAlignment = ( nextAlign ) => setAttributes( { align: nextAlign } );

const controls = (
focus && (
<BlockControls key="controls">
<BlockAlignmentToolbar
value={ align }
onChange={ updateAlignment }
controls={ [ 'left', 'center', 'right', 'wide', 'full' ] }
/>
</BlockControls>
)
);

if ( ! url ) {
const uploadButtonProps = { isLarge: true };
const setMediaURL = ( media ) => setAttributes( { url: media.url } );
return [
controls,
<Placeholder
key="placeholder"
instructions={ __( 'Drag image here or insert from media library' ) }
Expand All @@ -115,6 +84,7 @@ registerBlockType( 'core/image', {

/* eslint-disable jsx-a11y/no-static-element-interactions, jsx-a11y/onclick-has-role, jsx-a11y/click-events-have-key-events */
return [
controls,
focus && (
<InspectorControls key="inspector">
<TextControl label={ __( 'Alternate Text' ) } value={ alt } onChange={ updateAlt } />
Expand Down
Loading

0 comments on commit 705da6c

Please sign in to comment.