Skip to content

Alert dialog

A dialog that demands an answer — one question, Cancel and one confirming verb, over the scrim; no close, no click-away, no Escape-and-forget.

Beta · Feedback and status · packages/css/src/components/alert-dialog.css

.pui-alert-dialog (--medium; __texts __title __description __actions) over .pui-scrim. The confirming button carries the verb; destructive takes Button - danger.

Alert dialog — every size and every stateOpen in the workshop

Sizes across, states down.

  • Size small 440 (a one-line question) / medium 480 (Dialog’s medium — a longer explanation); no large, an alert dialog never holds content
  • Title, Description, Has description; the footer is an exposed Button group (standard · medium · Cancel + a primary verb) — edit the labels and swap the primary on the instance
  • No close button and no content slot, by design — if it needs either, it is a Dialog
  • The primary is one and last. A destructive verb takes Button - danger — the confirm example shows it; Save and Leave stay on Button.
  • Title is Medium 18 — body-sized, so 500, not 600; description Regular 14 text/subtle

Use when an action cannot be undone or costs something (delete, leave, overwrite, spend) and the person must confirm it knowingly.

Do not use when the action is reversible (do it and offer undo in a toast); the dialog holds a form or content (Dialog); the message needs no answer (Alert, Toast); it is a routine save.

Relates to Dialog, Scrim, Button group, Button, Button - secondary, Toast, Alert, Button - danger.

Anti-patterns OK / Cancel with no verb · a close X that pretends the question is optional · three or more buttons · a scary title with a friendly primary (Delete everything? — Continue) · using it for every save.

Keywords: alert dialog, confirm, confirmation, destructive, delete, are you sure, modal

Figma — page Alert dialog: Alert dialog (2 variants)

shadcn: alert-dialog

The class, the parts, and nothing that is not in the package. The same block opens alert-dialog.css.

<div class="pui-scrim"><div class="pui-alert-dialog" role="alertdialog" aria-modal="true" aria-labelledby="t">
<div class="pui-alert-dialog__texts"><h2 class="pui-alert-dialog__title" id="t">Delete “Q3 results”?</h2>
<p class="pui-alert-dialog__description">This cannot be undone.</p></div>
<div class="pui-button-group pui-alert-dialog__actions">
<button class="pui-button pui-button--secondary">Cancel</button>
<button class="pui-button pui-button--danger">Delete</button></div></div></div>
What it is Note
Size (none) small 440 · --medium 480 —

Rule — the confirming button carries the verb, never OK; a destructive verb is Button - danger.

Every number here is measured on the rendered component: contrast (npm run contrast:render), the focus ring (npm run focus) and the keyboard (npm run keyboard). The floors are principle 12’s.

ink on ground reads floor the matrix calls it
#ffffff on #e42521 4.57 4.5 Danger button label (promised) ok
#544d4d on #f2f2f7 7.39 4.5 text.muted on surface.card (promised) ok
#0b0202 on #f2f2f7 18.38 4.5 text.default on surface.card (promised) ok
#0b0202 on #ffffff 20.51 4.5 text.default on surface.page (promised) ok

4 distinct pair(s) rendered, 0 that axe calls a violation.

2 of 2 focus stop(s) in this block meet WCAG 2.4.13 on screen — the same crop screenshotted focused and unfocused, and the difference measured.

What the consumer’s script owes. as Dialog: focus in on open, held while open, Escape closes and returns it to the opener.

Tab order across the whole library is document order over 344 stops, and Shift+Tab is its exact reverse — no keyboard trap anywhere (WCAG 2.1.2).

Pepper UI v1.5.0

The Mobupps design system. 386 tokens, 88 components, 65 pages in the workshop — every page of this site generated from the repository, so nothing here is typed twice.