# AlertDialog

Modal yêu cầu người dùng xác nhận một hành động phá hủy. Trông giống Dialog nhưng hẹp hơn, không có nút đóng ở góc. Focus bắt đầu trên Cancel, và nhấn scrim không đóng.

**Phụ thuộc:** npm: 1 trực tiếp, 6 tổng; registry: 4 trực tiếp, 4 tổng.

## Cách dùng

### Khi nào dùng

- Xác nhận hành động phá dữ liệu hoặc không hoàn tác được, chẳng hạn xóa một dự án.
- Chặn hành động phá hủy khỏi phím hoặc cú nhấn nhầm: focus bắt đầu trên Cancel, và nhấn scrim không đóng dialog.

### Khi nào không dùng

- Form, lựa chọn không phá hủy, hoặc xác nhận hành động không phá dữ liệu và hoàn tác được. Dùng Dialog.
- Trạng thái không cần quyết định, chẳng hạn một bản build thất bại. Dùng Badge.

## Ví dụ

### Xóa dự án

```tsx
<AlertDialog>
  <AlertDialogTrigger asChild>
    <Button variant="destructive-soft">Xóa dự án</Button>
  </AlertDialogTrigger>
  <AlertDialogContent>
    <AlertDialogHeader>
      <AlertDialogTitle>Xóa dự án?</AlertDialogTitle>
      <AlertDialogDescription>Thao tác này xóa dự án và mọi tệp của dự án đối với mọi người trong nhóm của bạn. Bạn không thể hoàn tác.</AlertDialogDescription>
    </AlertDialogHeader>
    <AlertDialogFooter>
      <AlertDialogCancel>Hủy</AlertDialogCancel>
      <AlertDialogAction>Xóa dự án</AlertDialogAction>
    </AlertDialogFooter>
  </AlertDialogContent>
</AlertDialog>
```

## Nên và không nên

### Nên

- Chỉ dùng nó để xác nhận hành động phá dữ liệu hoặc không hoàn tác được.
- Viết title như một câu hỏi và button hành động như động từ kèm đối tượng ("Xóa dự án").
- Nói trong description thứ gì bị mất và của ai.
- Giữ Cancel đứng trước trong markup của footer; footer đặt nó bên trái trên desktop và ở dưới cùng trên mobile.

### Không nên

- Đừng gắn nhãn action là "Tiếp tục", "OK" hoặc "Có".
- Đừng thêm nút đóng ở góc hoặc đóng khi nhấn scrim.
- Đừng chuyển focus ban đầu tới button hành động.
- Đừng dùng nó cho form hoặc lựa chọn không phá hủy; dùng Dialog.
- Đừng bỏ sót AlertDialogDescription.

## Props

| Tên | Kiểu | Giá trị | Mặc định | Mô tả |
| --- | --- | --- | --- | --- |
| `open` | `boolean` |  |  | Đặt trên AlertDialog. Dialog có đang mở hay không, khi bạn điều khiển nó. Ghép với onOpenChange. |
| `defaultOpen` | `boolean` |  | `false` | Đặt trên AlertDialog. Mở dialog ở lần render đầu, khi bạn không điều khiển nó. |
| `onOpenChange` | `function` |  |  | Đặt trên AlertDialog. Được gọi với true hoặc false khi dialog mở hoặc đóng (trigger, Cancel, Action, Escape). Bạn tự đóng nó sau một hành động async bằng cách điều khiển open. |

### Slot

| Tên | Bắt buộc | Mô tả |
| --- | --- | --- |
| `trigger` | không | Phần tử mở dialog. |
| `title` | có | Câu hỏi, bắt buộc cho a11y. |
| `description` | có | Điều xảy ra nếu người dùng xác nhận. Bắt buộc. |
| `cancel` | có | AlertDialogCancel: chỉ đóng. Button secondary theo mặc định. |
| `action` | có | AlertDialogAction: đóng và chạy hành động phá hủy. Button destructive theo mặc định, nhãn theo hành động. |

## Cấu tạo

| Phần | Mô tả |
| --- | --- |
| `root` | Root. Điều khiển trạng thái open. |
| `overlay` | Scrim phía sau content. color-overlay-scrim. Nhấn vào thì không có gì xảy ra. |
| `content` | Panel nổi: panel của Dialog, rộng tối đa max-w-md. |
| `header` | Title và description, căn trái. Không có icon trong v1. |
| `title` | Tên truy cập. Nêu câu hỏi ("Xóa dự án?"). |
| `description` | Bắt buộc. Nói chuyện gì sẽ xảy ra và rằng không hoàn tác được. |
| `footer` | Cancel (secondary) rồi đến action (destructive). Cancel nằm bên trái trên desktop và ở dưới cùng trên mobile. |

## Khả năng truy cập

Role: `alertdialog`

| Phím | Hành động |
| --- | --- |
| `Escape` | Hủy: đóng dialog và trả focus về trigger. |
| `Tab` | Luân chuyển focus bên trong dialog (bẫy focus). |
| `Enter / Space` | Kích hoạt button đang focus. Cancel nhận focus khi dialog mở. |

- role="alertdialog", được đặt tên bởi AlertDialogTitle (aria-labelledby) và mô tả bởi AlertDialogDescription (aria-describedby). Cả hai đều bắt buộc.
- Giữ focus và ẩn phần còn lại của trang khỏi công nghệ hỗ trợ (aria-hidden trên các phần tử anh em), giống Dialog.
- Focus chuyển tới AlertDialogCancel khi mở, để một lần Enter nhầm không phá gì.
- Không có nút đóng ở góc và không đóng khi nhấn scrim. Cancel và Escape là những lối thoát duy nhất ngoài action.
- Focus trở về trigger khi đóng.

## Cài đặt

```bash
npx werewolf-ui add alert-dialog
```

Chạy `npx werewolf-ui init` một lần trong app trước khi thêm component. Init cài token, thêm CSS import và luật cho agent. Add cài component này cùng các dependency và giữ nguyên theme của bạn. Xem [Cài đặt](https://www.werewolf-ui.dev/vi/docs/installation.md) để biết yêu cầu và cách cài qua registry.
