Skip to content

fix(contextual-menu): route Tab into the menu when opened with the mouse - #1418

Open
guillaume-flambard wants to merge 1 commit into
canonical:mainfrom
guillaume-flambard:fix/contextual-menu-keyboard-focus
Open

fix(contextual-menu): route Tab into the menu when opened with the mouse#1418
guillaume-flambard wants to merge 1 commit into
canonical:mainfrom
guillaume-flambard:fix/contextual-menu-keyboard-focus

Conversation

@guillaume-flambard

Copy link
Copy Markdown

Done

Fixes #1363, following the smaller-step direction suggested in the issue thread by @edlerd: focus the first item when Tab is pressed while the menu is open and no menu item is focused yet.

  • ContextualMenuDropdown renders through a portal, so after opening the menu with the mouse the menu items sit after every other page element in tab order: pressing Tab walked the rest of the page instead of entering the menu. Keyboard-opened menus already moved focus to the first item (they satisfy the detail === 0 gate), which is why the bug only reproduces after a mouse click.
  • When the menu is open and Tab is pressed while focus is still on the toggle, focus now moves to the first menu item.
  • Tab pressed anywhere else is untouched (guarded on activeElement being the toggle).
  • Mouse behaviour is unchanged: no autofocus on click (the does not autofocus when opened by a mouse test still passes).
  • The existing wrap-around logic is preserved and now lives in the same document-level listener, since the toggle sits outside the dropdown element.

The full ARIA menu pattern discussed in the issue (arrow-key navigation, roving tabindex) can build on this as a follow-up.

QA

Pinging @canonical/react-library-maintainers for a review.

Storybook

  1. yarn start, open the ContextualMenu > Toggle story.
  2. Click the toggle with the mouse (options must not take focus: unchanged).
  3. Press Tab: focus now lands on the first menu option instead of walking the page.
  4. Tab / Shift+Tab still wrap within the options; Escape still closes.

Tests

yarn jest src/components/ContextualMenu:

Test Suites: 2 passed, 2 total
Tests:       51 passed, 51 total

New tests: routes Tab into the menu when it was opened by a mouse (fails before the fix, passes after) and leaves Tab alone when focus is not on the toggle (guards against over-eager routing). eslint and tsc --noEmit clean.

The dropdown renders through a portal, so when the menu was opened with
the mouse the menu items sat after every other page element in tab
order: pressing Tab walked the page instead of entering the menu.
Keyboard-opened menus already moved focus to the first item.

When the menu is open and Tab is pressed while focus is still on the
toggle, focus now moves to the first menu item. Tab from anywhere else
is untouched, mouse behaviour is unchanged (no autofocus on click), and
the existing wrap-around behaviour is preserved.

Signed-off-by: Guillaume Flambard <g.flambard@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ContextualMenu options do not receive keyboard focus when opened with mouse

1 participant