Accordion
접었다 펼 수 있는 섹션을 쌓아 놓습니다. 긴 내용을 제목만 보이게 접어 두고 필요한 것만 펼칠 때 씁니다.
import { Accordion, AccordionItem } from 'neba';
<Accordion defaultValue={['billing']}>
<AccordionItem value="billing" title="결제는 어떻게 되나요?" subtitle="요금제와 청구서">
매달 1일에 청구됩니다.
</AccordionItem>
<AccordionItem value="regions" title="빌드는 어디서 도나요?">
기본 브랜치에 가장 가까운 리전에서 돕니다.
</AccordionItem>
</Accordion>;Props
Accordion
| Prop | 타입 | 기본값 | 설명 |
|---|---|---|---|
| variant공통 | 'solid' | 'outline' | 'text' | 'outline' | 표면의 무게. 채움 / 하이라인 / 없음 |
| size공통 | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'md' | 시트의 반경과 각 섹션의 여백. Box와 같은 뜻입니다 |
| color공통 | 'primary' | 'secondary' | 'success' | 'warning' | 'danger' | 'info' | 'primary' | 의미론적 색 역할. 임의 색상값은 받지 않습니다 |
| density공통 | 'default' | 'compact' | 'default' | 여백만 바꿉니다. 높이와 글자 크기는 그대로 |
| elevation공통 | 0 | 1 | 2 | 3 | 0 | 그림자 깊이. 0은 그림자 없음 |
| multiple | boolean | false | 여러 섹션을 동시에 열 수 있는지. 기본이 꺼짐인 이유는 하나를 열 때 하나를 닫는 것이 아코디언이 접이식 목록과 다른 점 전부이기 때문입니다 |
| value | (string | number)[] | — | 열려 있는 섹션들. controlled |
| defaultValue | (string | number)[] | — | 처음 열려 있는 섹션들 |
| onValueChange | (value: (string | number)[]) => void | — | 열린 집합이 바뀔 때 |
| dividers | boolean | true | 섹션 사이를 여백 대신 실선으로 나눕니다. List와 기본값이 반대인 이유는 접히는 카드 더미가 아니라 한 덩어리로 읽혀야 하기 때문입니다 |
| headingLevel | 1 | 2 | 3 | 4 | 5 | 6 | 3 | 각 섹션 헤더가 문서 개요에서 갖는 제목 단계. h2 아래라면 3, h3 아래라면 4입니다 |
| disabled | boolean | false | 사용 불가. 모든 섹션이 접히지 않습니다 |
| hiddenUntilFound | boolean | false | 닫힌 패널을 DOM에 남겨 브라우저의 페이지 검색이 찾아 펼칠 수 있게 합니다. keepMounted보다 우선합니다 |
| keepMounted | boolean | false | 닫힌 패널을 DOM에 남깁니다. 만들기 비싼 내용이나 접혀도 살아 있어야 하는 폼 상태 |
| children | ReactNode | — | AccordionItem들 |
value와 onValueChange로 controlled, defaultValue로 uncontrolled 컴포넌트가 됩니다. 값은 열려 있는 항목의 value 배열입니다.
AccordionItem
| Prop | 타입 | 기본값 | 설명 |
|---|---|---|---|
| value | string | number | — | value / defaultValue가 가리키는 식별자. 생략하면 Base UI가 만들어 줍니다 |
| title | ReactNode | — | 접히는 부분의 제목 |
| subtitle | ReactNode | — | 제목 아래 한 줄 |
| startIcon | ReactNode | — | 제목 앞의 내용 |
| action | ReactNode | — | 헤더 끝에 고정되는 컨트롤. 접는 버튼 바깥에 놓입니다. 버튼 안의 버튼은 브라우저가 고쳐 씁니다 |
| lines | number | — | 제목과 부제목을 이 줄 수에서 자릅니다. 지정하지 않으면 줄바꿈해서 다 보여 줍니다 |
| disabled | boolean | false | 이 섹션만 접히지 않습니다. 나머지는 그대로 동작합니다 |
| children | ReactNode | — | 펼쳤을 때의 내용 |
예시
variant
sheet는 색으로 채워지지 않습니다. Card 안에 넣을 때는 text를 쓰세요. Card가 이미 sheet이므로 테두리가 겹치지 않습니다.
multiple · dividers · action
multiple의 기본값은 꺼짐이며, 하나를 열면 열려 있던 것이 닫힙니다. 섹션들이 서로 배타적인 답이 아니라 체크리스트라면 켜세요.
dividers는 섹션 사이에 선을 그어 여러 항목을 한 덩어리로 묶습니다. action은 접는 버튼 바깥에 놓이는 컨트롤 자리이므로, 헤더에 스위치를 두면서 헤더 자체를 눌러 접을 수 있습니다.
size
headingLevel · lines
각 섹션의 헤더는 실제 heading이므로 문서 개요에서 제 깊이에 놓여야 합니다. headingLevel이 스택 전체의 단계를 정합니다. <h2> 아래라면 3, <h3> 아래라면 4입니다. 섹션이 아니라 Accordion의 prop인 이유는 섹션들이 서로 형제여서입니다. 단계가 제각각인 heading이 이어지면 개요가 거짓말을 합니다.
title에는 일반 텍스트를 넘기세요. heading 요소를 넘기면 헤더가 이미 만든 heading 안에 heading이 또 들어갑니다.
섹션의 lines는 제목과 부제목을 그 줄 수에서 자릅니다. 지정하지 않으면 줄바꿈해서 다 보여 줍니다. FAQ의 제목은 문장이고, 거기서 말줄임표를 만나면 질문이 사라집니다.
<Accordion headingLevel={2}>
<AccordionItem lines={2} title="계정을 지우면 데이터는 어떻게 되나요?">
…
</AccordionItem>
</Accordion>hiddenUntilFound과 keepMounted
hiddenUntilFound는 닫힌 패널을 DOM에 남겨 브라우저의 find-on-page가 찾아 펼칠 수 있게 합니다. FAQ 페이지에 적합합니다. keepMounted는 닫힌 패널의 React 트리를 유지합니다.
접근성
- 헤더 버튼과 패널이
aria-controls·aria-expanded로 연결됩니다. - 각 헤더가
headingLevel(기본값3) 단계의 실제 heading 요소라서 섹션이 문서 개요에 들어갑니다.title에는 일반 텍스트를 넘기세요. heading을 넘기면 그 안에 또 들어갑니다. - 패널은
height를 애니메이션하며 열립니다. 내용이 패널 안에서 이동하지는 않습니다.