Skip to content
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

Merged
merged 4 commits into from
Jul 2, 2024

Conversation

d-rita
Copy link
Contributor

@d-rita d-rita commented Jun 23, 2024

Implements LIBS-623


Description

This feature handles keyboard accessibility of the menu and its children components in the following ways:

  • A user can use the Up and Down arrow keys to navigate a list of menu items by moving focus between them.
  • A user can use the Space or Enter key to trigger actionable menu items, e.g toggle, open link, act like a button, and open a submenu.

Checklist

  • API docs are generated
  • Tests were added
  • Storybook demos were added

@dhis2-bot
Copy link
Contributor

dhis2-bot commented Jun 23, 2024

🚀 Deployed on https://pr-1533--dhis2-ui.netlify.app

@dhis2-bot dhis2-bot temporarily deployed to netlify June 23, 2024 23:59 Inactive
@d-rita d-rita changed the title (menu): add keyboard accessibility to menus feat(menu): add keyboard accessibility to menus Jun 24, 2024
@d-rita d-rita marked this pull request as ready for review June 24, 2024 09:39
@d-rita d-rita requested a review from a team as a code owner June 24, 2024 09:39
@dhis2-bot dhis2-bot temporarily deployed to netlify June 26, 2024 22:32 Inactive
@d-rita d-rita force-pushed the LIBS-623/menus-keyboard-accessibility branch from 348ec89 to 4ed9a58 Compare June 28, 2024 16:14
@dhis2-bot dhis2-bot temporarily deployed to netlify June 28, 2024 16:18 Inactive
@d-rita d-rita force-pushed the LIBS-623/menus-keyboard-accessibility branch from 4ed9a58 to 543feab Compare June 28, 2024 16:58
@dhis2-bot dhis2-bot temporarily deployed to netlify June 28, 2024 17:06 Inactive
@d-rita d-rita force-pushed the LIBS-623/menus-keyboard-accessibility branch from 543feab to 2ccf6d0 Compare June 28, 2024 23:59
@dhis2-bot dhis2-bot temporarily deployed to netlify June 29, 2024 00:03 Inactive
@dhis2-bot dhis2-bot temporarily deployed to netlify June 30, 2024 16:00 Inactive
const handleFocus = (event) => {
if (event.target === menuRef.current) {
const firstItemIndex = focusableItemsIndices?.[0]
menuRef.current.children[firstItemIndex].focus()
Copy link
Contributor

@flaminic flaminic Jul 1, 2024

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?

Suggested change
menuRef.current.children[firstItemIndex].focus()
firstItemIndex && menuRef.current.children[firstItemIndex].focus()

Copy link
Contributor Author

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
Copy link
Contributor

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?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will do

@flaminic
Copy link
Contributor

flaminic commented Jul 1, 2024

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
@d-rita d-rita force-pushed the LIBS-623/menus-keyboard-accessibility branch from efb9c88 to 72ec46e Compare July 1, 2024 13:42
@dhis2-bot dhis2-bot temporarily deployed to netlify July 1, 2024 13:45 Inactive
@d-rita d-rita requested a review from flaminic July 1, 2024 13:53
const Menu = ({ children, className, dataTest, dense }) => {
const { menuRef, focusedIndex } = useMenuNavigation(children)

const childrenToRender = Children.map(children, (child, index) => {
Copy link
Collaborator

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:

  1. memoise childrenToRender to make sure we're not recalculating it unnecessarily
  2. 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

Copy link
Collaborator

@kabaros kabaros left a 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 😅

@d-rita
Copy link
Contributor Author

d-rita commented Jul 2, 2024

There definitely was a bit more to this task. 😅 Thank you for the review @flaminic and @kabaros. 🎉

as discussed privately, it'd be good to:

  1. memoise childrenToRender to make sure we're not recalculating it unnecessarily
  2. 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

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.

@kabaros kabaros merged commit 235a71e into master Jul 2, 2024
16 checks passed
@kabaros kabaros deleted the LIBS-623/menus-keyboard-accessibility branch July 2, 2024 14:12
dhis2-bot added a commit that referenced this pull request Jul 2, 2024
# [9.9.0](v9.8.10...v9.9.0) (2024-07-02)

### Features

* **menu:** add aria-attributes and roles to menu and its components ([#1514](#1514)) ([54b816c](54b816c))
* **menu:** add keyboard accessibility to menus ([#1533](#1533)) ([235a71e](235a71e))
@dhis2-bot
Copy link
Contributor

🎉 This PR is included in version 9.9.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

Successfully merging this pull request may close these issues.

None yet

4 participants