diff --git a/packages/react-aria-components/src/Menu.tsx b/packages/react-aria-components/src/Menu.tsx index fa95634f5b4..b7a893c499c 100644 --- a/packages/react-aria-components/src/Menu.tsx +++ b/packages/react-aria-components/src/Menu.tsx @@ -14,7 +14,7 @@ import {AriaMenuProps, FocusScope, mergeProps, useFocusRing, useMenu, useMenuItem, useMenuSection, useMenuTrigger} from 'react-aria'; import {BaseCollection, CollectionProps, ItemRenderProps, useCachedChildren, useCollection, useSSRCollectionNode} from './Collection'; import {MenuTriggerProps as BaseMenuTriggerProps, Node, TreeState, useMenuTriggerState, useTreeState} from 'react-stately'; -import {ContextValue, forwardRefType, Provider, RenderProps, ScrollableProps, SlotProps, StyleProps, useContextProps, useRenderProps, useSlot} from './utils'; +import {ContextValue, forwardRefType, Provider, RenderProps, ScrollableProps, SlotProps, StyleProps, useContextProps, useRenderProps, useSlot, useSlottedContext} from './utils'; import {filterDOMProps, mergeRefs, useObjectRef, useResizeObserver} from '@react-aria/utils'; import {Header} from './Header'; import {Key, LinkDOMProps} from '@react-types/shared'; @@ -31,7 +31,6 @@ import {UNSTABLE_useSubmenuTrigger} from '@react-aria/menu'; export const MenuContext = createContext, HTMLDivElement>>(null); export const MenuStateContext = createContext | null>(null); export const RootMenuTriggerStateContext = createContext(null); -export const SubmenuContext = createContext<{popoverContainer: Element | null} | null>(null); export interface MenuTriggerProps extends BaseMenuTriggerProps { children?: ReactNode @@ -181,7 +180,7 @@ function MenuInner({props, collection, menuRef: ref}: MenuInne values={[ [MenuStateContext, state], [SeparatorContext, {elementType: 'div'}], - [SubmenuContext, {popoverContainer}] + [PopoverContext, {UNSTABLE_portalContainer: popoverContainer || undefined}] ]}> {children} @@ -347,9 +346,9 @@ interface MenuItemTriggerInnerProps { function MenuItemTriggerInner({item, popover, parentMenuRef, delay}: MenuItemTriggerInnerProps) { let state = useContext(MenuStateContext)!; + let popoverContext = useSlottedContext(PopoverContext)!; let ref = useObjectRef(item.props.ref); let rootMenuTriggerState = useContext(RootMenuTriggerStateContext)!; - let submenuContext = useContext(SubmenuContext)!; let submenuTriggerState = UNSTABLE_useSubmenuTriggerState({triggerKey: item.key}, rootMenuTriggerState); let submenuRef = useRef(null); let {submenuTriggerProps, submenuProps, popoverProps} = UNSTABLE_useSubmenuTrigger({ @@ -398,7 +397,7 @@ function MenuItemTriggerInner({item, popover, parentMenuRef, delay}: MenuItem trigger: 'SubmenuTrigger', triggerRef: ref, placement: 'end top', - UNSTABLE_portalContainer: submenuContext.popoverContainer || undefined, + UNSTABLE_portalContainer: popoverContext.UNSTABLE_portalContainer || undefined, ...popoverProps }] ]}> diff --git a/packages/react-aria-components/test/Menu.test.js b/packages/react-aria-components/test/Menu.test.js index add39522bd5..ed832ef81a6 100644 --- a/packages/react-aria-components/test/Menu.test.js +++ b/packages/react-aria-components/test/Menu.test.js @@ -679,6 +679,7 @@ describe('Menu', () => { expect(document.activeElement).toBe(button); }); it('should restore focus to menu trigger if nested submenu is closed with Escape key', async () => { + document.elementFromPoint = jest.fn().mockImplementation(query => query); let {getByRole, getAllByRole} = render(