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.

Advanced Usage

Responsive Modal

You can control the rendering style of the Modal in different scenarios by passing the sheet parameter.

For example, show the style of a sheet on small-screen devices in mobile, and display the style of a modal on large-screen devices.

const App = () => {
  const isMobile = useIsMobile()
  return <ModalStackContainer sheet={isMobile}>{children}</ModalStackContainer>
}

If you do not pass the sheet parameter, the presentation style of the modal will always be that of a modal.

In the example above, a component is provided to make this scenario easier to use.

import { MobileDetector } from "rc-modal-sheet/mobile-detector"

const App = () => {
  return (
    <ModalStackContainer>
      <MobileDetector />
      {children}
    </ModalStackContainer>
  )
}

Declarative Modal

Typically, we create a stack of Modals using useModalStack.

import { useModalStack } from "rc-modal-sheet"

export const Basic = () => {
  const { present } = useModalStack()
  return (
    <Button
      onClick={() => {
        present({
          title: "Modal",
          content: () => (
            <p>
              This is a modal. You can put anything you want in here. And it can
              be nested.
            </p>
          ),
        })
      }}
    >
      Open a modal
    </Button>
  )
}

The above is the common way, but if you want a more declarative way, you can use the Modal component. This way, you can avoid the problem of not being able to use Context in imperative calls.

import { useState } from "react"
import { Modal } from "rc-modal-sheet"

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

Nested Modal

You can also nest Modals.

export const NestedModal = () => {
  const { present, dismissAll } = useModalStack()
  return (
    <>
      <Button
        onClick={() => {
          present({
            title: "Nested Modal",

            content: () => (
              <div>
                Modal 1
                <Button
                  onClick={() => {
                    present({
                      title: "Nested Modal 2",
                      content: () => (
                        <div>
                          Modal 2 <br />{" "}
                          <Button onClick={dismissAll}>Dismiss All</Button>
                        </div>
                      ),
                    })
                  }}
                >
                  Open Modal 2
                </Button>
              </div>
            ),
          })
        }}
      >
        Open Nested Modal
      </Button>
    </>
  )
}