ComponentsP3 본문

Accordion

APG Accordion 패턴 컴파운드 컴포넌트 — single/multiple 펼침을 비제어(defaultValue) 또는 제어(value)로 소유, h3+button과 region으로 구조화.

마지막 업데이트 2026-06-11

한눈에#

긴 콘텐츠를 섹션별로 접어 두고 필요한 것만 펼치는 APG Accordion입니다 — single(하나만)·multiple(동시) 펼침을 지원합니다.

tokens/ SSOT에서 생성됩니다 — CSS 변수와 Dart 상수가 같은 소스를 공유합니다.

  • APG Accordion
  • single·multiple 펼침
  • h3 > button + region
  • 제어·비제어

헤더는 h3 > button으로 문서 아웃라인에 노출되고, 패널은 region으로 연결됩니다

사용 시점#

긴 콘텐츠를 섹션별로 접어 필요한 것만 펼치면 Accordion — 한 뷰만 전환하거나 본문 없는 토글은 다른 컴포넌트입니다.

쓴다

필요한 항목만 펼쳐 봅니다.

FAQ·설정 그룹처럼 섹션을 접어 두고 필요한 것만 펼침(multiple로 동시 비교도)

대신 Tabs

한 번에 한 뷰만 보이고 패널을 전환할 때

대신 SegmentedButton

접을 본문 없이 옵션만 토글할 때

플레이그라운드#

컨트롤로 props를 조작하면 미리보기와 코드가 실시간 갱신됩니다.

main 브랜치 머지 시 자동 배포됩니다.

import { Accordion } from '@wds/ui-web';

<Accordion
  defaultValue="item-1"
>
  <Accordion.Item value="item-1">
      <Accordion.Trigger>배포는 어떻게 하나요?</Accordion.Trigger>
      <Accordion.Content>main 브랜치 머지 시 자동 배포됩니다.</Accordion.Content>
    </Accordion.Item>
    <Accordion.Item value="item-2">
      <Accordion.Trigger>권한은 어디서 바꾸나요?</Accordion.Trigger>
      <Accordion.Content>설정 → 멤버에서 역할을 변경합니다.</Accordion.Content>
    </Accordion.Item>
</Accordion>

변형#

type이 변형 축입니다 — 'single'(기본)은 새 항목을 펼치면 이전 항목이 접히고, 'multiple'은 여러 항목을 동시에 펼칩니다.

multiple에서는 defaultValue를 배열로 넘깁니다.

각 항목은 독립적으로 토글됩니다.

multiple — 여러 항목 동시 펼침 (defaultValue 배열)

크기#

단일 크기입니다 — 트리거 패딩 space.4/6, 레이블 font-size.body-1, 본문 font-size.body-2 고정. 3단 size는 component 토큰 신설 기준(§4) 미충족으로 도입하지 않았습니다.

상태#

비제어/제어 컴파운드입니다 — 기본은 비제어로 <Accordion type defaultValue>가 펼침 상태(내부적으로 항상 배열)를 소유합니다. value를 주면 제어 모드가 되어 부모가 상태를 소유하고, 트리거 클릭 등 모든 토글은 내부 상태를 쓰지 않고 onValueChange로 펼쳐진 value 배열만 통지합니다(렌더는 부모 value를 따름). valuedefaultValue와 같은 모양 — single은 문자열, multiple은 배열 — 을 받으며 둘 다 내부에서 배열로 정규화됩니다. 펼침/접힘은 aria-expandedhidden 토글로 표현되고 Hover/Focus는 CSS 의사클래스입니다.

Props#

점 표기(Accordion.Item)와 평탄 이름(AccordionItem)은 동일 함수입니다 — 서버 컴포넌트(RSC)에서는 클라이언트 참조에 점 접근이 해석되지 않으므로 평탄 이름을 사용하세요(이 문서의 데모도 평탄 이름).

<Accordion> (루트)

Prop타입기본값설명
type'single' | 'multiple''single'single: 한 번에 하나만 / multiple: 동시 펼침
valuestring | readonly string[]제어 펼침 값 — 제공하면 제어 모드(내부 상태 무시, 전환이 onValueChange로 통지). single=문자열, multiple=배열 권장
defaultValuestring | readonly string[]초기 펼침 항목 — 이후 상태는 내부 소유(비제어, value 미제공 시). multiple이면 배열 권장
onValueChange(value: readonly string[]) => void펼침 변경 콜백 — 항상 펼쳐진 value 배열
classNamestring루트 클래스 합성

<Accordion.Item>

Prop타입기본값설명
valuestring항목 식별자 — 필수
classNamestring클래스 합성

<Accordion.Trigger> — 네이티브 button 속성 확장

Prop타입기본값설명
childrenReactNode헤더 레이블 — h3 > button 안에 렌더

<Accordion.Content>

Prop타입기본값설명
childrenReactNode패널 본문
classNamestring클래스 합성

접근성#

계약구현
헤더 구조h3 > button — 문서 아웃라인에 헤딩으로 노출
펼침 상태버튼 aria-expanded + 셰브론 회전 표시
패널role="region" + aria-labelledby(헤더 버튼, useId 기반)
연결버튼 aria-controls → 패널 id
키보드Tab으로 헤더 이동, Enter·Space 토글 (네이티브 button)
접힘hidden 토글 — 접힌 내용은 탭 순서·접근성 트리에서 제외
모션펼침은 opacity/transform만(레이아웃 속성 애니 금지) + prefers-reduced-motion 존중

토큰#

component 토큰 없이 semantic을 직접 소비합니다(신설 기준 §4 미충족).

속성토큰
컨테이너/구분선color.border · radius.lg
트리거color.text · hover color.surface-hover · 눌림 color.surface-pressed
셰브론/본문color.text-muted
포커스 링color.focus-ring
타이포font.sans · font-size.body-1/body-2 · font-weight.medium · line-height.tight/normal
간격space.2/4/6
모션duration.fast · ease.standard / ease.out

관련#