Skip to content

Commit

Permalink
Try a different inbetweenserter approach (#6818)
Browse files Browse the repository at this point in the history
* Try a different inbetweenserter approach

This is an attempt to redesign the inbetweenserter to be less frustrating. Currently in master it's too easy to invoke it whe
n you don't mean to.

This branch changes that approach. You can still hover between two lines to reveal a line indicator. But you can't click this line. Instead, a new plus button sits at the center of this line, and you have to click that to insert between.

Please give this a spin. Depending on feedback, it needs visual love, and other tweaks. Right now it's definitely a try branch, and needs your thoughts.

* Hide inbetween inserter from empty paragraph blocks + css tweaks

* Use a labal prop instead of aria-label for the insertion point

* Make the inserter visible when focused

* Fix e2e tests
  • Loading branch information
jasmussen committed May 23, 2018
1 parent 84db5f5 commit 76e7b2a
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 61 deletions.
2 changes: 1 addition & 1 deletion edit-post/assets/stylesheets/_z-index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ $z-layers: (
'.editor-block-contextual-toolbar': 21,
'.editor-block-switcher__menu': 5,
'.components-popover__close': 5,
'.editor-block-list__insertion-point': 5,
'.editor-block-list__insertion-point': 82, // @todo, test that this new elevation doesn't cause issues, used to be 5, shoud now be above side UI
'.editor-format-toolbar__link-modal': 81, // should appear above block controls
'.editor-format-toolbar__link-container': 81, // link suggestions should also
'.core-blocks-gallery-item__inline-menu': 20,
Expand Down
5 changes: 0 additions & 5 deletions edit-post/components/visual-editor/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,3 @@
}
}
}

