-
Notifications
You must be signed in to change notification settings - Fork 4.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Block List: Display sibling inserter between blocks
Block List: Render inserter only while hovered, focused Inserter: Style insertion point below between-serter Inserter: Position between-serter as centered below Block: Refactor insertion point within sibling inserter Block List: Accumuate block list by Array#reduce Significant performance degredation when children as tuple. Instead, flatten into single array Inserter: Disallow container tabbable when visible Prevents shift-tab focus trap which can occur while button is focused, since focusFirstTabbable would continue to keep button focused
- Loading branch information
Showing
7 changed files
with
217 additions
and
71 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,6 +11,7 @@ | |
overflow: hidden; | ||
|
||
.dashicon { | ||
display: block; | ||
flex: 0 0 auto; | ||
} | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
/** | ||
* External dependencies | ||
*/ | ||
import { connect } from 'react-redux'; | ||
import classnames from 'classnames'; | ||
|
||
/** | ||
* WordPress dependencies | ||
*/ | ||
import { Component } from '@wordpress/element'; | ||
import { focus } from '@wordpress/utils'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import Inserter from '../../inserter'; | ||
import { | ||
getBlockInsertionPoint, | ||
isBlockInsertionPointVisible, | ||
} from '../../selectors'; | ||
|
||
class VisualEditorSiblingInserter extends Component { | ||
constructor() { | ||
super( ...arguments ); | ||
|
||
this.bindNode = this.bindNode.bind( this ); | ||
this.focusFirstTabbable = this.focusFirstTabbable.bind( this ); | ||
this.show = this.toggleVisible.bind( this, true ); | ||
this.hide = this.toggleVisible.bind( this, false ); | ||
this.showAndFocus = this.showAndFocus.bind( this ); | ||
this.suspendToggleVisible = this.suspendToggleVisible.bind( this ); | ||
|
||
this.state = { | ||
isVisible: false, | ||
isToggleVisibleSuspended: false, | ||
}; | ||
} | ||
|
||
componentDidUpdate( prevProps, prevState ) { | ||
const { visibleViaFocus, state } = this; | ||
const { isVisible, isToggleVisibleSuspended } = state; | ||
if ( isVisible && ! prevState.isVisible && visibleViaFocus ) { | ||
this.focusFirstTabbable(); | ||
|
||
// Reset for next toggle visible | ||
this.visibleViaFocus = false; | ||
} | ||
|
||
// If inserter is closed, we must check to see if focus is still within | ||
// the inserter, since it may have been closed by clicking outside. We | ||
// want to retain visible if still focused, or hide otherwise. | ||
if ( ! isToggleVisibleSuspended && prevState.isToggleVisibleSuspended && | ||
! this.node.contains( document.activeElement ) ) { | ||
this.toggleVisible( false ); | ||
} | ||
} | ||
|
||
bindNode( node ) { | ||
this.node = node; | ||
} | ||
|
||
focusFirstTabbable() { | ||
// Sibling inserter doesn't render its inserter button until after it | ||
// becomes visible by focus or hover. If visible by focus, move focus | ||
// into the now-visible button. | ||
const tabbable = focus.tabbable.find( this.node ); | ||
if ( tabbable.length ) { | ||
tabbable[ 0 ].focus(); | ||
} | ||
} | ||
|
||
toggleVisible( isVisible ) { | ||
if ( ! this.state.isToggleVisibleSuspended ) { | ||
this.setState( { isVisible } ); | ||
} | ||
} | ||
|
||
showAndFocus() { | ||
this.toggleVisible( true ); | ||
this.visibleViaFocus = true; | ||
} | ||
|
||
suspendToggleVisible( isOpen ) { | ||
// Prevent mouseout and blur while navigating the open inserter menu | ||
// from causing the inserter to be unmounted. | ||
this.setState( { isToggleVisibleSuspended: isOpen } ); | ||
} | ||
|
||
render() { | ||
const { insertIndex, showInsertionPoint } = this.props; | ||
const { isVisible } = this.state; | ||
|
||
const classes = classnames( 'editor-visual-editor__sibling-inserter', { | ||
'is-visible': isVisible || showInsertionPoint, | ||
} ); | ||
|
||
return ( | ||
<div | ||
ref={ this.bindNode } | ||
data-insert-index={ insertIndex } | ||
className={ classes } | ||
onFocus={ this.showAndFocus } | ||
onBlur={ this.hide } | ||
onMouseEnter={ this.show } | ||
onMouseLeave={ this.hide } | ||
tabIndex={ isVisible ? -1 : 0 }> | ||
{ showInsertionPoint && ( | ||
<div className="editor-visual-editor__insertion-point" /> | ||
) } | ||
{ isVisible && [ | ||
<hr | ||
key="rule" | ||
className="editor-visual-editor__sibling-inserter-rule" | ||
/>, | ||
<Inserter | ||
key="inserter" | ||
position="bottom" | ||
insertIndex={ insertIndex } | ||
onToggle={ this.suspendToggleVisible } | ||
/>, | ||
] } | ||
</div> | ||
); | ||
} | ||
} | ||
|
||
export default connect( | ||
( state, ownProps ) => { | ||
return { | ||
showInsertionPoint: ( | ||
isBlockInsertionPointVisible( state ) && | ||
getBlockInsertionPoint( state ) === ownProps.insertIndex | ||
), | ||
}; | ||
} | ||
)( VisualEditorSiblingInserter ); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters