I've been using @headlessui/react for a project and it's helped me be very productive! But I've found an issue where one component interferes with another. I think I've found the general area of the issue and can provide a reproduction but I want to know:
- Why specifically is this happening?
- What solutions might fix this behavior either as a workaround or within the headlessui/react library itself?
The Issue
When using the Popover component within a Tab.Panel component, the Popover.Panel does not behave correctly. According to the docs:
When the panel is open, clicking anywhere outside of its contents, pressing the Escape key, or tabbing away from it will close the Popover.
However, when the Popover is within a Tab component (docs) the behavior is inconsistent. For me, in Chrome, clicks within the Popover.Panel close the panel unless the click is on a button and in Safari the panel closes in all cases. Focusing the button with the keyboard allows selection though.
Reproduction
I created a simplified version of the issue in codesandbox
I think this has something to do with the Tab component capturing the focus from the Popover.Panel which in turn closes the Popover.Panel.
I added this snippet from "Console logging the focused element as it changes" to the reproduction and the Tab.Panel seems to have the focus after clicking in Popover.Panel:
document.addEventListener(
"focusin",
function () {
console.log("focused: ", document.activeElement);
},
true
);
Can anyone provide an explanation of what is happening and suggestions for simple remedies?
I can now answer why specifically this is happening and also provide a possible solution.
I was able to simplify my case a bit. This will happen whenever
Popoveris inside a focusable element (whichTab.Panelis). I think it's here in the PopoverRoot that whenever the activeElement is outside of the group the panel is closed.If the
Popoveris inside an element withtabindex="0"then that element will be theactiveElementand the panel will be closed. I updated the codesandbox reproduction to demo this without usingTaband also propose a workaround but I'm not sure if it's an appropriate solution or not.The workaround appears to be just adding
tabIndex="0"to thePopover.Panelso that it is theactiveElement. Is there a reason this shouldn't be done or could cause other unexpected behavior?