// preview in
saved for every page

AlertDialog

Interrupts to confirm a decision that is hard to undo, like deleting a project or sending an email to thousands of people. Focus starts on the safe choice, and an outside click doesn't close it.

Built on Base UIPattern WAI-ARIA Alert DialogClient componentSource ↗

Installation

Set up Camaleo once (Installation), then import what you need. It renders on the client.

import { AlertDialog, AlertDialogTrigger, AlertDialogContent, AlertDialogTitle, AlertDialogDescription, AlertDialogClose, DialogActions } from "@camaleo/react";

Anatomy

The same parts as Dialog, so every skin styles both alike. The popup adds data-kind="alert" and role="alertdialog".

Examples

Every example is a real file you can copy. Open them: the dialog wears the skin, mode and brand from the bar above.

minimal · light · #3fa34d

API keys (3)

  • Production server
    Created Mar 14, 2026
  • Staging server
    Created Jun 2, 2026
  • Zapier integration
    Created Sep 21, 2026

Delete a row, keep focus

Click Delete. The row and its button go away, so finalFocus moves focus to the list heading and a status message confirms it.

Type the name to confirm

For the worst mistakes, like deleting a repository, make people type the name. The button stays disabled until it matches.

Waits for the request

Click Sign out devices. While the request runs, Esc and Cancel do nothing, so people see whether it worked before the dialog closes.

Focus on Cancel

Focus goes to the first focusable element. When that is a checkbox, point initialFocus at Cancel, so a quick Enter can't confirm.

Opened from a menu

Keep the dialog outside the menu and control it with open: the menu closes, the dialog stays, and finalFocus returns to the menu button.

Not only for deletes

Anything that can't be taken back deserves a confirm, like sending a newsletter. Use a solid button when it isn't destructive.

In context

Confirms guard the actions that would hurt to get wrong. These are whole pieces of UI you can copy, in the skin you picked.

Danger zone

These actions affect everyone in the project.

Archive project

Hide it and make it read-only. You can restore it later.

Delete project

Delete it with all its pages. This can't be undone.

Danger zoneCard · Separator · AlertDialog

Release notes

Discard unsaved changesCard · Field · Textarea · AlertDialog

Billing

Team planActive

$24 per seat / month · 8 seats · renews on November 12, 2026

Cancel a subscriptionCard · Badge · AlertDialog

Guidelines

DoName the action on the button.

"Delete 3 files" says what happens. People can answer without rereading the question.

Don’t"Are you sure?" and "OK".

Neither says what will happen, so people click through without reading.

DoOnly for decisions that interrupt.

Deleting a workspace that 12 people use is worth stopping for.

Don’tAn alert to say it worked.

"Saved" doesn't need an answer. Interrupting for it teaches people to dismiss alerts. Use a toast.

Props

PropTypeDefaultDescription
onOpenChange(open, eventDetails) => void—Called when the dialog opens or closes. eventDetails.reason says why, for example escape-key. Ignore it to keep the dialog open while a request runs.
openboolean—Whether the dialog is open. Use it with onOpenChange to control the state.
defaultOpenbooleanfalseWhether the dialog starts open, without controlling the state.

It is always modal and never closes on an outside click. The other parts take the props of their element, plus render.

AlertDialogContent decides where focus goes:

PropTypeDefaultDescription
initialFocusboolean | RefObject | (openType) => HTMLElement | boolean—The element that gets focus on open. By default, the first focusable element: put Cancel first.
finalFocusboolean | RefObject | (closeType) => HTMLElement | boolean—The element that gets focus on close. By default, the trigger. Set it when the trigger is gone after the action.
Also accepts every prop of the underlying primitive and native attributes.

Styling hooks

It shares the dialog's slots. Target data-kind="alert" to style only the confirms.

Attributes

data-kind"alert" on the popup
data-openpresent while open
data-starting-stylepresent while opening
data-ending-stylepresent while closing

Tokens it reads

Color

--cml-border--cml-fg--cml-fg-muted--cml-focus-offset--cml-focus-ring--cml-focus-width--cml-radius-surface--cml-shadow-surface--cml-surface-padding--cml-surface-raised

Shape & size

--cml-border-width--cml-gap

Type & motion

--cml-duration-base--cml-ease-standard--cml-font-display--cml-font-weight-display--cml-motion-distance--cml-motion-scale

This component only

--cml-backdrop--cml-dialog-border
/* narrower and centered, only in confirms */
[data-slot="dialog-popup"][data-kind="alert"] {
  text-align: center;
  inline-size: min(24rem, calc(100vw - 2rem));
}

Accessibility

Enter / SpaceOn the trigger, opens the dialog with focus on the first button, Cancel.
TabMoves between the buttons. Focus stays inside the dialog and wraps around.
Shift + TabMoves back, wrapping to the last button.
EscapeCloses the dialog, like Cancel. Focus goes back to the trigger.
Was this page helpful? · Edit this page on GitHub