base-ui icon indicating copy to clipboard operation
base-ui copied to clipboard

[menu] Fix focus returning to root when submenus have exit transitions

Open atomiks opened this issue 6 months ago • 3 comments

The key is isFocusInsideFloatingTree needs to be true because sometimes the activeElement is one of the submenu items. However, the isFocusInsideFloatingTree check was faulty because getNodeChildren filters out closed children, but since they have an exit transition, they're closed-but-still-mounted (and the activeElement can be inside them). In this case it shouldn't filter the open children so the contains check can work.

https://github.com/mui/base-ui/blob/11cbf2185d74ce5468263f31828cec0b68ad49c1/packages/react/src/floating-ui-react/components/FloatingFocusManager.tsx#L682-L684

On https://deploy-preview-2171--base-ui.netlify.app/experiments/menu/menu-fully-featured Open root, navigate to the second nested submenu, press Escape. Try it several times since it didn't fail every time previously.

atomiks avatar Jun 26 '25 02:06 atomiks

Open in StackBlitz

npm i https://pkg.pr.new/@base-ui-components/react@2171

commit: 186fd76

pkg-pr-new[bot] avatar Jun 26 '25 02:06 pkg-pr-new[bot]

Bundle size report

@base-ui-components/reactparsed: ▼-884B(-0.29%) gzip: ▼-152B(-0.16%)

Show details for 39 more bundles

@base-ui-components/react/tabsparsed: 🔺+33B(+0.13%) gzip: 🔺+26B(+0.28%) @base-ui-components/react/menubarparsed: 🔺+31B(+0.15%) gzip: 🔺+33B(+0.42%) @base-ui-components/react/menuparsed: ▼-557B(-0.50%) gzip: ▼-131B(-0.34%) @base-ui-components/react/context-menuparsed: ▼-552B(-0.50%) gzip: ▼-132B(-0.35%) @base-ui-components/react/selectparsed: ▼-150B(-0.13%) gzip: 🔺+8B(+0.02%) @base-ui-components/react/collapsibleparsed: ▼-127B(-0.75%) gzip: ▼-44B(-0.74%) @base-ui-components/react/popoverparsed: ▼-105B(-0.13%) gzip: ▼-5B(-0.02%) @base-ui-components/react/navigation-menuparsed: ▼-89B(-0.10%) gzip: ▼-6B(-0.02%) @base-ui-components/react/preview-cardparsed: ▼-89B(-0.16%) gzip: ▼-6B(-0.03%) @base-ui-components/react/tooltipparsed: ▼-89B(-0.14%) gzip: 0B(0.00%) @base-ui-components/react/accordionparsed: ▼-67B(-0.30%) gzip: ▼-35B(-0.45%) @base-ui-components/react/alert-dialogparsed: ▼-55B(-0.11%) gzip: 🔺+2B(+0.01%) @base-ui-components/react/dialogparsed: ▼-55B(-0.11%) gzip: 🔺+5B(+0.03%) @base-ui-components/react/checkboxparsed: ▼-37B(-0.21%) gzip: ▼-6B(-0.09%) @base-ui-components/react/radioparsed: ▼-20B(-0.13%) gzip: ▼-6B(-0.11%) @base-ui-components/react/utilsparsed: ▼-20B(-0.26%) gzip: ▼-1B(-0.03%) @base-ui-components/react/sliderparsed: ▼-17B(-0.07%) gzip: 🔺+3B(+0.03%) @base-ui-components/react/avatarparsed: 0B(0.00%) gzip: 🔺+2B(+0.07%) @base-ui-components/react/checkbox-groupparsed: 0B(0.00%) gzip: 🔺+1B(+0.02%) @base-ui-components/react/direction-providerparsed: 0B(0.00%) gzip: 0B(0.00%) @base-ui-components/react/fieldparsed: 0B(0.00%) gzip: 🔺+1B(+0.02%) @base-ui-components/react/fieldsetparsed: 0B(0.00%) gzip: ▼-1B(-0.05%) @base-ui-components/react/formparsed: 0B(0.00%) gzip: 0B(0.00%) @base-ui-components/react/inputparsed: 0B(0.00%) gzip: 🔺+2B(+0.05%) @base-ui-components/react/merge-propsparsed: 0B(0.00%) gzip: 0B(0.00%) @base-ui-components/react/meterparsed: 0B(0.00%) gzip: 0B(0.00%) @base-ui-components/react/number-fieldparsed: 0B(0.00%) gzip: 🔺+4B(+0.04%) @base-ui-components/react/progressparsed: 0B(0.00%) gzip: 0B(0.00%) @base-ui-components/react/radio-groupparsed: 0B(0.00%) gzip: 🔺+12B(+0.15%) @base-ui-components/react/scroll-areaparsed: 0B(0.00%) gzip: 🔺+4B(+0.07%) @base-ui-components/react/separatorparsed: 0B(0.00%) gzip: 0B(0.00%) @base-ui-components/react/switchparsed: 0B(0.00%) gzip: 🔺+1B(+0.02%) @base-ui-components/react/toastparsed: 0B(0.00%) gzip: 🔺+2B(+0.02%) @base-ui-components/react/toggleparsed: 0B(0.00%) gzip: 🔺+1B(+0.03%) @base-ui-components/react/toggle-groupparsed: 0B(0.00%) gzip: 🔺+8B(+0.14%) @base-ui-components/react/toolbarparsed: 0B(0.00%) gzip: 🔺+10B(+0.14%) @base-ui-components/react/unstable-no-ssrparsed: 0B(0.00%) gzip: 0B(0.00%) @base-ui-components/react/unstable-use-media-queryparsed: 0B(0.00%) gzip: 0B(0.00%) @base-ui-components/react/use-renderparsed: 0B(0.00%) gzip: 0B(0.00%)

Details of bundle changes

Generated by :no_entry_sign: dangerJS against 186fd76148eb586897cb1e73ef4d0df1887e8c57

mui-bot avatar Jun 26 '25 02:06 mui-bot

Deploy Preview for base-ui ready!

Name Link
Latest commit 186fd76148eb586897cb1e73ef4d0df1887e8c57
Latest deploy log https://app.netlify.com/projects/base-ui/deploys/6861f48818c0d00008a8411f
Deploy Preview https://deploy-preview-2171--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.

netlify[bot] avatar Jun 26 '25 02:06 netlify[bot]