Accordion
먼저 보고, 그다음 계약을 읽습니다
collapsible disclosure 스택(single/multiple).
Component intent의도와 경계 읽기
Radix Accordion 위에 .axe-accordion__* 스타일을 얹은 접이식 항목 스택이다. type="single"(한 번에 하나) 과 type="multiple"(동시 여러 개) 을 모두 지원하며 FAQ, 설정 그룹, 긴 폼의 섹션 접기 등에 쓴다. 각 트리거는 heading 안 버튼으로 렌더되고 chevron 이 자동으로 붙는다. 부드러운 height 접기는 Radix 가 노출하는 --radix-accordion-content-height 변수를 @keyframes 로 잡아 처리한다(하나의 영역만 접는 경량 패턴은 Collapsible).
예제
SSOT에 등록된 실제 API 기준 snippet입니다. standalone 배지만 독립 실행 단위이며, fragment는 주변 state·handler 문맥을 생략합니다.
import { Accordion, AccordionItem, AccordionTrigger, AccordionContent } from "@axe/ui";<Accordion type="single" collapsible defaultValue="faq-1"> <AccordionItem value="faq-1"> <AccordionTrigger>배포는 어떻게 하나요?</AccordionTrigger> <AccordionContent>axe ship <svc> 로 합니다.</AccordionContent> </AccordionItem> <AccordionItem value="faq-2"> <AccordionTrigger>롤백은?</AccordionTrigger> <AccordionContent>blue/green 전환으로…</AccordionContent> </AccordionItem></Accordion>import { Accordion, AccordionItem, AccordionTrigger, AccordionContent } from "@axe/ui";<Accordion type="multiple" defaultValue={["a", "c"]}> <AccordionItem value="a"><AccordionTrigger>A</AccordionTrigger><AccordionContent>…</AccordionContent></AccordionItem> <AccordionItem value="b"><AccordionTrigger>B</AccordionTrigger><AccordionContent>…</AccordionContent></AccordionItem> <AccordionItem value="c"><AccordionTrigger>C</AccordionTrigger><AccordionContent>…</AccordionContent></AccordionItem></Accordion><div class="axe-accordion__item"> <h3 class="axe-accordion__header"> <button class="axe-accordion__trigger" data-state="open" aria-expanded="true"> <span class="axe-accordion__trigger-label">배포는 어떻게 하나요?</span> <svg class="axe-accordion__chevron" viewBox="0 0 12 12" aria-hidden="true"> <path d="M4 2.5 L8 6 L4 9.5" fill="none" stroke="currentColor" stroke-width="1.75" /> </svg> </button> </h3> <div class="axe-accordion__content" data-state="open"> <div class="axe-accordion__content-inner">axe ship <svc> 로 합니다.</div> </div></div>Props
TSX 소스가 진실입니다. 주요 export 컴포넌트의 public API만 노출합니다.
| 이름 | 타입 | 필수 | 기본값 | 설명 |
|---|---|---|---|---|
Accordion.type | "single" | "multiple" | 필수 | — | single = 한 번에 하나만 열림, multiple = 동시 여러 개. |
Accordion.collapsible | boolean | — | — | type="single" 에서 열린 항목을 다시 눌러 전부 닫기 허용. |
Accordion.defaultValue | string | string[] | — | — | uncontrolled 초기 열림 value(single=string, multiple=string[]). |
Accordion.value | string | string[] | — | — | controlled 열림 value. |
Accordion.onValueChange | (value: string | string[]) => void | — | — | 열림 value 변경 콜백. |
Accordion.…rest | React.ComponentPropsWithoutRef<Radix Accordion.Root> | — | — | Accordion 은 Radix Root 를 그대로 재노출(axe 클래스 없음) — className 등은 Root 로 직접 전파. |
AccordionItem.value | string | 필수 | — | 항목 식별 value(열림 상태 매핑 키). |
AccordionItem.…rest | React.ComponentPropsWithoutRef<Radix Accordion.Item> | — | — | className 은 axe-accordion__item 과 병합, 나머지는 Radix Item 으로 전파. |
AccordionTrigger.…rest | React.ComponentPropsWithoutRef<Radix Accordion.Trigger> | — | — | children=제목/질문. .axe-accordion__header 안에 렌더되고 chevron 자동. 나머지는 Radix Trigger 로 전파. |
AccordionContent.…rest | React.ComponentPropsWithoutRef<Radix Accordion.Content> | — | — | children 은 .axe-accordion__content-inner 로 감싸 렌더. 나머지는 Radix Content 로 전파. |
.axe-* 클래스 계약
React 밖에서도 같은 표면을 그리는 공개 계약입니다. stable은 minor 버전 안에서 이름을 바꾸지 않습니다.
| 클래스 | 안정성 | 용도 |
|---|---|---|
.axe-accordion__item | stable | 각 항목 래퍼 — 하단 border-subtle(마지막 항목 제외). |
.axe-accordion__header | stable | 트리거를 감싸는 heading 래퍼(margin 0, flex). |
.axe-accordion__trigger | stable | 트리거 버튼(전폭, label+chevron, hover/focus 트림). |
.axe-accordion__trigger-label | stable | 트리거 라벨 span(flex:1). |
.axe-accordion__chevron | stable | chevron SVG — [data-state=open] 시 90deg 회전. |
.axe-accordion__content | stable | 접히는 영역(overflow hidden). data-state open/closed 에 --radix-accordion-content-height 애니메이션. |
.axe-accordion__content-inner | stable | content 내부 padding 래퍼. |
접근성
키보드, ARIA, 구현 노트를 함께 검토합니다.
- ↑/↓ — 트리거 간 이동(roving tabindex)
- Home/End — 첫/마지막 트리거로
- Enter/Space — 항목 열기/접기
각 트리거는 heading(.axe-accordion__header) 안 버튼으로, aria-expanded + aria-controls 를 가지며 컨텐츠는 연결된 region 이다. 화살표 네비/포커스 관리는 Radix 가 제공. chevron 은 aria-hidden 장식.
smooth height 는 --radix-accordion-content-height 를 @keyframes from/to 로 잡아 처리하고 prefers-reduced-motion 시 즉시 토글한다. Accordion 루트는 axe 클래스 없이 Radix Root 그대로(레이아웃 중립) — 컨테이너 스타일이 필요하면 className 을 직접 부여한다.