Alert Dialog
A modal that interrupts to force an explicit confirm/cancel decision.
@garn/ui/alert-dialogOn this page
Default
Destructive delete confirmation.
Installation
garn is copy-in — the garn CLI writes this component's source into your project, so you own and can edit it. It resolves any base files and installs the npm dependencies below for you.
npx garn-ui add alert-dialog- Registry
alert-dialog- Deps
@radix-ui/react-alert-dialog- Registry deps
buttonutilsframe
Import
import { AlertDialog, AlertDialogTrigger, AlertDialogContent, AlertDialogTitle, AlertDialogDescription, AlertDialogHeader, AlertDialogFooter, AlertDialogAction, AlertDialogCancel } from "@garn/ui/alert-dialog";Anatomy
The parts this component is built from — compose them to assemble it.
AlertDialogRequiredRoot — owns the open state. No DOM of its own.
AlertDialogTrigger[data-slot="alert-dialog-trigger"]Opens the dialog (asChild to wrap your own button).
AlertDialogContentRequired[data-slot="alert-dialog-content"]Focus-trapped surface (portals its own overlay). No dismiss-X — closing is explicit.
AlertDialogTitleRequired[data-slot="alert-dialog-title"]Accessible name for the dialog (required; sr-only if visually hidden).
AlertDialogDescription[data-slot="alert-dialog-description"]The consequence text, wired to aria-describedby.
AlertDialogHeader[data-slot="alert-dialog-header"]Layout wrapper for title + description.
AlertDialogFooter[data-slot="alert-dialog-footer"]Layout wrapper for the actions (right-aligned on ≥sm).
AlertDialogActionRequired[data-slot="alert-dialog-action"]The confirm button (styled primary via buttonVariants).
AlertDialogCancelRequired[data-slot="alert-dialog-cancel"]The cancel button (styled outline); initial focus lands here.
Props
The component's public props and their types.
No component-specific props — this is a thin wrapper over its native element.
Styling
Target these data-slots and states, and remap these tokens, to restyle without forking the component.
[data-slot="alert-dialog-content"]States
| Selector | State | Description |
|---|---|---|
[data-state=open] | open | Content + overlay mounted and animated in. |
[data-state=closed] | closed | Animating out before unmount. |
| Property | Token | Tier |
|---|---|---|
padding | --garn-pad-surface | semantic · air |
gap | --garn-gap-stack | semantic · air |
headerGap | --garn-gap-field | semantic · air |
motion | --garn-motion-fast | semantic |
When to use
Force an explicit decision before continuing — confirming a destructive or irreversible action (delete, discard, sign out).
Reach for something else when
- A non-blocking message or a routine form (use dialog)
- a transient status (use a toast)
- contextual info near a control (use popover).
Overview
AlertDialog forces an explicit decision before continuing — confirming a destructive or irreversible action like delete, discard, or sign out. Unlike Dialog, AlertDialogContent has no dismiss-X and ignores outside-click: the only way out is the AlertDialogAction (confirm) or AlertDialogCancel (which takes initial focus). Use it sparingly, only when proceeding has real consequences; for a routine form or message, a Dialog is right, and for a non-blocking confirmation a Sonner toast with Undo is often kinder.
Guidelines
Reserve it for consequential, irreversible actions. If the action is easily undone, prefer an optimistic update with an Undo toast over interrupting the user. Overusing alert dialogs for harmless steps trains people to confirm on reflex.
Name the consequence, not the mechanism. The Title + Description should state what will happen ("Delete 3 files? This can't be undone"), and the action button should name the act ("Delete", not "OK"). Match the button's tone to the risk — destructive confirms read as danger.
Make Cancel the safe default. Initial focus lands on Cancel and Escape cancels, so an accidental Enter never destroys anything. Keep the choice binary and the copy short — this is a decision point, not a place for extra fields.
Best practices
- Always include an AlertDialogTitle and an AlertDialogDescription that states the consequence.
- Use AlertDialogAction for the confirm and AlertDialogCancel for the safe out; let Cancel keep initial focus.
- Style a destructive confirm's Action with the destructive intent.
- Don't use an alert-dialog for ordinary, non-destructive tasks — that's a dialog.
- Don't make Escape or overlay-click silently confirm — closing must be Cancel-safe.
- Don't omit the description; 'Are you sure?' alone doesn't state the stakes.
Content guidelines
- Title the decision, not the question — “Delete 3 files?” rather than “Are you sure?”.
- Use the description to state the consequence and whether it can be undone.
- Label the confirm button with the action (“Delete”), never “Yes” / “OK”.
Troubleshooting
Screen readers can't name the dialog / a console warning about a missing title.
Cause. AlertDialogContent without an AlertDialogTitle (Radix requires it).
Fix. Add an AlertDialogTitle (sr-only if you don't want it visible) and an AlertDialogDescription.
Users dismiss the prompt by clicking outside and nothing is confirmed — as intended, but surprising if you expected dialog behavior.
Cause. alert-dialog deliberately does not close on overlay click; only Action/Cancel/Escape resolve it.
Fix. If you want overlay-click dismissal, you want a dialog, not an alert-dialog.
Accessibility
- Role
alertdialog- ARIA APG
- alertdialog
- Focus
- Focus trapped inside the content, initially on Cancel; returns to the trigger on close.
Accessibility requirements
Every AlertDialogContent must contain an AlertDialogTitle (wrap it in sr-only to hide it visually).
when AlertDialogContent has no AlertDialogTitle
Keyboard
| Escape | Cancel and close (treated as the Cancel action). |
| TabShift+Tab | Cycle focus within the dialog (focus is trapped). |
| Enter | Activate the focused action button. |
- role=alertdialog + aria-modal; labelled by AlertDialogTitle and described by AlertDialogDescription.
- Initial focus lands on Cancel; focus returns to the trigger on close.
- Unlike dialog, clicking the overlay does NOT dismiss it — the choice is explicit.