import 'package:flutter/material.dart'; import 'package:shadcn_ui/shadcn_ui.dart'; /// Superport 전역에서 사용하는 토스트/스낵바 헬퍼. class SuperportToast { SuperportToast._(); /// 성공 처리 완료를 사용자에게 안내한다. static void success(BuildContext context, String message) { _show(context, message, _ToastVariant.success); } /// 정보성 피드백을 노출한다. static void info(BuildContext context, String message) { _show(context, message, _ToastVariant.info); } /// 주의가 필요한 상황을 경고한다. static void warning(BuildContext context, String message) { _show(context, message, _ToastVariant.warning); } /// 오류 발생 시 스낵바를 표시한다. static void error(BuildContext context, String message) { _show(context, message, _ToastVariant.error); } /// 공통 스낵바 렌더링 로직. static void _show( BuildContext context, String message, _ToastVariant variant, ) { final theme = ShadTheme.of(context); final (Color background, Color foreground) = switch (variant) { _ToastVariant.success => ( theme.colorScheme.primary, theme.colorScheme.primaryForeground, ), _ToastVariant.info => ( theme.colorScheme.accent, theme.colorScheme.accentForeground, ), _ToastVariant.warning => ( theme.colorScheme.secondary, theme.colorScheme.secondaryForeground, ), _ToastVariant.error => ( theme.colorScheme.destructive, theme.colorScheme.destructiveForeground, ), }; final messenger = ScaffoldMessenger.of(context); messenger ..hideCurrentSnackBar() ..showSnackBar( SnackBar( content: Text( message, style: theme.textTheme.small.copyWith( color: foreground, fontWeight: FontWeight.w600, ), ), backgroundColor: background, behavior: SnackBarBehavior.floating, duration: const Duration(seconds: 3), ), ); } } enum _ToastVariant { success, info, warning, error } /// 기본 골격을 표현하는 스켈레톤 블록. class SuperportSkeleton extends StatelessWidget { const SuperportSkeleton({ super.key, this.width, this.height = 16, this.borderRadius = const BorderRadius.all(Radius.circular(8)), }); final double? width; final double height; final BorderRadius borderRadius; @override Widget build(BuildContext context) { final theme = ShadTheme.of(context); return AnimatedContainer( duration: const Duration(milliseconds: 600), decoration: BoxDecoration( color: theme.colorScheme.muted, borderRadius: borderRadius, ), width: width, height: height, ); } } /// 리스트 데이터를 대체하는 반복 스켈레톤 레이아웃. class SuperportSkeletonList extends StatelessWidget { const SuperportSkeletonList({ super.key, this.itemCount = 6, this.height = 56, this.gap = 12, this.padding = const EdgeInsets.all(16), }); /// 렌더링할 스켈레톤 행 개수. final int itemCount; /// 각 항목 높이. final double height; /// 행 사이 간격. final double gap; /// 전체 패딩. final EdgeInsetsGeometry padding; @override Widget build(BuildContext context) { return Padding( padding: padding, child: Column( children: [ for (var i = 0; i < itemCount; i++) ...[ SuperportSkeleton( height: height, borderRadius: BorderRadius.circular(10), ), if (i != itemCount - 1) SizedBox(height: gap), ], ], ), ); } }