How to make HeadlessUI Popover behave correctly within a React portal?

40 Views Asked by At

Description

I have a component which will be used a filter selection menu. The layout is as shown below:

Diagram of component layout

Due to the black dotted containing div drawn above, I have to use a portal to raise the panels above the containing div. I have tried other ways of resolving this and decided on using a portal.

Here is the abstract layout of the component in React, using HeadlessUI components. Not shown is the use of PopperJS (not its successor FloatingUI) to position both panels:

<Popover>
    <Popover.Button />
    {ReactDOM.createPortal(
        <Popover.Panel> // This is the MAIN PANEL
            <Combobox>
                // Many options, scrollable, some Dialogs...
                // When an option is selected, the SUB PANEL opens
            </Combobox>
            {submenuIsOpen && ( // submenuIsOpen is a stateful variable
                <div> // Use a div instead of a nested Popover.Panel
                    <Combobox>
                        // Options to select a value
                        // Multi-select, should not close on clicking within
                    </Combobox>
                </div>)
            }
        </Popover.Panel>, 
        document.body) // Raise it as high in the DOM as possible
    }
</Popover>

The Issue

  1. Click on the button to open the main menu
  2. Click anywhere inside the main menu
  3. The main menu closes, as if it was clicked outside of and closed due to losing focus

My diagnosis is that this is something to do with Popover incorrectly thinking that the panel is "outside" of the popover due to the portal, and thus closes the popover incorrectly. However I might be wrong and the root cause of this might be something else. This problem only occurs when I introduce the portal.

Attempted solutions

  • Portal only the sub-menu.
    • Clicking inside the main menu now works, but clicking anywhere within the sub-menu closes the popover instantly.
  • Use HeadlessUI <Portal> instead.
    • Same effect as described above.
  • Try some arrangement of Popover.Group
    • A parent Popover.Group with each menu being an actual Popover.Panel did not have any effect.

Thank you for any advice. Please let me know if you need any more details. I cannot share any source code for this project unfortunately.

0

There are 0 best solutions below