-
Notifications
You must be signed in to change notification settings - Fork 13
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
feat(menu): add keyboard accessibility to menus #1533
Conversation
🚀 Deployed on https://pr-1533--dhis2-ui.netlify.app |
348ec89
to
4ed9a58
Compare
4ed9a58
to
543feab
Compare
543feab
to
2ccf6d0
Compare
components/menu/src/menu/use-menu.js
Outdated
const handleFocus = (event) => { | ||
if (event.target === menuRef.current) { | ||
const firstItemIndex = focusableItemsIndices?.[0] | ||
menuRef.current.children[firstItemIndex].focus() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this bit errors in the storybook for AutoHideFirstSectionHeaderDivider. it is because firstItemIndex in this case is undefined. Maybe we want to wrap this in a conditional?
menuRef.current.children[firstItemIndex].focus() | |
firstItemIndex && menuRef.current.children[firstItemIndex].focus() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, so the AutoHideFirstSectionHeaderDivider only contains 2 section headers as its children and in my implementation, those do not receive visual focus. So i have to adjust for cases where the menu does not contain any focusable items. Good catch, thank you
@@ -69,6 +77,7 @@ export interface MenuItemProps { | |||
* When true, nested menu items are shown in a Popper | |||
*/ | |||
showSubMenu?: boolean | |||
tabIndex?: number |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i think suffix (from a previous pr is missing here as well, can we add it as part of this pr?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will do
Thanks @d-rita . Looks good to me. I only have some minor comments above |
- Navigate menu items using Up and Down arrow keys - Space and Enter keys trigger the onClick handler attached to the menu items - Extract navigation and action logic into custom useMenuNavigation hook - Handle visual focus of menu items by tracking only the focusable items - Pass only native props to the native child elements, i.e. tabIndex - Implement tests simulating keyboard interactions
- wrap non-li children in li tags for consistency - assign tabIndex for visual focus to children with menuitem role - add active CSS class to focused MenuItem component - modify tests
- apply focus and keyboard navigation within the menu iff it contains focusable items
efb9c88
to
72ec46e
Compare
const Menu = ({ children, className, dataTest, dense }) => { | ||
const { menuRef, focusedIndex } = useMenuNavigation(children) | ||
|
||
const childrenToRender = Children.map(children, (child, index) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
as discussed privately, it'd be good to:
- memoise
childrenToRender
to make sure we're not recalculating it unnecessarily - add some comments for the reasons for the extra checks (handling warning when passing regular html etc...)
but this can be done in the subsequent PR
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
very nice work - this task is much harder than it looked on paper 😅
There definitely was a bit more to this task. 😅 Thank you for the review @flaminic and @kabaros. 🎉
I have implemented this feedback in this PR. I have also added the menu children role checks and warning if none is provided as was discussed. |
Implements LIBS-623
Description
This feature handles keyboard accessibility of the menu and its children components in the following ways:
Checklist