ef78d58a2e
This PR fixes an issue where React hooks were called unconditionally>
The `PopoverButton` and `DisclosureButton` act as a `CloseButton` when
used inside of a panel. We conditionally handled the `ref` when it's
inside a panel. To ensure that the callback is stable, the conditionally
used function was wrapped in a `useEvent(…)` hook.
This seemed to be ok (even though we break the rules of hooks) because a
button can only be in a panel or not be in a panel, but it can't switch
during the lifetime of the button. Aka, the rules of hooks are not
broken because all code paths lead to the same hooks being called.
```ts
<Disclosure defaultOpen>
<DisclosureButton>Open</DisclosureButton>
<DisclosurePanel>
<DisclosureButton>Close</DisclosureButton>
</DisclosurePanel>
<Disclosure>
```
But... it can be called conditionally, because the way we know whether
we are in a panel relies on a state value which comes from context and
is populated by a `useEffect(…)` hook.
The reason we didn't catch this in the `Disclosure` component, is
because all the state is stable and known by the time the
`DisclosurePanel` opens. But if you use the `defaultOpen` prop, the
`DisclosurePanel` is already open and then the state is not ready yet
(because we have to wait for the `useEffect(…)` hook).
Long story short, moved the `isWithinPanel` check inside the
`useEvent(…)` hook that holds the stable function which means that we
don't call this hook unconditionally anymore.
@headlessui/react
A set of completely unstyled, fully accessible UI components for React, designed to integrate beautifully with Tailwind CSS.
Installation
npm install @headlessui/react
Documentation
For full documentation, visit headlessui.dev.
Community
For help, discussion about best practices, or any other conversation that would benefit from being searchable:
For casual chit-chat with others using the library: