@@ -45,7 +45,10 @@ function MenuInner(props: MenuProps) {
4545 const tree = useFloatingTree ( ) ;
4646 const nodeId = useFloatingNodeId ( ) ;
4747 const parentId = useFloatingParentNodeId ( ) ;
48- const isNested = parentId != null ;
48+ // A submenu, not merely a menu inside some other floating element. A menu rendered in a popover
49+ // has a parent node id too, and treating that as nesting makes it hover-open, side-placed, and
50+ // unclickable by mouse.
51+ const isNested = parentId != null && parentContext != null ;
4952
5053 const [ open , setOpen ] = useControllableState ( props . open , props . defaultOpen ?? false , props . onOpenChange ) ;
5154
@@ -97,7 +100,17 @@ function MenuInner(props: MenuProps) {
97100 toggle : ! isNested ,
98101 ignoreMouse : isNested ,
99102 } ) ;
100- const role = useRole ( floatingContext , { role : 'menu' } ) ;
103+ const baseRole = useRole ( floatingContext , { role : 'menu' } ) ;
104+ // `useRole` decides submenu-ness from the floating tree alone, so a menu inside a popover gets
105+ // `role="menuitem"` on its trigger with no parent menu to be an item of. `isNested` is the real answer.
106+ const role = useMemo ( ( ) => {
107+ if ( isNested ) {
108+ return baseRole ;
109+ }
110+ const reference = { ...baseRole . reference } ;
111+ delete reference . role ;
112+ return { ...baseRole , reference } ;
113+ } , [ baseRole , isNested ] ) ;
101114 const dismiss = useDismiss ( floatingContext , { bubbles : true } ) ;
102115 const listNavigation = useListNavigation ( floatingContext , {
103116 listRef : elementsRef ,
0 commit comments