# Dialog
현재 HM 구현의 기준 문서. 공통 원칙은 `docs/guidelines/프로젝트-지침.md`(§6, §7), Token 구조 원칙은 `테마-토큰-가이드.md`를 따른다. 이 문서는 Dialog 고유의 API·Token·상태·결정만 기록한다.
> 근거 문서: ui_viz `docs/components/dialog.md`(Dialog / Modal). 문서가 스스로 `NO_SOURCE_EVIDENCE`(Source Dashboard에 Dialog specimen 없음)라고 밝히며, 값의 상당수는 D-093(2026-09-29) Dialog-local Confirmed다. Foundation `elevation.*`, `z-index.*`, `motion.*`는 TBD이고 Dialog 범위 값을 Foundation token으로 올리지 않는다.
## 1. 상태
| 항목 | 내용 |
|---|---|
| 구현 상태 | HM 스타일 적용 완료 (``만으로 적용, `hm-dialog` class 없음) |
| 기준일 | 2026-10-02 |
| 기반 | shadcn/ui Dialog + Radix `Dialog` |
| 대표 Story | `Components/Overlay/Dialog` → `All` (이름 "Dialog") |
| 보류 | Overlay 수치, Close 버튼 규격, 초기 focus 대상, 좁은 화면 Actions 배치 등 (§11) |
## 2. 적용 근거
- **ui_viz Confirmed (Dialog-local)**: radius 8px(USER_DECISION 2026-09-17), shadow `0 0 12px rgba(0,0,0,.2)`(D-093 D-088), 내용 기준 크기와 최대 너비·높이 공식(D-088), Header `24/24/16`·Title↔Description 8·Body 24·Actions `0/24/24`·Action gap 8(D-093), Header 아래 inset divider 위치·두께와 Footer divider 없음, Body만 scroll, 긴 텍스트 줄바꿈, 표는 Body 안 가로 scroll, 표면 `color.bg.surface`·전경 `color.fg.primary`, Title/Description/Body 타이포.
- **CANONICAL_OVERRIDE**: Title `heading-md` 20/28 중 weight **700**은 Dialog Title에만 적용(D-006, 600 대체). Foundation `heading-md`는 600 그대로.
- **현재 HM Actions**: Footer padding은 `16px 24px 24px`이며 divider는 없다. 위 ui_viz 도입 근거의 `0/24/24`와 구분한다.
- **Temporary / TBD(적용했으나 확정값 아님)**: 외곽선·Header divider 색 `#DEDBD2`는 `Temporary`, Token relation TBD(DIALOG-10 FOLLOW_UP). 이전 확정 색(`#9A9284`/`#E0DACE`)은 대체됐고 D-093 실행 화면과 같은 값이라 현재 구현을 따랐다. 색 역할이 정해지기 전까지 Dialog 범위 값이다.
- **PARTIAL / REFERENCE_ONLY(적용)**: Description 전경 `color.fg.secondary`(DIALOG-06 PARTIAL, 현재 style 보존). edge 16px(REVIEW).
- **REFERENCE_ONLY(미적용)**: Backdrop Black 42%. 확정값이 아니어서 shadcn 기본 Overlay를 유지했다.
- **HM 사용자 결정**: 없음.
- **shadcn 유지**: Overlay, 열림/닫힘 animation, Close 버튼, Footer `showCloseButton`, `showCloseButton` prop.
- **Radix 유지**: 아래 §7.
## 3. 기본 규격
| 항목 | 값 | 근거 |
|---|---|---|
| Overlay | shadcn 기본(`bg-black/10`, `backdrop-blur-xs`, `fixed inset-0`, z-50) | ui_viz backdrop 수치 TBD/REFERENCE_ONLY |
| Container 크기 | 내용 기준(`width: max-content` + max-width = `min(내용, 최대 너비)`). `fit-content`는 shadcn `left: 50%` 배치에서 가용 폭이 화면 절반이 되어 쓰지 않는다(2026-10-06) | Confirmed D-088 |
| max-width | `100vw − 2 × edge(16px)` | Confirmed 공식 / edge는 REVIEW |
| max-height | `100dvh − app header − app footer − 2 × edge` | Confirmed 공식, header/footer 기본 0 |
| 위치 | 가용 영역(앱 header·footer 제외) 가운데 | Confirmed |
| Background / 글자 | `--hm-sem-bg-surface` / `--hm-sem-fg-primary` | Confirmed reuse |
| Border | 1px solid `#DEDBD2` | 두께 Confirmed / 색 Temporary |
| Radius | 8px (Container만) | Confirmed |
| Shadow | `0 0 12px rgb(0 0 0 / 0.2)` | Confirmed (Dialog-local) |
| Container padding | 0 (영역별 padding) | 구조 |
| Header | padding `24px 0 15px` + 아래 1px divider `#DEDBD2`(= ui_viz `24/24/16`, 선은 16px 안쪽 마지막 1px), 좌우 margin 24px(inset 24px) | Confirmed 위치·두께 / 색 Temporary |
| Title ↔ Description | gap 8px (Description이 없으면 없음) | Confirmed |
| Title | 20px / 28px / 700, `fg.primary` | Confirmed (Dialog-local) |
| Description | 14px / 20px / 400, `fg.secondary` | 크기 Confirmed / 색 PARTIAL |
| Body | padding 24px 사방, 16px / 24px / 400, 첫·마지막 child margin 0 | Confirmed |
| Footer(Actions) | padding `16px 24px 24px`, gap 8px, 오른쪽 정렬, 위 divider 없음 | 현재 HM 구현 |
| 긴 텍스트 | `overflow-wrap: anywhere` | Confirmed |
| Close 버튼 | shadcn 기본 (ghost `icon-sm` 28px, 오른쪽 위 8px 안쪽, `XIcon`, sr-only "Close") | ui_viz 미정의 |
## 4. 상태 규격
| 상태 | 값 | 근거 |
|---|---|---|
| Closed / Open | Radix `data-state` (`open`/`closed`). Open 시 modal, 배경 inert, scroll lock | Radix |
| Open animation | shadcn 기본(fade + zoom, 100ms) | ui_viz motion TBD → shadcn 유지 |
| Focus | 전역 focus ring은 ui_viz TBD. 조합한 Button이 각자의 focus를 가짐 | TBD |
| Long Content | Header·Footer 고정, Body만 세로 scroll, 짧으면 scrollbar 없음 | Confirmed |
| Wide Content | Body 안 가로 scroll, 페이지 가로 overflow 없음 | Confirmed |
| Confirmation / Destructive | 컴포넌트 상태가 아니라 Button 조합: 일반 확인은 취소 `cancel`+`solid` / 확인 `primary`+`solid`, 삭제 확인은 취소 `cancel`+`outline` / 삭제 `destructive`+`outline`. 같은 세트의 appearance·size 통일, Brand 금지 | HM 사용자 확정 Button 세트 규칙 |
Loading, Selected, Disabled 등 Dialog 자체의 다른 상태는 ui_viz에 없어 만들지 않았다.
## 5. API
```
Dialog, DialogTrigger, DialogPortal, DialogOverlay, DialogContent,
DialogHeader, DialogTitle, DialogDescription, DialogFooter, DialogClose:
shadcn / Radix API 그대로 (open, defaultOpen, onOpenChange, modal, asChild, className ...)
DialogBody:
(신규)
— ui_viz Body region
DialogClose:
shadcn: 항상 data-slot="dialog-close"
→
HM: asChild일 때는 data-slot을 붙이지 않음 (자식 Button의 data-slot="button" 유지)
```
- `DialogContent`의 `showCloseButton`(기본 true), `DialogFooter`의 `showCloseButton`(기본 false)은 shadcn 그대로.
- 새 prop(`size`, `variant`, `destructive`, `loading`, `placement`, `dismissible`)은 근거가 없어 만들지 않았다.
- `DialogBody`를 추가한 이유: ui_viz가 Body를 필수 region이자 유일한 scroll owner로 정의하기 때문이다. Body 없이도 동작하지만(자식이 그대로 놓임) 이 경우 Body padding과 내부 scroll이 적용되지 않는다.
- `DialogClose` 변경 이유: shadcn은 `DialogClose asChild`의 `data-slot="dialog-close"`가 자식 `