-
Notifications
You must be signed in to change notification settings - Fork 4.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Inserter: Try showing a "line" between two blocks on hover to insert a new empty block #5198
Changes from all commits
c1525e4
f3deea9
95da6d0
802106c
375b201
c0aad6c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,36 +3,74 @@ | |
*/ | ||
import { connect } from 'react-redux'; | ||
|
||
/** | ||
* WordPress dependencies | ||
*/ | ||
import { __ } from '@wordpress/i18n'; | ||
import { isUnmodifiedDefaultBlock } from '@wordpress/blocks'; | ||
import { Component } from '@wordpress/element'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import { | ||
getBlockIndex, | ||
getBlockInsertionPoint, | ||
isBlockInsertionPointVisible, | ||
getBlockCount, | ||
getBlock, | ||
isTyping, | ||
} from '../../store/selectors'; | ||
import { | ||
insertDefaultBlock, | ||
startTyping, | ||
} from '../../store/actions'; | ||
|
||
function BlockInsertionPoint( { showInsertionPoint } ) { | ||
if ( ! showInsertionPoint ) { | ||
return null; | ||
class BlockInsertionPoint extends Component { | ||
constructor() { | ||
super( ...arguments ); | ||
this.onClick = this.onClick.bind( this ); | ||
} | ||
onClick() { | ||
const { layout, rootUID, index, ...props } = this.props; | ||
props.insertDefaultBlock( { layout }, rootUID, index ); | ||
props.startTyping(); | ||
} | ||
|
||
render() { | ||
const { showInsertionPoint, showInserter } = this.props; | ||
|
||
return <div className="editor-block-list__insertion-point" />; | ||
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> | ||
); | ||
} | ||
} | ||
|
||
export default connect( | ||
( state, { uid, rootUID } ) => { | ||
const blockIndex = uid ? getBlockIndex( state, uid, rootUID ) : -1; | ||
const insertIndex = blockIndex > -1 ? blockIndex + 1 : getBlockCount( state ); | ||
const insertIndex = blockIndex + 1; | ||
const insertionPoint = getBlockInsertionPoint( state ); | ||
const block = uid ? getBlock( state, uid ) : null; | ||
|
||
return { | ||
showInsertionPoint: ( | ||
isBlockInsertionPointVisible( state ) && | ||
insertionPoint.index === insertIndex && | ||
insertionPoint.rootUID === rootUID | ||
insertionPoint.rootUID === rootUID && | ||
( ! block || ! isUnmodifiedDefaultBlock( block ) ) | ||
), | ||
showInserter: ! isTyping( state ), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm looking to enhance the between-inserter and am unclear the intent with this condition. Why do we only render the inserter button while not typing? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Honestly, I don't remember why I added this exactly :) |
||
index: insertIndex, | ||
}; | ||
}, | ||
{ insertDefaultBlock, startTyping } | ||
)( BlockInsertionPoint ); |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -24,6 +24,7 @@ import { Component } from '@wordpress/element'; | |
*/ | ||
import './style.scss'; | ||
import BlockListBlock from './block'; | ||
import BlockInsertionPoint from './insertion-point'; | ||
import BlockSelectionClearer from '../block-selection-clearer'; | ||
import DefaultBlockAppender from '../default-block-appender'; | ||
import { | ||
|
@@ -215,6 +216,7 @@ class BlockListLayout extends Component { | |
|
||
return ( | ||
<BlockSelectionClearer className={ classes }> | ||
{ !! blockUIDs.length && <BlockInsertionPoint /> } | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This needed to be passed |
||
{ map( blockUIDs, ( uid, blockIndex ) => ( | ||
<BlockListBlock | ||
key={ 'block-' + uid } | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -371,21 +371,55 @@ | |
|
||
.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: 16px; | ||
height: 2px; | ||
left: 0; | ||
right: 0; | ||
background: $blue-medium-500; | ||
} | ||
|
||
.editor-block-list__insertion-point-inserter { | ||
position: absolute; | ||
background: none; | ||
border: none; | ||
display: block; | ||
top: 0; | ||
height: 34px; // Matches the whole empty space between two blocks | ||
width: 100%; | ||
cursor: pointer; | ||
|
||
&:before { | ||
position: absolute; | ||
top: -1px; | ||
top: 16px; | ||
height: 2px; | ||
left: 0; | ||
right: 0; | ||
background: $blue-medium-500; | ||
left: $block-padding; | ||
right: $block-padding; | ||
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:before { | ||
opacity: 1; | ||
transition: opacity 0.2s linear; | ||
} | ||
} | ||
|
||
.editor-block-list__block > .editor-block-list__insertion-point { | ||
position: absolute; | ||
bottom: -10px; | ||
bottom: -19px; | ||
height: 34px; // Matches the whole empty space between two blocks | ||
top: auto; | ||
left: 0; | ||
right: 0; | ||
|
@@ -396,6 +430,21 @@ | |
} | ||
} | ||
|
||
.editor-block-list__layout > .editor-block-list__insertion-point { | ||
position: relative; | ||
margin-top: -15px; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
margin-left: auto; | ||
margin-right: auto; | ||
top: -19px; | ||
left: 0; | ||
right: 0; | ||
|
||
@include break-small { | ||
left: $block-mover-padding-visible; | ||
right: $block-mover-padding-visible; | ||
} | ||
} | ||
|
||
.editor-block-list__block .editor-block-list__block-html-textarea { | ||
display: block; | ||
margin: 0; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Anticipating a future bug: Arrowing up or down from a block will focus the between-inserter.
There's no good reason we don't include
button
in this set:gutenberg/editor/components/writing-flow/index.js
Lines 76 to 85 in f3c1e22
...Actually, I'm seeing the "good reason", and it's to avoid focus moving into the block toolbar. This is very fragile, as I'd guess if someone did something like add an
input
(input type="button"
) into the toolbar, it'd break as-is.