diff --git a/app/soapbox/components/icon_button.js b/app/soapbox/components/icon_button.js index 21ed4ca95..9231ee133 100644 --- a/app/soapbox/components/icon_button.js +++ b/app/soapbox/components/icon_button.js @@ -13,6 +13,7 @@ export default class IconButton extends React.PureComponent { title: PropTypes.string.isRequired, icon: PropTypes.string.isRequired, onClick: PropTypes.func, + onMouseDown: PropTypes.func, onKeyUp: PropTypes.func, onKeyDown: PropTypes.func, onMouseEnter: PropTypes.func, @@ -54,6 +55,24 @@ export default class IconButton extends React.PureComponent { } } + handleMouseDown = (e) => { + if (!this.props.disabled && this.props.onMouseDown) { + this.props.onMouseDown(e); + } + } + + handleKeyDown = (e) => { + if (!this.props.disabled && this.props.onKeyDown) { + this.props.onKeyDown(e); + } + } + + handleKeyUp = (e) => { + if (!this.props.disabled && this.props.onKeyUp) { + this.props.onKeyUp(e); + } + } + render() { const style = { fontSize: `${this.props.size}px`, @@ -98,8 +117,9 @@ export default class IconButton extends React.PureComponent { title={title} className={classes} onClick={this.handleClick} - onKeyUp={this.props.onKeyUp} - onKeyDown={this.props.onKeyDown} + onMouseDown={this.handleMouseDown} + onKeyDown={this.handleKeyDown} + onKeyUp={this.handleKeyUp} onMouseEnter={this.props.onMouseEnter} onMouseLeave={this.props.onMouseLeave} tabIndex={tabIndex} @@ -125,8 +145,9 @@ export default class IconButton extends React.PureComponent { title={title} className={classes} onClick={this.handleClick} - onKeyUp={this.props.onKeyUp} - onKeyDown={this.props.onKeyDown} + onMouseDown={this.handleMouseDown} + onKeyDown={this.handleKeyDown} + onKeyUp={this.handleKeyUp} onMouseEnter={this.props.onMouseEnter} onMouseLeave={this.props.onMouseLeave} tabIndex={tabIndex} diff --git a/app/soapbox/features/compose/components/privacy_dropdown.js b/app/soapbox/features/compose/components/privacy_dropdown.js index 2e5f4e5f4..d59859603 100644 --- a/app/soapbox/features/compose/components/privacy_dropdown.js +++ b/app/soapbox/features/compose/components/privacy_dropdown.js @@ -73,6 +73,19 @@ class PrivacyDropdownMenu extends React.PureComponent { this.props.onChange(element.getAttribute('data-index')); } break; + case 'Tab': + if (e.shiftKey) { + element = this.node.childNodes[index - 1] || this.node.lastChild; + } else { + element = this.node.childNodes[index + 1] || this.node.firstChild; + } + if (element) { + element.focus(); + this.props.onChange(element.getAttribute('data-index')); + e.preventDefault(); + e.stopPropagation(); + } + break; case 'Home': element = this.node.firstChild; if (element) { @@ -192,6 +205,9 @@ class PrivacyDropdown extends React.PureComponent { } } else { const { top } = target.getBoundingClientRect(); + if (this.state.open && this.activeElement) { + this.activeElement.focus(); + } this.setState({ placement: top * 2 < innerHeight ? 'bottom' : 'top' }); this.setState({ open: !this.state.open }); } @@ -214,7 +230,25 @@ class PrivacyDropdown extends React.PureComponent { } } + handleMouseDown = () => { + if (!this.state.open) { + this.activeElement = document.activeElement; + } + } + + handleButtonKeyDown = (e) => { + switch(e.key) { + case ' ': + case 'Enter': + this.handleMouseDown(); + break; + } + } + handleClose = () => { + if (this.state.open && this.activeElement) { + this.activeElement.focus(); + } this.setState({ open: false }); } @@ -240,6 +274,8 @@ class PrivacyDropdown extends React.PureComponent { active={open} inverted onClick={this.handleToggle} + onMouseDown={this.handleMouseDown} + onKeyDown={this.handleButtonKeyDown} style={{ height: null, lineHeight: '27px' }} />