A modal window layered above the page, with focus trapped inside.
import {
Dialog,
DialogTrigger,
DialogContent,
DialogHeader,
DialogFooter,
DialogTitle,
DialogDescription,
DialogClose,
} from '@/components/ui/dialog'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
export default function DialogDemo() {
return (
<Dialog>
<DialogTrigger render={<Button variant="outline">Edit profile</Button>} />
<DialogContent>
<DialogHeader>
<DialogTitle>Edit profile</DialogTitle>
<DialogDescription>Make changes to your profile here. Click save when you're done.</DialogDescription>
</DialogHeader>
<div className="grid gap-3">
<div className="grid gap-1.5">
<Label htmlFor="dialog-name">Name</Label>
<Input id="dialog-name" defaultValue="Ada Lovelace" />
</div>
<div className="grid gap-1.5">
<Label htmlFor="dialog-username">Username</Label>
<Input id="dialog-username" defaultValue="@ada" />
</div>
</div>
<DialogFooter>
<DialogClose render={<Button variant="outline">Cancel</Button>} />
<DialogClose render={<Button>Save changes</Button>} />
</DialogFooter>
</DialogContent>
</Dialog>
)
}
Built on Base UI
Installation
pnpm dlx shadcn@latest add https://kagadmodyaa.vercel.app/r/dialog.jsonNeeds a React + Tailwind project set up with shadcn. Copies the component source straight into your project, so you can edit it.
Dialog imports cn() from lib/utils.ts — add it too if you don't have it yet:
import { clsx, type ClassValue } from 'clsx'
import { twMerge } from 'tailwind-merge'
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs))
}
Usage
import {
Dialog,
DialogTrigger,
DialogContent,
DialogHeader,
DialogFooter,
DialogTitle,
DialogDescription,
DialogClose,
} from '@/components/ui/dialog'
import { Button } from '@/components/ui/button'
<Dialog>
<DialogTrigger render={<Button variant="outline">Edit profile</Button>} />
<DialogContent>
<DialogHeader>
<DialogTitle>Edit profile</DialogTitle>
<DialogDescription>Make changes to your profile here.</DialogDescription>
</DialogHeader>
<DialogFooter>
<DialogClose render={<Button>Save changes</Button>} />
</DialogFooter>
</DialogContent>
</Dialog>API Reference
| Name | Type | Default | Description |
|---|---|---|---|
| open / onOpenChange | boolean / (open: boolean) => void | — | Control the open state from outside (set on Dialog). |
| defaultOpen | boolean | false | Initial open state (uncontrolled). |
| modal | boolean | 'trap-focus' | true | Traps focus and locks page scroll while open. |
| DialogTrigger render | ReactElement | — | Renders the trigger as a different element, e.g. a Button. |
| DialogContent showCloseButton | boolean | true | Shows the corner close button. Turn it off when the content has its own dismiss control. |
| DialogClose render | ReactElement | — | Renders a close control as a different element. |