Dialog
Installation
Add the component with the CLI.
npx shadcn@latest add @intentui/dialog
Composed components
When you install this component via the CLI, it automatically loads all composed components, so you don’t need to add them individually.
Manual installation
Install the dependencies, then copy the component source into your project.
npm install react-aria-components @heroicons/react cn
Anatomy
import { Button } from "@/components/ui/button"
import { Dialog, DialogBody, DialogClose, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog"<DialogTrigger>
<Button>Open Dialog</Button>
<Dialog>
<DialogHeader>
<DialogTitle>Dialog Title</DialogTitle>
<DialogDescription>Dialog Description</DialogDescription>
</DialogHeader>
<DialogBody>Dialog Body</DialogBody>
<DialogFooter>
<DialogClose>Close</DialogClose>
<Button>Confirm</Button>
</DialogFooter>
</Dialog>
</DialogTrigger>Examples
Alert dialog
Use role="alertdialog" for a critical message that requires an explicit response.
Alert dialogs cannot be dismissed by clicking outside by default, and the close icon is hidden. Provide an explicit action such as Cancel.
<Dialog role="alertdialog" />Controlled
You can control the dialog programmatically.
Sizes
The dialog defaults to md. Available sizes are 2xs, xs, sm, md, lg, xl, 2xl, 3xl, 4xl, 5xl, and fullscreen.
Dialog overlay styles
The overlay uses a subtle 1px blur by default. You can increase it or disable it entirely.
<DialogTrigger>
<Button intent="outline">Rename</Button>
<Dialog overlay={{ className: "backdrop-blur-2xl" }}>If you want to turn it off, use backdrop-blur-none. If you do not need any blur at all, the recommended approach is to remove the blur class from the component defaults.
-"bg-background/15 backdrop-blur-[1px] motion-reduce:backdrop-blur-none",
+"bg-background/15",Or, you can override it per instance from the component usage:
<DialogTrigger>
<Button intent="outline">Rename</Button>
<Dialog overlay={{ className: "backdrop-blur-none" }}>Sticky
Use DialogBody for scrollable content while the header and footer stay visible.
Nested
Open a dialog from within another dialog to present a nested confirmation.
Header
Pass a string to DialogHeader to render it as the title:
<DialogHeader>
Title
</DialogHeader>Use the title and description props to configure the header:
<DialogHeader title='Title' description='Description' />Triggered by menu
You can also trigger the dialog by clicking on a menu item.
Extract the dialog into a component to reuse it for multiple menu actions.
interface DialogActionProps {
state: string | null
onOpenChange: () => void
actionType: { description: string; action: () => void; confirmText: string; title: string }
disabled: boolean
}
const DialogAction = (props: DialogActionProps) => (
<Dialog isOpen={props.state !== null} onOpenChange={props.onOpenChange}>
<DialogHeader>
<DialogTitle>{props.actionType?.title}</DialogTitle>
<DialogDescription>{props.actionType?.description}</DialogDescription>
</DialogHeader>
<DialogFooter>
<DialogClose>Cancel</DialogClose>
<Button
intent={props.state === "ban" ? "danger" : "primary"}
className="min-w-24"
isDisabled={props.disabled}
onPress={props.actionType?.action}
>
{props.disabled ? <Loader variant="spin" /> : props.actionType?.confirmText}
</Button>
</DialogFooter>
</Dialog>
)Pass the current action and loading state to the dialog:
<DialogAction
state={state}
onOpenChange={closeDialog}
actionType={actionType(state)}
disabled={loading}
/>With that, now we can modify the actionType function to return the initial state.
const actionType = (t: string | null) => {
const initialsState = {
title: '',
description: '',
confirmText: '',
action: () => {}
}
switch (t) {
case 'delete': ...
case 'ban': ...
case 'restore': ...
default:
return initialsState
}
}Component API
DialogTrigger
DialogTrigger extends the React Aria Components <DialogTrigger> component.
Dialog
Dialog extends the React Aria Components <ModalOverlay> component.
classNamestringisOpenbooleanonOpenChange(isOpen: boolean) => voidisDismissablebooleantrue, except for alertdialogrole"dialog" | "alertdialog"dialogcloseButtonbooleantrueoverlayPick<ModalOverlayProps, "className">sizekeyof typeof sizesmdDialogBody
DialogBody extends the native <div> element.
classNamestringDialogCloseIcon
DialogCloseIcon renders a React Aria Button with the close slot. Dialog renders it automatically when closeButton and isDismissable are enabled.
classNamestringisDismissableboolean | undefinedDialogClose
DialogClose extends the Intent UI <Button> component.
classNamestringintent"primary" | "secondary" | "warning" | "danger" | "success" | "outline" | "plain"plainDialogDescription
DialogDescription renders a native <p> element.
classNamestringDialogFooter
DialogFooter extends the native <div> element.
classNamestringDialogHeader
DialogHeader extends the native <div> element.
classNamestringdescriptionstringtitlestringDialogTitle
DialogTitle extends the React Aria Components <Heading> component.
classNamestring