본문으로 건너뛰기
Dot Design System
v0.3.1

AlertDialog

되돌리기 어렵거나 중요한 결정을 명시적으로 확인합니다.

목적

AlertDialog는 사용자가 실행 결과를 확인한 뒤 명시적으로 계속하거나 취소해야 하는 중요한 결정을 다룬다. 삭제, 연결 해제, 저장하지 않고 나가기처럼 되돌리기 어렵거나 작업 손실 가능성이 있는 행동에 사용한다. 단순한 안내나 짧은 편집은 Dialog를 사용한다.

선택 기준

  • 행동을 실행하기 전에 대상과 영향을 다시 확인해야 할 때 사용한다.
  • 취소와 계속 중 하나를 반드시 선택하게 해야 할 때 사용한다.
  • 일반적인 확인 흐름은 제품 문구와 위험 수준을 함께 고정하는 ConfirmActionDialog 구성을 우선한다.
  • 성공 알림, 도움말, 추가 옵션 노출에는 사용하지 않는다.

구조

AlertDialog 아래에 AlertDialogTriggerAlertDialogContent를 둔다. Content는 theme 경계 안의 portal과 overlay를 함께 만든다. Content 안에서는 AlertDialogHeaderAlertDialogTitleAlertDialogDescription을 배치하고, AlertDialogFooterAlertDialogCancelAlertDialogAction을 배치한다.

직접 overlay나 portal을 조정해야 하는 고급 구성에만 AlertDialogOverlay, AlertDialogPortal을 사용한다.

변형과 크기

별도 크기 prop은 없다. Content는 전체 너비를 사용하되 max-w-lg로 제한되고 기본 padding은 24px이다. 작은 화면에서는 모서리가 화면과 이어지고, sm 이상에서 둥근 모서리가 적용된다.

AlertDialogAction은 기본 Button 스타일, AlertDialogCancel은 outline Button 스타일을 사용한다. 파괴 행동이라면 Action에 className을 임의로 덧대기보다 제품 공통 composition을 사용해 위험 표현과 문구를 함께 검토한다.

상태와 동작

AlertDialogopen, defaultOpen, onOpenChange를 통한 제어·비제어 구성을 지원한다. 열린 동안 배경은 overlay로 분리되고 focus는 결정 영역 안에서 관리된다. Action은 결정을 확정하고 Cancel은 중단한다.

비동기 처리 중에는 Action을 비활성화하고 버튼 문구를 삭제 중…처럼 진행형으로 유지한다. 실패했을 때 dialog를 조용히 닫지 말고 설명 가까이에 원인과 복구 행동을 제공한다.

콘텐츠

  • Title은 커리큘럼을 삭제할까요?처럼 대상과 행동을 함께 쓴다.
  • Description은 영향, 되돌릴 수 있는지, 남는 데이터를 짧게 설명한다.
  • Action은 삭제, 연결 해제보다 커리큘럼 삭제, 연동 해제처럼 결과가 분명해야 한다.
  • Cancel은 보통 취소를 사용하되, 저장하지 않고 나가기처럼 의미가 모호하면 계속 편집처럼 현재 맥락을 유지하는 결과를 쓴다.

접근성

AlertDialogTitleAlertDialogDescription을 생략하지 않는다. Trigger에는 그 자체로 이해 가능한 접근 가능한 이름을 제공한다. Action과 Cancel의 시각적 순서만으로 안전성을 전달하지 않고 문장으로 결과를 설명한다. 비동기 결과는 필요한 경우 live region 또는 toast로 알린다.

좁은 화면과 긴 콘텐츠

Footer는 작은 화면에서 세로로 배치되며 DOM 순서와 시각 순서가 다를 수 있으므로 Tab 이동을 확인한다. 설명이 길어지면 핵심 영향과 복구 가능성만 남긴다. 긴 약관, 여러 입력 필드, 스크롤이 필요한 편집은 Sheet나 별도 화면으로 옮긴다.

공개 API

  • AlertDialog, AlertDialogTrigger: root와 trigger
  • AlertDialogContent, AlertDialogOverlay, AlertDialogPortal: overlay 표면과 portal
  • AlertDialogHeader, AlertDialogFooter: 내부 레이아웃
  • AlertDialogTitle, AlertDialogDescription: 접근 가능한 제목과 설명
  • AlertDialogAction, AlertDialogCancel: 확정과 취소

래퍼가 별도 선언하지 않은 props는 각 기반 요소의 props를 그대로 전달한다.

예제

사용 코드 · TSX
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
  AlertDialogTrigger,
  Button,
} from '@classum/dot-design-system/ui';

export function DeleteCurriculumAlert() {
  return (
    <AlertDialog>
      <AlertDialogTrigger asChild>
        <Button variant="outline">삭제 설정 열기</Button>
      </AlertDialogTrigger>
      <AlertDialogContent>
        <AlertDialogHeader>
          <AlertDialogTitle>커리큘럼을 삭제할까요?</AlertDialogTitle>
          <AlertDialogDescription>
            연결된 학습 기록은 유지되지만 이 커리큘럼은 다시 복구할 수 없어요.
          </AlertDialogDescription>
        </AlertDialogHeader>
        <AlertDialogFooter>
          <AlertDialogCancel>계속 관리</AlertDialogCancel>
          <AlertDialogAction>커리큘럼 삭제</AlertDialogAction>
        </AlertDialogFooter>
      </AlertDialogContent>
    </AlertDialog>
  );
}

피해야 할 사용

  • 모든 저장이나 이동에 확인 단계를 추가하지 않는다.
  • 영향 설명 없이 확인할까요?만 쓰지 않는다.
  • Action과 Cancel에 같은 강조도를 주지 않는다.
  • dialog 안에 또 다른 dialog나 popover를 연속으로 중첩하지 않는다.
  • 비동기 요청이 진행 중인데 Action을 반복 실행할 수 있게 두지 않는다.

관련 항목