본문으로 건너뛰기
TDSMoring 디자인 시스템

dialog

화면 가운데 뜨는 확인 대화상자와 아래에서 올라오는 메뉴를 함수 호출 하나로 여는 도구다. 결과(눌린 버튼)를 약속(Promise)으로 돌려준다.

이 페이지의 목차
분류
알림과 안내
가져오기
import { DialogHost, DialogCard } from '@/ui/dialog'
코드 위치
apps/mobile/src/ui/dialog.tsx:73

미리보기#

실제 컴포넌트를 화면에 그린 것이다. 화면 아래의 서비스 색 선택기로 색을 바꿔 볼 수 있다. 버튼과 입력 칸은 직접 눌러 볼 수 있다.

저장했어요

오답 노트에서 다시 볼 수 있어요.

alert

이 자료를 열까요?

지금까지 푼 기록은 그대로 남아요.

confirm

자료를 삭제할까요?

문제와 풀이 기록이 모두 사라져요. 되돌릴 수 없어요.

confirm (danger)
menu

언제 쓰는가#

쓴다

  • 알려야 하고 꼭 확인받아야 하는 일에 dialog.alert를 쓴다.
  • "삭제할까요?" 같은 확인에는 dialog.confirm을 쓴다. 되돌릴 수 없는 일은 tone: "danger"로 한다.
  • 선택지 여러 개를 세로로 늘어놓으려면 dialog.choose, 행동 목록(이름 바꾸기, 삭제)은 dialog.menu를 쓴다.

쓰지 않는다

  • 사용자를 막지 않아도 되는 알림에는 쓰지 않는다. toast나 Notice를 쓴다.
  • 대화상자 위에 대화상자를 연속으로 띄우지 않는다. 연속으로 부르면 하나씩 차례로 뜬다.
  • 긴 입력이나 양식을 넣지 않는다. Sheet를 쓴다.

종류#

dialog 종류
이름설명
dialog.alert제목, 본문, 버튼 하나("확인"). 닫으면 끝.
dialog.confirm취소와 확인 버튼 두 개가 가로로 놓인다. 확인을 누르면 true.
dialog.choose선택지가 세로로 쌓이고 맨 아래에 취소가 붙는다. 고른 번호를 돌려준다.
dialog.menu아래에서 올라오는 메뉴 시트. 행마다 아이콘, 이름, 보조 글.

크기#

dialog 크기
이름값설명
대화상자폭 최대 420, 좌우 28 여백안쪽 여백 22(위 24). 버튼 높이 48.
메뉴행 최소 높이 56

상태#

dialog 상태
상태모습과 동작
열림대화상자는 180ms 동안 0.96배에서 1배로 커지며 나타난다. 메뉴는 220ms 동안 올라온다.
닫힘130ms. 바깥을 누르거나 뒤로 가기를 누르면 닫히고 취소(false/null)로 처리된다.
여러 개 호출순서대로 하나씩 뜬다(대기열).

사용 방법#

앱 맨 위에 한 번 놓기

앱 맨 위에 한 번 놓기
import { DialogHost } from '@/ui/dialog';

// 루트 레이아웃에서 한 번만 렌더링한다.
<DialogHost />

확인받기

확인받기
import { dialog } from '@/ui/dialog';

const ok = await dialog.confirm({
  title: '자료를 삭제할까요?',
  body: '문제와 풀이 기록이 모두 사라져요. 되돌릴 수 없어요.',
  confirmLabel: '삭제',
  tone: 'danger',
  icon: Trash2,
});
if (ok) await remove();

알림과 메뉴

알림과 메뉴
await dialog.alert('저장했어요', '오답 노트에서 다시 볼 수 있어요.');

const i = await dialog.menu({
  title: '자료 관리',
  options: [
    { label: '이름 바꾸기', icon: Pencil },
    { label: '삭제', icon: Trash2, tone: 'danger' },
  ],
});
if (i === 1) await remove();

속성(props)#

