# AlertDialog

A modal that asks the user to confirm a destructive action. Same look as Dialog but narrower, with no corner close. Focus starts on Cancel, and a scrim click does not close it.

## Usage

### When to use

- Confirm an action that destroys data or can't be undone, such as deleting a project.
- Guard a destructive action against a stray key press or click: focus starts on Cancel, and a scrim click doesn't close the dialog.

### When not to use

- Forms, non-destructive choices, or confirming an action that destroys no data and can be undone. Use Dialog.
- A status that asks for no decision, such as a failed build. Use Badge.

## Examples

### Delete project

```tsx
<AlertDialog>
  <AlertDialogTrigger asChild>
    <Button variant="destructive-soft">Delete project</Button>
  </AlertDialogTrigger>
  <AlertDialogContent>
    <AlertDialogHeader>
      <AlertDialogTitle>Delete project?</AlertDialogTitle>
      <AlertDialogDescription>This removes the project and all its files for everyone on your team. You can't undo it.</AlertDialogDescription>
    </AlertDialogHeader>
    <AlertDialogFooter>
      <AlertDialogCancel>Cancel</AlertDialogCancel>
      <AlertDialogAction>Delete project</AlertDialogAction>
    </AlertDialogFooter>
  </AlertDialogContent>
</AlertDialog>
```

## Do and don't

### Do

- Use it only to confirm an action that destroys data or can't be undone.
- Write the title as the question and the action button as the verb plus the object ("Delete project").
- Say in the description what is lost and for whom.
- Keep Cancel first in the footer markup; the footer puts it left on desktop and at the bottom on mobile.

### Don't

- Don't label the action "Continue", "OK" or "Yes".
- Don't add a corner close or close on a scrim click.
- Don't move initial focus to the action button.
- Don't use it for forms or non-destructive choices; use Dialog.
- Don't leave out AlertDialogDescription.

## Props

| Name | Type | Values | Default | Description |
| --- | --- | --- | --- | --- |
| `open` | `boolean` |  |  | Set on AlertDialog. Whether the dialog is open, when you control it. Pair it with onOpenChange. |
| `defaultOpen` | `boolean` |  | `false` | Set on AlertDialog. Opens the dialog on first render, when you don't control it. |
| `onOpenChange` | `function` |  |  | Set on AlertDialog. Called with true or false when the dialog opens or closes (trigger, Cancel, Action, Escape). Close it yourself after an async action by controlling open. |

### Slots

| Name | Required | Description |
| --- | --- | --- |
| `trigger` | no | Element that opens the dialog. |
| `title` | yes | The question, required for a11y. |
| `description` | yes | What happens if the user confirms. Required. |
| `cancel` | yes | AlertDialogCancel: closes only. Secondary button by default. |
| `action` | yes | AlertDialogAction: closes and runs the destructive action. Destructive button by default, labeled with the action. |

## Anatomy

| Part | Description |
| --- | --- |
| `root` | Root. Controls open state. |
| `overlay` | Scrim behind the content. color-overlay-scrim. Clicking it does nothing. |
| `content` | The floating panel: Dialog's panel, at most max-w-md wide. |
| `header` | Title and description, left-aligned. No icon in v1. |
| `title` | Accessible name. States the question ("Delete project?"). |
| `description` | Required. Says what will happen and that it can't be undone. |
| `footer` | Cancel (secondary) then the action (destructive). Cancel sits left on desktop and at the bottom on mobile. |

## Accessibility

Role: `alertdialog`

| Keys | Action |
| --- | --- |
| `Escape` | Cancels: closes the dialog and returns focus to the trigger. |
| `Tab` | Cycles focus inside the dialog (focus trap). |
| `Enter / Space` | Activates the focused button. Cancel has focus when the dialog opens. |

- role="alertdialog", named by AlertDialogTitle (aria-labelledby) and described by AlertDialogDescription (aria-describedby). Both are required.
- Traps focus and hides the rest of the page from assistive tech (aria-hidden on siblings), same as Dialog.
- Focus moves to AlertDialogCancel on open, so a stray Enter doesn't destroy anything.
- No corner close and no close on a scrim click. Cancel and Escape are the only ways out besides the action.
- Focus returns to the trigger on close.

## Install

```bash
npx shadcn add https://werewolf-ui.vercel.app/r/alert-dialog.json
```

This also adds `styles/werewolf.css`, the tokens every component uses, and any other component it needs. Import that file once in your root CSS, after `@import "tailwindcss"`, with a path relative to that CSS file (from `app/globals.css` it is `@import "../styles/werewolf.css"`).