.edit-post-visual-editor .editor-block-list__layout > .editor-block-list__insertion-point {
max-width: $content-width;
position: relative;
}
25 changes: 13 additions & 12 deletions editor/components/block-list/block.js
Original file line number Diff line number Diff line change
Expand Up @@ -407,11 +407,12 @@ export class BlockListBlock extends Component {
isSelected,
isMultiSelected,
isFirstMultiSelected,
isLastInSelection,
isTypingWithinBlock,
isMultiSelecting,
hoverArea,
isLargeViewport,
isEmptyDefaultBlock,
isPreviousBlockADefaultEmptyBlock,
} = this.props;
const isHovered = this.state.isHovered && ! isMultiSelecting;
const { name: blockName, isValid } = block;
Expand All @@ -423,7 +424,6 @@ export class BlockListBlock extends Component {

// If the block is selected and we're typing the block should not appear.
// Empty paragraph blocks should always show up as unselected.
const isEmptyDefaultBlock = isUnmodifiedDefaultBlock( block );
const isSelectedNotTyping = isSelected && ! isTypingWithinBlock;
const showEmptyBlockSideInserter = ( isSelected || isHovered ) && isEmptyDefaultBlock;
const shouldAppearSelected = ! showEmptyBlockSideInserter && isSelectedNotTyping;
Expand All @@ -438,11 +438,8 @@ export class BlockListBlock extends Component {
// Insertion point can only be made visible when the side inserter is
// not present, and either the block is at the extent of a selection or
// is the first block in the top-level list rendering.
const shouldShowInsertionPoint = (
( ! isMultiSelected && ! isFirst ) ||
( isMultiSelected && isLastInSelection ) ||
( isFirst && ! rootUID && ! isEmptyDefaultBlock )
);
const shouldShowInsertionPoint = ( isMultiSelected && isFirst ) || ! isMultiSelected;
const canShowInBetweenInserter = ! isEmptyDefaultBlock && ! isPreviousBlockADefaultEmptyBlock;

// Generate the wrapper class names handling the different states of the block.
const wrapperClassName = classnames( 'editor-block-list__block', {
Expand Down Expand Up @@ -513,6 +510,7 @@ export class BlockListBlock extends Component {
uid={ uid }
rootUID={ rootUID }
layout={ layout }
canShowInserter={ canShowInBetweenInserter }
/>
) }
<BlockDropZone
Expand Down Expand Up @@ -621,20 +619,19 @@ const applyWithSelect = withSelect( ( select, { uid, rootUID } ) => {
getBlockMode,
isSelectionEnabled,
getSelectedBlocksInitialCaretPosition,
getBlockSelectionEnd,
getEditorSettings,
} = select( 'core/editor' );
const isSelected = isBlockSelected( uid );
const { templateLock, hasFixedToolbar } = getEditorSettings();
const block = getBlock( uid );
const previousBlockUid = getPreviousBlockUid( uid );
const previousBlock = getBlock( previousBlockUid );

return {
previousBlockUid: getPreviousBlockUid( uid ),
nextBlockUid: getNextBlockUid( uid ),
block: getBlock( uid ),
isMultiSelected: isBlockMultiSelected( uid ),
isFirstMultiSelected: isFirstMultiSelectedBlock( uid ),
isMultiSelecting: isMultiSelecting(),
isLastInSelection: getBlockSelectionEnd() === uid,
// We only care about this prop when the block is selected
// Thus to avoid unnecessary rerenders we avoid updating the prop if the block is not selected.
isTypingWithinBlock: isSelected && isTyping(),
Expand All @@ -643,8 +640,12 @@ const applyWithSelect = withSelect( ( select, { uid, rootUID } ) => {
mode: getBlockMode( uid ),
isSelectionEnabled: isSelectionEnabled(),
initialPosition: getSelectedBlocksInitialCaretPosition(),
isSelected,
isEmptyDefaultBlock: block && isUnmodifiedDefaultBlock( block ),
isPreviousBlockADefaultEmptyBlock: previousBlock && isUnmodifiedDefaultBlock( previousBlock ),
isLocked: !! templateLock,
previousBlockUid,
block,
isSelected,
hasFixedToolbar,
};
} );
Expand Down
45 changes: 37 additions & 8 deletions editor/components/block-list/insertion-point.js
Original file line number Diff line number Diff line change
@@ -1,43 +1,72 @@
/**
* External dependencies
*/
import classnames from 'classnames';

/**
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';
import { isUnmodifiedDefaultBlock } from '@wordpress/blocks';
import { Component, compose } from '@wordpress/element';
import { ifCondition } from '@wordpress/components';
import { ifCondition, IconButton } from '@wordpress/components';
import { withSelect, withDispatch } from '@wordpress/data';

class BlockInsertionPoint extends Component {
constructor() {
super( ...arguments );
this.state = {
isInserterFocused: false,
};

this.onBlurInserter = this.onBlurInserter.bind( this );
this.onFocusInserter = this.onFocusInserter.bind( this );
this.onClick = this.onClick.bind( this );
}

onFocusInserter() {
this.setState( {
isInserterFocused: true,
} );
}

onBlurInserter() {
this.setState( {
isInserterFocused: false,
} );
}

onClick() {
const { layout, rootUID, index, ...props } = this.props;
props.insertDefaultBlock( { layout }, rootUID, index );
props.startTyping();
}

render() {
const { isInserterFocused } = this.state;
const { showInsertionPoint, showInserter } = this.props;

return (
<div className="editor-block-list__insertion-point">
{ showInsertionPoint && <div className="editor-block-list__insertion-point-indicator" /> }
{ showInserter && (
<button
className="editor-block-list__insertion-point-inserter"
onClick={ this.onClick }
aria-label={ __( 'Insert block' ) }
/>
<div className={ classnames( 'editor-block-list__insertion-point-inserter', { 'is-visible': isInserterFocused } ) }>
<IconButton
icon="insert"
className="editor-block-list__insertion-point-button"
onClick={ this.onClick }
label={ __( 'Insert block' ) }
onFocus={ this.onFocusInserter }
onBlur={ this.onBlurInserter }
/>
</div>
) }
</div>
);
}
}
export default compose(
withSelect( ( select, { uid, rootUID } ) => {
withSelect( ( select, { uid, rootUID, canShowInserter } ) => {
const {
getBlockIndex,
getBlockInsertionPoint,
Expand All @@ -59,7 +88,7 @@ export default compose(

return {
templateLock: getEditorSettings().templateLock,
showInserter: ! isTyping(),
showInserter: ! isTyping() && canShowInserter,
index: insertIndex,
showInsertionPoint,
};
Expand Down
67 changes: 33 additions & 34 deletions editor/components/block-list/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -550,80 +550,79 @@
/**
* In-Canvas Inserter
*/

.editor-block-list .editor-inserter {
margin: $item-spacing;
cursor: move;/* Fallback for IE/Edge < 14 */
cursor: grab;
}

// Insertion point (includes inbetween inserter and insertion indicator)
.editor-block-list__insertion-point {
position: relative;
z-index: z-index( '.editor-block-list__insertion-point' );
}

.editor-block-list__insertion-point-indicator {
position: absolute;
top: $block-padding - 1px; // Half the empty space between two blocks, minus the 2px height
top: calc( 50% - 1px);
height: 2px;
left: 0;
right: 0;
background: theme( primary );
}

.editor-block-list__insertion-point-inserter {
display: flex;
position: absolute;
background: none;
border: none;
display: block;
top: 0;
bottom: auto;
left: 0;
right: 0;
height: $block-padding * 2; // Matches the whole empty space between two blocks
width: 100%;
cursor: pointer;
padding: 0; // Unstyle inherited padding from core button
justify-content: center;

// Show a clickable plus
.editor-block-list__insertion-point-button {
margin-top: -4px;
border-radius: 50%;
color: $dark-gray-100;
background: $white;
height: $block-padding * 2 + 8px;
width: $block-padding * 2 + 8px;

&:not(:disabled):not([aria-disabled="true"]):hover {
box-shadow: none;
}

}

// Show a line indicator when hovering, but this is unclickable
&:before {
position: absolute;
top: $block-padding - 1px; // Half the empty space between two blocks, minus the 2px height
top: calc( 50% - 1px);
height: 2px;
left: $block-padding;
right: $block-padding;
left: 0;
right: 0;
background: $dark-gray-100;
content: '';
opacity: 0;
transition: opacity 0.1s linear 0.1s;
}

&:hover:before {
opacity: 1;
transition: opacity 0.2s linear 0.5s;
}

&:focus {
outline: none;
}
// Hide both the line and button until hovered
opacity: 0;
transition: opacity 0.1s linear 0.1s;

// Show focus style when tabbing
&:focus:before {
&:hover, &.is-visible {
opacity: 1;
transition: opacity 0.2s linear;
outline: 1px solid $dark-gray-300;
outline-offset: 2px;
}

// Don't show focus style when clicking
&:focus:active:before {
outline: none;
}
}

.editor-block-list__block > .editor-block-list__insertion-point {
position: absolute;
top: -$block-padding;
top: -$block-padding - $block-spacing / 2;
height: $block-padding * 2; // Matches the whole empty space between two blocks
bottom: auto;
left: 0;
right: 0;
left: -1px;
right: -1px;
}

.editor-block-list__block .editor-block-list__block-html-textarea {
Expand Down
2 changes: 1 addition & 1 deletion test/e2e/specs/adding-blocks.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ describe( 'adding blocks', () => {
// Using the between inserter
await page.mouse.move( 200, 300 );
await page.mouse.move( 250, 350 );
const inserter = await page.$( '[data-type="core/quote"] .editor-block-list__insertion-point-inserter' );
const inserter = await page.$( '[data-type="core/quote"] .editor-block-list__insertion-point-button' );
await clickAtRightish( inserter );
await page.keyboard.type( 'Second paragraph' );

Expand Down

0 comments on commit 76e7b2a

Please sign in to comment.