diff --git a/app/soapbox/components/dropdown_menu.js b/app/soapbox/components/dropdown_menu.js index 8c1d709d1..7067e8e9e 100644 --- a/app/soapbox/components/dropdown_menu.js +++ b/app/soapbox/components/dropdown_menu.js @@ -45,8 +45,6 @@ class DropdownMenu extends React.PureComponent { document.addEventListener('click', this.handleDocumentClick, false); document.addEventListener('keydown', this.handleKeyDown, false); document.addEventListener('touchend', this.handleDocumentClick, listenerOptions); - if (this.focusedItem && this.props.openedViaKeyboard) this.focusedItem.focus(); - this.activeElement = document.activeElement; if (this.focusedItem && this.props.openedViaKeyboard) { this.focusedItem.focus(); } @@ -57,9 +55,6 @@ class DropdownMenu extends React.PureComponent { document.removeEventListener('click', this.handleDocumentClick, false); document.removeEventListener('keydown', this.handleKeyDown, false); document.removeEventListener('touchend', this.handleDocumentClick, listenerOptions); - if (this.activeElement) { - this.activeElement.focus(); - } } setRef = c => { @@ -118,7 +113,7 @@ class DropdownMenu extends React.PureComponent { } } - handleItemKeyUp = e => { + handleItemKeyPress = e => { if (e.key === 'Enter' || e.key === ' ') { this.handleClick(e); } @@ -173,7 +168,7 @@ class DropdownMenu extends React.PureComponent { ref={i === 0 ? this.setFocusRef : null} onClick={this.handleClick} onAuxClick={this.handleAuxClick} - onKeyUp={this.handleItemKeyUp} + onKeyPress={this.handleItemKeyPress} data-index={i} target={newTab ? '_blank' : null} data-method={isLogout ? 'delete' : null} @@ -248,9 +243,39 @@ export default class Dropdown extends React.PureComponent { } handleClose = () => { + if (this.activeElement) { + this.activeElement.focus(); + this.activeElement = null; + } this.props.onClose(this.state.id); } + handleMouseDown = () => { + if (!this.state.open) { + this.activeElement = document.activeElement; + } + } + + handleButtonKeyDown = (e) => { + switch(e.key) { + case ' ': + case 'Enter': + this.handleMouseDown(); + break; + } + } + + handleKeyPress = (e) => { + switch(e.key) { + case ' ': + case 'Enter': + this.handleClick(e); + e.stopPropagation(); + e.preventDefault(); + break; + } + } + handleItemClick = e => { const i = Number(e.currentTarget.getAttribute('data-index')); const { action, to } = this.props.items[i]; @@ -294,6 +319,9 @@ export default class Dropdown extends React.PureComponent { size={size} ref={this.setTargetRef} onClick={this.handleClick} + onMouseDown={this.handleMouseDown} + onKeyDown={this.handleButtonKeyDown} + onKeyPress={this.handleKeyPress} /> diff --git a/app/soapbox/components/icon_button.js b/app/soapbox/components/icon_button.js index 9231ee133..0d290c781 100644 --- a/app/soapbox/components/icon_button.js +++ b/app/soapbox/components/icon_button.js @@ -16,6 +16,7 @@ export default class IconButton extends React.PureComponent { onMouseDown: PropTypes.func, onKeyUp: PropTypes.func, onKeyDown: PropTypes.func, + onKeyPress: PropTypes.func, onMouseEnter: PropTypes.func, onMouseLeave: PropTypes.func, size: PropTypes.number, @@ -73,6 +74,12 @@ export default class IconButton extends React.PureComponent { } } + handleKeyPress = (e) => { + if (this.props.onKeyPress && !this.props.disabled) { + this.props.onKeyPress(e); + } + } + render() { const style = { fontSize: `${this.props.size}px`, @@ -120,6 +127,7 @@ export default class IconButton extends React.PureComponent { onMouseDown={this.handleMouseDown} onKeyDown={this.handleKeyDown} onKeyUp={this.handleKeyUp} + onKeyPress={this.handleKeyPress} onMouseEnter={this.props.onMouseEnter} onMouseLeave={this.props.onMouseLeave} tabIndex={tabIndex} @@ -148,6 +156,7 @@ export default class IconButton extends React.PureComponent { onMouseDown={this.handleMouseDown} onKeyDown={this.handleKeyDown} onKeyUp={this.handleKeyUp} + onKeyPress={this.handleKeyPress} onMouseEnter={this.props.onMouseEnter} onMouseLeave={this.props.onMouseLeave} tabIndex={tabIndex}