Dialog
A modal window layered over the page, built on Base UI. A centered card with header, content and footer in three width presets.
Playground
<Dialog>
<DialogTrigger render={<Button variant="outline">Open dialog</Button>} />
<DialogContent>
<DialogHeader>
<DialogTitle>Dialog title</DialogTitle>
<DialogDescription>
A short description of the dialog contents.
</DialogDescription>
</DialogHeader>
<DialogFooter>
<DialogClose render={<Button variant="outline">Cancel</Button>} />
<Button>Save changes</Button>
</DialogFooter>
</DialogContent>
</Dialog>Preview
DialogTrigger opens the dialog – pass your button via the Base UI render prop. DialogContent portals the card over a dimmed overlay and includes a top-right close button by default.
<Dialog>
<DialogTrigger render={<Button variant="outline">Open dialog</Button>} />
<DialogContent>
<DialogHeader>
<DialogTitle>Dialog title</DialogTitle>
<DialogDescription>
A short description of the dialog contents.
</DialogDescription>
</DialogHeader>
<p className="text-sm text-muted-foreground">
This is the main content of the dialog.
</p>
<DialogFooter>
<DialogClose render={<Button variant="outline">Cancel</Button>} />
<Button>Save changes</Button>
</DialogFooter>
</DialogContent>
</Dialog>Installation
npx shadcn@latest add https://espresso-base-ui.vercel.app/r/dialog.jsonUsage
import {
Dialog,
DialogClose,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogOverlay,
DialogPortal,
DialogTitle,
DialogTrigger,
} from "@/components/ui/dialog"<Dialog>
<DialogTrigger render={<Button variant="outline">Open</Button>} />
<DialogContent>
<DialogHeader>
<DialogTitle>Title</DialogTitle>
<DialogDescription>Description</DialogDescription>
</DialogHeader>
<DialogFooter showCloseButton>
<Button>Confirm</Button>
</DialogFooter>
</DialogContent>
</Dialog>Sizes
size on DialogContent sets the width preset: sm (max-w-sm), default (max-w-md) and lg (max-w-2xl) – all clamp to the viewport on small screens.
<DialogContent size="sm">...</DialogContent>
<DialogContent size="default">...</DialogContent>
<DialogContent size="lg">...</DialogContent>Destructive confirmation
Compose DialogClose with the render prop to make any button dismiss the dialog – a common pattern for cancel/confirm footers.
<Dialog>
<DialogTrigger render={<Button variant="destructive">Delete account</Button>} />
<DialogContent>
<DialogHeader>
<DialogTitle>Are you absolutely sure?</DialogTitle>
<DialogDescription>
This action cannot be undone. This will permanently delete your
account.
</DialogDescription>
</DialogHeader>
<DialogFooter>
<DialogClose render={<Button variant="outline">Cancel</Button>} />
<DialogClose render={<Button variant="destructive">Delete</Button>} />
</DialogFooter>
</DialogContent>
</Dialog>API reference
Dialog is the Base UI root and accepts its props – open, defaultOpen, onOpenChange, modal and dismissible. Interactive parts (DialogTrigger, DialogClose) support the Base UI render prop to swap in your own element; when the rendered element is not a native button, also pass nativeButton={false}.
DialogContent
| Prop | Type | Default | Description |
|---|---|---|---|
| size | "sm" | "default" | "lg" | "default" | Width preset: max-w-sm, max-w-md or max-w-2xl (reflected as data-size). |
| showCloseButton | boolean | true | Render the ghost icon close button in the top-right corner. |
DialogFooter
| Prop | Type | Default | Description |
|---|---|---|---|
| showCloseButton | boolean | false | Append an outline "Close" button that dismisses the dialog after your custom actions. |
| Component | Description |
|---|---|
| DialogTrigger | Opens the dialog (data-slot="dialog-trigger"); compose your button via the render prop. |
| DialogContent | Centered popup card (data-slot="dialog-content") rendered in a portal above the overlay, with zoom/fade animations. |
| DialogOverlay | Dimmed backdrop (data-slot="dialog-overlay") rendered automatically by DialogContent. |
| DialogHeader | Vertical stack for title and description (data-slot="dialog-header"). |
| DialogTitle | Accessible heading (data-slot="dialog-title") announced when the dialog opens. |
| DialogDescription | Muted supporting copy (data-slot="dialog-description") with underlined links. |
| DialogFooter | Action row (data-slot="dialog-footer"): stacked on mobile, right-aligned on desktop. |
| DialogClose | Dismisses the dialog (data-slot="dialog-close"); compose any button via the render prop. |
| DialogPortal | Portals dialog parts to the document body (data-slot="dialog-portal"); used internally by DialogContent. |
The dialogContentVariants cva helper is also exported for building custom dialog surfaces with the same size classes.
Accessibility & styling hooks
Base UI renders the popup with role="dialog" and aria-modal, wires aria-labelledby / aria-describedby to DialogTitle and DialogDescription, traps focus while open, and closes on Escape or backdrop click. Every part exposes a data-slot attribute, the content reflects its size as data-size, and open/close state is exposed as data-open / data-closed for animation and styling hooks.