Alert Dialog
A modal dialog that interrupts the user with important content and expects a response.
import {
AlertDialog,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
AlertDialogTrigger,
} from '@/components/ui/alert-dialog';
import { Button } from '@/components/ui/button';
export default function AlertDialogDemo() {
return (
<AlertDialog>
<AlertDialogTrigger render={<Button variant="outline" />}>
Delete account
</AlertDialogTrigger>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>Are you absolutely sure?</AlertDialogTitle>
<AlertDialogDescription>
This action cannot be undone. This will permanently delete your
account and remove your data from our servers.
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel>Cancel</AlertDialogCancel>
<AlertDialogCancel variant="destructive">Delete</AlertDialogCancel>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
);
}
Install
npx shadcn@latest add @madeui/alert-dialog
Usage
import {
AlertDialog,
AlertDialogAction,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogMedia,
AlertDialogTitle,
AlertDialogTrigger,
} from '@/components/ui/alert-dialog';
Composition
<AlertDialog>
<AlertDialogTrigger />
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogMedia />
<AlertDialogTitle />
<AlertDialogDescription />
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel />
<AlertDialogAction />
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
Media
import {
AlertDialog,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogMedia,
AlertDialogTitle,
AlertDialogTrigger,
} from '@/components/ui/alert-dialog';
import { Button } from '@/components/ui/button';
export default function AlertDialogMediaDemo() {
return (
<AlertDialog>
<AlertDialogTrigger render={<Button variant="outline" />}>
Empty trash
</AlertDialogTrigger>
<AlertDialogContent size="sm">
<AlertDialogHeader>
<AlertDialogMedia>
<svg
width="24"
height="24"
viewBox={`0 0 24 24`}
fill="none"
stroke="currentColor"
strokeWidth="1.5"
strokeLinecap="round"
strokeLinejoin="round"
aria-hidden
>
<path d={`M4 7h16M9 7V5a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v2m-9 0 1 13h8l1-13`} />
</svg>
</AlertDialogMedia>
<AlertDialogTitle>Empty trash?</AlertDialogTitle>
<AlertDialogDescription>
All items in the trash will be permanently deleted.
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel>Cancel</AlertDialogCancel>
<AlertDialogCancel variant="destructive">Empty</AlertDialogCancel>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
);
}
Small
import {
AlertDialog,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
AlertDialogTrigger,
} from '@/components/ui/alert-dialog';
import { Button } from '@/components/ui/button';
export default function AlertDialogSmall() {
return (
<AlertDialog>
<AlertDialogTrigger render={<Button variant="outline" />}>
Leave page
</AlertDialogTrigger>
<AlertDialogContent size="sm">
<AlertDialogHeader>
<AlertDialogTitle>Leave without saving?</AlertDialogTitle>
<AlertDialogDescription>
Your changes will be lost.
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel>Stay</AlertDialogCancel>
<AlertDialogCancel variant="destructive">Leave</AlertDialogCancel>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
);
}
Destructive action
Use AlertDialogAction (a plain Button) instead of AlertDialogCancel when
the confirming action needs to run async work — like this delete request —
before the dialog closes.
'use client';
import * as React from 'react';
import {
AlertDialog,
AlertDialogAction,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
AlertDialogTrigger,
} from '@/components/ui/alert-dialog';
import { Button } from '@/components/ui/button';
import { Spinner } from '@/components/ui/spinner';
function deleteAccount() {
return new Promise<void>((resolve) => setTimeout(resolve, 1500));
}
export default function AlertDialogDestructive() {
const [open, setOpen] = React.useState(false);
const [deleting, setDeleting] = React.useState(false);
async function handleDelete() {
setDeleting(true);
await deleteAccount();
setDeleting(false);
setOpen(false);
}
return (
<AlertDialog open={open} onOpenChange={setOpen}>
<AlertDialogTrigger render={<Button variant="destructive" />}>
Delete account
</AlertDialogTrigger>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>Delete your account?</AlertDialogTitle>
<AlertDialogDescription>
This action cannot be undone. This will permanently delete your
account and remove your data from our servers.
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel disabled={deleting}>Cancel</AlertDialogCancel>
<AlertDialogAction
variant="destructive"
disabled={deleting}
onClick={handleDelete}
>
{deleting && <Spinner />}
{deleting ? 'Deleting…' : 'Delete account'}
</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
);
}
API reference
Built on Base UI Alert Dialog. The tables below cover the props this library adds or changes — every other prop is forwarded to the underlying Base UI part; see the Base UI Alert Dialog API reference.
AlertDialogContent
| Prop | Type | Default | Description |
|---|---|---|---|
size |
'md' | 'sm' |
'md' |
sm is narrower and keeps the footer buttons in a two-column grid. |
style |
StyleXStyles |
— | StyleX styles merged last — always win over the component’s own styles. |
AlertDialogAction
A plain Button (accepts variant, size). Wire your own onClick and close via the dialog’s open state, so destructive actions can await work first.
AlertDialogCancel
Base UI Close rendered as a Button.
| Prop | Type | Default |
|---|---|---|
variant |
ButtonVariant |
'outline' |
size |
ButtonSize |
'md' |