Powerful and customizable React modal components built for modern applications and websites. These modals are built using React Aria and styled with Tailwind CSS.
Installation
You can add this modal component using our CLI or manually:
npx untitledui add modal
Modals examples
Below are examples and variations of this modals component:
API reference
DatePickerModal
Import DatePickerModal from @/components/application/modals/date-picker-modal. Renders React Aria’s DateRangePicker — all of its props are supported.
Props from React Aria (41)
Dialog
Import Dialog from @/components/application/modals/modal. Renders React Aria’s Dialog — all of its props are supported.
Styling (4)
Accessibility (5)
Also accepts the global HTML attributes (dir, lang, hidden, inert, translate), all standard React DOM event handlers.
Modal
Import Modal from @/components/application/modals/modal. Renders React Aria’s Modal — all of its props are supported.
Styling (5)
Also accepts the global HTML attributes (dir, lang, hidden, inert, translate), all standard React DOM event handlers.
ModalOverlay
Import ModalOverlay from @/components/application/modals/modal. Renders React Aria’s ModalOverlay — all of its props are supported.
Styling (5)
Also accepts the global HTML attributes (dir, lang, hidden, inert, translate), all standard React DOM event handlers.
FAQs
Please refer to our frequently asked questions page for more.
Add the base modal.tsx with npx untitledui add modal. The examples on this page are PRO and install one at a time with the command shown on each, for example npx untitledui@latest add modals/stacked-left-aligned.
Put the isOpen and onOpenChange props directly on ModalOverlay and drive them from your own state: <ModalOverlay isOpen={isOpen} onOpenChange={setIsOpen} isDismissable>. Anything inside the modal can then close it by calling setIsOpen(false), and a CloseButton closes it without a handler because it fills React Aria's "close" slot.
Three components from modal.tsx, nested in this order: ModalOverlay (holds the open state through isOpen/onOpenChange and renders the backdrop and positioning), Modal (the container, including the zoom animations), and Dialog (the content wrapper). Add a CloseButton inside the Dialog yourself if you want a close icon in the corner.
Leave isDismissable off ModalOverlay (it defaults to false) so clicking the backdrop does nothing, and pass isKeyboardDismissDisabled to stop Escape from closing it. Neither prop affects a CloseButton, so remove that too if the examples you copied include one.
ModalOverlay fades in over 300ms and out over 200ms, and Modal zooms in from and out to 95% scale with the same timings. Both accept a className function that receives isEntering and isExiting, and your classes are merged last with tailwind-merge, so they override the defaults.
Below the sm breakpoint the overlay aligns the modal to the bottom of the screen; from sm up it is centered. The modal's max height is capped to the visible viewport minus the overlay padding, and Dialog scrolls its content when it is taller than that.
Give each Dialog an accessible name, either with a React Aria Heading using slot="title", as the examples do, or with aria-label. React Aria handles the rest: focus is contained inside the modal while it is open and returns to the previously focused element when it closes, and Escape closes it unless isKeyboardDismissDisabled is set.