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

[Menubar] Adds keyboard behaviors to the menubar, improves accessibility #3320

Open
wants to merge 83 commits into
base: develop
Choose a base branch
from

Conversation

tespin
Copy link
Contributor

@tespin tespin commented Jan 17, 2025

Fixes #2933

Just setting this up to track next steps for the component! This PR focuses on adding proper keyboard behaviors to the recently refactored Menubar. Currently in progress


Update

The Menubar component now has keyboard navigation and enhanced accessibility support. There are some other improvements to make which are listed at the end, but I'll implement them in future PRs seeing as this one has gotten rather large.

Before:
Navigation happened purely through Tab / Shift + Tab. Escape functionality worked but otherwise behaviors were not intuitive or accessible. Focus is not tied to state.

old_menubar_2.mov

After:
Most keyboard behaviors from the WAI ARIA authoring guide implemented. Tab behavior works as expected and initial focus styles are available.

menubar_test.mov

Key Changes

  • Implemented roving tab index in Menubar.jsx for focus management
  • Updated aria roles, such as aria-orientation='horizontal'on Menubar and aria-labels where applicable
  • Navigation support, including:
    • Horizontal and vertical navigation
    • Home/end, enter/space support
    • Basic focus trapping in submenus
  • Improved HTML structure
    • wrapped Menubar in nav element
    • moved from div-based menubar to ul/li
    • Logo is moved outside of the nav, UserMenu is back in
    • left and right menu items now wrapped in ul elements with role=group
  • added SubmenuContext for managing submenu state
  • MenubarSubmenu supports listbox aria roles, such as with the options in LanguageMenu
  • basic tests checking for checking component renders, keyboard behavior, and aria roles
  • added keyboard styles
  • added basic JSDoc comments for components

To Do

  • testing:
    • test with screen readers
    • verify aria structure and role handling
  • errors:
    • focus is not properly entering certain modals
    • some timing issues with effects and blur/focus handlers
  • optimizations:
    • consider refactoring context structure
    • memoize index and menuItem calculations
    • menuItems and menuItemToId could probably be combined into a better data structure
    • consolidate the more complex state updates with useReducer
  • other features/improvements:
    • add support for matching focused menu item to pressed character key
    • complete focus styles
    • extract common logic into hooks
    • tests could be more thorough
    • implement better compound component pattern

I have verified that this pull request:

  • has no linting errors (npm run lint)
  • has no test errors (npm run test)
  • is from a uniquely-named feature branch and is up to date with the develop branch.
  • is descriptively named and links to an issue number, i.e. Fixes #123

@tespin tespin mentioned this pull request Jan 17, 2025
10 tasks
Copy link
Contributor Author

Choose a reason for hiding this comment

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

  • Extract logo to header level for better semantic structure
  • Ensure arrow keys only cycle through menu items, excluding the logo

@tespin tespin marked this pull request as ready for review February 1, 2025 09:32
import usePrevious from '../../common/usePrevious';

/**
* @component
Copy link
Collaborator

Choose a reason for hiding this comment

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

I love the addition of documentation for the components!

Copy link
Collaborator

@raclim raclim left a comment

Choose a reason for hiding this comment

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

Thanks so much for continuing the work on the navigation menu section—I really love the transformation you've been giving it!

I think overall this PR looks great so far! I feel like there's also a few great practices that are being introduced here (such as the formatting of the PR, component documentation, more detailed commenting) that could be adopted throughout the codebase as well! I also agree that this is a good point to stop at for this PR, and the rest of the tasks outlined in the description could be addressed in future ones.

I think the only issue I might've found is that I noticed that when using the arrow keys to navigate specifically the File SubMenu, it ends up skipping over "Open".

nav_file_menu.mov

Besides this, I mostly had a few questions while testing it out and looking through the code, which I'll list out below!

  1. When navigating the SubMenus, I noticed that both the mouse hover and arrow key inputs are visible, which I tried to depict in the video. I feel like this could get a bit confusing, but unsure if it might've been intentional!
nav_language_menu.mov
  1. I also noticed that the focus state immediately appears on the Menubar as soon as I landed on the editor page. I was wondering if this might've been intended as well!
Screenshot 2025-02-17 at 10 08 18 PM
  1. I know there's a few different opinions around adding comments, I was curious about why you decided to add more explanatory comments throughout the components!

  2. While looking through MenubarSubmenu.jsx, I feel like it could be broken down into maybe a few files, but was wondering if you felt that way as well!

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

Successfully merging this pull request may close these issues.

Up/Down arrow keys not working on dropdown
2 participants