Skip to content

Commit

Permalink
Block Controls: Treat alignments toolbar as an inline toolbar (#533)
Browse files Browse the repository at this point in the history
  • Loading branch information
youknowriad authored May 1, 2017
1 parent e622a12 commit 928de66
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 89 deletions.
72 changes: 61 additions & 11 deletions blocks/components/editable/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* External dependencies
*/
import classnames from 'classnames';
import { last, isEqual } from 'lodash';
import { last, isEqual, capitalize } from 'lodash';
import { Parser as HtmlToReactParser } from 'html-to-react';
import { Fill } from 'react-slot-fill';

Expand All @@ -23,7 +23,7 @@ const formatMap = {
del: 'strikethrough'
};

const formattingControls = [
const FORMATTING_CONTROLS = [
{
icon: 'editor-bold',
title: wp.i18n.__( 'Bold' ),
Expand All @@ -41,6 +41,24 @@ const formattingControls = [
}
];

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'
}
];

export default class Editable extends wp.element.Component {
constructor() {
super( ...arguments );
Expand All @@ -54,7 +72,8 @@ export default class Editable extends wp.element.Component {
this.onNodeChange = this.onNodeChange.bind( this );
this.onKeyDown = this.onKeyDown.bind( this );
this.state = {
formats: {}
formats: {},
alignment: null
};
}

Expand Down Expand Up @@ -195,18 +214,26 @@ export default class Editable extends wp.element.Component {
}

onNodeChange( { parents } ) {
const formats = parents.reduce( ( result, node ) => {
let alignment = null;
const formats = {};

parents.forEach( ( node ) => {
const tag = node.nodeName.toLowerCase();

if ( formatMap.hasOwnProperty( tag ) ) {
result[ formatMap[ tag ] ] = true;
formats[ formatMap[ tag ] ] = true;
}

return result;
}, {} );
if ( tag === 'p' ) {
alignment = node.style.textAlign || 'left';
}
} );

if ( ! isEqual( this.state.formats, formats ) ) {
this.setState( { formats } );
if (
this.state.alignment !== alignment ||
! isEqual( this.state.formats, formats )
) {
this.setState( { alignment, formats } );
}
}

Expand Down Expand Up @@ -289,8 +316,22 @@ export default class Editable extends wp.element.Component {
}
}

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: Tag = 'div', style, focus, className } = this.props;
const { tagName: Tag = 'div', style, focus, className, showAlignments = false } = this.props;
const classes = classnames( 'blocks-editable', className );

let element = (
Expand All @@ -304,8 +345,17 @@ export default class Editable extends wp.element.Component {
if ( focus ) {
element = [
<Fill name="Formatting.Toolbar" key="fill">
{ showAlignments &&
<Toolbar
controls={ ALIGNMENT_CONTROLS.map( ( control ) => ( {
...control,
onClick: () => this.toggleAlignment( control.align ),
isActive: this.isAlignmentActive( control.align )
} ) ) } />
}

<Toolbar
controls={ formattingControls.map( ( control ) => ( {
controls={ FORMATTING_CONTROLS.map( ( control ) => ( {
...control,
onClick: () => this.toggleFormat( control.format ),
isActive: this.isFormatActive( control.format )
Expand Down
20 changes: 8 additions & 12 deletions blocks/library/heading/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@ registerBlock( 'core/heading', {

attributes: {
content: children( 'h1,h2,h3,h4,h5,h6' ),
nodeName: prop( 'h1,h2,h3,h4,h5,h6', 'nodeName' ),
align: prop( 'h1,h2,h3,h4,h5,h6', 'style.textAlign' )
nodeName: prop( 'h1,h2,h3,h4,h5,h6', 'nodeName' )
},

controls: [
Expand All @@ -36,16 +35,15 @@ registerBlock( 'core/heading', {
{
type: 'block',
blocks: [ 'core/text' ],
transform: ( { content, align } ) => {
transform: ( { content } ) => {
if ( Array.isArray( content ) ) {
// TODO this appears to always be true?
// TODO reject the switch if more than one paragraph
content = content[ 0 ];
}
return {
nodeName: 'H2',
content,
align
content
};
}
}
Expand All @@ -54,10 +52,9 @@ registerBlock( 'core/heading', {
{
type: 'block',
blocks: [ 'core/text' ],
transform: ( { content, align } ) => {
transform: ( { content } ) => {
return {
content: [ content ],
align
content: [ content ]
};
}
}
Expand All @@ -71,7 +68,7 @@ registerBlock( 'core/heading', {
},

edit( { attributes, setAttributes, focus, setFocus, mergeWithPrevious } ) {
const { content, nodeName = 'H2', align } = attributes;
const { content, nodeName = 'H2' } = attributes;

return (
<Editable
Expand All @@ -80,18 +77,17 @@ registerBlock( 'core/heading', {
focus={ focus }
onFocus={ setFocus }
onChange={ ( value ) => setAttributes( { content: value } ) }
style={ align ? { textAlign: align } : null }
onMerge={ mergeWithPrevious }
/>
);
},

save( { attributes } ) {
const { align, nodeName = 'H2', content } = attributes;
const { nodeName = 'H2', content } = attributes;
const Tag = nodeName.toLowerCase();

return (
<Tag style={ align ? { textAlign: align } : null }>
<Tag>
{ content }
</Tag>
);
Expand Down
1 change: 1 addition & 0 deletions blocks/library/quote/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ registerBlock( 'core/quote', {
}
focus={ focus && focus.editable === 'value' ? focus : null }
onFocus={ () => setFocus( { editable: 'value' } ) }
showAlignments
/>
{ ( citation || !! focus ) && (
<footer>
Expand Down
50 changes: 3 additions & 47 deletions blocks/library/text/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,41 +21,14 @@ registerBlock( 'core/text', {
content: <p />
},

controls: [
{
icon: 'editor-alignleft',
title: wp.i18n.__( 'Align left' ),
isActive: ( { align } ) => ! align || 'left' === align,
onClick( attributes, setAttributes ) {
setAttributes( { align: undefined } );
}
},
{
icon: 'editor-aligncenter',
title: wp.i18n.__( 'Align center' ),
isActive: ( { align } ) => 'center' === align,
onClick( attributes, setAttributes ) {
setAttributes( { align: 'center' } );
}
},
{
icon: 'editor-alignright',
title: wp.i18n.__( 'Align right' ),
isActive: ( { align } ) => 'right' === align,
onClick( attributes, setAttributes ) {
setAttributes( { align: 'right' } );
}
}
],

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

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

return (
<Editable
Expand All @@ -67,37 +40,20 @@ registerBlock( 'core/text', {
} }
focus={ focus }
onFocus={ setFocus }
style={ align ? { textAlign: align } : null }
onSplit={ ( before, after ) => {
setAttributes( { content: before } );
insertBlockAfter( wp.blocks.createBlock( 'core/text', {
content: after
} ) );
} }
onMerge={ mergeWithPrevious }
showAlignments
/>
);
},

save( { attributes } ) {
// An empty block will have an undefined content field. Return early
// as an empty string.
const { content } = attributes;
if ( ! content ) {
return '';
}

// We only need to transform content if we need to apply the alignment
// style. Otherwise we can return unmodified.
const { align } = attributes;
if ( ! align ) {
return content;
}

return wp.element.Children.map( content, ( paragraph ) => (
wp.element.cloneElement( paragraph, {
style: { textAlign: align }
} )
) );
return content;
}
} );
38 changes: 19 additions & 19 deletions languages/gutenberg.pot
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,24 @@ msgstr ""
msgid "Strikethrough"
msgstr ""

#: blocks/components/editable/index.js:47
#: blocks/library/image/index.js:41
#: blocks/library/list/index.js:25
msgid "Align left"
msgstr ""

#: blocks/components/editable/index.js:52
#: blocks/library/image/index.js:47
#: blocks/library/list/index.js:33
msgid "Align center"
msgstr ""

#: blocks/components/editable/index.js:57
#: blocks/library/image/index.js:53
#: blocks/library/list/index.js:41
msgid "Align right"
msgstr ""

#: blocks/library/embed/index.js:10
msgid "Embed"
msgstr ""
Expand All @@ -32,32 +50,14 @@ msgstr ""
msgid "Heading"
msgstr ""

#: blocks/library/heading/index.js:25
#: blocks/library/heading/index.js:24
msgid "Heading %s"
msgstr ""

#: blocks/library/image/index.js:25
msgid "Image"
msgstr ""

#: blocks/library/image/index.js:41
#: blocks/library/list/index.js:25
#: blocks/library/text/index.js:27
msgid "Align left"
msgstr ""

#: blocks/library/image/index.js:47
#: blocks/library/list/index.js:33
#: blocks/library/text/index.js:35
msgid "Align center"
msgstr ""

#: blocks/library/image/index.js:53
#: blocks/library/list/index.js:41
#: blocks/library/text/index.js:43
msgid "Align right"
msgstr ""

#: blocks/library/image/index.js:59
msgid "No alignment"
msgstr ""
Expand Down

0 comments on commit 928de66

Please sign in to comment.