Skip to content

[menu] Fix race conditions#3821

Merged
atomiks merged 1 commit into
mui:masterfrom
atomiks:fix/menu-races
Jan 22, 2026
Merged

[menu] Fix race conditions#3821
atomiks merged 1 commit into
mui:masterfrom
atomiks:fix/menu-races

Conversation

@atomiks

@atomiks atomiks commented Jan 21, 2026

Copy link
Copy Markdown
Contributor

Found a couple of these working on #3783

  1. Sometimes the highlight would remain stuck on an item despite the pointer leaving. onFocus gets called after onPointerLeave is called with null incorrectly.
  2. Sometimes a submenu would incorrectly close on mouseleave despite being hovered over already (where it should remain open).

Both are hard to reproduce; more frequent with CPU slowdown

@atomiks atomiks added component: menu Changes related to the menu component. type: bug It doesn't behave as expected. labels Jan 21, 2026
@pkg-pr-new

pkg-pr-new Bot commented Jan 21, 2026

Copy link
Copy Markdown
  • vite-css-base-ui-example

    pnpm add https://pkg.pr.new/mui/base-ui/@base-ui/react@3821
    
    pnpm add https://pkg.pr.new/mui/base-ui/@base-ui/utils@3821
    

commit: 909603c

@mui-bot

mui-bot commented Jan 21, 2026

Copy link
Copy Markdown

Bundle size report

Bundle Parsed size Gzip size
@base-ui/react ▼-43B(-0.01%) ▼-6B(0.00%)

Details of bundle changes


Check out the code infra dashboard for more information about this PR.

@netlify

netlify Bot commented Jan 21, 2026

Copy link
Copy Markdown

Deploy Preview for base-ui ready!

Name Link
🔨 Latest commit 909603c
🔍 Latest deploy log https://app.netlify.com/projects/base-ui/deploys/69720f5008075a0008ce76d1
😎 Deploy Preview https://deploy-preview-3821--base-ui.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@atomiks atomiks marked this pull request as ready for review January 22, 2026 08:46
@greptile-apps

greptile-apps Bot commented Jan 22, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

Fixed two race conditions in the menu component's hover and focus handling:

  • useListNavigation: Added synchronous focus clearing in onPointerLeave to prevent highlight from getting stuck on items when the pointer leaves. Previously, onFocus could fire after onPointerLeave had already cleared the index, incorrectly re-highlighting the item.

  • MenuPositioner: Removed the logic that re-enabled hover on parent menus when child submenus closed. This logic was causing submenus to incorrectly close on mouseleave despite being hovered over, because the hoverEnabled state could toggle while hovering submenu triggers, temporarily unregistering event listeners during the cleanup/re-execution phase.

  • MenuSubmenuTrigger: Changed arrow function to method shorthand syntax (no functional change)

These race conditions were difficult to reproduce under normal conditions but became more obvious with CPU slowdown or when dealing with many submenu triggers.

Confidence Score: 5/5

  • This PR is safe to merge with minimal risk
  • The changes are surgical fixes targeting specific race conditions without introducing new functionality. The added enqueueFocus(null, { sync: true }) call ensures focus state is cleared synchronously before updating the index, preventing the highlight-stuck issue. The removal of the hoverEnabled re-enabling logic eliminates a problematic state toggle that caused event listener cleanup issues. Both fixes address real bugs without changing the overall architecture or adding complexity.
  • No files require special attention

Important Files Changed

Filename Overview
packages/react/src/floating-ui-react/hooks/useListNavigation.ts Added synchronous focus clearing to fix race condition where onFocus fires after onPointerLeave with null
packages/react/src/menu/positioner/MenuPositioner.tsx Removed logic that re-enabled hover on parent when child closes to prevent race conditions

() => ({
type: 'submenu-trigger' as const,
setActive: () => parentMenuStore.set('activeIndex', listItem.index),
setActive() {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Any particular reason for this change?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

No, was just testing things. I left it because I prefer the formatting

@atomiks atomiks merged commit c68b2cf into mui:master Jan 22, 2026
23 checks passed
@atomiks atomiks deleted the fix/menu-races branch January 22, 2026 11:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

component: menu Changes related to the menu component. type: bug It doesn't behave as expected.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants