Dialog
A modal window layered over the page. Opens with a soft scale and blur, closes fast so it never gets in the way.
Playground
Tweak the props, the preview and the code follow.
<Dialog>
<DialogTrigger asChild>
<Button variant="outline">Open dialog</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>Rename project</DialogTitle>
<DialogDescription>This changes the URL of every deployment.</DialogDescription>
</DialogHeader>
<DialogFooter>
<DialogClose asChild>
<Button variant="ghost">Cancel</Button>
</DialogClose>
<Button>Continue</Button>
</DialogFooter>
</DialogContent>
</Dialog>Installation
npx @plumsydev/plum-ui add dialogUsage
import {
Dialog,
DialogClose,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "@/components/ui/dialog"<Dialog>
<DialogTrigger asChild>
<Button variant="outline">Open</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>Are you sure?</DialogTitle>
<DialogDescription>This action can be undone later.</DialogDescription>
</DialogHeader>
<DialogFooter>
<DialogClose asChild>
<Button>Continue</Button>
</DialogClose>
</DialogFooter>
</DialogContent>
</Dialog>Examples
Scrollable content
Pin the header and footer and let the body scroll with a three-row grid.
Nested dialogs
Open a confirmation from inside a dialog: the parent steps back like a stack of cards. Type something, then try to close it.
Form with validation
Live preview, inline errors that animate in, and a loading submit button.
API Reference
Dialog
Root. Controls the open state.
| Prop | Type | Default |
|---|---|---|
openControlled open state. | boolean | — |
defaultOpenInitial open state when uncontrolled. | boolean | false |
onOpenChangeCalled when the open state changes. | (open: boolean) => void | — |
modalBlocks interaction with the rest of the page. | boolean | true |
DialogContent
The panel. Rendered in a portal together with the overlay.
| Prop | Type | Default |
|---|---|---|
sizeMax width of the panel. | "sm" | "default" | "lg" | "xl" | "full" | "default" |
showCloseButtonRenders the close button in the top-right corner. | boolean | true |
onEscapeKeyDownCall `event.preventDefault()` to keep the dialog open. | (event: KeyboardEvent) => void | — |
onInteractOutsideFires on pointer down or focus outside the content. | (event: Event) => void | — |
Notes
- Always render a
DialogTitle. Hide it withsr-onlyif the design has no visible title — screen readers still need it. - Focus is trapped inside and returned to the trigger on close.
- A
DialogorAlertDialogopened from inside another dialog makes its parent recede automatically — no extra props. DialogBodygives you a scrollable middle section with edge-to-edge dividers.