fix(menu): prevent menu items from stealing focus on mouseover
Description
Problem
Menu items were stealing focus when users hovered over them, which caused several UX issues:
- Input field disruption: When users were typing in input fields (search, textfield, combobox, etc.) and accidentally hovered over menu items, focus would be stolen, interrupting their typing
- Inconsistent behavior: Focus management was inconsistent between hover and keyboard navigation
- Accessibility concerns: Screen readers and keyboard users experienced unexpected focus changes
Solution
Changes Made
- Updated
MenuItem.handleMouseover(): Removedthis.focus()call and replaced with hover tracking - Added hover tracking in
Menu: ImplementedsetHoveredItem()method to track hovered items without stealing focus - Enhanced keyboard listener: Added global keyboard listener to enable smooth transition from hover to keyboard navigation
Technical Details
- MenuItem.ts:
handleMouseover()now callsthis.menuData.parentMenu?.setHoveredItem(this)instead ofthis.focus() - Menu.ts: Added
hoveredItemproperty andsetHoveredItem()method for tracking hover state - Focus management: When users press arrow keys after hovering, focus transitions smoothly to the hovered item
- Global keyboard listener: Automatically cleans up when keyboard navigation begins
Files Changed:
packages/menu/src/MenuItem.ts- Updated hover behaviorpackages/menu/src/Menu.ts- Added hover tracking and keyboard transitionpackages/menu/test/menu.test.ts- Updated tests for new behavior
Motivation and context
When users were typing in input fields (search, textfield, combobox, etc.) and accidentally hovered over menu items, focus would be stolen, interrupting their typing
Related issue(s)
- fixes SWC-1027
Screenshots (if appropriate)
Author's checklist
- [ ] I have read the CONTRIBUTING and PULL_REQUESTS documents.
- [ ] I have reviewed at the Accessibility Practices for this feature, see: Aria Practices
- [ ] I have added automated tests to cover my changes.
- [ ] I have included a well-written changeset if my change needs to be published.
- [ ] I have included updated documentation if my change required it.
Reviewer's checklist
- [ ] Includes a Github Issue with appropriate flag or Jira ticket number without a link
- [ ] Includes thoughtfully written changeset if changes suggested include
patch,minor, ormajorfeatures - [ ] Automated tests cover all use cases and follow best practices for writing
- [ ] Validated on all supported browsers
- [ ] All VRTs are approved before the author can update Golden Hash
Manual review test cases
-
[ ] Test Case 1: Input Field Focus Preservation
- Go to
- Focus the input field and start typing
- Hover over menu items while typing
- ✅ Expected: Focus remains in input field, typing continues uninterrupted
- ❌ Failure: Focus jumps to menu items, typing stops
-
[ ] Test Case 2: Keyboard Navigation After Hover
- Go to
- Hover over different menu items
- Press
Tabto focus the menu, then use arrow keys (↑↓) - Press
Enterto select an item - ✅ Expected: Smooth transition from hover to keyboard navigation, selection works
- ❌ Failure: Arrow keys don't work, focus doesn't transition properly
-
[ ] Test Case 3: Menu Selection Behavior
- Go to
- Click on different menu items
- ✅ Expected: Selection changes correctly on click
- ❌ Failure: Clicking doesn't change selection
Breaking Changes
None. This is a behavior improvement that maintains backward compatibility.
Device review
- [ ] Did it pass in Desktop?
- [ ] Did it pass in (emulated) Mobile?
- [ ] Did it pass in (emulated) iPad?
⚠️ No Changeset found
Latest commit: 425cab174d7de55a939b9984b13b8a388a4da880
Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.
This PR includes no changesets
When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types
Click here to learn what changesets are, and how to add one.
Click here if you're a maintainer who wants to add a changeset to this PR
📚 Branch Preview
🔍 Visual Regression Test Results
When a visual regression test fails (or has previously failed while working on this branch), its results can be found in the following URLs:
- Spectrum | Light | Medium | LTR
- Spectrum | Dark | Large | RTL
- Express | Light | Medium | LTR
- Express | Dark | Large | RTL
- Spectrum-two | Light | Medium | LTR
- Spectrum-two | Dark | Large | RTL
- High Contrast Mode | Medium | LTR
Deployed to Azure Blob Storage: pr-5753
If the changes are expected, update the current_golden_images_cache hash in the circleci config to accept the new images. Instructions are included in that file.
If the changes are unexpected, you can investigate the cause of the differences and update the code accordingly.
Tachometer results
Currently, no packages are changed by this PR...
Submenus are flaky. WIP