dialog 함수 목록
함수형태설명
dialog.alert(title: string, body?: string, label = '확인'): Promise<void>알림. 닫힐 때 끝나는 약속을 돌려준다.
dialog.confirm({ title, body, confirmLabel = '확인', cancelLabel = '취소', tone = 'primary', icon }: { title: string; body?: string; confirmLabel?: string; cancelLabel?: string; tone?: 'primary' | 'danger'; icon?: Icon; }): Promise<boolean>확인. 확인을 눌렀으면 true, 취소하거나 바깥을 눌렀으면 false.
dialog.choose({ title, body, options, cancelLabel = '취소', icon, tone }: { title: string; body?: string; options: Option[]; cancelLabel?: string | null; icon?: Icon; tone?: Tone; }): Promise<number | null>선택지 목록. 고른 번호(0부터), 취소면 null.
dialog.menu({ title, body, options }: { title: string; body?: string; options: Option[] }): Promise<number | null>메뉴 시트. 고른 번호, 닫으면 null.

DialogHost

속성이 없다.

DialogCard

DialogCard 속성
이름타입기본값필수설명
childrenReactNode—필수카드 안의 내용. 대화상자와 같은 면(surface, 모서리 24, shadow(3))을 직접 그릴 때 쓴다.

DialogHost는 속성이 없다. 앱 루트에 한 번 두면 dialog.* 호출을 받아 그린다. 선택지 항목(Option)은 { label, tone?: "primary" | "danger" | "neutral", icon?, detail? }이다.

치수와 토큰#

대화상자
surface, 모서리 radius.sheet(24), 안쪽 22(위 24), shadow(3), 좌우 28 여백, 최대 폭 420
아이콘 타일
44 × 44, 모서리 14, 톤 색 12% 투명도, 아이콘 22 선 2.2
제목과 본문
제목 headline, 본문 body textSecondary(제목 아래 6)
버튼
높이 48, 모서리 14, 둘이면 가로로 같은 폭, 그 밖에는 세로로 쌓기(사이 8). neutral은 segmentTrack 바탕, primary는 primary, danger는 danger
메뉴
card 바탕 목록, 행 최소 56, 아이콘 타일 34(색 10%)
어둠막
scrim

접근성#

  • 대화상자의 역할은 alert이고 모달이다(accessibilityViewIsModal).
  • 버튼에는 이름(글자)이 있고 글자가 길면 80%까지 줄어든다.
  • 위험한 확인(danger)은 색, 아이콘, 제목·본문 글자로 함께 알린다.
  • Android 뒤로 가기는 닫기와 같다.

글자 색 대비

글자 크기별 기준: 작은 글자는 4.5:1 이상, 큰 글자(굵은 18.66px 이상)는 3:1 이상이다. 값은 선택한 서비스와 모드의 토큰으로 계산했다.

dialog 글자 색 대비
쓰임글자색바탕대비기준
primary 버튼 글자 (15px 굵게)onPrimaryprimary3.93:1 미달3.31:1 미달4.60:1 통과7.25:1 통과4.5:1 (작은 글자)
danger 버튼 글자 (15px 굵게)onDangerdanger4.55:1 통과3.02:1 미달5.15:1 통과7.36:1 통과4.5:1 (작은 글자)
neutral 버튼 글자 (15px 굵게)textsegmentTrack15.54:1 통과14.08:1 통과14.95:1 통과9.62:1 통과4.5:1 (작은 글자)
본문 (15px)textSecondarysurface4.23:1 미달6.95:1 통과4.88:1 통과7.11:1 통과4.5:1 (작은 글자)

잘한 예와 잘못한 예#

자료를 삭제할까요?

기록이 모두 사라져요.

잘한 예되돌릴 수 없는 일은 무엇이 사라지는지 쓰고 danger로 한다.
저장할 때마다 뜨는 확인 대화상자
잘못한 예사용자를 막지 않아도 되는 알림("저장했어요")은 toast로 충분하다.
  • Sheet: 화면 아래에서 올라오는 시트다. 위쪽 두 모서리가 둥글고, 손잡이와 제목 줄, 닫기 버튼이 있다.
  • toast: 화면 아래에 잠깐 떴다 사라지는 짧은 확인 메시지다. 함수 한 번 호출로 띄운다. 되돌리기 같은 행동 하나를 붙일 수 있다.
  • Notice: 화면 안에 끼워 넣는 한 줄 안내 상자다. 안내(파랑), 주의(주황), 오류(빨강) 세 가지 톤이 있다.
  • PrimaryButton: 서비스 주색 그라데이션으로 채운 알약 모양 버튼이다. 한 화면에서 가장 중요한 행동 하나에 쓴다.