Skip to content

Commit

Permalink
Surface alignment toolbar as block control
Browse files Browse the repository at this point in the history
  • Loading branch information
aduth committed Jun 7, 2017
1 parent 1997e78 commit cb815ad
Show file tree
Hide file tree
Showing 9 changed files with 109 additions and 76 deletions.
40 changes: 40 additions & 0 deletions blocks/alignment-toolbar/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/**
* WordPress dependencies
*/
import { __ } from 'i18n';
import { Toolbar } from 'components';

const ALIGNMENT_CONTROLS = [
{
icon: 'editor-alignleft',
title: __( 'Align left' ),
align: 'left',
},
{
icon: 'editor-aligncenter',
title: __( 'Align center' ),
align: 'center',
},
{
icon: 'editor-alignright',
title: __( 'Align right' ),
align: 'right',
},
];

export default function AlignmentToolbar( { value, onChange } ) {
return (
<Toolbar
controls={ ALIGNMENT_CONTROLS.map( ( control ) => {
const { align } = control;
const isActive = ( value === align );

return {
...control,
isActive,
onClick: () => onChange( isActive ? null : align ),
};
} ) }
/>
);
}
3 changes: 2 additions & 1 deletion blocks/block-controls/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@ import { Fill } from 'react-slot-fill';
*/
import { Toolbar } from 'components';

