Toast
전역 알림 스택 — ToastProvider + useToast 3분할 구조. 5초 자동 해제에 hover 일시정지, error/warning은 role="alert"로 즉시 낭독됩니다.
마지막 업데이트 2026-06-28
한눈에#
발사는 훅 호출입니다 — 트리 상단에 ToastProvider를 두고, 클라이언트 컴포넌트에서 useToast()로 발사합니다. 아래 버튼으로 각 variant를 직접 쏴서 우하단 스택을 확인하세요.
- 전역 스택
- useToast 훅
- 5초 자동 해제
- hover 일시정지
우하단 z.toast 레이어에 세로로 쌓이고, hover하면 남은 시간이 보존됩니다
import { ToastProvider, useToast } from '@wds/ui-web';
function SaveButton() {
const { toast } = useToast();
return (
<Button onClick={() => toast({ title: '저장 완료', variant: 'success' })}>
저장
</Button>
);
}
// 앱 루트
<ToastProvider>
<App />
</ToastProvider>;
사용 시점#
작업 결과처럼 흘려보내도 되는 일시 피드백이면 Toast — 머물러야 하거나 차단이 필요하면 다른 컴포넌트입니다.
권장 — 이렇게 쓰세요
지양 — 이러지 마세요
쓴다 — 저장 완료처럼 흐름을 막지 않고 지나가는 일시 피드백(5초 자동 해제)
대신 Alert — 폼 오류 요약·페이지 공지처럼 머물러야 할 인라인 배너
대신 Modal — 결제 확인·삭제 경고처럼 반드시 읽고 확인/차단해야 할 때
화면 단위 판단은 Loading Feedback을 따릅니다. Toast는 지나가도 되는 결과 보조 수단이며, 실패 원인·재시도·수정 위치는 화면 안에 남겨야 합니다.
플레이그라운드#
컨트롤로 props를 조작하면 미리보기와 코드가 실시간 갱신됩니다.
ToastProvider를 직접 조작해 보세요
속성·테마·토큰을 바꾸고 React·Flutter 코드를 확인하는 풀스크린 빌더로 엽니다.
플레이그라운드는 넓은 작업 영역이 필요해 웹·태블릿에서 편집할 수 있어요.
해부#
토스트는 훅·포털로만 떠서 인라인 렌더가 안 되므로, 실제 구조·토큰을 미러링한 정적 specimen 위에 실측을 핀으로 얹습니다.
저장 완료
변경사항이 반영되었습니다
- width
- 20rem (320px)
- padding
- 12 · 16px
space-3 · space-4 - gap
- 12px
space-3 - radius
- 14px
radius.lg - border
- 1px
toast.border - icon
- 20px
icon.size-md - title / desc
- 14 / 12px
body-2 · caption
변형#
variant 4종(info·success·warning·error)은 표면이나 좌측 라인에 색을 쓰지 않고, 아이콘 형태와 아이콘 잉크 색, 라이브 리전 등급만 결정합니다. Toast는 일시 피드백이므로 배너처럼 강한 색 면을 만들지 않고, 의미는 제목 텍스트와 아이콘으로 전달합니다.
동기화 시작
- surface
toast.surface- icon
color.info-text
저장 완료
- surface
toast.surface- icon
color.success-text
토큰 만료 임박
- surface
toast.surface- icon
color.warning-text
저장 실패
- surface
toast.surface- icon
color.error-text
- info(기본) · success —
role="status"로 조용히(polite) 낭독 - warning · error —
role="alert"로 즉시(assertive) 낭독
변형 색은 Toast 표면이나 좌측 라인에 직접 쓰지 않고 아이콘 강조에만 남깁니다. 실패 원인·복구 행동처럼 강한 색 면이나 유지되는 피드백이 필요하면 Toast 대신 화면 안의 FormMessage나 Alert에 남깁니다.
크기#
size prop이 없습니다 — 폭 20rem 고정(좁은 화면에서는 뷰포트에 맞게 축소),
우하단 z.toast 레이어에 세로로 쌓입니다.
상태#
- 자동 해제 —
TOAST_AUTO_DISMISS_MS(5초) 후 퇴장 - hover 일시정지 — 마우스를 올리면 남은 시간이 보존되고, 이탈 시 재개됩니다
- 닫기 버튼 — 즉시 해제 (
closeLabel, 기본 ‘닫기’) - 입·퇴장 모션 — opacity/transform 250ms,
prefers-reduced-motion에서는 없음
Props#
ToastProvider#
| Prop | 타입 | 기본값 | 설명 |
|---|---|---|---|
children | ReactNode | — | 앱 트리 — Provider 하위에서만 useToast 사용 가능 |
closeLabel | string | '닫기' | 닫기 버튼 aria-label |
useToast().toast(options)#
| Prop | 타입 | 기본값 | 설명 |
|---|---|---|---|
title | string | — | 토스트 제목 (필수) |
description | string | — | 보조 설명 — 미제공 시 영역 미렌더 |
variant | ToastVariant | — | 의미 변형 — 라이브 리전 등급과 아이콘 결정 (기본 info) |
useToast()는 ToastProvider 바깥에서 호출하면 명시적 에러를 던집니다.
접근성#
- error/warning은
role="alert"(assertive), info/success는role="status"(polite) — 라이브 리전에는 상태 텍스트만 담습니다(WCAG 4.1.3) - hover 일시정지로 읽을 시간을 연장할 수 있습니다 — 자동 해제 단독에 의존하지 않습니다
- 닫기 버튼은 시각 32px + 44px 히트 영역,
:focus-visible2px primary 링 - 아이콘은 장식(
aria-hidden) — 의미는 제목 텍스트와 라이브 리전 등급이 전달합니다 prefers-reduced-motion: reduce에서 입·퇴장 애니메이션이 제거됩니다
토큰#
component 토큰 없이 semantic을 직접 소비합니다(신설 기준 §4 미충족).
| 속성 | 토큰 |
|---|---|
| 카드 | color.surface-raised · color.border · radius.lg · shadow.lg |
| 스택 | z.toast · space.2/4 |
| 변형 | 좌측 색 라인 없음 — 아이콘 종류 + role=status/alert만 분기 |
| 아이콘 잉크 | color.info/success/warning/error-text |
| 제목/설명 | color.text + font-weight.semibold / color.text-muted + font-size.caption |
| 닫기 hover/pressed | color.surface-hover / color.surface-pressed |
| 모션 | duration.normal + ease.emphasized-decelerate(입장) / ease.standard(퇴장) |