From 5ff733b614fee51eebbc5f3f8aa2b96339181235 Mon Sep 17 00:00:00 2001 From: Thibaut Girka Date: Tue, 11 Sep 2018 22:35:17 +0200 Subject: Only focus first item of dropdown if it was opened via keyboard --- .../flavours/glitch/components/dropdown_menu.js | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'app/javascript/flavours/glitch/components/dropdown_menu.js') diff --git a/app/javascript/flavours/glitch/components/dropdown_menu.js b/app/javascript/flavours/glitch/components/dropdown_menu.js index 1c2b0bf25..cc63f7d98 100644 --- a/app/javascript/flavours/glitch/components/dropdown_menu.js +++ b/app/javascript/flavours/glitch/components/dropdown_menu.js @@ -23,6 +23,7 @@ class DropdownMenu extends React.PureComponent { placement: PropTypes.string, arrowOffsetLeft: PropTypes.string, arrowOffsetTop: PropTypes.string, + openedViaKeyboard: PropTypes.bool, }; static defaultProps = { @@ -43,7 +44,7 @@ class DropdownMenu extends React.PureComponent { componentDidMount () { document.addEventListener('click', this.handleDocumentClick, false); document.addEventListener('touchend', this.handleDocumentClick, listenerOptions); - if (this.focusedItem) this.focusedItem.focus(); + if (this.focusedItem && this.props.openedviaKeyBoard) this.focusedItem.focus(); this.setState({ mounted: true }); } @@ -170,6 +171,7 @@ export default class Dropdown extends React.PureComponent { onClose: PropTypes.func.isRequired, dropdownPlacement: PropTypes.string, openDropdownId: PropTypes.number, + openedViaKeyboard: PropTypes.bool, }; static defaultProps = { @@ -180,14 +182,14 @@ export default class Dropdown extends React.PureComponent { id: id++, }; - handleClick = ({ target }) => { + handleClick = ({ target, type }) => { if (this.state.id === this.props.openDropdownId) { this.handleClose(); } else { const { top } = target.getBoundingClientRect(); const placement = top * 2 < innerHeight ? 'bottom' : 'top'; - this.props.onOpen(this.state.id, this.handleItemClick, placement); + this.props.onOpen(this.state.id, this.handleItemClick, placement, type !== 'click'); } } @@ -197,6 +199,11 @@ export default class Dropdown extends React.PureComponent { handleKeyDown = e => { switch(e.key) { + case ' ': + case 'Enter': + this.handleClick(e); + e.preventDefault(); + break; case 'Escape': this.handleClose(); break; @@ -232,7 +239,7 @@ export default class Dropdown extends React.PureComponent { } render () { - const { icon, items, size, ariaLabel, disabled, dropdownPlacement, openDropdownId } = this.props; + const { icon, items, size, ariaLabel, disabled, dropdownPlacement, openDropdownId, openedViaKeyboard } = this.props; const open = this.state.id === openDropdownId; return ( @@ -248,7 +255,7 @@ export default class Dropdown extends React.PureComponent { /> - + ); -- cgit From c3ab2973c5383f66fa64b95d2036b89cb5dc6678 Mon Sep 17 00:00:00 2001 From: Thibaut Girka Date: Tue, 11 Sep 2018 22:44:20 +0200 Subject: Improve keyboard VS mouse navigation of dropdown menus --- .../flavours/glitch/components/dropdown_menu.js | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'app/javascript/flavours/glitch/components/dropdown_menu.js') diff --git a/app/javascript/flavours/glitch/components/dropdown_menu.js b/app/javascript/flavours/glitch/components/dropdown_menu.js index cc63f7d98..05611c135 100644 --- a/app/javascript/flavours/glitch/components/dropdown_menu.js +++ b/app/javascript/flavours/glitch/components/dropdown_menu.js @@ -43,13 +43,15 @@ class DropdownMenu extends React.PureComponent { componentDidMount () { 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(); + if (this.focusedItem && this.props.openedViaKeyboard) this.focusedItem.focus(); this.setState({ mounted: true }); } componentWillUnmount () { document.removeEventListener('click', this.handleDocumentClick, false); + document.removeEventListener('keydown', this.handleKeyDown, false); document.removeEventListener('touchend', this.handleDocumentClick, listenerOptions); } @@ -63,13 +65,10 @@ class DropdownMenu extends React.PureComponent { handleKeyDown = e => { const items = Array.from(this.node.getElementsByTagName('a')); - const index = items.indexOf(e.currentTarget); + const index = items.indexOf(document.activeElement); let element; switch(e.key) { - case 'Enter': - this.handleClick(e); - break; case 'ArrowDown': element = items[index+1]; if (element) { @@ -97,6 +96,12 @@ class DropdownMenu extends React.PureComponent { } } + handleItemKeyDown = e => { + if (e.key === 'Enter') { + this.handleClick(e); + } + } + handleClick = e => { const i = Number(e.currentTarget.getAttribute('data-index')); const { action, to } = this.props.items[i]; @@ -121,7 +126,7 @@ class DropdownMenu extends React.PureComponent { return (
  • - + {text}
  • -- cgit