Components

Dialog

A modal window for a short, focused task - with focus trapping, focus return and a labelled close button.

Loading...

Installation

npx shadcn@latest add @fujin/dialog

Usage

import {
  Dialog,
  DialogClose,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
  DialogTrigger,
} from "@/components/ui/dialog"
<Dialog>
  <DialogTrigger render={<Button variant="outline">Edit profile</Button>} />
  <DialogContent>
    <DialogHeader>
      <DialogTitle>Edit profile</DialogTitle>
      <DialogDescription>Update your name and username.</DialogDescription>
    </DialogHeader>
    {/* fields */}
    <DialogFooter>
      <DialogClose render={<Button variant="outline" />}>Cancel</DialogClose>
      <Button type="submit">Save changes</Button>
    </DialogFooter>
  </DialogContent>
</Dialog>

Forms: keep what the user typed

Base UI unmounts the popup when the dialog closes, so uncontrolled inputs are reset every time it reopens. If closing by accident (Esc, a stray click on the backdrop) should not cost the user their input, keep the draft in state outside the dialog, as the demo does:

const [open, setOpen] = React.useState(false)
const [draft, setDraft] = React.useState(profile)
 
<Dialog open={open} onOpenChange={setOpen}>
  <DialogContent>
    <form
      onSubmit={(event) => {
        event.preventDefault()
        save(draft)
        setOpen(false)
      }}
    >
      <Input
        value={draft.name}
        onValueChange={(name) => setDraft({ ...draft, name })}
      />
    </form>
  </DialogContent>
</Dialog>

Opening from a menu

Control the dialog and open it from the menu item's onClick. Nesting the Dialog inside DropdownMenuContent unmounts it as soon as the menu closes.

const [open, setOpen] = React.useState(false)
 
<DropdownMenuItem onClick={() => setOpen(true)}>Rename...</DropdownMenuItem>
<Dialog open={open} onOpenChange={setOpen}>...</Dialog>

What's different from shadcn/ui

  • render replaces asChild, from Base UI.
  • The close button is a 32px Button (shadcn's is a 16px icon), so it clears the WCAG 2.5.8 24px minimum target size, and it has a solid focus ring.
  • The popup is capped at the viewport height and scrolls internally, so a long form never pushes the footer off-screen.

API Reference

Prop

Type

Every other prop is forwarded to the Base UI Dialog.

On this page