Toast | CoUI

Toast

토스트 알림 컴포넌트

Toast#

사용자에게 간단한 피드백 메시지를 일시적으로 표시하는 토스트 컴포넌트입니다.

Live Preview#

사용 시기 (When to Use)#

이 컴포넌트를 사용하세요:

  • 작업 결과(성공/실패)를 간단히 알릴 때
  • 되돌리기(undo) 액션을 제공할 때
  • 사용자 흐름을 방해하지 않는 비침입적 알림이 필요할 때

대신 다른 컴포넌트를 사용하세요:

  • Dialog: 사용자 확인이 반드시 필요한 중요한 알림일 때
  • Alert / Banner: 페이지에 고정된 영구적 알림이 필요할 때
  • Tooltip: 특정 요소에 대한 설명이 필요할 때

기본 사용법 (Basic Usage)#

// 기본 토스트 카드
CoToast(
  message: '저장되었습니다.',
  description: '변경사항이 성공적으로 저장되었습니다.',
  onDismiss: () {},
)

// destructive 변형
CoToast(
  message: '오류가 발생했습니다.',
  description: '네트워크 연결을 확인해 주세요.',
  variant: CoreToastVariant.destructive,
  onDismiss: () {},
)

// showToast와 함께 사용
showToast(
  context: context,
  builder: (context, overlay) => CoToast(
    message: '파일이 업로드되었습니다.',
    onDismiss: overlay.close,
  ),
)
// 기본 토스트 (default 변형)
CoToast(
  message: '저장되었습니다.',
  description: '변경사항이 성공적으로 저장되었습니다.',
  onDismiss: handleDismiss,
)

// destructive 변형
CoToast(
  message: '오류가 발생했습니다.',
  description: '네트워크 연결을 확인해 주세요.',
  variant: CoreToastVariant.destructive,
  onDismiss: handleDismiss,
)

스타일 시스템 — toastStyle (Epic #1302)#

CoToast 의 panel chrome / 슬롯 미세 조정은 단일 toastStyle (CoreToastStyle) 으로 흐릅니다. 시맨틱 enum (variant) 은 위젯 파라미터.

CoToast(
  message: '저장 완료',
  description: '변경사항이 적용되었습니다',
  variant: CoreToastVariant.success,
  onDismiss: handleDismiss,
  action: CoButton(
    variant: .ghost,
    onPressed: undo,
    child: Text('되돌리기'),
  ),
  toastStyle: CoreToastStyle(
    panelBackgroundColor: cs.surface,
    panelBorderColor: cs.outline,
    panelBorderRadius: 12,
    panelPadding: 16,
    gap: 12,
    messageStyle: CoreTextStyle(
      fontSize: 14,
      fontWeight: CoreFontWeight.semiBold,
    ),
    descriptionStyle: CoreTextStyle(
      fontSize: 12,
      color: cs.onSurfaceVariant,
    ),
    // actionButtonStyle 은 action 안의 CoButton 이 자동 적용 가능
    // (위처럼 variant 직접 주입 — Epic #1302 원칙 8 asChild)
  ),
)

CoreToastStyle 필드#

필드타입설명
panelBackgroundColor / panelBorderColor Color? / String? panel 배경 / 보더 색
panelBorderRadiusdouble?panel 보더 반경
panelPaddingdouble?panel 내부 패딩
gapdouble?message+description 영역 ↔ action 슬롯 간격
messageStyle CoreTextStyle? 메시지 (primary text) 스타일
descriptionStyle CoreTextStyle? 설명 (secondary text) 스타일
actionButtonStyle CoreButtonStyle? action 버튼 chrome 미세 조정 (variant 변경은 위젯 슬롯 주입)

asChild 패턴 — action 버튼 변경#

action 버튼의 시맨틱 (variant) 변경이 필요할 때는 action 슬롯에 직접 위젯을 주입합니다 (Epic #1302 원칙 8):

CoToast(
  message: '...',
  action: CoButton(variant: .ghost, child: Text('되돌리기')),  // ← variant 직접
)

toastStyle.actionButtonStyle 은 chrome 미세 조정용 (paddingH / labelStyle 등).

Resolve chain#

design system default for variant
  → CoreToastTheme.style                       // 프로젝트 공통
  → CoreToastTheme.variantStyles[widget.variant]   // variant 별
  → 부모 컴포넌트 슬롯 오버라이드
  → widget.toastStyle                          // 인스턴스별

Props / Parameters#

속성타입기본값설명
messageString필수토스트 메시지
description String? null 보조 설명 텍스트
variant CoreToastVariant default_ 시각적 변형 (위젯 파라미터)
onDismiss VoidCallback? null 닫기 버튼 콜백 (null이면 닫기 버튼 없음)
actionWidget?null액션 위젯
toastStyle CoreToastStyle? null panel chrome / nested 슬롯 묶음

변형 (Variants)#

default_#

기본 토스트 스타일입니다. surface 배경에 onSurface 텍스트를 사용합니다.

CoToast(
  message: 'Success',
  description: 'Your changes have been saved.',
  onDismiss: handleDismiss,
)

destructive#

오류/경고 토스트 스타일입니다. error 배경에 onError 텍스트를 사용합니다.

CoToast(
  message: 'Error',
  description: 'Something went wrong.',
  variant: CoreToastVariant.destructive,
  onDismiss: handleDismiss,
)

Flutter 인프라 (ToastLayer)#

Flutter에서는 ToastLayershowToast()로 토스트 표시/스태킹/애니메이션을 관리합니다.

// 앱 최상단에 ToastLayer 배치
ToastLayer(
  maxStackedEntries: 3,
  expandMode: ExpandMode.expandOnHover,
  child: MyApp(),
)

// 토스트 표시
final overlay = showToast(
  context: context,
  builder: (context, overlay) => CoToast(
    message: '처리 완료',
    onDismiss: overlay.close,
  ),
  location: ToastLocation.bottomRight,
  showDuration: Duration(seconds: 5),
);

// 프로그래밍 방식으로 닫기
overlay.close();

테마 커스터마이징#

CoreComponentTheme(
  toast: CoreToastTheme<Color>(
    style: CoreToastStyle<Color>(
      panelBorderRadius: 12.0,
    ),
  ),
)

접근성 (Accessibility)#

스크린 리더#

  • Flutter: Semantics(liveRegion: true) 적용으로 스크린 리더에 자동 알림
  • Web: role="status", aria-live="polite" 적용으로 비침입적 알림

닫기 버튼#

  • onDismiss가 제공되면 aria-label="Close" 속성이 있는 닫기 버튼 렌더링

크로스 플랫폼 차이점 (Platform Differences)#

항목FlutterWeb
토스트 카드CoToast (통일)CoToast (통일)
인프라ToastLayer + showToast()외부 관리
스태킹내장 (hover 확장, 최대 개수)외부 관리
닫기 방식스와이프 + 클릭 + 프로그래밍닫기 버튼 클릭
  • Dialog: 사용자 확인이 필요한 모달 알림
  • Alert: 페이지에 고정된 알림
  • Banner: 페이지 상단의 전체 너비 알림