Dev view
Confirmation Flow
A modal interruption that asks the user to commit to or back out of a consequential action — typically a destructive one (delete, discard, unsubscribe, sign out of every device). The pattern composes a Modal in its `alertdialog` variant with a destructive primary Button and a cancel secondary Button. The Modal blocks the page; the user must resolve before continuing.
Composition
-
Modal container Use the `alertdialog` variant. `alertdialog` raises the screen reader announcement priority — assistive tech announces the contents the moment focus enters, instead of waiting for the user to navigate. `dialog` is wrong here even when the dialog asks for a decision; the variant exists precisely to mark "this is a decision the user must hear."
-
Button primary action (destructive) Use the `destructive` variant for the action that completes the consequential operation. The button text names the action, not the agreement — "Delete account", not "OK" or "Yes". Destructive tone is a brand-warm-mix accent in the canonical palette; it signals risk before the click, not after.
-
Button cancel action Use the `secondary` or `tertiary` variant. Cancel is the defensive default; it should be the focused button when the modal opens (per APG alertdialog guidance) so a reflexive Enter keypress does not commit the destructive action.
Framework skeletons
Composition shape only. Each library will diverge in API surface (see the linked component pages for divergence audits).
Web Components
<ui-modal variant="alertdialog" open> <h2 slot="title">Delete this project?</h2> <p slot="body"> This will permanently remove the project and its history. This cannot be undone. </p> <div slot="footer"> <ui-button variant="secondary" data-modal-cancel autofocus> Cancel </ui-button> <ui-button variant="destructive" data-modal-confirm> Delete project </ui-button> </div></ui-modal>React
<Modal variant="alertdialog" open={open} onOpenChange={setOpen}> <Modal.Title>Delete this project?</Modal.Title> <Modal.Body> This will permanently remove the project and its history. This cannot be undone. </Modal.Body> <Modal.Footer> <Button variant="secondary" ref={cancelRef} onClick={() => setOpen(false)}> Cancel </Button> <Button variant="destructive" onClick={handleDelete}> Delete project </Button> </Modal.Footer></Modal>Vue
<Modal variant="alertdialog" v-model:open="open" :initial-focus="cancelRef"> <template #title>Delete this project?</template> <template #body> This will permanently remove the project and its history. This cannot be undone. </template> <template #footer> <Button ref="cancelRef" variant="secondary" @click="open = false"> Cancel </Button> <Button variant="destructive" @click="handleDelete"> Delete project </Button> </template></Modal>Angular (signals)
<ui-modal variant="alertdialog" [open]="open()" (openChange)="open.set($event)"> <h2 ui-modal-title>Delete this project?</h2> <p ui-modal-body> This will permanently remove the project and its history. This cannot be undone. </p> <div ui-modal-footer> <ui-button #cancelRef variant="secondary" cdkFocusInitial (click)="open.set(false)"> Cancel </ui-button> <ui-button variant="destructive" (click)="handleDelete()"> Delete project </ui-button> </div></ui-modal>Notes
This is the first canonical pattern entry. Prose was triangulated against APG (alertdialog role), Radix, Headless UI, CDK, Polaris, and Material 3 documentation as of 2026-04. Library APIs change; re-validate the framework skeletons against current docs before citing them in production reviews.