import 'package:flutter/material.dart'; /// A Material 3 badge widget class BadgeWidget extends StatelessWidget { final Widget child; final String? label; final int? count; final Color? backgroundColor; final Color? textColor; final Alignment alignment; final bool show; const BadgeWidget({ super.key, required this.child, this.label, this.count, this.backgroundColor, this.textColor, this.alignment = Alignment.topRight, this.show = true, }); @override Widget build(BuildContext context) { if (!show) return child; return Badge( label: _buildLabel(context), alignment: alignment, backgroundColor: backgroundColor, textColor: textColor, child: child, ); } Widget? _buildLabel(BuildContext context) { if (count != null) { return Text(count! > 99 ? '99+' : '$count'); } if (label != null) { return Text(label!); } return null; } } /// A status badge for products class StatusBadge extends StatelessWidget { final String label; final StatusBadgeType type; final IconData? icon; const StatusBadge({ super.key, required this.label, required this.type, this.icon, }); @override Widget build(BuildContext context) { final theme = Theme.of(context); final colorScheme = theme.colorScheme; final Color backgroundColor; final Color textColor; switch (type) { case StatusBadgeType.success: backgroundColor = const Color(0xFF4CAF50); textColor = Colors.white; break; case StatusBadgeType.warning: backgroundColor = Colors.orange; textColor = Colors.white; break; case StatusBadgeType.error: backgroundColor = colorScheme.error; textColor = colorScheme.onError; break; case StatusBadgeType.info: backgroundColor = colorScheme.primaryContainer; textColor = colorScheme.onPrimaryContainer; break; case StatusBadgeType.neutral: backgroundColor = colorScheme.surfaceContainerHighest; textColor = colorScheme.onSurface; break; } return Container( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), decoration: BoxDecoration( color: backgroundColor, borderRadius: BorderRadius.circular(12), ), child: Row( mainAxisSize: MainAxisSize.min, children: [ if (icon != null) ...[ Icon( icon, size: 14, color: textColor, ), const SizedBox(width: 4), ], Text( label, style: theme.textTheme.labelSmall?.copyWith( color: textColor, fontWeight: FontWeight.bold, ), ), ], ), ); } } enum StatusBadgeType { success, warning, error, info, neutral, } /// A count badge for displaying numbers class CountBadge extends StatelessWidget { final int count; final Color? backgroundColor; final Color? textColor; final double size; const CountBadge({ super.key, required this.count, this.backgroundColor, this.textColor, this.size = 20, }); @override Widget build(BuildContext context) { final theme = Theme.of(context); final colorScheme = theme.colorScheme; return Container( constraints: BoxConstraints( minWidth: size, minHeight: size, ), padding: const EdgeInsets.all(4), decoration: BoxDecoration( color: backgroundColor ?? colorScheme.primary, shape: BoxShape.circle, ), child: Center( child: Text( count > 99 ? '99+' : '$count', style: theme.textTheme.labelSmall?.copyWith( color: textColor ?? colorScheme.onPrimary, fontWeight: FontWeight.bold, fontSize: size * 0.4, ), textAlign: TextAlign.center, ), ), ); } } /// A notification badge (simple dot) class NotificationBadge extends StatelessWidget { final Widget child; final bool show; final Color? color; final double size; const NotificationBadge({ super.key, required this.child, this.show = true, this.color, this.size = 8, }); @override Widget build(BuildContext context) { final theme = Theme.of(context); final colorScheme = theme.colorScheme; if (!show) return child; return Stack( clipBehavior: Clip.none, children: [ child, Positioned( right: 0, top: 0, child: Container( width: size, height: size, decoration: BoxDecoration( color: color ?? colorScheme.error, shape: BoxShape.circle, border: Border.all( color: theme.scaffoldBackgroundColor, width: 1.5, ), ), ), ), ], ); } }