Dialog
A window overlaid on either the primary window or another dialog window, rendering the content underneath inert.
Installation
npx shadcn@latest add dialogUsage
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogHeader,
  DialogTitle,
  DialogTrigger,
} from "@/components/ui/dialog"<Dialog>
  <DialogTrigger>Open</DialogTrigger>
  <DialogContent>
    <DialogHeader>
      <DialogTitle>Are you absolutely sure?</DialogTitle>
      <DialogDescription>
        This action cannot be undone. This will permanently delete your account
        and remove your data from our servers.
      </DialogDescription>
    </DialogHeader>
  </DialogContent>
</Dialog>Examples
Custom close button
Notes
To activate the Dialog component from within a Context Menu or Dropdown Menu, you must encase the Context Menu or
Dropdown Menu component in the Dialog component. For more information, refer to the linked issue here.
<Dialog>
  <ContextMenu>
    <ContextMenuTrigger>Right click</ContextMenuTrigger>
    <ContextMenuContent>
      <ContextMenuItem>Open</ContextMenuItem>
      <ContextMenuItem>Download</ContextMenuItem>
      <DialogTrigger asChild>
        <ContextMenuItem>
          <span>Delete</span>
        </ContextMenuItem>
      </DialogTrigger>
    </ContextMenuContent>
  </ContextMenu>
  <DialogContent>
    <DialogHeader>
      <DialogTitle>Are you absolutely sure?</DialogTitle>
      <DialogDescription>
        This action cannot be undone. Are you sure you want to permanently
        delete this file from our servers?
      </DialogDescription>
    </DialogHeader>
    <DialogFooter>
      <Button type="submit">Confirm</Button>
    </DialogFooter>
  </DialogContent>
</Dialog>This approach is not feasible if you plan to activate different types of dialogs from the same Context Menu or
Dropdown Menu. In such cases, it is recommended to colocate the dialogs and control their visibility by making them
controlled components. To achieve this, you can use the following utility hook, as suggested here:
"use client"
 
import { useRef, useState } from "react"
 
function useDialog<TriggerRef extends HTMLElement>() {
  const [isOpen, setIsOpen] = useState(false)
  const triggerRef = useRef<TriggerRef>(null)
 
  function trigger() {
    setIsOpen(true)
  }
 
  function dismiss() {
    setIsOpen(false)
    triggerRef.current?.focus()
  }
 
  return {
    triggerProps: {
      ref: triggerRef,
      onClick: trigger,
    },
    dialogProps: {
      open: isOpen,
      onOpenChange: (open: boolean) => {
        if (open) trigger()
        else dismiss()
      },
    },
    trigger,
    dismiss,
  }
}The useDialog hook allows you to spread the necessary props to both the trigger, which toggles the Dialog, and the
Dialog itself, making it a controlled component. Additionally, to ensure accessibility, the hook will attempt to focus
the trigger (such as a button) when the Dialog closes.
const editDialog = useDialog<HTMLDivElement>()
const deleteDialog = useDialog<HTMLDivElement>()
 
<>
  <DropdownMenu>
    <DropdownMenuTrigger asChild>
      <Button variant="ghost" className="h-8 w-8 p-0">
        Actions
      </Button>
    </DropdownMenuTrigger>
    <DropdownMenuContent align="end">
      <DropdownMenuItem {...editDialog.triggerProps}>
        Edit
      </DropdownMenuItem>
      <DropdownMenuItem {...deleteDialog.triggerProps}>
        Delete
      </DropdownMenuItem>
    </DropdownMenuContent>
  </DropdownMenu>
  <Dialog {...editDialog.dialogProps}>
    {/* ... */}
  </Dialog>
  <Dialog {...deleteDialog.dialogProps}>
    {/* ... */}
  </Dialog>
</>