-
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
Block List: Display inserter button after block on hover, focus #2890
Changes from 1 commit
7e0f2e3
4708e7c
ac2888c
e3e0741
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 |
---|---|---|
|
@@ -51,11 +51,11 @@ export class InserterMenu extends Component { | |
} | ||
|
||
componentDidMount() { | ||
document.addEventListener( 'keydown', this.onKeyDown ); | ||
document.addEventListener( 'keydown', this.onKeyDown, true ); | ||
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. Could you explain why this change is necessary? 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 is a similar issue to the one discussed at #2706: Namely, WritingFlow is handling the arrow presses and moving between blocks. The |
||
} | ||
|
||
componentWillUnmount() { | ||
document.removeEventListener( 'keydown', this.onKeyDown ); | ||
document.removeEventListener( 'keydown', this.onKeyDown, true ); | ||
} | ||
|
||
componentDidUpdate( prevProps, prevState ) { | ||
|
@@ -239,28 +239,32 @@ export class InserterMenu extends Component { | |
return; | ||
} | ||
this.focusPrevious( this ); | ||
|
||
break; | ||
|
||
case UP: | ||
keydown.preventDefault(); | ||
this.focusPrevious( this ); | ||
|
||
break; | ||
|
||
case RIGHT: | ||
if ( this.state.currentFocus === 'search' ) { | ||
return; | ||
} | ||
this.focusNext( this ); | ||
|
||
break; | ||
|
||
case DOWN: | ||
keydown.preventDefault(); | ||
this.focusNext( this ); | ||
|
||
break; | ||
default : | ||
break; | ||
|
||
default: | ||
return; | ||
} | ||
|
||
// Since unhandled key will return in the default case, we can assume | ||
// having reached this point implies that the key is handled. | ||
keydown.stopImmediatePropagation(); | ||
} | ||
|
||
changeMenuSelection( refName ) { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,6 +23,7 @@ import BlockDropZone from './block-drop-zone'; | |
import BlockMover from '../../block-mover'; | ||
import BlockRightMenu from '../../block-settings-menu'; | ||
import BlockToolbar from '../../block-toolbar'; | ||
import Inserter from '../../inserter'; | ||
import { | ||
clearSelectedBlock, | ||
editPost, | ||
|
@@ -49,6 +50,7 @@ import { | |
isBlockSelected, | ||
isFirstMultiSelectedBlock, | ||
isTyping, | ||
isInsertingSiblingBlock, | ||
} from '../../selectors'; | ||
|
||
const { BACKSPACE, ESCAPE, DELETE, ENTER } = keycodes; | ||
|
@@ -61,6 +63,7 @@ class VisualEditorBlock extends Component { | |
this.setAttributes = this.setAttributes.bind( this ); | ||
this.maybeHover = this.maybeHover.bind( this ); | ||
this.maybeStartTyping = this.maybeStartTyping.bind( this ); | ||
this.mouseLeaveUnlessInserting = this.mouseLeaveUnlessInserting.bind( this ); | ||
this.stopTypingOnMouseMove = this.stopTypingOnMouseMove.bind( this ); | ||
this.removeOrDeselect = this.removeOrDeselect.bind( this ); | ||
this.mergeBlocks = this.mergeBlocks.bind( this ); | ||
|
@@ -157,9 +160,9 @@ class VisualEditorBlock extends Component { | |
} | ||
|
||
maybeHover() { | ||
const { isHovered, isSelected, isMultiSelected, onHover } = this.props; | ||
const { isHovered, isSelected, isMultiSelected, isInserterOpen, onHover } = this.props; | ||
|
||
if ( isHovered || isSelected || isMultiSelected ) { | ||
if ( isHovered || isSelected || isMultiSelected || isInserterOpen ) { | ||
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 guess this check is to avoid "removing" the inserter when we hover out of the block? 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.
That sounds like a good idea! I'll give it a try. |
||
return; | ||
} | ||
|
||
|
@@ -177,6 +180,12 @@ class VisualEditorBlock extends Component { | |
} | ||
} | ||
|
||
mouseLeaveUnlessInserting() { | ||
if ( ! this.props.isInserterOpen ) { | ||
this.props.onMouseLeave(); | ||
} | ||
} | ||
|
||
stopTypingOnMouseMove( { clientX, clientY } ) { | ||
const { lastClientX, lastClientY } = this; | ||
|
||
|
@@ -278,7 +287,7 @@ class VisualEditorBlock extends Component { | |
} | ||
|
||
render() { | ||
const { block, multiSelectedBlockUids, order } = this.props; | ||
const { block, multiSelectedBlockUids, order, nextBlock } = this.props; | ||
const { name: blockName, isValid } = block; | ||
const blockType = getBlockType( blockName ); | ||
// translators: %s: Type of block (i.e. Text, Image etc) | ||
|
@@ -310,7 +319,7 @@ class VisualEditorBlock extends Component { | |
'is-hovered': isHovered, | ||
} ); | ||
|
||
const { onMouseLeave, onFocus, onReplace } = this.props; | ||
const { onFocus, onReplace } = this.props; | ||
|
||
// Determine whether the block has props to apply to the wrapper. | ||
let wrapperProps; | ||
|
@@ -331,7 +340,7 @@ class VisualEditorBlock extends Component { | |
onFocus={ this.onFocus } | ||
onMouseMove={ this.maybeHover } | ||
onMouseEnter={ this.maybeHover } | ||
onMouseLeave={ onMouseLeave } | ||
onMouseLeave={ this.mouseLeaveUnlessInserting } | ||
className={ wrapperClassname } | ||
data-type={ block.name } | ||
tabIndex="0" | ||
|
@@ -381,6 +390,9 @@ class VisualEditorBlock extends Component { | |
} | ||
</BlockCrashBoundary> | ||
</div> | ||
{ ( showUI || isHovered ) && !! nextBlock && ( | ||
<Inserter insertIndex={ order + 1 } /> | ||
) } | ||
{ !! error && <BlockCrashWarning /> } | ||
</div> | ||
); | ||
|
@@ -403,6 +415,7 @@ export default connect( | |
order: getBlockIndex( state, ownProps.uid ), | ||
multiSelectedBlockUids: getMultiSelectedBlockUids( state ), | ||
meta: getEditedPostAttribute( state, 'meta' ), | ||
isInserterOpen: isInsertingSiblingBlock( state ), | ||
}; | ||
}, | ||
( dispatch, ownProps ) => ( { | ||
|
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.
I guess we don't need this to be a class component, but probably the same discussion for/against inline props.
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.
I hope we will see the day where there is only one supported way of creating components in React. I feel like some components are converted back and forth whenever requirements change.