Dialog
Modal dialog component
Dialog
A modal dialog component for important interactions.
Usage
import {
Dialog,
DialogContent,
DialogDescription,
DialogHeader,
DialogTitle,
DialogTrigger,
} from '@/components/ui/dialog';
import { Button } from '@/components/ui/button';
export function Example() {
return (
<Dialog>
<DialogTrigger asChild>
<Button>Open Dialog</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>Dialog Title</DialogTitle>
<DialogDescription>
This is a description of the dialog.
</DialogDescription>
</DialogHeader>
<div className="py-4">
Dialog content goes here
</div>
</DialogContent>
</Dialog>
);
}Controlled Dialog
'use client';
import { useState } from 'react';
export function ControlledDialog() {
const [open, setOpen] = useState(false);
return (
<Dialog open={open} onOpenChange={setOpen}>
<DialogTrigger asChild>
<Button>Open</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>Controlled Dialog</DialogTitle>
</DialogHeader>
<div className="py-4">
<p>This dialog is controlled</p>
<Button onClick={() => setOpen(false)} className="mt-4">
Close
</Button>
</div>
</DialogContent>
</Dialog>
);
}Confirmation Dialog
export function ConfirmDialog({ onConfirm }) {
const [open, setOpen] = useState(false);
const handleConfirm = () => {
onConfirm();
setOpen(false);
};
return (
<Dialog open={open} onOpenChange={setOpen}>
<DialogTrigger asChild>
<Button variant="destructive">Delete</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>Are you sure?</DialogTitle>
<DialogDescription>
This action cannot be undone. This will permanently delete your data.
</DialogDescription>
</DialogHeader>
<div className="flex justify-end gap-2 mt-4">
<Button variant="outline" onClick={() => setOpen(false)}>
Cancel
</Button>
<Button variant="destructive" onClick={handleConfirm}>
Delete
</Button>
</div>
</DialogContent>
</Dialog>
);
}Form Dialog
export function FormDialog() {
const [open, setOpen] = useState(false);
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
// Handle form submission
setOpen(false);
};
return (
<Dialog open={open} onOpenChange={setOpen}>
<DialogTrigger asChild>
<Button>Create New</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>Create Item</DialogTitle>
<DialogDescription>
Fill in the details below
</DialogDescription>
</DialogHeader>
<form onSubmit={handleSubmit} className="space-y-4">
<div>
<label htmlFor="name" className="block text-sm font-medium mb-2">
Name
</label>
<Input id="name" required />
</div>
<div>
<label htmlFor="description" className="block text-sm font-medium mb-2">
Description
</label>
<Textarea id="description" />
</div>
<div className="flex justify-end gap-2">
<Button type="button" variant="outline" onClick={() => setOpen(false)}>
Cancel
</Button>
<Button type="submit">Create</Button>
</div>
</form>
</DialogContent>
</Dialog>
);
}Scrollable Dialog
<Dialog>
<DialogTrigger asChild>
<Button>Open Long Content</Button>
</DialogTrigger>
<DialogContent className="max-h-[80vh] overflow-y-auto">
<DialogHeader>
<DialogTitle>Long Content</DialogTitle>
</DialogHeader>
<div className="py-4">
{/* Long scrollable content */}
<p>Lorem ipsum dolor sit amet...</p>
</div>
</DialogContent>
</Dialog>Custom Width
<DialogContent className="max-w-2xl">
{/* Wider dialog content */}
</DialogContent>Props
Dialog
| Prop | Type | Description |
|---|---|---|
| open | boolean | Controlled open state |
| onOpenChange | (open: boolean) => void | Callback when open state changes |
| defaultOpen | boolean | Default open state |
| modal | boolean | Whether dialog is modal (default: true) |
DialogContent
| Prop | Type | Description |
|---|---|---|
| className | string | Additional CSS classes |
| children | ReactNode | Dialog content |
Best Practices
- Use for important actions: Don't overuse dialogs
- Keep content focused: One clear purpose per dialog
- Provide clear actions: Make it obvious what users should do
- Handle escape key: Allow users to dismiss easily
- Mobile responsive: Test on different screen sizes
Accessibility
The dialog component is built with accessibility in mind:
- Focus trap keeps focus within dialog
- Escape key closes dialog
- Click outside closes dialog
- Proper ARIA attributes
- Screen reader support