Nested Portals
Open Popovers, OptionMenus, and other portalled components from within other portalled components without losing focus.
Background
When you render a portalled component (like a Popover or OptionMenu) inside another portalled component, the inner component renders in a separate DOM node via a React portal. This can cause the outer component to lose focus and close unexpectedly, since the inner component's DOM is outside the outer component's focus trap.
The nested portal pattern solves this by:
- Marking the inner component with
className="nested-portal"so the outer component knows not to close when focus moves into it - Manually controlling the outer component's focus trap when needed
Using className="nested-portal"
For simple cases — like a Popover or OptionMenu rendered inside another Popover — adding className="nested-portal" to the inner component is all you need.
Editable example
Nested portals inside OptionMenu
When rendering a portalled component inside an OptionMenu, you need to also manage the OptionMenu's focus trap. Use OptionMenuNestedPortalConsumer to get access to focus trap controls, and toggle them when the nested component opens and closes.
Editable example
Key points for OptionMenu nesting:
- Wrap the nested component in
OptionMenuNestedPortalConsumerto access the focus trap context - Call
context.deactivateFocusTrap()when the nested component opens - Call
context.activateFocusTrap()when the nested component closes - Set
closeOnClick={false}on the triggerOptionMenuItemto prevent the menu from closing when the nested component is activated
Nested OptionMenu inside another portalled component
You can also nest an OptionMenu inside a Popover or other portalled component. The same className="nested-portal" pattern applies.
Editable example
Summary
| Scenario | What you need |
|---|---|
Portalled component inside a Popover | Add className="nested-portal" to the inner component |
Portalled component inside an OptionMenu | Add className="nested-portal" + use OptionMenuNestedPortalConsumer to manage the focus trap |
OptionMenu inside a Popover | Add className="nested-portal" to the OptionMenu |