7.8 KiB
Alert Dialog
2026-10-10 추가 수정 요청 기준: 취소 Gray Solid / 삭제 Red Solid, 기존 Radix focus·닫기 계약 유지. 과거 검증 기록은 당시 결과이며 현재 검증은 추가 수정 보고서를 따릅니다.
현재 HM 구현의 기준 문서. 공통 원칙은 docs/guidelines/프로젝트-지침.md(§6, §7), Token 구조 원칙은 테마-토큰-가이드.md를 따른다. 이 문서는 Alert Dialog 고유의 API·Token·상태·결정만 기록한다. Dialog(dialog.md)와 값을 공유하지 않는다.
1. 상태
| 항목 | 내용 |
|---|---|
| 구현 상태 | 구현 완료 (현재 HM 규격) |
| 기준일 | 2026-10-02 |
| 기반 | shadcn/ui Alert Dialog (Radix AlertDialog) |
| 대표 Story | Components/Overlay/Alert Dialog → All (이름 "Alert Dialog") |
| 보류 | 아래 §11 |
2. 적용 근거
- 참고 근거: 외부 ui_viz Reference (ZIP 미포함)의 Dialog 문서가 Alert Dialog를 FOLLOW_UP(DIALOG-03)으로만 두고 규격은 없다. 의도(확인·취소를 명시적으로 요구하는 중요한 결정)를 참고했다. 현재 Button 조합은 사용자 확정 규칙에 따라 일반 확인은 취소 Gray Solid / 확인 Green Solid, 삭제 확인은 취소 Gray Solid / 삭제 Red Solid이며 같은 세트의 appearance·size를 통일한다.
- 현재 HM 규격: 아래 §3~§4. Dialog의 접근성 원칙과
asChild처리 규칙은 재사용하고 수치는 현재 HM Semantic으로 새로 정했다. - 구현 방식: shadcn / Radix AlertDialog 구조 유지. Dialog + destructive 플래그로 합치지 않고 별도 컴포넌트로 둔다.
- Dialog와의 차이: Close(X) 없음, 바깥 클릭으로 닫히지 않음, 초기 focus가 Cancel, Body·Header divider 없음, 폭 400px 고정 상한.
3. 기본 규격 (현재 HM 규격)
| 항목 | 값 |
|---|---|
| Surface / 전경 | --hm-sem-bg-surface / --hm-sem-fg-primary |
| Border / Radius / Shadow | 1px --hm-sem-stroke-input-default / 8px / 0 0 12px rgb(0 0 0 / .2) |
| 위치 | viewport 가운데(shadcn 기본) |
| 폭 | min(400px, 100vw − 32px), 최대 높이 100dvh − 32px(넘치면 content scroll) |
| Padding | 24px 사방 |
| Title | 18 / 28 / 700 |
| Description | 14 / 20 / 400, --hm-sem-fg-secondary, Title과 gap 8px |
| Footer(Actions) | Header와 24px 간격, gap 8px, 오른쪽 정렬(좁은 화면은 세로, Cancel이 아래) |
| Action / Cancel | HM Button(아래 §5) |
| Overlay / animation | shadcn 기본(bg-black/10 + blur, fade + zoom) |
4. 상태 규격
| 상태 | 값 |
|---|---|
| Closed / Open | Radix data-state, 열림 시 modal, 배경 aria-hidden, scroll lock, role=alertdialog |
| 초기 focus | Cancel(Radix AlertDialog 기본: 파괴적 action 대신 안전한 쪽) |
| 닫힘 조건 | Cancel, Action, Escape. 바깥 클릭으로는 닫히지 않음 |
| focus 복귀 | 닫히면 trigger로 복귀 |
| Confirmation / Destructive | 컴포넌트 상태가 아니라 Button 조합(§5) |
5. API
Radix AlertDialog props 그대로. export: AlertDialog, AlertDialogTrigger, AlertDialogPortal, AlertDialogOverlay, AlertDialogContent, AlertDialogHeader, AlertDialogFooter, AlertDialogTitle, AlertDialogDescription, AlertDialogAction, AlertDialogCancel.
AlertDialogAction: HM Button을 Radix Action 위에asChild로 합성(<Button asChild><AlertDialogPrimitive.Action/></Button>). 기본variant="primary"appearance="solid",size기본default. 위험한 작업은variant="destructive" appearance="solid".AlertDialogCancel: 같은 방식, 기본variant="cancel"appearance="solid".AlertDialogAction variant="destructive"의 기본solid는 지원된다. 삭제 확인은 Action과 Cancel 모두 Standard Solid와 같은 size를 사용한다. 자동 appearance 변경은 없다. Button 허용 조합·기본값 주의를 따른다.- 합성한 Radix 요소에는
data-slot을 붙이지 않는다. 붙이면asChildSlot 병합에서 자식 값이 이겨 Button의data-slot="button"이 사라지고 HM Button 스타일이 적용되지 않는다(Dialog에서 해결한 문제와 같은 원인). 출력 속성은 Button의data-slot="button",data-variant,data-appearance,data-size. - Alert Dialog 자체에는 Button 스타일을 정의하지 않는다. Button API(
variant/appearance/size)만 전달한다. AlertDialogContent에 Close(X)는 없다. 새 prop(size,variant,destructive)은 만들지 않았다.
6. Token
Component Mapping 위치: packages/ui/src/theme/alert-dialog.css (--hm-alert-dialog-*).
background, text, border-width, border-color, radius, shadow, width, edge, padding, header-gap, actions-gap, actions-margin-top, title-*, description-*. Semantic과 Theme palette만 참조하며 --hm-dialog-*를 참조하지 않는다. 신규 Primitive 없음. Button 색은 Button 문서의 token을 따른다.
7. shadcn / Radix에서 유지한 항목
Radix AlertDialog 구조 전부: Portal·Overlay·modal·focus trap·초기 focus(Cancel)·Escape·바깥 클릭 무시·focus 복귀·role=alertdialog·aria-labelledby/describedby, 중앙 위치 class, 열림/닫힘 animation class, data-slot(Content·Header·Footer·Title·Description).
8. HM에서 변경한 항목
- shadcn
bg-background,ring-1,rounded-xl,p-4,gap-4,max-w-xs/sm:max-w-sm, size 변형 제거 → theme CSS. AlertDialogAction/Cancel을buttonVariantsclass 적용 방식에서 HM Button 합성으로 변경. 선택지variant/appearance/size를 Button API로 받는다.- 방향별 Header/Footer 배치와
AlertDialogMedia같은 shadcn 부가 요소는 추가하지 않았다.
9. Storybook
- 대표 Story
All("Alert Dialog"): 트리거 2개(로그아웃 = 일반 확인, 삭제 = destructive)가 각각 실제 Alert Dialog를 연다. - verification:
Confirmation,Destructive(처음부터 열림).
10. 사용자 확정 결정
- 2026-10-02: ui-viz는 참고 자료이며 최종 기준은 현재 HM 구현과 이 문서다(작업 지시). 개별 수치에 대한 별도 결정은 없다.
11. 미확정 / 보류
- 수치(400px, 18px Title, 24px padding, 그림자)는 현재 HM 규격이며 디자인 확정 시 재검토.
- Overlay 색·blur, Motion은 shadcn 기본 유지.
- 파괴적 작업의 기본 강조(Red Solid)는 Dialog 삭제 확인과 같은 조합이며 Alert Dialog 고유 규칙이 아니다.
- 아이콘/Media slot, non-dismissible 정책 변경(예: Escape 막기)은 만들지 않았다.
- 소비 화면의 공통 header/footer 높이 대응 없음.
12. 관련 파일
packages/ui/src/components/ui/alert-dialog.tsx
packages/ui/src/theme/alert-dialog.css
packages/ui/src/theme.css (import)
packages/ui/src/index.ts (export)
src/components/alert-dialog.stories.tsx
13. 검증 상태
npm run typecheck,npm run build: 통과(2026-10-02).- 실제 interaction(Browser pane): 키보드(Enter)로 열기,
role=alertdialog, 초기 focus가 "취소", Tab으로 "삭제" 이동 후 다시 Tab하면 "취소"로 순환(focus trap), 바깥 클릭에 닫히지 않음, Escape 닫힘과 trigger focus 복귀, Cancel·Action 클릭 닫힘과 trigger 복귀, Close(X) 없음. - Button 합성: Action·Cancel 모두
data-slot="button",data-variant(destructive/cancel),data-appearance가 유지되고 HM 색(Cancelrgb(118,118,118), 삭제 글자rgb(211,47,47))이 적용됨. - computed style: width 400px, radius 8px, padding 24px, shadow
0 0 12px .2. - 390×844: 폭 358px(좌우 16px), Footer 세로 쌓임(Cancel 아래), 가로 overflow 없음.
- 미확인: Enter/Space로 Action 키보드 실행, Radix
AlertDialogAction비동기 처리, 닫기 animation 시각.