Files

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의 asChild data-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로 닫기, 닫힌 content display: 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로 대체 확인).