Skip to content

Now in the official shadcn registry directory.

Start free

Alert Dialog

A confirmation dialog for destructive or irreversible actions: no close X, no click-outside dismiss, and the cancel button is focused first.

overlayfeedback
A free styled version is available

Installation

Run the following command

npx shadcn@latest add @ai2/alert-dialog

Dependencies, the @ai2/tokens theme and the component file are installed together. @ai2/button installs alongside, since the action and cancel buttons reuse its variants.

Usage

TS
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
  AlertDialogTrigger,
} from "@/components/ui/alert-dialog"

<AlertDialog>
  <AlertDialogTrigger asChild>
    <Button variant="outline" tone="danger">Delete project</Button>
  </AlertDialogTrigger>
  <AlertDialogContent>
    <AlertDialogHeader>
      <AlertDialogTitle>Delete this project?</AlertDialogTitle>
      <AlertDialogDescription>This action cannot be undone.</AlertDialogDescription>
    </AlertDialogHeader>
    <AlertDialogFooter>
      <AlertDialogCancel>Cancel</AlertDialogCancel>
      <AlertDialogAction>Delete</AlertDialogAction>
    </AlertDialogFooter>
  </AlertDialogContent>
</AlertDialog>

Unlike Dialog, there is no close X and clicking outside does not dismiss. The user must choose AlertDialogCancel or AlertDialogAction.

Examples

Destructive confirmation

The action button defaults to tone="danger", so no prop is needed for the destructive case.

Non-destructive action

For irreversible but non-destructive confirmations, set tone="brand" (or "neutral") on AlertDialogAction.

Action tones

All three values of the tone axis on AlertDialogAction: open each dialog to compare the action button. The default is danger.

Props

AlertDialogAction adds one prop; every part also forwards its underlying radix props, e.g. open / onOpenChange on AlertDialog.

AlertDialogAction props

PropTypeDefaultDescription
tone"neutral" | "brand" | "danger""danger"Semantic color of the action button. Styled as a solid medium button via buttonVariants.

ai2 Alert Dialog: destructive confirmations done right in React

The ai2 Alert Dialog is a shadcn-compatible react alert dialog, built on the radix-ui AlertDialog primitive and styled with Tailwind CSS v4. It exists for one job: confirming destructive or irreversible actions. Delete a project, revoke a key, cancel a subscription: the dialog interrupts, explains the consequence and forces an explicit choice between cancel and confirm.

It ships through the shadcn registry format, so you install it with one CLI command, an MCP agent, or a copy-paste, and the TypeScript source lands in your own project. You own the file; there is no runtime dependency on ai2 itself. The live example above is the exact component you get.

What is the ai2 Alert Dialog?

It is a nine-part composition matching shadcn/ui: AlertDialog, AlertDialogTrigger, AlertDialogContent, AlertDialogHeader, AlertDialogFooter, AlertDialogTitle, AlertDialogDescription, AlertDialogAction and AlertDialogCancel.

Unlike a regular dialog, there is no close X and clicking the overlay does not dismiss it: the user must pick a button. The footer buttons are styled through the shared buttonVariants function from the ai2 Button: the cancel button is a neutral outline button, and the action button is a solid button whose tone defaults to danger, so the destructive case needs zero extra props.

Why use it

  • Danger is the default: AlertDialogAction defaults to tone="danger", so the most common case, a red destructive confirm button, is the zero-config path instead of an override.
  • No accidental dismissal: The radix AlertDialog primitive intentionally omits outside-click dismissal, so a stray click cannot silently cancel (or worse, skip) a decision about data loss.
  • Cancel is focused first: Per the WAI-ARIA alertdialog pattern, initial focus lands on the cancel button, so pressing Enter reflexively does not destroy anything.
  • Buttons match your system: Action and cancel reuse buttonVariants from the ai2 Button, so dialog buttons are pixel-identical to every other button in your product.
  • Agent-readable metadata: The registry item describes the parts and the danger default in plain words, so an MCP agent can wire a correct destructive confirmation without guessing.

Features

  • Radix AlertDialog primitive: Focus trap, role="alertdialog", aria-labelledby and aria-describedby wiring, Escape handling and scroll lock come from radix-ui.
  • Tone-aware action button: AlertDialogAction accepts tone="neutral" | "brand" | "danger" and defaults to danger; it renders as a solid medium button via buttonVariants.
  • Token-driven motion: Open and close animate with fade and zoom using the shared --motion-base duration token, matching the rest of ai2.
  • Responsive footer: AlertDialogFooter stacks buttons in reverse column order on small screens and aligns them to the end in a row on larger ones.
  • Composable trigger: AlertDialogTrigger supports asChild, so any ai2 Button (or other element) opens the dialog without wrapper markup.
  • Data attributes for styling: Every part exposes data-slot (alert-dialog, alert-dialog-content, alert-dialog-action and so on) for targeted CSS overrides without forking.

Production tips

  • Name the object in the title: "Delete this project?" beats "Are you sure?". Users skimming a focused dialog should know exactly what is at stake from the title alone.
  • State the consequence in the description: One sentence on what happens and whether it is reversible: "Requests using this key will start failing immediately." Skip boilerplate.
  • Label the action with a verb, not OK: "Delete", "Revoke", "Publish". A verb label plus the danger tone makes the button self-describing even out of context.
  • Match the action tone to the risk: Keep the danger default for destructive actions; switch to tone="brand" or "neutral" for irreversible but constructive ones like publishing, so red keeps meaning danger.
  • Do not overuse it: Interrupting confirmation is for irreversible actions. For reversible ones, prefer doing the action immediately and offering undo via a toast.

Works with the rest of ai2

The natural trigger is an ai2 Button (often soft or outline danger) via asChild, and destructive entries in an ai2 Dropdown Menu or row actions in an ai2 Table commonly open one before anything is deleted.

For non-blocking flows, use the ai2 Dialog instead: it has a close X and outside-click dismissal. After the action completes, confirm the result with an ai2 Sonner toast. All three share the same tokens, so the flow stays visually coherent in both modes.

FAQs

Get new components in your inbox

Component drops, new themes and release notes. No spam, and you can unsubscribe from any email.

© 2026 ai2 design system · MIT licensed · Built with its own components