Confirm Dialog
The one recipe for a destructive confirmation, over Alert Dialog. A "Verb object?" title, one sentence on what is lost, a focused safe answer, and the owner closes it.
Installation
$ pnpm dlx shadcn@latest add @videorc/confirm-dialogUsage
import { ConfirmDialog } from "@/components/confirm-dialog";<ConfirmDialog
confirmLabel="Delete scene"
description="Only the saved snapshot is deleted. Your current scene and recording continue."
onCancel={() => setOpen(false)}
onConfirm={deleteScene}
open={open}
title="Delete saved scene?"
/>Confirm and undo
Every destructive action either asks first or can be undone.
- Confirm with
ConfirmDialogwhen the loss is real and hard to restore:- the title is "Verb object?": "Delete saved scene?";
- one sentence names exactly what is lost;
- the safe answer ("Cancel", or "Keep …") is a ghost button with focus on open, and Escape is the same answer;
- the destructive button reads verb + object: "Delete scene";
- there's no close button: the two answers are the only way out.
- Undo a frequent, cheap-to-restore action instead of asking: run it after a short window unless it's undone, with an Undo action on its toast. Asking every time trains people to click through the question.
The dialog is controlled, and the owner closes it by dropping open: at once after a synchronous action, or once an async one settles. Meanwhile confirmLabel says "Deleting…" and confirmDisabled keeps it from running twice, as in the demo above.
Use it for deletes and anything else that destroys work. Don't use it for a question that isn't a destructive confirmation, or for a cheap action that can be undone.
Examples
A replace that destroys nothing
A consequential step that destroys nothing, such as replacing what's been typed, passes confirmVariant="default", so the answer is the chrome fill instead of the destructive tint. The safe answer can name what it keeps.
Theming
It's Alert Dialog underneath: the dialog tier of the float glass, the panel radius and no backdrop blur.
| Token or attribute | Meaning |
|---|---|
Button ghost | The safe answer |
Button destructive or default | The answer, by confirmVariant |
data-testid | {testId}-dialog, {testId}-cancel and {testId}-confirm |
Keyboard
| Key | Action |
|---|---|
| Esc | Cancels: the same answer as the safe button |
| Tab | Moves between the answers; focus stays inside |
| Enter Space | Presses the focused answer, which starts on the safe one |
Accessibility
The dialog is an alertdialog, named by its title and described by its sentence. The safe answer has focus on open, so a stray Enter never destroys anything. A click outside doesn't close it.
API reference
Prop
Type