wongx
wongx

Reputation: 12097

How to use `@headlessui/react` Transition component in Uncontrolled `@radix-ui` Dialog component

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.

// 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>
  )

Any help would be appreciated.

Upvotes: 2

Views: 1767

Answers (1)

R&#250;bel Mujica
R&#250;bel Mujica

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

Related Questions