Skip to content

Commit

Permalink
Block List: Move deselect behavior to block component
Browse files Browse the repository at this point in the history
  • Loading branch information
aduth committed Nov 30, 2017
1 parent 1efbb9f commit 2bd32f8
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 57 deletions.
33 changes: 31 additions & 2 deletions editor/components/block-list/block.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@
import { connect } from 'react-redux';
import classnames from 'classnames';
import { get, partial, reduce, size } from 'lodash';
import 'element-closest';

/**
* WordPress dependencies
*/
import { Component, compose, createElement } from '@wordpress/element';
import { keycodes } from '@wordpress/utils';
import { getBlockType, BlockEdit, getBlockDefaultClassname, createBlock, hasBlockSupport } from '@wordpress/blocks';
import { withFilters } from '@wordpress/components';
import { withFilters, withFocusOutside } from '@wordpress/components';
import { __, sprintf } from '@wordpress/i18n';

/**
Expand Down Expand Up @@ -168,6 +169,33 @@ class BlockListBlock extends Component {
this.props.blockRef( node, this.props.uid );
}

handleFocusOutside( event ) {
if ( ! this.props.isSelected ) {
return;
}

// There are several cases in which focus transitions outside the DOM
// space of a block, but is not truly outside, typically when managing
// toolbar or inspector controls. While this implementation binds
// awareness to ancestry, it still retains more self-sufficiency to a
// block than attempting to externally manage focus transitions. An
// alternative here would leverage React 16 portal virtual event
// bubbling, but we must first eliminate dependencies between toolbar
// and multi-selection DOM-based event bubbling.
//
// See: https://github.com/WordPress/gutenberg/pull/3083
// See: https://reactjs.org/docs/portals.html#event-bubbling-through-portals
const { relatedTarget } = event;
const isOutside = ! relatedTarget || ! relatedTarget.closest( [
'.editor-header',
'.editor-sidebar',
].join( ',' ) );

if ( isOutside ) {
this.props.onDeselect();
}
}

bindBlockNode( node ) {
this.node = node;
}
Expand Down Expand Up @@ -516,5 +544,6 @@ const mapDispatchToProps = ( dispatch, ownProps ) => ( {

export default compose(
withFilters( 'Editor.BlockItem' ),
connect( mapStateToProps, mapDispatchToProps )
connect( mapStateToProps, mapDispatchToProps ),
withFocusOutside
)( BlockListBlock );
67 changes: 12 additions & 55 deletions editor/edit-post/modes/visual-editor/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,6 @@
*/
import { connect } from 'react-redux';

/**
* WordPress dependencies
*/
import { Component, findDOMNode } from '@wordpress/element';

/**
* Internal dependencies
*/
Expand All @@ -17,56 +12,18 @@ import VisualEditorInserter from './inserter';
import { isFeatureActive } from '../../../selectors';
import { clearSelectedBlock } from '../../../actions';

class VisualEditor extends Component {
constructor() {
super( ...arguments );
this.bindContainer = this.bindContainer.bind( this );
this.bindBlocksContainer = this.bindBlocksContainer.bind( this );
this.onClick = this.onClick.bind( this );
}

bindContainer( ref ) {
this.container = ref;
}

bindBlocksContainer( ref ) {
// Disable reason: Need DOM node to determine if clicking on layout
// canvas when intending to clear block selection.
// TODO: Refactor block selection clearing using blur events on block.
// eslint-disable-next-line react/no-find-dom-node
this.blocksContainer = findDOMNode( ref );
}

onClick( event ) {
if ( event.target === this.container || event.target === this.blocksContainer ) {
this.props.clearSelectedBlock();
}
}

render() {
// Disable reason: Clicking the canvas should clear the selection
/* eslint-disable jsx-a11y/no-static-element-interactions */
return (
<div
className="editor-visual-editor"
onMouseDown={ this.onClick }
onTouchStart={ this.onClick }
ref={ this.bindContainer }
>
<EditorGlobalKeyboardShortcuts />
<WritingFlow>
<PostTitle />
<BlockList
ref={ this.bindBlocksContainer }
showContextualToolbar={ ! this.props.hasFixedToolbar }
/>
<DefaultBlockAppender />
</WritingFlow>
<VisualEditorInserter />
</div>
);
/* eslint-enable jsx-a11y/no-static-element-interactions */
}
function VisualEditor( { hasFixedToolbar } ) {
return (
<div className="editor-visual-editor">
<EditorGlobalKeyboardShortcuts />
<WritingFlow>
<PostTitle />
<BlockList showContextualToolbar={ ! hasFixedToolbar } />
<DefaultBlockAppender />
</WritingFlow>
<VisualEditorInserter />
</div>
);
}

export default connect(
Expand Down

0 comments on commit 2bd32f8

Please sign in to comment.