Accordion
접었다 펴는 목록이다. 항목은 index 로 식별하고 Head 와 Panel 이 같은 index 를 공유해 연결된다.
import { Accordion } from "@nui-kit/react";
// 서브패스로 좁힐 때
import { Accordion } from "@nui-kit/react/accordion";
import "@nui-kit/react/styles/accordion.css"; // 온디맨드일 때import { Accordion } from "@nui-kit/react";
<Accordion type="single">
<Accordion.Item index={0}>
<Accordion.Head buttonIndex={0}>제목</Accordion.Head>
<Accordion.Panel index={0}>내용</Accordion.Panel>
</Accordion.Item>
</Accordion>Accordion.Head 에 buttonIndex 를 주면 Head 가 스스로 버튼을 렌더한다. 그 Head 를 다시 Accordion.Button 으로 감싸면 버튼 안에 버튼 이 되어 하이드레이션이 깨진다.// ✅ 모드 A — 헤더 전체가 버튼
<Accordion.Button index={0}>
<Accordion.Head>제목</Accordion.Head>
</Accordion.Button>
// ✅ 모드 B — 화살표 아이콘만 버튼
// 헤더에 체크박스 등 다른 조작 요소가 있을 때
<Accordion.Head buttonIndex={0}>제목</Accordion.Head>
// ❌ 둘을 겹치면 button 안에 button
<Accordion.Button index={0}>
<Accordion.Head buttonIndex={0}>제목</Accordion.Head>
</Accordion.Button>Accordion.Item 표기를 쓴다. Server Component 에서는 AccordionItem 같은 named export 를 쓴다.단일 · 다중
type="single" 은 하나만 열리고, 기본값 "multiple" 은 여러 개를 동시에 열 수 있다.
<Accordion type="single" defaultActiveIndices={[0]}>…</Accordion>type="single" — 하나를 열면 다른 하나가 닫힌다
<Accordion type="multiple">…</Accordion>type="multiple" (기본) — 여러 개 동시에
토글 영역 — 두 가지 모드
헤더 전체를 버튼으로 만들지, 화살표 아이콘만 버튼으로 만들지 고른다. 헤더 안에 체크박스처럼 다른 조작 요소를 둔다면 반드시 아이콘만 버튼으로 해야 한다 — 버튼 안에 버튼을 넣을 수 없기 때문이다.
<Accordion.Button index={0}>
<Accordion.Head>제목</Accordion.Head>
</Accordion.Button>모드 A — 헤더 전체가 버튼
<Accordion.Head buttonIndex={0}>제목</Accordion.Head>모드 B — 화살표 아이콘만 버튼 (Head 에 buttonIndex)
변형
<Accordion variant="line" type="single">…</Accordion>variant="line" — 카드 대신 구분선
비활성
Accordion.Button 에 disabled 를 준다. 배경이 없는 버튼이라 글자와 화살표 색만 바뀐다.
<Accordion.Button index={1} disabled>…</Accordion.Button>disabled — 펼칠 수 없다
제어 모드
activeIndices 를 주면 열림 상태를 소비자가 소유한다.
<Accordion activeIndices={indices} onChange={setIndices}>…</Accordion>activeIndices + onChange
내용을 DOM 에 남기기
shouldKeepMounted 를 주면 닫혀도 패널이 DOM 에 남는다. 폼 입력값을 잃지 않아야 하거나, 브라우저 검색(Ctrl+F)에 걸려야 할 때 쓴다.
<Accordion shouldKeepMounted type="single">…</Accordion>shouldKeepMounted — 접었다 펴도 입력값이 유지된다
접근성
- 토글 버튼에
aria-expanded와aria-controls가 붙는다 - 패널은
role="region"+aria-labelledby로 자기 버튼과 연결된다 Head에 제목이 있으면 그것이 버튼의 접근 이름이 된다 (aria-labelledby). 없으면 대체 텍스트를 붙인다- 패널이 DOM 에 없을 때는
aria-controls를 생략한다 — 존재하지 않는 id 를 가리키지 않도록 prefers-reduced-motion에서 펼침 애니메이션이 꺼진다
커스터마이징
색은 컴포넌트별로 열지 않는다. 한 곳만 바꾸려면 className 을, 화면 전체를 바꾸려면 브랜드 프리셋을 쓴다.
| 컴포넌트 | 변수 | 기본값 | 비고 |
|---|---|---|---|
| Accordion | --nui-accordion--border-width | var(--nui-border-width-1) | — · 4자리를 함께 움직인다 |
| --nui-accordion--gap | var(--nui-space-3) | — | |
| --nui-accordion--radius | var(--nui-radius-2_5) | — |
API
Accordion
| 이름 | 타입 | 기본값 | 설명 |
|---|---|---|---|
children * | ReactNode | — | — |
activeIndices | number[] | [] | 제어 모드. 주면 열림 상태를 소비자가 소유한다 |
className | string | — | — |
defaultActiveIndices | number[] | [] | — |
onChange | (nextActiveIndices: number[]) => void | — | — |
shouldKeepMounted | boolean | false | 닫혀 있어도 패널 내용을 DOM 에 남긴다 (폼 입력값 유지 등) |
type | AccordionType | "multiple" | single 은 하나만, multiple 은 여러 개를 동시에 펼친다 |
variant | AccordionVariant | "box" | — |
AccordionProps 에서 자동 생성됨 (components/Accordion/Accordion.tsx).
Accordion.Item
| 이름 | 타입 | 기본값 | 설명 |
|---|---|---|---|
children * | ReactNode | — | — |
index * | number | — | — |
AccordionItemProps 에서 자동 생성됨 (components/Accordion/AccordionItem.tsx). 표준 DOM 속성 277개는 그대로 전달되며 표에서 생략했다.
Accordion.Head
| 이름 | 타입 | 기본값 | 설명 |
|---|---|---|---|
buttonIndex | number | — | 주면 화살표 자리에 토글 버튼이 놓인다. 주지 않으면 장식용 화살표만 렌더된다 |
children | ReactNode | — | — |
toggleLabel | string | "아코디언 패널 토글" | 제목이 없을 때 토글 버튼의 접근 이름. 소비자의 어휘·언어로 바꿀 수 있어야 한다 (a11y.md §9) |
AccordionHeadProps 에서 자동 생성됨 (components/Accordion/AccordionHead.tsx). 표준 DOM 속성 277개는 그대로 전달되며 표에서 생략했다.
Accordion.Button
| 이름 | 타입 | 기본값 | 설명 |
|---|---|---|---|
children * | ReactNode | — | — |
index * | number | — | 이 버튼이 토글할 항목의 index |
onClick | (index: number, event: MouseEvent<HTMLButtonElement>) => void | — | — |
AccordionButtonProps 에서 자동 생성됨 (components/Accordion/AccordionButton.tsx). 표준 DOM 속성 285개는 그대로 전달되며 표에서 생략했다.
Accordion.Panel
| 이름 | 타입 | 기본값 | 설명 |
|---|---|---|---|
children * | ReactNode | — | — |
index * | number | — | — |
className | string | — | — |
AccordionPanelProps 에서 자동 생성됨 (components/Accordion/AccordionPanel.tsx).