Beautifully designed Modal Component built with Radix UI and Tailwind CSS.

Click the button below to present a modal. You can also click outside the modal to dismiss it.

Best Practices

Reusing components and abstractions

The advantage of invoking Modal imperatively is that it's easy to encapsulate component logic. For example, we can quickly refactor and encapsulate a declarative Modal in scenarios where it is used multiple times.

const MyModal = ({
  open,
  onOpenChange,
}: {
  open: boolean
  onOpenChange: (open: boolean) => void
}) => {
  return (
    <Modal
      title="A declaratively modal"
      open={open}
      onOpenChange={onOpenChange}
    >
      <p>
        This is a modal. You can put anything you want in here. And It can be
        nested.
      </p>
    </Modal>
  )
}
const Component1 = () => {
  const [open, setOpen] = useState(false)
  return (
    <>
      <Button
        onClick={() => {
          setOpen(true)
        }}
      >
        Open Modal
      </Button>

      <MyModal open={open} onOpenChange={setOpen} />
    </>
  )
}

const Component2 = () => {
  const [open, setOpen] = useState(false)
  return (
    <>
      <Button
        onClick={() => {
          setOpen(true)
        }}
      >
        Other biz button also use modal
      </Button>

      <MyModal open={open} onOpenChange={setOpen} />
    </>
  )
}

Refactoring into an imperative call Hook, so you no longer have to control the opening and closing state of the Modal within the component.

const useMyModal = () => {
  const { present } = useModalStack()
  return useCallback(() => {
    present({
      title: "My Modal",
      content: () => (
        <p>
          This is a modal. You can put anything you want in here. And It can be
          nested.
        </p>
      ),
    })
  }, [present])
}

const Component1 = () => {
  const showModal = useMyModal()
  return (
    <>
      <Button onClick={showModal}>Open Modal</Button>
    </>
  )
}

const Component2 = () => {
  const showModal = useMyModal()
  return (
    <>
      <Button onClick={showModal}>Other biz button also use modal</Button>
    </>
  )
}

Isn't it more concise and convenient to use?