6.4 KiB
Sheet
2026-10-10 추가 수정 요청 기준: 화면 가장자리 모서리는 직각, 안쪽 두 모서리만 기존 --hm-radius-control-md를 임시 재사용. 신규 확정 radius 수치가 아니며 GNB/LNB 모바일 Sheet도 같은 계약. 과거 검증 기록은 당시 결과이며 현재 검증은 추가 수정 보고서를 따릅니다.
현재 HM 구현의 기준 문서. 공통 원칙은 docs/guidelines/프로젝트-지침.md(§6, §7), Token 구조 원칙은 테마-토큰-가이드.md를 따른다. 이 문서는 Sheet 고유의 API·Token·상태·결정만 기록한다. Dialog 문서(dialog.md)와 값을 공유하지 않는다.
1. 상태
| 항목 | 내용 |
|---|---|
| 구현 상태 | 구현 완료 (현재 HM 규격) |
| 기준일 | 2026-10-02 |
| 기반 | shadcn/ui Sheet (Radix Dialog) |
| 대표 Story | Components/Overlay/Sheet → All (이름 "Sheet") |
| 보류 | 아래 §11 |
2. 적용 근거
- 참고 근거: 외부 ui_viz Reference (ZIP 미포함)의 기존 테스트 규격에는 Sheet가 없다(Dialog 문서가 "side sheet"를 범위 밖으로 둠). 참고할 수치가 없었다.
- 현재 HM 규격: 아래 §3~§4. Dialog에서 검증한 접근성 원칙(Radix modal,
asChild처리)은 재사용하고, 면·윤곽·그림자 등 수치는 현재 HM Semantic으로 새로 정했다.--hm-dialog-*를 참조하지 않는다. - 구현 방식: shadcn / Radix Dialog 기반 Sheet 구조와
sideAPI 유지, theme CSS로 HM 스타일 연결. - 보류: §11.
3. 기본 규격 (현재 HM 규격)
| 항목 | 값 |
|---|---|
| Surface / 전경 | --hm-sem-bg-surface / --hm-sem-fg-primary |
| Border | 1px --hm-sem-stroke-input-default, 페이지를 향한 한 변에만 |
| Shadow | 0 0 12px rgb(0 0 0 / .2) |
| Radius | 없음(viewport edge에 붙음) |
| left / right | 폭 min(400px, 100vw − 48px), 높이 100% |
| top / bottom | 폭 100%, 높이 내용 기준, 최대 100dvh − 48px |
| Padding | 24px (Header·Footer·Body 좌우) |
| Header | padding 24 (24+36) 16 24 (오른쪽은 Close 버튼 자리), Title↔Description gap 8px |
| Title | 20 / 28 / 700 |
| Description | 14 / 20 / 400, --hm-sem-fg-secondary |
| Body | 14 / 20 / 400, 좌우 padding 24px, 유일한 scroll 영역 |
| Footer | padding 16 24 24, gap 8px, 오른쪽 정렬(좁은 화면은 세로, shadcn flex-col-reverse sm:flex-row) |
| Close(X) | shadcn 기본(ghost icon-sm, 오른쪽 위 12px, sr-only "Close") |
| Overlay / animation | shadcn 기본(bg-black/10 + blur, side별 slide) |
4. 상태 규격
| 상태 | 값 |
|---|---|
| Closed / Open | Radix data-state, 열림 시 modal, 배경 aria-hidden, scroll lock |
| Focus | 열릴 때 Radix 기본(첫 tabbable), 닫힐 때 trigger로 복귀 |
| Long Content | Header·Footer 고정, Body만 세로 scroll |
| Form | 소비 조합(Body 안 Label + Input) |
5. API
Radix Dialog props 그대로. export: Sheet, SheetTrigger, SheetClose, SheetPortal, SheetOverlay, SheetContent, SheetHeader, SheetBody, SheetFooter, SheetTitle, SheetDescription.
SheetContent:side"top" | "right" | "bottom" | "left"(기본right, shadcn API 유지),showCloseButton(기본 true). 출력data-side.SheetBody(신규): scroll owner. 없어도 동작하지만 이 경우 Body padding과 내부 scroll이 없다.SheetClose:asChild일 때 자식의data-slot을 유지(DialogClose와 같은 규칙, Button HM 스타일 보존).- 새 prop(
size,variant)은 만들지 않았다.
6. Token
Component Mapping 위치: packages/ui/src/theme/sheet.css (--hm-sheet-*).
background, text, border-width, border-color, shadow, width, edge-gap, padding, header-gap, footer-gap, close-clearance, title-*, description-*, body-font-size, body-line-height. Semantic과 Theme palette(--hm-sem-stroke-input-default)만 참조한다. 신규 Primitive 없음.
7. shadcn / Radix에서 유지한 항목
Radix 구조·ARIA(role=dialog, aria-labelledby/describedby)·focus trap·initial focus·focus 복귀·Escape·바깥 클릭 닫힘·scroll lock, Portal·Overlay, position(inset-*)·side별 slide animation class, data-slot, cn(..., className), Close 버튼.
8. HM에서 변경한 항목
- shadcn
bg-popover text-popover-foreground shadow-lg gap-4 border-*, side별w-3/4 sm:max-w-sm·h-auto, Header/Footerp-4제거 → theme CSS. SheetBody추가(scroll owner),SheetClose asChilddata-slot 처리.- 폭을
min(400px, 100vw − 48px)로 지정(좁은 화면에서 Overlay 띠 48px 유지).
9. Storybook
- 대표 Story
All("Sheet"): 트리거 6개(right, left, top, bottom, 폼, 긴 내용)가 각각 실제 Sheet를 연다. - verification:
Right,Left,Top,Bottom,Form,Long Content(처음부터 열림).
10. 사용자 확정 결정
- 2026-10-02: ui-viz는 참고 자료이며 최종 기준은 현재 HM 구현과 이 문서다(작업 지시). 개별 수치에 대한 별도 결정은 없다.
11. 미확정 / 보류
- 수치(400px 폭, 24px padding, 그림자, 48px edge gap)는 현재 HM 규격이며 디자인 확정 시 재검토.
- Overlay 색·blur, Motion은 정해진 규칙이 없어 shadcn 기본 유지.
- Header/Footer divider 없음(미정의). Close 버튼 규격은 shadcn 기본.
- top/bottom side 사용처는 Drawer와 겹친다. 둘의 역할 경계(Drawer = 드래그로 닫는 하단 panel)는 사용 가이드로 정리 예정.
- 소비 화면이 쓰는 공통 header/footer 높이 대응은 없음.
12. 관련 파일
packages/ui/src/components/ui/sheet.tsx
packages/ui/src/theme/sheet.css
packages/ui/src/theme.css (import)
packages/ui/src/index.ts (export)
src/components/sheet.stories.tsx
13. 검증 상태
npm run typecheck,npm run build: 통과(2026-10-02).- 실제 interaction(Browser pane): 클릭 열기(focus가 "취소"로 이동,
role=dialog), Escape 닫힘과 trigger focus 복귀, 바깥(Overlay) 클릭 닫힘과 focus 복귀, X 닫기, 네 방향 위치(right 우측 400px, left 좌측 0, top/bottom 전체 폭), 긴 내용에서 Body만 scroll하고 Footer가 화면 안. - 390×844: right Sheet 폭 342px(left 82px), 가로 overflow 없음.
- computed style: white, border-left
rgb(222,219,210), shadow0 0 12px .2. - 미확인: focus trap의 Tab 순환(코드 경로는 Radix 기본), side별 닫힘 animation 시각, top/bottom의 모바일 높이 한계.