# Combobox

Chọn một giá trị từ danh sách dài bằng cách gõ để lọc: một quốc gia, một người, một repository. Nó có hộp của Input với caret, và mở danh sách của Select dưới field; các phím mũi tên đi qua các kết quả khớp và Enter chọn một.

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

## Cách dùng

### Khi nào dùng

- Chọn một giá trị từ danh sách quá dài để lướt, bằng cách gõ một phần của nó: một quốc gia, một người, một repository.
- Danh sách mà người dùng đã biết tên các lựa chọn.

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

- Danh sách lựa chọn ngắn. Dùng Select, hoặc RadioGroup để hiện tất cả.
- Chữ tự do. Dùng Input.
- Nhiều giá trị. Dùng Tokenizer, hoặc Checkbox cho danh sách ngắn.

## Biến thể

### size

Chiều cao field theo size-element-*. Khớp Input hoặc Button cạnh nó: md trong form, sm chỉ trong UI dày đặc ưu tiên chuột, lg hoặc xl cho field chính của một màn hình và trên màn hình ưu tiên cảm ứng.

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

## Ví dụ

### Quốc gia

```tsx
<Field className="w-full max-w-sm">
  <FieldLabel>Quốc gia</FieldLabel>
  <FieldControl>
    <Combobox placeholder="Tìm kiếm quốc gia" emptyText="Không tìm thấy quốc gia.">
      <ComboboxItem value="de">Đức</ComboboxItem>
      <ComboboxItem value="jp">Nhật Bản</ComboboxItem>
      <ComboboxItem value="vn">Việt Nam</ComboboxItem>
      <ComboboxItem value="us">Hoa Kỳ</ComboboxItem>
    </Combobox>
  </FieldControl>
</Field>
```

### Nhóm

Một tiêu đề trên mỗi nhóm; lựa chọn disabled vẫn ở trong danh sách nhưng không chọn được.

```tsx
<Field className="w-full max-w-sm">
  <FieldLabel>Người được giao</FieldLabel>
  <FieldControl>
    <Combobox defaultValue="ada" emptyText="Không tìm thấy ai.">
      <ComboboxGroup heading="Thiết kế">
        <ComboboxItem value="ada">Ada Lovelace</ComboboxItem>
        <ComboboxItem value="grace">Grace Hopper</ComboboxItem>
      </ComboboxGroup>
      <ComboboxGroup heading="Kỹ thuật">
        <ComboboxItem value="alan">Alan Turing</ComboboxItem>
        <ComboboxItem value="edsger" disabled>Edsger Dijkstra</ComboboxItem>
      </ComboboxGroup>
    </Combobox>
  </FieldControl>
</Field>
```

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

### Nên

- Dùng nó cho danh sách quá dài để lướt, khi người dùng biết mình đang tìm gì.
- Viết emptyText nói thứ không tìm thấy: Không thấy quốc gia.
- Đặt nó trong một Field với label nhìn thấy.

### Không nên

- Đừng dùng nó cho danh sách ngắn; dùng Select hoặc RadioGroup.
- Đừng dùng nó cho chữ tự do; dùng Input.
- Đừng dùng nó cho nhiều giá trị; dùng Tokenizer hoặc Checkbox.

## Props

| Tên | Kiểu | Giá trị | Mặc định | Mô tả |
| --- | --- | --- | --- | --- |
| `defaultValue` | `string` |  |  | Giá trị được chọn ở lần render đầu, khi bạn không kiểm soát nó. |
| `value` | `string` |  |  | Giá trị đã chọn, khi bạn kiểm soát nó. Ghép với onValueChange. |
| `onValueChange` | `function` |  |  | Được gọi với value của lựa chọn mà người dùng chọn. |
| `open` | `boolean` |  |  | Danh sách có đang mở hay không, khi bạn kiểm soát nó. Ghép với onOpenChange. |
| `defaultOpen` | `boolean` |  | `false` | Mở danh sách ở lần render đầu. |
| `onOpenChange` | `function` |  |  | Được gọi với true hoặc false khi danh sách mở hoặc đóng. |
| `placeholder` | `string` |  |  | Việc cần gõ, hiện khi field trống: Tìm quốc gia. Không phải label. |
| `emptyText` (bắt buộc) | `string` |  |  | Danh sách nói gì khi chữ không khớp lựa chọn nào: Không thấy quốc gia. |
| `size` | `enum` | `sm`, `md`, `lg`, `xl` | `md` | Chiều cao field theo size-element-*. Khớp Input hoặc Button cạnh nó: md trong form, sm chỉ trong UI dày đặc ưu tiên chuột, lg hoặc xl cho field chính của một màn hình và trên màn hình ưu tiên cảm ứng. |
| `disabled` | `boolean` |  | `false` | Không focus hoặc mở được; vẻ disabled trung tính. |
| `name` | `string` |  |  | Tên trong form. Giá trị đã chọn được gửi dưới tên đó. |

### Slot

| Tên | Bắt buộc | Mô tả |
| --- | --- | --- |
| `items` | có | Các phần tử ComboboxItem (value, chữ, textValue tùy chọn và disabled), hoặc các phần tử ComboboxGroup với một tiêu đề bao quanh. Giữ chúng là con trực tiếp. |

## Cấu tạo

| Phần | Mô tả |
| --- | --- |
| `root` | Combobox: field và danh sách của nó. |
| `group` | Hộp field: nền lõm của Input, viền control, góc và kích thước, với ô chữ và caret. Nó hiện vòng focus của field, vẻ disabled và viền danger. |
| `groupIcon` | Tabler CaretDown ở cuối, 16px (20px ở xl), màu phụ. |
| `placeholder` | Chữ placeholder khi chưa chọn hoặc chưa gõ gì. |
| `content` | Danh sách dưới field, rộng bằng field: bề mặt raised của Select. Nó cuộn khi dài hơn 288px. |
| `item` | Một lựa chọn, vẻ option của Select: chiều cao control md, góc trong, overlay hover trung tính khi được tô sáng. |
| `indicator` | Tabler Check, 16px, ở cuối lựa chọn đã chọn. |
| `groupLabel` | Tiêu đề của một ComboboxGroup, tiêu đề nhóm của Select. |
| `empty` | emptyText khi không có gì khớp: chữ phụ 14px. |

## Khả năng truy cập

Role: `combobox`

| Phím | Hành động |
| --- | --- |
| `Type` | Lọc các lựa chọn còn những cái chứa chữ đó, và mở danh sách. |
| `ArrowDown, ArrowUp` | Mở danh sách, hoặc đi qua các kết quả khớp; các lựa chọn disabled bị bỏ qua. |
| `Enter` | Chọn lựa chọn đang tô sáng và đóng danh sách. |
| `Escape` | Đóng danh sách và trả lại chữ của lựa chọn đã chọn. |
| `Tab` | Đóng danh sách và chuyển tiếp. |

- Field là một combobox với aria-expanded, aria-controls và aria-autocomplete="list"; lựa chọn đang tô sáng là aria-activedescendant của nó, nên focus ở lại trong field.
- Đặt tên bằng label của Field hoặc aria-label. Các lựa chọn được đọc kèm trạng thái selected; một nhóm được đặt tên bằng tiêu đề của nó.
- Khi không lựa chọn nào khớp, danh sách nói emptyText.
- Khi có name, giá trị đã chọn được gửi dưới tên đó trong một input ẩn.

## Cài đặt

```bash
npx werewolf-ui add combobox
```

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.
