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.

Props
<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 dialog

Usage

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.

PropTypeDefault
open

Controlled open state.

boolean—
defaultOpen

Initial open state when uncontrolled.

booleanfalse
onOpenChange

Called when the open state changes.

(open: boolean) => void—
modal

Blocks interaction with the rest of the page.

booleantrue

DialogContent

The panel. Rendered in a portal together with the overlay.

PropTypeDefault
size

Max width of the panel.

"sm" | "default" | "lg" | "xl" | "full""default"
showCloseButton

Renders the close button in the top-right corner.

booleantrue
onEscapeKeyDown

Call `event.preventDefault()` to keep the dialog open.

(event: KeyboardEvent) => void—
onInteractOutside

Fires on pointer down or focus outside the content.

(event: Event) => void—

Notes

  • Always render a DialogTitle. Hide it with sr-only if the design has no visible title — screen readers still need it.
  • Focus is trapped inside and returned to the trigger on close.
  • A Dialog or AlertDialog opened from inside another dialog makes its parent recede automatically — no extra props.
  • DialogBody gives you a scrollable middle section with edge-to-edge dividers.