Components
AlertDialog
파괴적 액션 확인용 모달. 삭제·영구 취소 등 비가역 액션의 명시적 확인에 사용.
Variants
confirm— 신중한 확인이 필요한 액션destructive— 복구 불가한 파괴적 액션 (삭제, 영구 취소)
Mobile
AlertDialog는 모바일에서도 Dialog Mobile Presentation (BottomSheet)을 따른다. 단, 파괴적 액션의 신중성을 보장하기 위한 추가 제약이 있다:
- Swipe-to-dismiss 금지: 일반 Dialog와 달리 AlertDialog는 드래그 다운으로 dismiss하지 않는다. 사용자가 명시적으로 cancel/confirm 버튼을 눌러야만 닫힘 — 실수 닫기 방지
- 외부 탭 dismiss 금지: backdrop tap도 cancel로 동작하지 않음. cancel 버튼만 유일한 비파괴 dismiss 경로
- Grabber 표시 금지: 시트가 드래그 가능하다는 시각적 신호를 주지 않음
- Detent 고정:
[auto]단일 detent. full-screen 확장 불필요 - Primary action:
confirmvariant: brown-800 primary 버튼destructivevariant:rose-600배경 + white 텍스트로 색상 변경 — Button의 destructive type 사용
- 버튼 layout: 모바일은 세로 스택, destructive 액션이 위쪽(시각적 무게)·cancel이 아래. 이는 위험한 액션을 우연히 누르지 않게 하기 위한 의도적 배치
- 초기 focus: 파괴적 액션 버튼에 자동 focus 금지. cancel에 focus하거나 focus 없이 시작
- Haptic: destructive 확인 시
notificationWarning(iOS) / 동등한 패턴 (Android)
Preview
Anatomy
AlertDialog는 Dialog의 파괴적 변형. Pagination·Media·Close 슬롯 없음, CancelAction 필수.
AlertDialogRoot
├─ AlertDialogOverlay (배경 dim, dismissOnOverlayClick=false)
└─ AlertDialogContent
├─ AlertDialogHeader
│ ├─ AlertDialogTitle (Text · subtitle1)
│ └─ AlertDialogDescription (Text · body1)
└─ AlertDialogFooter
├─ CancelAction (Button outlined variant — 필수)
└─ ConfirmAction (Button variant='primary' | 'destructive')슬롯 규칙
| Slot | Required | Primitive | 비고 |
|---|---|---|---|
| AlertDialogOverlay | always | — | overlay 클릭 닫기 금지 |
| AlertDialogTitle | always | Text | subtitle1SemiBold, 짧고 명확하게 |
| AlertDialogDescription | always | Text | body1Regular — 비가역성 설명 필수 |
| CancelAction | always | Button (outlined) | label은 안전 옵션 명확히 ("취소", "유지") |
| ConfirmAction | always | Button (primary or destructive variant) | label은 동사 명확히 ("삭제", "초기화", "계속") |
Layout invariants
- Container: 모바일/데스크탑 공통
max-width 472px. 폭은 유지하되 내부 여백을 더 줘서 더 차분하게 보이게 함 - Mobile: 세로 스택.
CancelAction → ConfirmAction순. 두 버튼 모두 full-width - Desktop: 가로 2버튼.
CancelAction (left) → ConfirmAction (right).flex-1금지, 우측 정렬 + 각 버튼min-width 96px - Header: title/description만으로 맥락을 전달. 타이포는 낮추고 spacing으로 안정감 확보
- 첫 focus는 반드시 CancelAction — 실수 Enter로 인한 파괴 실행 방지
- Esc 키는 Cancel과 동일 (파괴 액션 실행 없음)
Spec
| Token | Value (web) | Value (mobile — BottomSheet) |
|---|---|---|
| container bg | #FFFFFF | #FFFFFF |
| container width | max-w-[472px], w-[calc(100vw-32px)] | 100vw (full-width) |
| container padding | px-7 py-7 (28px) | px-5 pt-5 pb-6 |
| border radius | rounded-[20px] (4면) | top corners only r4 (16px) |
| elevation | shadow-[0_24px_80px_rgba(28,25,23,0.18)] | native sheet elevation |
| overlay | stone-950/55 + backdrop-blur-[2px] | stone-950/40 (backdrop tap dismiss 불가) |
| title | subtitle1SemiBold (18/27, SemiBold) | 동일 |
| body | body1Regular (14/20, Regular) | 동일 |
confirm button (confirm) | bg-brown-800, white, button2Medium, rounded-lg, height 40 | bg-brown-800, white, button1Medium, rounded-lg, height 44 (Button lg) |
destructive button (destructive) | bg-rose-600, white, button2Medium, rounded-lg, height 40 | bg-rose-600, white, button1Medium, rounded-lg, height 44 (Button lg) |
| cancel button | bg-transparent text-brown-800 border-stone-200, button2Medium, rounded-lg, height 40 | 동일 스타일, height 44 (Button lg) |
| button layout (2버튼) | 가로, 자연 폭 + 우측 정렬 | 세로 스택, destructive 위쪽 + cancel 아래쪽 (실수 방지) |
Props
type AlertDialogProps = {
open: boolean
onOpenChange: (open: boolean) => void
title: string
description?: string
confirmText?: string // default "확인"
cancelText?: string // default "취소"
confirmVariant?: 'confirm' | 'destructive'
loading?: boolean
onConfirm: () => void
}Usage
<AlertDialog
open={showDelete}
onOpenChange={setShowDelete}
title="이 노트를 삭제하시겠습니까?"
description="삭제된 노트는 복구할 수 없습니다."
confirmText="삭제"
cancelText="취소"
confirmVariant="destructive"
onConfirm={deleteNote}
/>A11y
- 첫 focus는 반드시 CancelAction — 사고 확정 방지
- 파괴적 버튼은 시각(
rose-600) + 텍스트로 이중 경고 - Overlay 클릭 닫기 금지 — Radix AlertDialog 기본 동작
- Esc로 닫기 가능, 단 파괴 액션 실행 없음
Do / Don't
- Do: 삭제, 영구 취소, 복구 불가 액션에 사용
- Do: 대상을 명확히 명시 — "3개의 노트를 삭제하시겠습니까?" ✅ / "계속할까요?" ❌
- Do: Description에 비가역성 명시 — "삭제된 노트는 복구할 수 없습니다."
- Do: 데스크탑에서는 버튼을 내용 기준 폭으로 유지하고, 액션 그룹 전체를 우측에 정렬
- Don't: 일반 정보성 모달에 사용 금지 →
Dialog - Don't: 파괴 버튼에 초기 focus 금지
- Don't: Close X 추가 금지
- Don't: Overlay 클릭 닫기 활성화 금지
