Files

111 lines
6.4 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Sheet
> 2026-10-10 추가 수정 요청 기준: 화면 가장자리 모서리는 직각, 안쪽 두 모서리만 기존 --hm-radius-control-md를 임시 재사용. 신규 확정 radius 수치가 아니며 GNB/LNB 모바일 Sheet도 같은 계약. 과거 검증 기록은 당시 결과이며 현재 검증은 [추가 수정 보고서](../guidelines/publisher-additional-review-2026-10-10.md)를 따릅니다.
현재 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 구조와 `side` API 유지, 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/Footer `p-4` 제거 → theme CSS.
- `SheetBody` 추가(scroll owner), `SheetClose asChild` data-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)`, shadow `0 0 12px .2`.
- 미확인: focus trap의 Tab 순환(코드 경로는 Radix 기본), side별 닫힘 animation 시각, top/bottom의 모바일 높이 한계.