## Confirm Dialog (S—024)

A modal confirmation with typed-phrase protection, pending and error states, built on native <dialog>.

- URL: https://sundaeui.dev/components/confirm-dialog
- Category: UI components · Art direction: Understated
- Access: Free (no account needed)
- Stack: React 18+, TypeScript, Tailwind CSS; dependencies: none
- Install: `npx shadcn@latest add https://sundaeui.dev/r/confirm-dialog.json`
- Tags: destructive, tailwind, overlay, modal, react, dialog, confirmation

For actions that can’t be undone. The dialog rises slightly into place over a softly blurred page and stays on screen until the decision is made. Optionally, the destructive button only enables once the person types an exact phrase, such as the workspace name, so a misclick can’t delete production.
onConfirm can be async. The button shows a spinner and the dialog can’t be dismissed mid-request. If it throws, the error appears inline and the dialog stays open, so the person can try again or cancel. Cancel is focused by default when no phrase is required.
Use it for deletions, revoking access and billing changes. Don’t use it for reversible actions: an undo toast is kinder.

### Usage

```tsx
import { ConfirmDialog } from '@/components/sundae/confirm-dialog'

<ConfirmDialog
  open={open}
  onOpenChange={setOpen}
  title="Delete “acme-prod”?"
  description="This permanently deletes the workspace."
  confirmText="acme-prod"
  confirmLabel="Delete workspace"
  onConfirm={() => deleteWorkspace(id)}
/>
```

### Props

- `open / onOpenChange` (`boolean / (open) => void`, required): Controlled visibility.
- `title` (`string`, required): Dialog heading (aria-labelledby).
- `description` (`ReactNode`, required): Consequences, in plain words (aria-describedby).
- `confirmText` (`string`): Phrase that must be typed exactly to enable confirm.
- `tone` (`'danger' | 'default'`, default `'danger'`): Danger adds the warning icon and red action.
- `onConfirm` (`() => void | Promise<void>`, required): Async aware. Throw to show an inline error.
- `confirmLabel / cancelLabel` (`string`): Button text. Name the action, not “OK”.

### Accessibility

- A native <dialog> opened with showModal(): focus is trapped, the page behind is inert, and focus returns when it closes.
- Labelled and described by its title and description. Errors use role="alert".
- Escape and backdrop clicks are ignored while a request is pending.
