/// Overlay
AlertDialog
A modal that interrupts to confirm a consequential or destructive action — no backdrop escape, an explicit choice required.
import { AlertDialog, ConfirmDialog } from "@protocore/pds";Basics
The compound mirrors Dialog but with alert semantics: focus is trapped, there is no dismiss-on-outside-click, and the user must pick Cancel or Action. Cancel receives initial focus so the safe choice is the default.
ConfirmDialog convenience
Most confirmations are the same shape, so ConfirmDialog packages it: pass title, description, labels, an onConfirm handler, and a trigger. It renders tone-styled Cancel / Confirm actions for you.
validator-07 is active
Confirm tone
tone="danger" (the default) renders the destructive confirm button; tone="primary" styles a non-destructive but still deliberate confirmation.
When to use it
Use an AlertDialog when proceeding is destructive, irreversible, or expensive — deleting data, revoking access, rolling back a deploy. Unlike a plain [Dialog](/overlay/dialog), it cannot be dismissed by clicking the backdrop; the user must consciously choose Cancel or the action. That friction is the point.
Reach for the ConfirmDialog convenience for the common yes/no case, and drop to the raw AlertDialog.* parts only when you need custom content between the title and the actions. If the message is purely informational and needs no decision, don't use an AlertDialog at all — a [Banner](/feedback/banner) or a toast is enough. And never use it for routine, reversible actions; that trains users to click through the friction.
Usage
Do
- Name the consequence in the title ("Revoke key?") and the effect in the description.
- Make the confirm label a verb ("Revoke now"), not a generic "OK".
- Use tone="danger" for anything that destroys or revokes.
- Let Cancel keep initial focus so the safe path is the default.
Don't
- Use it for reversible or low-stakes actions — that's a plain Dialog or inline control.
- Re-enable outside-click dismissal — the deliberate choice is the whole point.
- Bury the destructive button as the default focus.
- Show an AlertDialog with no decision to make — use a Banner or toast.
Accessibility
| Keys | Action |
|---|---|
| Esc | Cancels and closes (equivalent to the Cancel action). |
| Tab | Moves between Cancel and Action, trapped within the panel. |
| Shift + Tab | Moves focus backward, trapped within the panel. |
| Enter / Space | Activates the focused Cancel or Action button. |
- Role=alertdialog: assistive tech announces it more assertively than a plain dialog.
- Focus is trapped and Cancel receives it first; focus returns to the trigger on close.
- There is intentionally no dismiss on outside-click — only Cancel, Action, or Esc close it.
- Title labels the dialog and Description describes it, both wired by Radix.
ConfirmDialog props
| Prop | Type | Default | Description |
|---|---|---|---|
cancelLabel | string | Cancel | Label for the cancel action. |
confirmLabel | string | Confirm | Label for the confirm action. |
defaultOpen | boolean | — | Uncontrolled initial open state. |
description | ReactNode | — | Optional supporting copy explaining the consequence. |
onConfirm | (() => void) | — | Called when the user confirms. May be async; the dialog closes on click. |
onOpenChange | ((open: boolean) => void) | — | Fires when the open state changes. |
open | boolean | — | Controlled open state. |
title * | ReactNode | — | Heading of the confirmation. |
tone | enum | danger | Severity of the confirm action — danger renders the destructive button. |
trigger | ReactNode | — | Optional element that opens the dialog (rendered via `asChild`). |
AlertDialog.Content props
| Prop | Type | Default | Description |
|---|---|---|---|
asChild | boolean | — | |
className | string | — | |
style | CSSProperties | — |