# Spinner

Một cung quay cho thấy việc đang chạy khi không biết lượng: đang tải một danh sách, đang kiểm tra một giá trị. Tên được trình đọc màn hình đọc và không bao giờ hiện.

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

## Cách dùng

### Khi nào dùng

- Cho thấy việc đang chạy khi không biết độ dài: đang tải bình luận, đang kiểm tra một giá trị.
- Một vùng nhỏ hoặc một control đang chờ, đúng chỗ kết quả sẽ hiện.

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

- Việc đã biết lượng, như một lần tải lên. Dùng Progress.
- Một trang hoặc danh sách mà bạn biết bố cục trong lúc tải. Dùng Skeleton.

## Biến thể

### size

sm (16px) trong control sm và md; md (20px) trong control lg; lg (24px) khi đứng một mình trong vùng đang tải.

Giá trị: `sm`, `md`, `lg`. Mặc định: `md`.

### tone

secondary trên surface; accent khi spinner là thứ chính trên màn hình; current lấy màu chữ xung quanh, như label bên trong một Button.

Giá trị: `secondary`, `accent`, `current`. Mặc định: `secondary`.

## Ví dụ

### Đang tải một danh sách

```tsx
<div className="flex items-center gap-sm text-sm text-text-secondary">
  <Spinner size="sm" label="Đang tải bình luận" />
  <span aria-hidden="true">Đang tải bình luận</span>
</div>
```

### Đứng một mình

lg và accent khi spinner là thứ duy nhất trong vùng.

```tsx
<Spinner size="lg" tone="accent" label="Đang tải bảng điều khiển" />
```

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

### Nên

- Đặt tên việc đang tải trong label: Đang tải bình luận.
- Đặt spinner ở chỗ nội dung sẽ xuất hiện, để mắt đã ở đó khi nội dung tới.
- Dùng tone current bên trong control, để nó lấy màu chữ của control.

### Không nên

- Đừng dùng khi biết lượng việc, như một lần tải lên. Dùng Progress.
- Đừng dùng cho cả trang hoặc danh sách mà bạn biết bố cục. Dùng Skeleton.
- Đừng hiện nhiều spinner cho một việc.

## Props

| Tên | Kiểu | Giá trị | Mặc định | Mô tả |
| --- | --- | --- | --- | --- |
| `size` | `enum` | `sm`, `md`, `lg` | `md` | sm (16px) trong control sm và md; md (20px) trong control lg; lg (24px) khi đứng một mình trong vùng đang tải. |
| `tone` | `enum` | `secondary`, `accent`, `current` | `secondary` | secondary trên surface; accent khi spinner là thứ chính trên màn hình; current lấy màu chữ xung quanh, như label bên trong một Button. |
| `label` | `string` |  | `Loading` | Việc gì đang tải, cho trình đọc màn hình: Đang tải bình luận. Không bao giờ hiện. |

## Cấu tạo

| Phần | Mô tả |
| --- | --- |
| `root` | Hộp inline cỡ icon, dùng màu icon. |
| `icon` | Tabler Loader2: 16px (sm), 20px (md) hoặc 24px (lg). Nó quay khi có motion-safe. |
| `label` | Chữ giấu khỏi mắt, đặt tên việc đang tải. |

## Khả năng truy cập

Role: `status`

- Root là một vùng status, và label (mặc định Đang tải) là chữ giấu khỏi mắt của vùng. Đặt tên việc đang tải: Đang tải bình luận.
- Cung chỉ để trang trí (aria-hidden); label mang nghĩa.
- Nó chỉ quay khi người dùng cho phép chuyển động. Dưới prefers-reduced-motion thì đứng yên, và label vẫn nói việc đang xảy ra.
- Gỡ spinner khi việc xong, và chỉ chuyển focus tới kết quả nếu người dùng đã yêu cầu việc đó.

## Cài đặt

```bash
npx werewolf-ui add spinner
```

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.
