Improve keyboard VS mouse navigation of dropdown menus

This commit is contained in:
Thibaut Girka 2018-09-11 22:44:20 +02:00 committed by ThibG
parent 44192cb9d2
commit 85befb90b2

View file

@ -43,13 +43,15 @@ class DropdownMenu extends React.PureComponent {
componentDidMount () { componentDidMount () {
document.addEventListener('click', this.handleDocumentClick, false); document.addEventListener('click', this.handleDocumentClick, false);
document.addEventListener('keydown', this.handleKeyDown, false);
document.addEventListener('touchend', this.handleDocumentClick, listenerOptions); document.addEventListener('touchend', this.handleDocumentClick, listenerOptions);
if (this.focusedItem && this.props.openedviaKeyBoard) this.focusedItem.focus(); if (this.focusedItem && this.props.openedViaKeyboard) this.focusedItem.focus();
this.setState({ mounted: true }); this.setState({ mounted: true });
} }
componentWillUnmount () { componentWillUnmount () {
document.removeEventListener('click', this.handleDocumentClick, false); document.removeEventListener('click', this.handleDocumentClick, false);
document.removeEventListener('keydown', this.handleKeyDown, false);
document.removeEventListener('touchend', this.handleDocumentClick, listenerOptions); document.removeEventListener('touchend', this.handleDocumentClick, listenerOptions);
} }
@ -63,13 +65,10 @@ class DropdownMenu extends React.PureComponent {
handleKeyDown = e => { handleKeyDown = e => {
const items = Array.from(this.node.getElementsByTagName('a')); const items = Array.from(this.node.getElementsByTagName('a'));
const index = items.indexOf(e.currentTarget); const index = items.indexOf(document.activeElement);
let element; let element;
switch(e.key) { switch(e.key) {
case 'Enter':
this.handleClick(e);
break;
case 'ArrowDown': case 'ArrowDown':
element = items[index+1]; element = items[index+1];
if (element) { if (element) {
@ -97,6 +96,12 @@ class DropdownMenu extends React.PureComponent {
} }
} }
handleItemKeyDown = e => {
if (e.key === 'Enter') {
this.handleClick(e);
}
}
handleClick = e => { handleClick = e => {
const i = Number(e.currentTarget.getAttribute('data-index')); const i = Number(e.currentTarget.getAttribute('data-index'));
const { action, to } = this.props.items[i]; const { action, to } = this.props.items[i];
@ -121,7 +126,7 @@ class DropdownMenu extends React.PureComponent {
return ( return (
<li className='dropdown-menu__item' key={`${text}-${i}`}> <li className='dropdown-menu__item' key={`${text}-${i}`}>
<a href={href} target='_blank' rel='noopener' role='button' tabIndex='0' ref={i === 0 ? this.setFocusRef : null} onClick={this.handleClick} onKeyDown={this.handleKeyDown} data-index={i}> <a href={href} target='_blank' rel='noopener' role='button' tabIndex='0' ref={i === 0 ? this.setFocusRef : null} onClick={this.handleClick} onKeyDown={this.handleItemKeyDown} data-index={i}>
{text} {text}
</a> </a>
</li> </li>