From 76f8742068381dc85df94e1a63a787db0936fde1 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Wed, 26 Apr 2017 10:56:23 +0100 Subject: [PATCH 1/5] Quote Block: Adding alignment controls to the quote block --- blocks/library/quote/index.js | 63 ++++++++++++++++++++++------- editor/modes/visual-editor/block.js | 12 ++++-- languages/gutenberg.pot | 5 ++- 3 files changed, 62 insertions(+), 18 deletions(-) diff --git a/blocks/library/quote/index.js b/blocks/library/quote/index.js index f6bedc0b8506a9..51b72c62d3837d 100644 --- a/blocks/library/quote/index.js +++ b/blocks/library/quote/index.js @@ -5,7 +5,7 @@ import './style.scss'; import { registerBlock, query as hpq } from 'api'; import Editable from 'components/editable'; -const { children, query, attr } = hpq; +const { children, query, attr, prop } = hpq; registerBlock( 'core/quote', { title: wp.i18n.__( 'Quote' ), @@ -15,6 +15,7 @@ registerBlock( 'core/quote', { attributes: { value: query( 'blockquote > p', children() ), citation: children( 'footer' ), + align: prop( 'blockquote', 'style.textAlign' ), style: ( node ) => { const value = attr( 'blockquote', 'class' )( node ); if ( ! value ) { @@ -30,21 +31,52 @@ registerBlock( 'core/quote', { } }, - controls: [ 1, 2 ].map( ( variation ) => ( { - icon: 'format-quote', - title: wp.i18n.sprintf( wp.i18n.__( 'Quote style %d' ), variation ), - isActive: ( { style = 1 } ) => style === variation, - onClick( attributes, setAttributes ) { - setAttributes( { style: variation } ); - }, - subscript: variation - } ) ), + 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' } ); + } + } + ], + [ 1, 2 ].map( ( variation ) => ( { + icon: 'format-quote', + title: wp.i18n.sprintf( wp.i18n.__( 'Quote style %d' ), variation ), + isActive: ( { style = 1 } ) => style === variation, + onClick( attributes, setAttributes ) { + setAttributes( { style: variation } ); + }, + subscript: variation + } ) ) + ], edit( { attributes, setAttributes, focus, setFocus } ) { - const { value, citation, style = 1 } = attributes; + const { align, value, citation, style = 1 } = attributes; return ( -
+
+
{ value && value.map( ( paragraph, i ) => (

{ paragraph }

) ) } diff --git a/editor/modes/visual-editor/block.js b/editor/modes/visual-editor/block.js index 31789867c6b1bb..c0307cfdf9dcb1 100644 --- a/editor/modes/visual-editor/block.js +++ b/editor/modes/visual-editor/block.js @@ -4,6 +4,7 @@ import { connect } from 'react-redux'; import classnames from 'classnames'; import { Slot } from 'react-slot-fill'; +import { first } from 'lodash'; /** * Internal dependencies @@ -137,6 +138,10 @@ class VisualEditorBlock extends wp.element.Component { wrapperProps = settings.getEditWrapperProps( block.attributes ); } + const toolbars = settings.controls && settings.controls.length && ! Array.isArray( first( settings.controls ) ) + ? [ settings.controls ] + : settings.controls; + // Disable reason: Each block can receive focus but must be able to contain // block children. Tab keyboard navigation enabled by tabIndex assignment. @@ -159,14 +164,15 @@ class VisualEditorBlock extends wp.element.Component { { isSelected && ! isTyping &&
- { !! settings.controls && ( + { !! toolbars && toolbars.map( ( controls, index ) => ( ( { + key={ index } + controls={ controls.map( ( control ) => ( { ...control, onClick: () => control.onClick( block.attributes, this.setAttributes ), isActive: control.isActive( block.attributes ) } ) ) } /> - ) } + ) ) }
} diff --git a/languages/gutenberg.pot b/languages/gutenberg.pot index 616d851037d34f..b9a797af83187c 100644 --- a/languages/gutenberg.pot +++ b/languages/gutenberg.pot @@ -42,18 +42,21 @@ msgstr "" #: blocks/library/image/index.js:41 #: blocks/library/list/index.js:25 +#: blocks/library/quote/index.js:38 #: blocks/library/text/index.js:23 msgid "Align left" msgstr "" #: blocks/library/image/index.js:47 #: blocks/library/list/index.js:33 +#: blocks/library/quote/index.js:46 #: blocks/library/text/index.js:31 msgid "Align center" msgstr "" #: blocks/library/image/index.js:53 #: blocks/library/list/index.js:41 +#: blocks/library/quote/index.js:54 #: blocks/library/text/index.js:39 msgid "Align right" msgstr "" @@ -74,7 +77,7 @@ msgstr "" msgid "Quote" msgstr "" -#: blocks/library/quote/index.js:35 +#: blocks/library/quote/index.js:63 msgid "Quote style %d" msgstr "" From 39abb03cc8d9ebbd6ea69e457db8edfc45746951 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Wed, 26 Apr 2017 19:30:27 +0100 Subject: [PATCH 2/5] Controls: Take into account mixed controls use-case --- editor/modes/visual-editor/block.js | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/editor/modes/visual-editor/block.js b/editor/modes/visual-editor/block.js index c0307cfdf9dcb1..a1779b919f7b32 100644 --- a/editor/modes/visual-editor/block.js +++ b/editor/modes/visual-editor/block.js @@ -4,7 +4,7 @@ import { connect } from 'react-redux'; import classnames from 'classnames'; import { Slot } from 'react-slot-fill'; -import { first } from 'lodash'; +import { reduce, last } from 'lodash'; /** * Internal dependencies @@ -138,9 +138,11 @@ class VisualEditorBlock extends wp.element.Component { wrapperProps = settings.getEditWrapperProps( block.attributes ); } - const toolbars = settings.controls && settings.controls.length && ! Array.isArray( first( settings.controls ) ) - ? [ settings.controls ] - : settings.controls; + const toolbars = reduce( settings.controls, ( memo, toolbar ) => ( + Array.isArray( toolbar ) + ? [ ...memo, toolbar ] + : [ ...memo.slice( 0, -1 ), [ ...( last( memo ) || [] ), toolbar ] ] + ), [] ); // Disable reason: Each block can receive focus but must be able to contain // block children. Tab keyboard navigation enabled by tabIndex assignment. @@ -164,7 +166,7 @@ class VisualEditorBlock extends wp.element.Component { { isSelected && ! isTyping &&
- { !! toolbars && toolbars.map( ( controls, index ) => ( + { toolbars.map( ( controls, index ) => ( ( { From 95723f39a83934c83651c9068fc8bce249d29a46 Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Wed, 26 Apr 2017 14:38:07 -0400 Subject: [PATCH 3/5] Document toolbar control normalization --- editor/modes/visual-editor/block.js | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/editor/modes/visual-editor/block.js b/editor/modes/visual-editor/block.js index a1779b919f7b32..f2cee2da3e8295 100644 --- a/editor/modes/visual-editor/block.js +++ b/editor/modes/visual-editor/block.js @@ -138,10 +138,15 @@ class VisualEditorBlock extends wp.element.Component { wrapperProps = settings.getEditWrapperProps( block.attributes ); } - const toolbars = reduce( settings.controls, ( memo, toolbar ) => ( + // Normalize controls as an array of arrays (toolbars of controls) + const toolbars = reduce( settings.controls, ( result, toolbar ) => ( Array.isArray( toolbar ) - ? [ ...memo, toolbar ] - : [ ...memo.slice( 0, -1 ), [ ...( last( memo ) || [] ), toolbar ] ] + // Array entry is simply concatenated into normalized value + // Example: [ [ 1, 2 ], [ 3, 4 ] ] => [ [ 1, 2 ], [ 3, 4 ] ] + ? [ ...result, toolbar ] + // Singular values are appended to the last array in the result + // Example: [ 1, 2, 3, 4 ] => [ [ 1, 2, 3, 4 ] ] + : [ ...result.slice( 0, -1 ), [ ...( last( result ) || [] ), toolbar ] ] ), [] ); // Disable reason: Each block can receive focus but must be able to contain From e5ba308b65a1b46a0547d1bcfff575850cfd732a Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Thu, 27 Apr 2017 13:49:37 +0100 Subject: [PATCH 4/5] Simplify the toolbar computing --- editor/modes/visual-editor/block.js | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/editor/modes/visual-editor/block.js b/editor/modes/visual-editor/block.js index f2cee2da3e8295..ad334a7184d3ad 100644 --- a/editor/modes/visual-editor/block.js +++ b/editor/modes/visual-editor/block.js @@ -4,7 +4,6 @@ import { connect } from 'react-redux'; import classnames from 'classnames'; import { Slot } from 'react-slot-fill'; -import { reduce, last } from 'lodash'; /** * Internal dependencies @@ -139,15 +138,9 @@ class VisualEditorBlock extends wp.element.Component { } // Normalize controls as an array of arrays (toolbars of controls) - const toolbars = reduce( settings.controls, ( result, toolbar ) => ( - Array.isArray( toolbar ) - // Array entry is simply concatenated into normalized value - // Example: [ [ 1, 2 ], [ 3, 4 ] ] => [ [ 1, 2 ], [ 3, 4 ] ] - ? [ ...result, toolbar ] - // Singular values are appended to the last array in the result - // Example: [ 1, 2, 3, 4 ] => [ [ 1, 2, 3, 4 ] ] - : [ ...result.slice( 0, -1 ), [ ...( last( result ) || [] ), toolbar ] ] - ), [] ); + const toolbars = settings.controls && settings.controls.length && ! Array.isArray( settings.controls[ 0 ] ) + ? [ settings.controls ] + : settings.controls; // Disable reason: Each block can receive focus but must be able to contain // block children. Tab keyboard navigation enabled by tabIndex assignment. From be27f94378876a0ca8bcd14de6e07f4a6bfb48a0 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Thu, 27 Apr 2017 15:25:54 +0100 Subject: [PATCH 5/5] Restore truthiness check to avoid errors on blocks without controls --- editor/modes/visual-editor/block.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/editor/modes/visual-editor/block.js b/editor/modes/visual-editor/block.js index ad334a7184d3ad..d988b293ffc4c1 100644 --- a/editor/modes/visual-editor/block.js +++ b/editor/modes/visual-editor/block.js @@ -164,7 +164,7 @@ class VisualEditorBlock extends wp.element.Component { { isSelected && ! isTyping &&
- { toolbars.map( ( controls, index ) => ( + { !! toolbars && toolbars.map( ( controls, index ) => ( ( {