export default function BlockControls( { controls } ) {
export default function BlockControls( { controls, children } ) {
return (
<Fill name="Formatting.Toolbar">
<Toolbar controls={ controls } />
{ children }
</Fill>
);
}
56 changes: 2 additions & 54 deletions blocks/editable/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,14 @@
* External dependencies
*/
import classnames from 'classnames';
import { last, isEqual, capitalize, omitBy, forEach, merge, identity, find } from 'lodash';
import { last, isEqual, omitBy, forEach, merge, identity, find } from 'lodash';
import { nodeListToReact } from 'dom-react';
import { Fill } from 'react-slot-fill';
import 'element-closest';

/**
* WordPress dependencies
*/
import { Toolbar } from 'components';
import { BACKSPACE, DELETE } from 'utils/keycodes';

/**
Expand All @@ -20,30 +19,6 @@ import './style.scss';
import FormatToolbar from './format-toolbar';
import TinyMCE from './tinymce';

const alignmentMap = {
alignleft: 'left',
alignright: 'right',
aligncenter: 'center',
};

const ALIGNMENT_CONTROLS = [
{
icon: 'editor-alignleft',
title: wp.i18n.__( 'Align left' ),
align: 'left',
},
{
icon: 'editor-aligncenter',
title: wp.i18n.__( 'Align center' ),
align: 'center',
},
{
icon: 'editor-alignright',
title: wp.i18n.__( 'Align right' ),
align: 'right',
},
];

function createElement( type, props, ...children ) {
if ( props[ 'data-mce-bogus' ] === 'all' ) {
return null;
Expand Down Expand Up @@ -78,7 +53,6 @@ export default class Editable extends wp.element.Component {

this.state = {
formats: {},
alignment: null,
bookmark: null,
empty: ! props.value || ! props.value.length,
};
Expand Down Expand Up @@ -296,12 +270,10 @@ export default class Editable extends wp.element.Component {
}
const activeFormats = this.editor.formatter.matchAll( [ 'bold', 'italic', 'strikethrough' ] );
activeFormats.forEach( ( activeFormat ) => formats[ activeFormat ] = true );
const alignments = this.editor.formatter.matchAll( [ 'alignleft', 'aligncenter', 'alignright' ] );
const alignment = alignments.length > 0 ? alignmentMap[ alignments[ 0 ] ] : null;

const focusPosition = this.getRelativePosition( element );
const bookmark = this.editor.selection.getBookmark( 2, true );
this.setState( { alignment, bookmark, formats, focusPosition } );
this.setState( { bookmark, formats, focusPosition } );
}

updateContent() {
Expand Down Expand Up @@ -400,28 +372,13 @@ export default class Editable extends wp.element.Component {
this.editor.setDirty( true );
}

isAlignmentActive( align ) {
return this.state.alignment === align;
}

toggleAlignment( align ) {
this.editor.focus();

if ( this.isAlignmentActive( align ) ) {
this.editor.execCommand( 'JustifyNone' );
} else {
this.editor.execCommand( 'Justify' + capitalize( align ) );
}
}

render() {
const {
tagName,
style,
value,
focus,
className,
showAlignments = false,
inlineToolbar = false,
formattingControls,
placeholder,
Expand All @@ -446,15 +403,6 @@ export default class Editable extends wp.element.Component {
<div className={ classes }>
{ focus &&
<Fill name="Formatting.Toolbar">
{ showAlignments &&
<Toolbar
controls={ ALIGNMENT_CONTROLS.map( ( control ) => ( {
...control,
onClick: () => this.toggleAlignment( control.align ),
isActive: this.isAlignmentActive( control.align ),
} ) ) }
/>
}
{ ! inlineToolbar && formatToolbar }
</Fill>
}
Expand Down
2 changes: 2 additions & 0 deletions blocks/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,7 @@ import './library';
// Blocks are inferred from the HTML source of a post through a parsing mechanism
// and then stored as objects in state, from which it is then rendered for editing.
export * from './api';
export { default as AlignmentToolbar } from './alignment-toolbar';
export { default as BlockControls } from './block-controls';
export { default as Editable } from './editable';
export { default as MediaUploadButton } from './media-upload-button';
36 changes: 28 additions & 8 deletions blocks/library/quote/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import { switchChildrenNodeName } from 'element';
*/
import './style.scss';
import { registerBlockType, createBlock, query as hpq } from '../../api';
import AlignmentToolbar from '../../alignment-toolbar';
import BlockControls from '../../block-controls';
import Editable from '../../editable';

const { children, query } = hpq;
Expand Down Expand Up @@ -111,11 +113,24 @@ registerBlockType( 'core/quote', {
},

edit( { attributes, setAttributes, focus, setFocus, mergeBlocks } ) {
const { value, citation, style = 1 } = attributes;
const { align, value, citation, style = 1 } = attributes;
const focusedEditable = focus ? focus.editable || 'value' : null;

return (
<blockquote className={ `blocks-quote blocks-quote-style-${ style }` }>
return [
focus && (
<BlockControls key="controls">
<AlignmentToolbar
value={ align }
onChange={ ( nextAlign ) => {
setAttributes( { align: nextAlign } );
} }
/>
</BlockControls>
),
<blockquote
key="quote"
className={ `blocks-quote blocks-quote-style-${ style }` }
>
<Editable
value={ value }
onChange={
Expand All @@ -126,7 +141,7 @@ registerBlockType( 'core/quote', {
focus={ focusedEditable === 'value' ? focus : null }
onFocus={ () => setFocus( { editable: 'value' } ) }
onMerge={ mergeBlocks }
showAlignments
style={ { textAlign: align } }
/>
{ ( ( citation && citation.length > 0 ) || !! focus ) && (
<Editable
Expand All @@ -143,17 +158,22 @@ registerBlockType( 'core/quote', {
inline
/>
) }
</blockquote>
);
</blockquote>,
];
},

save( { attributes } ) {
const { value, citation, style = 1 } = attributes;
const { align, value, citation, style = 1 } = attributes;

return (
<blockquote className={ `blocks-quote-style-${ style }` }>
{ value && value.map( ( paragraph, i ) => (
<p key={ i }>{ paragraph }</p>
<p
key={ i }
style={ { textAlign: align ? align : null } }
>
{ paragraph }
</p>
) ) }
{ citation && citation.length > 0 && (
<footer>{ citation }</footer>
Expand Down
43 changes: 32 additions & 11 deletions blocks/library/text/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
/**
* WordPress dependencies
*/
import { Children, cloneElement } from 'element';

/**
* Internal dependencies
*/
import { registerBlockType, createBlock, query } from '../../api';
import AlignmentToolbar from '../../alignment-toolbar';
import BlockControls from '../../block-controls';
import Editable from '../../editable';

const { children } = query;
Expand All @@ -17,21 +24,28 @@ registerBlockType( 'core/text', {
content: children(),
},

defaultAttributes: {
content: <p />,
},

merge( attributes, attributesToMerge ) {
return {
content: wp.element.concatChildren( attributes.content, attributesToMerge.content ),
};
},

edit( { attributes, setAttributes, insertBlockAfter, focus, setFocus, mergeBlocks } ) {
const { content } = attributes;
const { align, content } = attributes;

return (
return [
focus && (
<BlockControls key="controls">
<AlignmentToolbar
value={ align }
onChange={ ( nextAlign ) => {
setAttributes( { align: nextAlign } );
} }
/>
</BlockControls>
),
<Editable
key="editable"
value={ content }
onChange={ ( nextContent ) => {
setAttributes( {
Expand All @@ -47,13 +61,20 @@ registerBlockType( 'core/text', {
} ) );
} }
onMerge={ mergeBlocks }
showAlignments
/>
);
style={ { textAlign: align } }
/>,
];
},

save( { attributes } ) {
const { content } = attributes;
return content;
const { align, content } = attributes;

if ( ! align ) {
return content;
}

return Children.map( content, ( paragraph ) => (
cloneElement( paragraph, { style: { textAlign: align } } )
) );
},
} );
2 changes: 1 addition & 1 deletion blocks/test/fixtures/core-text-align-right.html
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
<!-- wp:core/text -->
<!-- wp:core/text align="right" -->
<p style="text-align:right;">... like this one, which is separate from the above and right aligned.</p>
<!-- /wp:core/text -->
1 change: 1 addition & 0 deletions blocks/test/fixtures/core-text-align-right.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"uid": "_uid_0",
"name": "core/text",
"attributes": {
"align": "right",
"content": [
{
"type": "p",
Expand Down
2 changes: 1 addition & 1 deletion blocks/test/fixtures/core-text-align-right.serialized.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<!-- wp:core/text -->
<!-- wp:core/text align="right" -->
<p style="text-align:right;">... like this one, which is separate from the above and right aligned.</p>
<!-- /wp:core/text -->

0 comments on commit cb815ad

Please sign in to comment.