Overview
Use for
- Blocking confirmations, forms, or creation flows.
- Previewing larger assets without leaving the page.
- Communicating critical system feedback (errors, required upgrades).
Avoid for
- Passive notifications—use `Toast` or `Sonner` integration.
- Lightweight tooltips or menus; they should not block background interaction.
- Mobile full-screen flows; consider dedicated routes.
Examples
Invite flow
<Dialog>
<DialogTrigger asChild>
<Button>Invite teammate</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>Invite teammate</DialogTitle>
<DialogDescription>
Send a one-time invite link to join your workspace.
</DialogDescription>
</DialogHeader>
<form className="space-y-4">
<div className="space-y-2">
<Label htmlFor="email">Email</Label>
<Input id="email" type="email" placeholder="teammate@pixexid.com" />
</div>
<DialogFooter>
<DialogClose asChild>
<Button type="button" variant="ghost">Cancel</Button>
</DialogClose>
<Button type="submit">Send invite</Button>
</DialogFooter>
</form>
</DialogContent>
</Dialog>Controlled dialog
import { useState } from "react"
import { Dialog, DialogTrigger, DialogContent } from "@/components/ui/dialog"
export function ControlledDialog() {
const [open, setOpen] = useState(false)
return (
<Dialog open={open} onOpenChange={setOpen}>
<DialogTrigger asChild>
<Button variant="outline">Open dialog</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>Dialog title</DialogTitle>
<DialogDescription>Controlled with React state.</DialogDescription>
</DialogHeader>
<DialogFooter>
<DialogClose asChild>
<Button variant="ghost">Close</Button>
</DialogClose>
<Button onClick={() => setOpen(false)}>Confirm</Button>
</DialogFooter>
</DialogContent>
</Dialog>
)
}Props
| Prop | Type | Default | Description |
|---|---|---|---|
open | boolean | — | Controls the dialog in a controlled pattern. Pair with `onOpenChange`. |
defaultOpen | boolean | false | Initial open state for uncontrolled usage. |
onOpenChange | (open: boolean) => void | — | Callback invoked when the dialog requests to open or close. |
modal | boolean | true | Radix option to trap focus; leave true for Pixexid modals. |
Accessibility
Keyboard
- Tab stays trapped inside the dialog while open.
- Esc closes the dialog.
- `DialogClose` ensures buttons and links dismiss the overlay and return focus to the trigger.
Best practices
- Always provide `DialogTitle` and `DialogDescription` to communicate context quickly.
- Keep content concise—move multi-step flows to dedicated pages.
- Use `aria-describedby` via `DialogDescription` for screen-reader hints.