-
-
Notifications
You must be signed in to change notification settings - Fork 32.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Dividers in menus receive keyboard focus #13708
Comments
@eric-parsons Thank you for opening this issue. We are already aware of this issue, not proud of it. It comes down to a non-ideal focus implementation logic, that also causes: #10847. I have been discussing it with @RobertPurcea he was proposing an alternative implementation of the class MenuList extends React.Component {
componentDidMount() {
if (!this.props.disableAutoFocusItem) {
this.defaultFocus();
}
}
// focus selected or first child
defaultFocus = () => {
const { children } = this.props;
let indexOfChildToFocus = 0;
React.Children.forEach(children, (child, index) => {
if (child.props.selected) {
indexOfChildToFocus = index;
}
});
this.listRef.children[indexOfChildToFocus].focus();
}
handleBlur = event => {
if (this.props.onBlur) {
this.props.onBlur(event);
}
};
// TODO: focus a certain kind of elements (up to us, we could focus all elements with a tabIndex, or all focusable elements like buttons, inputs etc.)
handleKeyDown = event => {
const key = keycode(event);
const list = this.listRef;
const currentFocus = ownerDocument(list).activeElement;
if (
(key === 'up' || key === 'down') &&
(!currentFocus || (currentFocus && !list.contains(currentFocus)))
) {
this.defaultFocus();
} else if (key === 'down') {
event.preventDefault();
if (currentFocus.nextElementSibling) {
currentFocus.nextElementSibling.focus();
}
} else if (key === 'up') {
event.preventDefault();
if (currentFocus.previousElementSibling) {
currentFocus.previousElementSibling.focus();
}
}
if (this.props.onKeyDown) {
this.props.onKeyDown(event, key);
}
};
render() {
const { children, className, onBlur, onKeyDown, ...other } = this.props;
return (
<List
role="menu"
ref={ref => {
this.listRef = ReactDOM.findDOMNode(ref);
}}
className={className}
onKeyDown={this.handleKeyDown}
onBlur={this.handleBlur}
{...other}
>
{children}
</List>
);
}
} It's going in the right direction. |
This bug appears to still be occurring, can we re-open this issue? |
@Billy- If you can reproduce on v5, please open a new issue with a codesandbox to showcase the problem. |
When navigating through items in a menu using arrow keys, dividers don't get skipped over. Instead, they will receive keyboard focus like any other item. Since dividers serve no purpose other than to visually group menu items, this is a hindrance for keyboard navigation.
Expected Behavior 🤔
Using arrow key navigation in a Menu component should skip over any contained Divider elements when changing focus.
Current Behavior 😯
Divider elements get keyboard focus.
Steps to Reproduce 🕹
Link: https://codesandbox.io/s/q8p57z1j4
Your Environment 🌎
The text was updated successfully, but these errors were encountered: