Skip to content

Shadcn Dialog

The shadcn/ui Dialog is a copy-paste modal overlay for focused tasks: confirmations, forms, and detail views. Built on Base UI and styled with Tailwind CSS v4, it traps focus, closes on Escape, and returns focus to the trigger. Dialogs handle confirmations and quick edits across ShadcnStore blocks.

Key features

  • Modal overlay with focus trap and Escape-to-close.
  • Composable Trigger, Content, Header, Footer, and Close parts.
  • Controlled or uncontrolled open state.
  • Rendered in a portal over a dimmed overlay.
  • Accessible name and description via Title and Description.

Installation

bash
npx shadcn@latest add dialog

Usage

tsx
import {
  Dialog,
  DialogTrigger,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogDescription,
  DialogFooter,
} from "@/components/ui/dialog"
import { Button } from "@/components/ui/button"

export function Example() {
  return (
    <Dialog>
      <DialogTrigger render={<Button variant="outline" />}>Open</DialogTrigger>
      <DialogContent>
        <DialogHeader>
          <DialogTitle>Delete project</DialogTitle>
          <DialogDescription>
            This action cannot be undone.
          </DialogDescription>
        </DialogHeader>
        <DialogFooter>
          <Button variant="destructive">Delete</Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  )
}

Anatomy

PartPurpose
DialogRoot that manages open state.
DialogTriggerElement that opens the dialog.
DialogContentThe modal panel, rendered in a portal over an overlay.
DialogHeader / DialogFooterLayout regions for title and actions.
DialogTitle / DialogDescriptionAccessible name and description.
DialogCloseAny element that closes the dialog.

With a form

A common use is a compact edit form inside the dialog, with the primary action in the footer and a DialogClose for cancel.

tsx
<DialogContent>
  <DialogHeader>
    <DialogTitle>Edit profile</DialogTitle>
    <DialogDescription>Update your details and save when you are done.</DialogDescription>
  </DialogHeader>
  <div className="grid gap-4 py-2">
    <div className="grid gap-2">
      <Label htmlFor="name">Name</Label>
      <Input id="name" defaultValue="Pedro Duarte" />
    </div>
  </div>
  <DialogFooter>
    <DialogClose render={<Button variant="outline" />}>Cancel</DialogClose>
    <Button>Save changes</Button>
  </DialogFooter>
</DialogContent>

Controlled open state

Drive the dialog from your own state when you need to open it programmatically (for example after an async action):

tsx
const [open, setOpen] = useState(false)

<Dialog open={open} onOpenChange={setOpen}>
  <DialogContent>…</DialogContent>
</Dialog>

Composition

Use the render prop on DialogTrigger and DialogClose to compose with a Button or other element. Put label text as children on the outer component, not inside the render element:

tsx
<DialogTrigger render={<Button />}>Open</DialogTrigger>
<DialogClose render={<Button variant="outline" />}>Cancel</DialogClose>

Accessibility

  • Always include a DialogTitle, even if visually hidden, so the modal has an accessible name.
  • Focus moves into the dialog on open and returns to the trigger on close; do not disable this.
  • For destructive confirmations that must not be dismissed by an outside click, use Alert Dialog instead of Dialog.

When to use the Dialog

Use a Dialog for a focused, interrupting task the user should finish or cancel before returning: confirming a delete, editing a single record, or completing a short form. For non-blocking, contextual content prefer a Popover; for transient side content use a Sheet; and for grouped actions triggered from a button, use a Dropdown Menu.

Used in these blocks

A Dialog is opened by a Button, often holds a Form with Input and Select fields, and pairs with a Card layout inside. For lightweight action lists, reach for a Dropdown Menu.

FAQ

What is the shadcn dialog used for?

The Dialog is a modal overlay for focused tasks: confirmations, forms, and detail views that interrupt the page until the user acts or dismisses it.

How do I control a shadcn dialog open state?

Pass open and onOpenChange to Dialog to control it, or use DialogTrigger for uncontrolled open behavior.

What is the difference between Dialog and Alert Dialog?

Dialog is a general modal that can be dismissed by clicking outside or pressing Escape. Alert Dialog is for confirmations and requires an explicit action, so it does not dismiss on outside click.

How do I close the dialog after submitting a form?

Control the dialog with open/onOpenChange state and set it to false in your submit handler after the async action resolves.