From 928de669bb721839c7f52afac5586cd179bdc72d Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Mon, 1 May 2017 09:30:07 +0100 Subject: [PATCH] Block Controls: Treat alignments toolbar as an inline toolbar (#533) --- blocks/components/editable/index.js | 72 ++++++++++++++++++++++++----- blocks/library/heading/index.js | 20 ++++---- blocks/library/quote/index.js | 1 + blocks/library/text/index.js | 50 ++------------------ languages/gutenberg.pot | 38 +++++++-------- 5 files changed, 92 insertions(+), 89 deletions(-) diff --git a/blocks/components/editable/index.js b/blocks/components/editable/index.js index 58a336a1f2d9e..8d5c96c0f3cf2 100644 --- a/blocks/components/editable/index.js +++ b/blocks/components/editable/index.js @@ -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'; @@ -23,7 +23,7 @@ const formatMap = { del: 'strikethrough' }; -const formattingControls = [ +const FORMATTING_CONTROLS = [ { icon: 'editor-bold', title: wp.i18n.__( 'Bold' ), @@ -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 ); @@ -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 }; } @@ -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 } ); } } @@ -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 = ( @@ -304,8 +345,17 @@ export default class Editable extends wp.element.Component { if ( focus ) { element = [ + { showAlignments && + ( { + ...control, + onClick: () => this.toggleAlignment( control.align ), + isActive: this.isAlignmentActive( control.align ) + } ) ) } /> + } + ( { + controls={ FORMATTING_CONTROLS.map( ( control ) => ( { ...control, onClick: () => this.toggleFormat( control.format ), isActive: this.isFormatActive( control.format ) diff --git a/blocks/library/heading/index.js b/blocks/library/heading/index.js index 8c2c5d4e546c6..6d9104bba0a1c 100644 --- a/blocks/library/heading/index.js +++ b/blocks/library/heading/index.js @@ -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: [ @@ -36,7 +35,7 @@ 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 @@ -44,8 +43,7 @@ registerBlock( 'core/heading', { } return { nodeName: 'H2', - content, - align + content }; } } @@ -54,10 +52,9 @@ registerBlock( 'core/heading', { { type: 'block', blocks: [ 'core/text' ], - transform: ( { content, align } ) => { + transform: ( { content } ) => { return { - content: [ content ], - align + content: [ content ] }; } } @@ -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 ( 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 ( - + { content } ); diff --git a/blocks/library/quote/index.js b/blocks/library/quote/index.js index f6bedc0b8506a..1c45b3eadf195 100644 --- a/blocks/library/quote/index.js +++ b/blocks/library/quote/index.js @@ -54,6 +54,7 @@ registerBlock( 'core/quote', { } focus={ focus && focus.editable === 'value' ? focus : null } onFocus={ () => setFocus( { editable: 'value' } ) } + showAlignments /> { ( citation || !! focus ) && (