From 158d21fb15c9da36f87280f0b7210f911fce3f49 Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Thu, 6 Apr 2017 17:33:29 -0400 Subject: [PATCH 1/5] Enable styling of Editable element --- blocks/components/editable/index.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/blocks/components/editable/index.js b/blocks/components/editable/index.js index 7ae87e74d5087..3edc64980f1b4 100644 --- a/blocks/components/editable/index.js +++ b/blocks/components/editable/index.js @@ -75,11 +75,12 @@ export default class Editable extends wp.element.Component { } render() { - const { tagName: Tag = 'div' } = this.props; + const { tagName: Tag = 'div', style } = this.props; return ( ); } From 8683f42c17d7ef494c787e8c1a52008ebb030963 Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Fri, 7 Apr 2017 10:07:45 -0400 Subject: [PATCH 2/5] Rename block onChange to setAttributes --- editor/blocks/list/index.js | 5 ++--- editor/blocks/text/index.js | 4 ++-- editor/modes/visual-editor/block.js | 4 ++-- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/editor/blocks/list/index.js b/editor/blocks/list/index.js index 9434b6e2aab93..4aa74eefe4bce 100644 --- a/editor/blocks/list/index.js +++ b/editor/blocks/list/index.js @@ -16,7 +16,7 @@ wp.blocks.registerBlock( 'core/list', { ) }, - edit( { attributes, onChange } ) { + edit( { attributes } ) { const { listType = 'ol', items = [] } = attributes; const value = items.map( item => { return `
  • ${ item.value }
  • `; @@ -25,8 +25,7 @@ wp.blocks.registerBlock( 'core/list', { return ( + value={ value } /> ); }, diff --git a/editor/blocks/text/index.js b/editor/blocks/text/index.js index ba07e1051ede6..0f1c9a1a2ef5b 100644 --- a/editor/blocks/text/index.js +++ b/editor/blocks/text/index.js @@ -12,12 +12,12 @@ wp.blocks.registerBlock( 'core/text', { value: html( 'p' ) }, - edit( { attributes, onChange } ) { + edit( { attributes, setAttributes } ) { return ( onChange( { value } ) } + onChange={ ( value ) => setAttributes( { value } ) } /> ); }, diff --git a/editor/modes/visual-editor/block.js b/editor/modes/visual-editor/block.js index a6babfbdacfa6..1a9097da7b180 100644 --- a/editor/modes/visual-editor/block.js +++ b/editor/modes/visual-editor/block.js @@ -17,7 +17,7 @@ function VisualEditorBlock( props ) { return null; } - function onAttributesChange( attributes ) { + function setAttributes( attributes ) { props.onChange( { attributes: { ...block.attributes, @@ -50,7 +50,7 @@ function VisualEditorBlock( props ) { > + setAttributes={ setAttributes } /> ); /* eslint-enable jsx-a11y/no-static-element-interactions */ From d7d716d586dcb6b023139859aacb9515c0037bba Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Thu, 6 Apr 2017 17:50:34 -0400 Subject: [PATCH 3/5] Display toolbar of controls on selected block --- editor/components/toolbar/index.js | 38 +++++++++++++++++++++++++ editor/components/toolbar/style.scss | 35 +++++++++++++++++++++++ editor/modes/visual-editor/block.js | 40 +++++++++++++++++++++------ editor/modes/visual-editor/style.scss | 8 ++++++ 4 files changed, 112 insertions(+), 9 deletions(-) create mode 100644 editor/components/toolbar/index.js create mode 100644 editor/components/toolbar/style.scss diff --git a/editor/components/toolbar/index.js b/editor/components/toolbar/index.js new file mode 100644 index 0000000000000..a704b5b820ee1 --- /dev/null +++ b/editor/components/toolbar/index.js @@ -0,0 +1,38 @@ +/** + * External dependencies + */ +import classNames from 'classnames'; + +/** + * Internal dependencies + */ +import './style.scss'; +import Dashicon from '../dashicon'; + +function Toolbar( { controls } ) { + if ( ! controls || ! controls.length ) { + return null; + } + + return ( +
      + { controls.map( ( control, index ) => ( + + ) ) } +
    + ); +} + +export default Toolbar; diff --git a/editor/components/toolbar/style.scss b/editor/components/toolbar/style.scss new file mode 100644 index 0000000000000..e9d95b51fae2f --- /dev/null +++ b/editor/components/toolbar/style.scss @@ -0,0 +1,35 @@ +.editor-toolbar { + margin: 0; + border: 1px solid $light-gray-500; + box-shadow: 0px 3px 20px rgba( 18, 24, 30, .1 ), 0px 1px 3px rgba( 18, 24, 30, .1 ); + background-color: $white; +} + +.editor-toolbar__control { + margin: 2px; + margin-left: 0; + padding: 6px; + background: none; + border: 1px solid transparent; + outline: none; + color: $dark-gray-500; + cursor: pointer; + + &:first-child { + margin-left: 2px; + } + + &.is-active, + &:hover { + border-color: $dark-gray-500; + } + + &.is-active { + background-color: $dark-gray-500; + color: $white; + } +} + +.editor-toolbar__control .dashicon { + display: block; +} diff --git a/editor/modes/visual-editor/block.js b/editor/modes/visual-editor/block.js index 1a9097da7b180..ff89178b93bdd 100644 --- a/editor/modes/visual-editor/block.js +++ b/editor/modes/visual-editor/block.js @@ -4,6 +4,11 @@ import { connect } from 'react-redux'; import classnames from 'classnames'; +/** + * Internal dependencies + */ +import Toolbar from '../../components/toolbar'; + function VisualEditorBlock( props ) { const { block } = props; const settings = wp.blocks.getBlockSettings( block.blockType ); @@ -17,8 +22,17 @@ function VisualEditorBlock( props ) { return null; } + const { isHovered } = props; + const isSelected = props.isSelected; + const className = classnames( 'editor-visual-editor__block', { + 'is-selected': isSelected, + 'is-hovered': isHovered + } ); + + const { onChange, onSelect, onDeselect, onMouseEnter, onMouseLeave } = props; + function setAttributes( attributes ) { - props.onChange( { + onChange( { attributes: { ...block.attributes, ...attributes @@ -26,13 +40,13 @@ function VisualEditorBlock( props ) { } ); } - const { isSelected, isHovered } = props; - const className = classnames( 'editor-visual-editor__block', { - 'is-selected': isSelected, - 'is-hovered': isHovered - } ); - - const { onSelect, onDeselect, onMouseEnter, onMouseLeave } = props; + function maybeDeselect( event ) { + // Annoyingly React does not support focusOut and we're forced to check + // related target to ensure it's not a child when blur fires. + if ( ! event.currentTarget.contains( event.relatedTarget ) ) { + onDeselect(); + } + } // Disable reason: Each block can receive focus but must be able to contain // block children. Tab keyboard navigation enabled by tabIndex assignment. @@ -42,12 +56,20 @@ function VisualEditorBlock( props ) {
    + { isSelected && settings.controls ? ( + ( { + ...control, + onClick: () => control.onClick( block.attributes, setAttributes ), + isActive: () => control.isActive( block.attributes ) + } ) ) } /> + ) : null } diff --git a/editor/modes/visual-editor/style.scss b/editor/modes/visual-editor/style.scss index 5d5d1ee39c39b..19d4b1f7ed438 100644 --- a/editor/modes/visual-editor/style.scss +++ b/editor/modes/visual-editor/style.scss @@ -16,6 +16,7 @@ } .editor-visual-editor__block { + position: relative; padding: 15px; border: 2px solid transparent; transition: 0.2s border-color; @@ -28,3 +29,10 @@ border: 2px solid $light-gray-500; } } + +.editor-visual-editor__block .editor-toolbar { + position: absolute; + bottom: 100%; + margin-bottom: -4px; + left: 8px; +} From 91e0a0e46fe404ffe8061c9dfd8b9cc21025a95e Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Thu, 6 Apr 2017 18:21:16 -0400 Subject: [PATCH 4/5] Bump hpq dependency For support of deep path lookup --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 046b7ea918ecc..8d35ff040b5b8 100644 --- a/package.json +++ b/package.json @@ -57,7 +57,7 @@ }, "dependencies": { "classnames": "^2.2.5", - "hpq": "^1.1.1", + "hpq": "^1.2.0", "jed": "^1.1.1", "lodash": "^4.17.4", "react-redux": "^5.0.3", From 52ed37eaad22281d91d2b8f759816878eeaca422 Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Thu, 6 Apr 2017 18:22:02 -0400 Subject: [PATCH 5/5] Add text block controls --- editor/blocks/text/index.js | 47 +++++++++++++++++++++++++++++++++---- languages/gutenberg.pot | 12 ++++++++++ 2 files changed, 54 insertions(+), 5 deletions(-) diff --git a/editor/blocks/text/index.js b/editor/blocks/text/index.js index 0f1c9a1a2ef5b..9c1aa1c17d92b 100644 --- a/editor/blocks/text/index.js +++ b/editor/blocks/text/index.js @@ -1,4 +1,4 @@ -const { html } = wp.blocks.query; +const { html, prop } = wp.blocks.query; const Editable = wp.blocks.Editable; wp.blocks.registerBlock( 'core/text', { @@ -9,20 +9,57 @@ wp.blocks.registerBlock( 'core/text', { category: 'common', attributes: { - value: html( 'p' ) + content: html( 'p' ), + align: prop( 'p', 'style.textAlign' ) }, + 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' } ); + } + } + ], + edit( { attributes, setAttributes } ) { + const { content, align } = attributes; + return ( setAttributes( { value } ) } + value={ content } + onChange={ ( value ) => setAttributes( { content: value } ) } + style={ align ? { textAlign: align } : null } /> ); }, save( { attributes } ) { - return

    ; + const { align, content } = attributes; + + return ( +

    + ); } } ); diff --git a/languages/gutenberg.pot b/languages/gutenberg.pot index 2d14e2c9ef7bd..5ccb62ab2f8d7 100644 --- a/languages/gutenberg.pot +++ b/languages/gutenberg.pot @@ -11,6 +11,18 @@ msgstr "" msgid "List" msgstr "" +#: editor/blocks/text/index.js:19 +msgid "Align left" +msgstr "" + +#: editor/blocks/text/index.js:27 +msgid "Align center" +msgstr "" + +#: editor/blocks/text/index.js:35 +msgid "Align right" +msgstr "" + #: editor/header/mode-switcher/index.js:30 msgid "Visual" msgstr ""