Toast#
사용자에게 간단한 피드백 메시지를 일시적으로 표시하는 토스트 컴포넌트입니다.
Live Preview#
default
Web
Success
Your changes have been saved.
Flutter
Loading Flutter...
class ToastDefaultExample extends StatelessComponent {
const ToastDefaultExample({super.key});
@override
Component build(BuildContext context) {
return CoToast(
message: 'Success',
description: 'Your changes have been saved.',
onDismiss: () {},
);
}
}
class ToastDefaultExample extends StatefulWidget {
const ToastDefaultExample({super.key});
@override
State<ToastDefaultExample> createState() => _ToastDefaultExampleState();
}
class _ToastDefaultExampleState extends State<ToastDefaultExample> {
@override
Widget build(BuildContext context) {
return CoToast(
message: 'Success',
description: 'Your changes have been saved.',
onDismiss: () {},
);
}
}
destructive
Web
Error
Something went wrong.
Flutter
Loading Flutter...
class ToastDestructiveExample extends StatelessComponent {
const ToastDestructiveExample({super.key});
@override
Component build(BuildContext context) {
return CoToast(
message: 'Error',
description: 'Something went wrong.',
variant: CoreToastVariant.destructive,
onDismiss: () {},
);
}
}
class ToastDestructiveExample extends StatefulWidget {
const ToastDestructiveExample({super.key});
@override
State<ToastDestructiveExample> createState() =>
_ToastDestructiveExampleState();
}
class _ToastDestructiveExampleState extends State<ToastDestructiveExample> {
@override
Widget build(BuildContext context) {
return CoToast(
message: 'Error',
description: 'Something went wrong.',
variant: CoreToastVariant.destructive,
onDismiss: () {},
);
}
}
사용 시기 (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 배경 / 보더 색 |
panelBorderRadius | double? | panel 보더 반경 |
panelPadding | double? | panel 내부 패딩 |
gap | double? | 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#
| 속성 | 타입 | 기본값 | 설명 |
|---|---|---|---|
message | String | 필수 | 토스트 메시지 |
description |
String? |
null |
보조 설명 텍스트 |
variant |
CoreToastVariant |
default_ |
시각적 변형 (위젯 파라미터) |
onDismiss |
VoidCallback? |
null |
닫기 버튼 콜백 (null이면 닫기 버튼 없음) |
action | Widget? | 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에서는 ToastLayer와 showToast()로 토스트 표시/스태킹/애니메이션을 관리합니다.
// 앱 최상단에 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)#
| 항목 | Flutter | Web |
|---|---|---|
| 토스트 카드 | CoToast (통일) | CoToast (통일) |
| 인프라 | ToastLayer + showToast() | 외부 관리 |
| 스태킹 | 내장 (hover 확장, 최대 개수) | 외부 관리 |
| 닫기 방식 | 스와이프 + 클릭 + 프로그래밍 | 닫기 버튼 클릭 |