import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import '../../theme/app_theme.dart'; enum CardVariant { elevated, outlined, filled, glass, gradient, } enum CardSize { compact, standard, expanded, } class SophisticatedCard extends StatefulWidget { final Widget child; final CardVariant variant; final CardSize size; final Color? backgroundColor; final Color? borderColor; final Gradient? gradient; final List? customShadow; final VoidCallback? onTap; final VoidCallback? onLongPress; final bool animated; final bool showRipple; final EdgeInsets? padding; final EdgeInsets? margin; final double? elevation; final BorderRadius? borderRadius; final Widget? header; final Widget? footer; final bool blurBackground; const SophisticatedCard({ super.key, required this.child, this.variant = CardVariant.elevated, this.size = CardSize.standard, this.backgroundColor, this.borderColor, this.gradient, this.customShadow, this.onTap, this.onLongPress, this.animated = true, this.showRipple = true, this.padding, this.margin, this.elevation, this.borderRadius, this.header, this.footer, this.blurBackground = false, }); @override State createState() => _SophisticatedCardState(); } class _SophisticatedCardState extends State with SingleTickerProviderStateMixin { late AnimationController _animationController; late Animation _scaleAnimation; late Animation _shadowAnimation; bool _isPressed = false; @override void initState() { super.initState(); _animationController = AnimationController( duration: const Duration(milliseconds: 200), vsync: this, ); _scaleAnimation = Tween( begin: 1.0, end: 0.98, ).animate(CurvedAnimation( parent: _animationController, curve: Curves.easeInOut, )); _shadowAnimation = Tween( begin: 1.0, end: 0.7, ).animate(CurvedAnimation( parent: _animationController, curve: Curves.easeInOut, )); } @override void dispose() { _animationController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { final borderRadius = widget.borderRadius ?? _getDefaultBorderRadius(); final padding = widget.padding ?? _getDefaultPadding(); final margin = widget.margin ?? EdgeInsets.zero; Widget card = AnimatedBuilder( animation: _animationController, builder: (context, child) { return Transform.scale( scale: widget.animated ? _scaleAnimation.value : 1.0, child: Container( margin: margin, decoration: _getDecoration(borderRadius), child: ClipRRect( borderRadius: borderRadius, child: Material( color: Colors.transparent, child: Column( mainAxisSize: MainAxisSize.min, children: [ if (widget.header != null) ...[ widget.header!, const Divider(height: 1), ], Flexible( child: Padding( padding: padding, child: widget.child, ), ), if (widget.footer != null) ...[ const Divider(height: 1), widget.footer!, ], ], ), ), ), ), ); }, ); if (widget.onTap != null || widget.onLongPress != null) { card = InkWell( onTap: widget.onTap != null ? _handleTap : null, onLongPress: widget.onLongPress, onTapDown: widget.animated ? (_) => _animationController.forward() : null, onTapUp: widget.animated ? (_) => _animationController.reverse() : null, onTapCancel: widget.animated ? () => _animationController.reverse() : null, borderRadius: borderRadius, splashColor: widget.showRipple ? null : Colors.transparent, highlightColor: widget.showRipple ? null : Colors.transparent, child: card, ); } return card; } EdgeInsets _getDefaultPadding() { switch (widget.size) { case CardSize.compact: return const EdgeInsets.all(12); case CardSize.standard: return const EdgeInsets.all(16); case CardSize.expanded: return const EdgeInsets.all(24); } } BorderRadius _getDefaultBorderRadius() { switch (widget.size) { case CardSize.compact: return BorderRadius.circular(12); case CardSize.standard: return BorderRadius.circular(16); case CardSize.expanded: return BorderRadius.circular(20); } } double _getDefaultElevation() { switch (widget.variant) { case CardVariant.elevated: return widget.elevation ?? 8; case CardVariant.glass: return 12; default: return 0; } } Decoration _getDecoration(BorderRadius borderRadius) { final elevation = _getDefaultElevation(); switch (widget.variant) { case CardVariant.elevated: return BoxDecoration( color: widget.backgroundColor ?? Colors.white, borderRadius: borderRadius, boxShadow: widget.customShadow ?? [ BoxShadow( color: Colors.black.withOpacity(0.1 * _shadowAnimation.value), blurRadius: elevation * _shadowAnimation.value, offset: Offset(0, elevation * 0.5 * _shadowAnimation.value), ), ], ); case CardVariant.outlined: return BoxDecoration( color: widget.backgroundColor ?? Colors.white, borderRadius: borderRadius, border: Border.all( color: widget.borderColor ?? AppTheme.textHint.withOpacity(0.2), width: 1, ), ); case CardVariant.filled: return BoxDecoration( color: widget.backgroundColor ?? AppTheme.backgroundLight, borderRadius: borderRadius, ); case CardVariant.glass: return BoxDecoration( color: (widget.backgroundColor ?? Colors.white).withOpacity(0.9), borderRadius: borderRadius, border: Border.all( color: Colors.white.withOpacity(0.3), width: 1, ), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.1 * _shadowAnimation.value), blurRadius: 20 * _shadowAnimation.value, offset: Offset(0, 8 * _shadowAnimation.value), ), ], ); case CardVariant.gradient: return BoxDecoration( gradient: widget.gradient ?? LinearGradient( colors: [ widget.backgroundColor ?? AppTheme.primaryColor, (widget.backgroundColor ?? AppTheme.primaryColor).withOpacity(0.8), ], begin: Alignment.topLeft, end: Alignment.bottomRight, ), borderRadius: borderRadius, boxShadow: [ BoxShadow( color: (widget.backgroundColor ?? AppTheme.primaryColor) .withOpacity(0.3 * _shadowAnimation.value), blurRadius: 15 * _shadowAnimation.value, offset: Offset(0, 8 * _shadowAnimation.value), ), ], ); } } void _handleTap() { if (widget.animated) { HapticFeedback.lightImpact(); } widget.onTap?.call(); } } // Predefined card variants class ElevatedCard extends SophisticatedCard { const ElevatedCard({ super.key, required super.child, super.onTap, super.padding, super.margin, super.elevation, }) : super(variant: CardVariant.elevated); } class OutlinedCard extends SophisticatedCard { const OutlinedCard({ super.key, required super.child, super.onTap, super.padding, super.margin, super.borderColor, }) : super(variant: CardVariant.outlined); } class GlassCard extends SophisticatedCard { const GlassCard({ super.key, required super.child, super.onTap, super.padding, super.margin, }) : super(variant: CardVariant.glass); } class GradientCard extends SophisticatedCard { const GradientCard({ super.key, required super.child, super.onTap, super.padding, super.margin, super.gradient, super.backgroundColor, }) : super(variant: CardVariant.gradient); }