Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix incorrect Transition boundary for Dialog component #3331

Merged
merged 3 commits into from
Jun 26, 2024

Conversation

RobinMalfait
Copy link
Member

Ensure that each Dialog is always a new Transition boundary such that nested TransitionChild components are correctly handled.

If you happen to nest Dialog components in places where you shouldn't (e.g.: inside a Disclosure instead of a DisclosurePanel) then it could lead to a crash that has been fixed by this change.

Fixes: #3316
Fixes: #3322

Initially we didn't do this, because it's a bit silly to do that if you
already had a `Transition` component on the outside. E.g.:

```tsx
<Transition show={open}>
  <Dialog onClose={() => setOpen(false)}>
    {/* ... */}
  </Dialog>
</Transition>
```

Because this means that we technically have this:
```tsx
<Transition show={open}>
  <Dialog onClose={() => setOpen(false)}>
    <Transition>
      <InternalDialog>
        {/* ... */}
      </InternalDialog>
    </Dialog>
  </Transition>
</Transition>
```

The good part is that the inner `Transition` is rendering a `Fragment`
and forwards all the props to the underlying element (the internal
dialog).

This way we have a guaranteed transition boundary.
This also mimics better what we are actually trying to do.
Copy link

vercel bot commented Jun 26, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
headlessui-react ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jun 26, 2024 11:50am
headlessui-vue ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jun 26, 2024 11:50am

Comment on lines -393 to -394
let inTransitionComponent = usesOpenClosedState !== null
if (!inTransitionComponent && open !== undefined && !rest.static) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now we are not relying on the OpenClosed state from a parent to know whether we should wrap the Dialog in a Transition

Instead, we will always do that. If you happen to already wrap your Dialog in a Transition on the outside, then the props will be forwarded to the underlying element because Transition renders as Fragment by default.

@RobinMalfait RobinMalfait merged commit 3224a9e into main Jun 26, 2024
8 checks passed
@RobinMalfait RobinMalfait deleted the fix/issue-3322 branch June 26, 2024 13:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants