diff --git a/editor/modes/visual-editor/block-list.js b/editor/modes/visual-editor/block-list.js index e04c8dace616e5..c9b0ba868ec8eb 100644 --- a/editor/modes/visual-editor/block-list.js +++ b/editor/modes/visual-editor/block-list.js @@ -2,7 +2,6 @@ * External dependencies */ import { connect } from 'react-redux'; -import classnames from 'classnames'; import { throttle, reduce, noop } from 'lodash'; /** @@ -11,7 +10,6 @@ import { throttle, reduce, noop } from 'lodash'; import { __ } from '@wordpress/i18n'; import { Component } from '@wordpress/element'; import { serialize, getDefaultBlockName, createBlock } from '@wordpress/blocks'; -import { IconButton } from '@wordpress/components'; import { keycodes } from '@wordpress/utils'; /** @@ -19,7 +17,6 @@ import { keycodes } from '@wordpress/utils'; */ import VisualEditorBlock from './block'; import BlockDropZone from './block-drop-zone'; -import Inserter from '../../inserter'; import { getBlockUids, getBlockInsertionPoint, @@ -37,9 +34,7 @@ const { ENTER } = keycodes; class VisualEditorBlockList extends Component { constructor( props ) { super( props ); - this.state = { - showContinueWritingControls: false, - }; + this.onSelectionStart = this.onSelectionStart.bind( this ); this.onSelectionChange = this.onSelectionChange.bind( this ); this.onSelectionEnd = this.onSelectionEnd.bind( this ); @@ -50,7 +45,6 @@ class VisualEditorBlockList extends Component { this.setLastClientY = this.setLastClientY.bind( this ); this.onPointerMove = throttle( this.onPointerMove.bind( this ), 250 ); this.onPlaceholderKeyDown = this.onPlaceholderKeyDown.bind( this ); - this.toggleContinueWritingControls = this.toggleContinueWritingControls.bind( this ); // Browser does not fire `*move` event when the pointer position changes // relative to the document, so fire it with the last known position. this.onScroll = () => this.onPointerMove( { clientY: this.lastClientY } ); @@ -199,15 +193,6 @@ class VisualEditorBlockList extends Component { this.props.onInsertBlock( newBlock ); } - insertBlock( name ) { - const newBlock = createBlock( name ); - this.props.onInsertBlock( newBlock ); - } - - toggleContinueWritingControls( showContinueWritingControls ) { - return () => this.setState( { showContinueWritingControls } ); - } - render() { const { blocks, @@ -222,9 +207,6 @@ class VisualEditorBlockList extends Component { ...blocks.slice( insertionPoint ), ] : blocks; - const continueWritingClassname = classnames( 'editor-visual-editor__continue-writing', { - 'is-showing-controls': this.state.showContinueWritingControls, - } ); return (
@@ -260,29 +242,6 @@ class VisualEditorBlockList extends Component { />
} -
- - this.insertBlock( 'core/paragraph' ) } - label={ __( 'Insert paragraph block' ) } - > - { __( 'Paragraph' ) } - - this.insertBlock( 'core/image' ) } - label={ __( 'Insert image block' ) } - > - { __( 'Image' ) } - -
); } diff --git a/editor/modes/visual-editor/index.js b/editor/modes/visual-editor/index.js index 70e248d8b42a13..6e31faff576e36 100644 --- a/editor/modes/visual-editor/index.js +++ b/editor/modes/visual-editor/index.js @@ -16,6 +16,7 @@ import { KeyboardShortcuts } from '@wordpress/components'; */ import './style.scss'; import VisualEditorBlockList from './block-list'; +import VisualEditorInserter from './inserter'; import PostTitle from '../../post-title'; import WritingFlow from '../../writing-flow'; import TableOfContents from '../../table-of-contents'; @@ -104,6 +105,7 @@ class VisualEditor extends Component { + ); diff --git a/editor/modes/visual-editor/inserter.js b/editor/modes/visual-editor/inserter.js new file mode 100644 index 00000000000000..db2ea83685e608 --- /dev/null +++ b/editor/modes/visual-editor/inserter.js @@ -0,0 +1,81 @@ +/** + * External dependencies + */ +import { connect } from 'react-redux'; +import classnames from 'classnames'; + +/** + * WordPress dependencies + */ +import { __ } from '@wordpress/i18n'; +import { IconButton } from '@wordpress/components'; +import { Component } from '@wordpress/element'; +import { createBlock } from '@wordpress/blocks'; + +/** + * Internal dependencies + */ +import Inserter from '../../inserter'; +import { insertBlock } from '../../actions'; + +export class VisualEditorInserter extends Component { + constructor() { + super( ...arguments ); + + this.showControls = this.toggleControls.bind( this, true ); + this.hideControls = this.toggleControls.bind( this, false ); + this.insertParagraph = this.insertBlock.bind( this, 'core/paragraph' ); + this.insertImage = this.insertBlock.bind( this, 'core/image' ); + + this.state = { + isShowingControls: false, + }; + } + + toggleControls( isShowingControls ) { + this.setState( { isShowingControls } ); + } + + insertBlock( name ) { + const { onInsertBlock } = this.props; + onInsertBlock( createBlock( name ) ); + } + + render() { + const { isShowingControls } = this.state; + const classes = classnames( 'editor-visual-editor__inserter', { + 'is-showing-controls': isShowingControls, + } ); + + return ( +
+ + + { __( 'Paragraph' ) } + + + { __( 'Image' ) } + +
+ ); + } +} + +export default connect( + null, + { onInsertBlock: insertBlock }, +)( VisualEditorInserter ); diff --git a/editor/modes/visual-editor/style.scss b/editor/modes/visual-editor/style.scss index 1f29f3cf0481c2..7c027ee679509d 100644 --- a/editor/modes/visual-editor/style.scss +++ b/editor/modes/visual-editor/style.scss @@ -459,7 +459,7 @@ $sticky-bottom-offset: 20px; } } -.editor-visual-editor__continue-writing { +.editor-visual-editor__inserter { display: flex; align-items: baseline; max-width: $visual-editor-max-width + ( 2 * $block-mover-padding-visible ); diff --git a/editor/modes/visual-editor/test/inserter.js b/editor/modes/visual-editor/test/inserter.js new file mode 100644 index 00000000000000..8d16992690820a --- /dev/null +++ b/editor/modes/visual-editor/test/inserter.js @@ -0,0 +1,56 @@ +/** + * External dependencies + */ +import { shallow } from 'enzyme'; + +/** + * Internal dependencies + */ +import { VisualEditorInserter } from '../inserter'; + +describe( 'VisualEditorInserter', () => { + it( 'should show controls when receiving focus', () => { + const wrapper = shallow( ); + + wrapper.simulate( 'focus' ); + + expect( wrapper.state( 'isShowingControls' ) ).toBe( true ); + } ); + + it( 'should hide controls when losing focus', () => { + const wrapper = shallow( ); + + wrapper.simulate( 'focus' ); + wrapper.simulate( 'blur' ); + + expect( wrapper.state( 'isShowingControls' ) ).toBe( false ); + } ); + + it( 'should insert paragraph block', () => { + const onInsertBlock = jest.fn(); + const wrapper = shallow( + + ); + + wrapper + .findWhere( ( node ) => node.prop( 'children' ) === 'Paragraph' ) + .simulate( 'click' ); + + expect( onInsertBlock ).toHaveBeenCalled(); + expect( onInsertBlock.mock.calls[ 0 ][ 0 ].name ).toBe( 'core/paragraph' ); + } ); + + it( 'should insert image block', () => { + const onInsertBlock = jest.fn(); + const wrapper = shallow( + + ); + + wrapper + .findWhere( ( node ) => node.prop( 'children' ) === 'Image' ) + .simulate( 'click' ); + + expect( onInsertBlock ).toHaveBeenCalled(); + expect( onInsertBlock.mock.calls[ 0 ][ 0 ].name ).toBe( 'core/image' ); + } ); +} );