BMcV
BMcV

Reputation: 613

Why do clicks within Popover.Panel close the panel when within Tab.Panel?

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:

  1. Why specifically is this happening?
  2. 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?

Upvotes: 1

Views: 2553

Answers (1)

BMcV
BMcV

Reputation: 613

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 Popover is inside a focusable element (which Tab.Panel is). I think it's here in the PopoverRoot that whenever the activeElement is outside of the group the panel is closed.

If the Popover is inside an element with tabindex="0" then that element will be the activeElement and the panel will be closed. I updated the codesandbox reproduction to demo this without using Tab and 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 the Popover.Panel so that it is the activeElement. Is there a reason this shouldn't be done or could cause other unexpected behavior?

Upvotes: 5

Related Questions