I have a navbar that uses HeadlessUI's Popover
on mobile for the hamburger menu. By default, this menu closes when you click out/focus on an element that is not in it.
Now I'm trying to add a modal (HeadlessUI Dialog
) that I want to open when clicking on a button that is in the popover menu. The modal is used within a ModalButton
component definition (<><button><dialog></>
). This is done for separation of concerns (everything relating to the modal is within ModalButton
).
The issue is: when I'm in the navbar's popover menu and click on the button to open the dialog. The browser focuses on this new dialog, and so the popover loses focus, making it close. Since it closed, the button (and thus the dialog sibling) are no longer rendered, and so the dialog disappears instantly.
For reference, this is a pseudocode of the react tree:
<navbar>
<popover>
<> {/* "ModalButton" containing both the button and the dialog */}
<button /> {/* Button that opens the dialog */}
<dialog /> {/* This uses a portal internally (with HeadlessUI) */}
</>
</popover>
</navbar>
I can think of a few ways to solve this but neither are very good:
Popover
from closing when focusing on the dialog? (but still allow it to close when focusing anything that is not the dialog)I'd love to hear any ideas on fixing this issue.
You should put the dialog higher up in the tree. Usually these can go at the page level, or even the app level, depending on how global these dialogs are.
You can then use your favourite global state manager or the useContext
hook to tell these dialogs to open programmatically from anywhere in your app.
In which case the popover closing automatically shouldn't be an issue anymore.