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.
Sizes across, states down.
What it is for
Section titled “What it is for”- 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 markup — copy this
Section titled “The markup — copy this”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>The modifiers
Section titled “The modifiers”| 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.
Accessibility — measured, not assumed
Section titled “Accessibility — measured, not assumed”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.
Contrast
Section titled “Contrast”| 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.
The focus ring
Section titled “The focus ring”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.
Keyboard
Section titled “Keyboard”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.