patterns
Confirmation and destructive actions
Friction proportional to consequence. Titles are questions, descriptions state what's affected, buttons use verbs — never 'Yes' or 'OK.'
Read the full specLive specimen — destructive confirm
Trigger opens the shared ConfirmDialog with the destructive variant. Initial focus lands on Cancel; Escape cancels.
import { ConfirmDialog } from "@wolf/design-system";
const [open, setOpen] = useState(false);
<Button variant="destructive" onClick={() => setOpen(true)}>
<Trash2 /> Delete report
</Button>
<ConfirmDialog
open={open}
onOpenChange={setOpen}
title="Delete this report?"
description="The report will be removed from the feed, along with 3 attached notes. This can't be undone."
confirmLabel="Delete report"
destructive
onConfirm={async () => { await deleteReport(id); }}
/>Non-destructive confirm — add friction, not alarm
Use the default variant when the action needs a second thought but isn't irreversible.
When to confirm
Friction proportional to consequence. Delete a report? Yes. Mark as read? No.
Always confirm
- — Deleting a report, area, user or patrol
- — Removing a guard from a group
- — Sending a mass alert (>10 recipients)
- — Cancelling a subscription
- — Bulk actions affecting more than 10 items
Don't confirm
- — Saving a draft or a setting
- — Marking a report as read
- — Toggling a preference
- — Filtering or sorting a list
- — Single low-stakes reversible actions
Copy rules
Question title, plain description, verb in the confirm button — never 'Yes' or 'OK.'
Avoid
Are you sure you want to delete this?
Good
Delete this report?
Avoid
This action cannot be undone.
Good
This can't be undone.
Avoid
Please confirm.
Good
[Cancel] [Delete report]
Avoid
Yes / No · OK / Cancel
Good
Cancel / Delete report · Keep subscription / Cancel subscription
Keyboard and a11y
ConfirmDialog uses role=alertdialog. Cancel has initial focus; Escape cancels; backdrop click does not dismiss destructive dialogs.
- EnterActivates the confirming button
- EscapeCancels and closes the dialog
- Initial focusLands on Cancel — prevents accidental destruction
- Backdrop clickDismisses non-destructive only; destructive requires explicit click