# Accordion

Một chồng các phần mở tại chỗ, từng phần một hoặc nhiều phần: câu hỏi và câu trả lời, nhóm cài đặt, chi tiết dài. Mỗi phần là một hàng gồm tiêu đề và caret xoay, với đường kẻ bên dưới.

**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

- Trang dài gồm câu hỏi và câu trả lời, hoặc nhóm cài đặt mà người dùng mở từng phần một.
- Chi tiết hầu hết mọi người bỏ qua, giữ trên trang cho người cần.

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

- Chuyển giữa các chế độ xem của cùng nội dung. Dùng Tabs.
- Nội dung mọi người đều cần. Để nó trên trang, mở sẵn.
- Một phần nằm trong phần accordion khác.

## Biến thể

### type

Đặt trên Accordion. single mở một phần mỗi lần; multiple cho phép nhiều phần cùng mở, cho cài đặt mà người dùng so sánh.

Giá trị: `single`, `multiple`. Mặc định: `single`.

### headingLevel

Đặt trên Accordion. Cấp heading của mọi tiêu đề: thấp hơn một cấp so với heading mà accordion nằm dưới.

Giá trị: `2`, `3`, `4`. Mặc định: `3`.

## Ví dụ

### Câu hỏi

```tsx
<Accordion defaultValue="refunds" className="max-w-md">
  <AccordionItem value="refunds">
    <AccordionTrigger>Tôi có thể được hoàn tiền không?</AccordionTrigger>
    <AccordionContent>Có, trong vòng 14 ngày kể từ ngày mua.</AccordionContent>
  </AccordionItem>
  <AccordionItem value="seats">
    <AccordionTrigger>Tôi có thể thêm người sau không?</AccordionTrigger>
    <AccordionContent>Thêm hoặc gỡ chỗ ngồi bất kỳ lúc nào từ mục Thanh toán.</AccordionContent>
  </AccordionItem>
</Accordion>
```

### Nhiều phần mở

type multiple giữ mọi phần người dùng đã mở.

```tsx
<Accordion type="multiple" headingLevel={4} className="max-w-md">
  <AccordionItem value="email">
    <AccordionTrigger>Email</AccordionTrigger>
    <AccordionContent>Đề cập, trả lời và bản tin hàng tuần.</AccordionContent>
  </AccordionItem>
  <AccordionItem value="push">
    <AccordionTrigger>Đẩy</AccordionTrigger>
    <AccordionContent>Chỉ đề cập và trả lời.</AccordionContent>
  </AccordionItem>
  <AccordionItem value="sms" disabled>
    <AccordionTrigger>Tin nhắn văn bản</AccordionTrigger>
    <AccordionContent>Không có trong gói của bạn.</AccordionContent>
  </AccordionItem>
</Accordion>
```

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

### Nên

- Viết tiêu đề để người dùng lướt tìm: một câu hỏi, hoặc tên của một nhóm cài đặt.
- Đặt headingLevel thấp hơn một cấp so với heading mà accordion nằm dưới.
- Dùng type multiple khi người dùng so sánh các phần cạnh nhau.

### Không nên

- Đừng giấu thứ mọi người cần; để nó trên trang.
- Đừng dùng nó để chuyển giữa các chế độ xem của cùng nội dung; dùng Tabs.
- Đừng đặt accordion bên trong một phần accordion.

## Props

| Tên | Kiểu | Giá trị | Mặc định | Mô tả |
| --- | --- | --- | --- | --- |
| `type` | `enum` | `single`, `multiple` | `single` | Đặt trên Accordion. single mở một phần mỗi lần; multiple cho phép nhiều phần cùng mở, cho cài đặt mà người dùng so sánh. |
| `collapsible` | `boolean` |  | `true` | Đặt trên Accordion, cùng type single. Phần đang mở đóng lại khi nhấn lại tiêu đề. |
| `defaultValue` | `string` |  |  | Đặt trên Accordion. Value của phần mở ở lần render đầu (một mảng value khi type multiple). |
| `value` | `string` |  |  | Đặt trên Accordion. Phần đang mở, khi bạn điều khiển nó. Ghép với onValueChange. |
| `onValueChange` | `function` |  |  | Đặt trên Accordion. Được gọi với value đang mở (hoặc các value) khi một phần mở hoặc đóng. |
| `headingLevel` | `enum` | `2`, `3`, `4` | `3` | Đặt trên Accordion. Cấp heading của mọi tiêu đề: thấp hơn một cấp so với heading mà accordion nằm dưới. |
| `disabled` | `boolean` |  | `false` | Đặt trên AccordionItem, hoặc trên Accordion cho mọi phần. Tiêu đề không nhấn được và mờ đi. |

### Slot

| Tên | Bắt buộc | Mô tả |
| --- | --- | --- |
| `item` | có | Một AccordionItem cho mỗi phần, mỗi cái có value riêng, một AccordionTrigger và một AccordionContent. |

## Cấu tạo

| Phần | Mô tả |
| --- | --- |
| `root` | Accordion: một cột rộng bằng phần tử cha. |
| `item` | AccordionItem: một phần, có đường kẻ bên dưới. |
| `trigger` | AccordionTrigger: hàng tiêu đề, một button bên trong heading. Cao ít nhất bằng control md, chữ medium 14px, caret ở cuối. |
| `icon` | Tabler ChevronDown, 16px, secondary, ở cuối tiêu đề; xoay nửa vòng khi mở. |
| `content` | AccordionContent: phần mở ra, chữ secondary 14px. |
| `body` | Khối có padding bên trong content, pb-md, để không có gì hiện trong lúc nó lớn lên. |

## Khả năng truy cập

Role: `region`

| Phím | Hành động |
| --- | --- |
| `Space, Enter` | Mở hoặc đóng phần đang focus. |
| `ArrowDown, ArrowUp` | Chuyển focus tới tiêu đề phần tiếp theo hoặc trước đó. |
| `Home, End` | Chuyển focus tới tiêu đề phần đầu hoặc cuối. |
| `Tab` | Chuyển từ tiêu đề vào nội dung đang mở, rồi đi tiếp. |

- Mỗi tiêu đề là một button có aria-expanded bên trong heading thật, mặc định h3; đặt headingLevel để khớp outline của trang.
- Phần đang mở là một region được đặt tên theo tiêu đề.
- Caret chỉ để trang trí; aria-expanded cho biết phần có đang mở hay không.
- Nó mở bằng giãn ngắn và mờ dần chỉ khi người dùng cho phép chuyển động, và đóng theo chiều ngược như vậy (ease-exit); khi giảm chuyển động thì chỉ mờ dần.

## Cài đặt

```bash
npx werewolf-ui add accordion
```

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.
