5.9 KiB
5.9 KiB
Collapsible
현재 HM 구현의 기준 문서. 공통 원칙은 docs/guidelines/프로젝트-지침.md(§6, §7), Token 구조 원칙은 테마-토큰-가이드.md를 따른다. 이 문서는 Collapsible 고유의 API·Token·상태·결정만 기록한다. Accordion(accordion.md)과 값을 공유하지 않는다.
1. 상태
| 항목 | 내용 |
|---|---|
| 구현 상태 | 구현 완료 (현재 HM 규격) |
| 기준일 | 2026-10-02 |
| 기반 | shadcn/ui Collapsible (Radix Collapsible) |
| 대표 Story | Components/Disclosure/Collapsible → All (이름 "Collapsible") |
| 보류 | 아래 §11 |
2. 적용 근거
- 참고 근거: 외부 ui_viz Reference (ZIP 미포함)의 기존 테스트 규격에는 Collapsible이 없다. 참고할 수치가 없었다.
- 현재 HM 규격: 아래 §3~§4. 현재 HM Semantic 체계로 새로 정했다.
- 구현 방식: shadcn / Radix Collapsible 구조(Root·Trigger·Content)를 유지. shadcn Collapsible은 스타일이 없는 primitive라, 일반 trigger(asChild 없음)에만 텍스트 trigger 모양을 주고 content 간격·타이포를 정했다.
- Accordion과의 구분: Collapsible은 단일 영역의 간단한 disclosure다. divider 구조와 chevron 내장이 없다. Accordion을 항목 하나로 쓰는 용도가 아니다.
- 보류: §11.
3. 기본 규격 (현재 HM 규격)
| 항목 | 값 |
|---|---|
| Trigger(일반) | inline-flex, gap 8px, 배경·border·padding 없음, 14 / 20 / 500, --hm-sem-fg-primary, 포인터 커서 |
Trigger(asChild) |
자식이 자기 스타일을 유지(예: HM Button). HM trigger 스타일은 적용되지 않는다 |
| Indicator | trigger 바로 아래 자식 svg가 있으면 16px, --hm-sem-fg-secondary, 열리면 180° 회전 |
| Content | 위 padding 8px, 14 / 20 / 400, --hm-sem-fg-primary |
| 긴 텍스트 | overflow-wrap: anywhere, 고정 높이 없음 |
| Divider / border | 없음 |
4. 상태 규격
| 상태 | 값 |
|---|---|
| Closed / Open | Radix data-state. 닫힌 content는 hidden(display: none) |
| Hover | 일반 trigger 밑줄(disabled 제외) |
Focus (:focus-visible) |
ring 모양 0 0 0 3px ring 50% (일반 trigger) |
| Disabled | opacity: 0.6(이 컴포넌트 값, 전역 Disabled 규칙으로 승격 안 함), cursor: not-allowed |
| Animation | 없음(shadcn Collapsible에 없고 HM Motion 규칙도 없다) |
5. API
Radix Collapsible props 그대로. export: Collapsible, CollapsibleTrigger, CollapsibleContent.
Collapsible:open/defaultOpen/onOpenChange,disabled.CollapsibleTrigger:asChild.asChild일 때는data-slot을 붙이지 않는다(DialogClose와 같은 규칙). 붙이면 자식 Button의data-slot="button"이 덮여 HM Button 스타일이 사라진다. 일반 trigger 출력은data-slot="collapsible-trigger".CollapsibleContent: 출력data-slot="collapsible-content".- 새 prop은 만들지 않았다.
6. Token
Component Mapping 위치: packages/ui/src/theme/collapsible.css (--hm-collapsible-*).
trigger-text, trigger-gap, trigger-font-size|line-height|font-weight, icon-size, icon-color, content-gap, content-text, content-font-size|line-height, disabled-opacity. Semantic만 참조하고 --hm-accordion-* 등 다른 컴포넌트의 Token을 쓰지 않는다. 신규 Primitive 없음.
7. shadcn / Radix에서 유지한 항목
Radix 구조·ARIA(aria-expanded, aria-controls)·Enter/Space·controlled/uncontrolled·disabled·asChild, data-slot, cn(..., className), Content의 hidden 처리.
8. HM에서 변경한 항목
- 일반 trigger의 텍스트 trigger 스타일, Content 간격·타이포, indicator 회전은 shadcn에 없던 시각 규격을 추가한 것이다.
CollapsibleTrigger의asChilddata-slot 처리(위 §5).- Animation은 추가하지 않았다.
9. Storybook
- 대표 Story
All("Collapsible"):StateBoard로 Closed, Open, Disabled, Long Content, Controlled + Button trigger를 한 페이지에 둔다. trigger 안 chevron은 일반 소비 조합(lucide-react아이콘)이다. - verification:
Closed,Open,Disabled,Long Content.
10. 사용자 확정 결정
- 2026-10-02: ui-viz는 참고 자료이며 최종 기준은 현재 HM 구현과 이 문서다(작업 지시). 개별 수치에 대한 별도 결정은 없다.
11. 미확정 / 보류
- 수치(14/20/500, gap 8px, Disabled opacity 0.6)는 현재 HM 규격이며 디자인 확정 시 재검토.
- 열림/닫힘 animation 없음. Motion 규칙이 정해지면 Accordion과 함께 재검토.
- indicator는 컴포넌트에 내장하지 않고 소비 조합으로 둔다(Accordion과 다름). 내장 여부는 사용 사례가 쌓이면 결정.
- 박스형(border/배경) Content variant는 만들지 않았다.
- Hover 밑줄은 일반 trigger에만 적용한다.
12. 관련 파일
packages/ui/src/components/ui/collapsible.tsx
packages/ui/src/theme/collapsible.css
packages/ui/src/theme.css (import)
packages/ui/src/index.ts (export)
src/components/collapsible.stories.tsx
13. 검증 상태
npm run typecheck,npm run build: 통과(2026-10-02).- 실제 interaction(Browser pane): Enter로 열기(
aria-expanded=true, indicator 180° 회전), Space로 닫기, 닫힌 contentdisplay: none, disabled 클릭 무반응(opacity 0.6, cursor not-allowed), controlled(Button trigger asChild)에서 클릭으로 열리고 상태 문구와 버튼 라벨(접기)이 갱신됨. - Button trigger:
data-slot="button",data-variant="primary"와 HM Button 색이 유지됨. - computed style: 일반 trigger 14/20/500,
rgb(10,34,29), 배경 투명, icon 16px, content 위 padding 8px. 긴 콘텐츠에서 가로 overflow 없음. - 미확인: 포인터 클릭(JS click과 키보드만 사용), focus ring 시각, 390px 폭, uncontrolled
defaultOpen=false에서 trigger 클릭(키보드 Enter로 대체 확인).