Reputation: 12097
I'm trying to wrap the radixUI dialog primitive and having a very hard time triggering the Transition element on mount and unmount in an uncontrolled way (ie., that doesn't require an external useState.
I know this controlled version works (simplified for this question)...
import { Transition } from '@headlessui/react';
import * as DialogPrimitive from '@radix-ui/react-dialog';
function Controlled () {
const [open, setOpen] = React.useState(false);
return (
<Dialog.Root open={open} onOpenChange={setOpen}>
<Dialog.Trigger>Button Trigger</Dialog.Trigger>
<Dialog.Portal forceMount>
<Transition.Root show={open}>
<Transition.Child as={Fragment}>
<DialogPrimitive.Overlay forceMount />
</Transition.Child>
<Transition.Child as={Fragment}>
<Dialog.Content> Content </Dialog.Content>
</Transition.Child>
</Transition.Child>
</Dialog.Portal>
</Dialog.Root>
)
But I can't seem to get an uncontrolled version to work.
appear={true}
prop in the Transition.Root
which activates the transition on mount. But when unmounting, the transition doesn't occur. I think because show
remains true and the Portal simply unmounts without allowing for the Transition
to happen.// Props removed in `Dialog.Root`
// Removed `forceMount` in Dialog.Portal
// appear={true} added in `Transition.Root`
function Uncontrolled () {
return (
<Dialog.Root>
<Dialog.Trigger>Button Trigger</Dialog.Trigger>
<Dialog.Portal>
<Transition.Root show={true} appear={true}>
<Transition.Child as={Fragment}>
<DialogPrimitive.Overlay forceMount />
</Transition.Child>
<Transition.Child as={Fragment}>
<Dialog.Content> Content </Dialog.Content>
</Transition.Child>
</Transition.Child>
</Dialog.Portal>
</Dialog.Root>
)
Transition
component to trigger the leave transition when unmounting?Dialog.Content
component has a [data-state]
attribute of open
and closed
. Is there a way to extract that attribute into a javascript variable so I can pass it into the Transition.Root
, in the show
prop?Dialog.Root
and have the open/setOpen state passed down to the Portal/Content component.Any help would be appreciated.
Upvotes: 2
Views: 1767
Reputation: 31
I had a similar issue and I solved it by adding the prop "show" (or open...) to the uncontrolled component and use that for the Transition:
function Uncontrolled ({show}) {
return (
<Dialog.Root>
<Dialog.Trigger>Button Trigger</Dialog.Trigger>
<Dialog.Portal>
<Transition.Root show={show} appear={true}>
(...)
}
Then you can use the component like
<Uncontroled show={showModal}>...</Uncontroled>
where "showModal" is typically a boolean state that you change accordingly to show or hide the dialog
Upvotes: 0