import 'package:flutter/material.dart'; import '../../../theme/app_colors.dart'; /// 부차적인 액션에 사용되는 Secondary 버튼 /// 취소, 되돌아가기, 부가 옵션 등에 사용됩니다. class SecondaryButton extends StatefulWidget { final String text; final VoidCallback? onPressed; final IconData? icon; final double? width; final double height; final Color? borderColor; final Color? textColor; final double fontSize; final EdgeInsetsGeometry? padding; final double borderRadius; final double borderWidth; final bool enableHoverEffect; const SecondaryButton({ super.key, required this.text, this.onPressed, this.icon, this.width, this.height = 56, this.borderColor, this.textColor, this.fontSize = 16, this.padding, this.borderRadius = 16, this.borderWidth = 1.5, this.enableHoverEffect = true, }); @override State createState() => _SecondaryButtonState(); } class _SecondaryButtonState extends State { bool _isHovered = false; @override Widget build(BuildContext context) { final effectiveBorderColor = widget.borderColor ?? AppColors.secondaryColor; final effectiveTextColor = widget.textColor ?? AppColors.primaryColor; Widget button = AnimatedContainer( duration: const Duration(milliseconds: 200), width: widget.width, height: widget.height, transform: widget.enableHoverEffect && _isHovered ? (Matrix4.identity()..scale(1.02)) : Matrix4.identity(), child: OutlinedButton( onPressed: widget.onPressed, style: OutlinedButton.styleFrom( foregroundColor: effectiveTextColor, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(widget.borderRadius), ), side: BorderSide( color: _isHovered ? effectiveBorderColor.withValues(alpha: 0.4) : effectiveBorderColor, width: widget.borderWidth, ), padding: widget.padding ?? const EdgeInsets.symmetric( vertical: 12, horizontal: 24, ), backgroundColor: _isHovered ? AppColors.glassBackground : Colors.transparent, ), child: Row( mainAxisAlignment: MainAxisAlignment.center, mainAxisSize: MainAxisSize.min, children: [ if (widget.icon != null) ...[ Icon( widget.icon, color: effectiveTextColor, size: 20, ), const SizedBox(width: 8), ], Text( widget.text, style: TextStyle( fontSize: widget.fontSize, fontWeight: FontWeight.w500, color: effectiveTextColor, ), ), ], ), ), ); if (widget.enableHoverEffect) { return MouseRegion( onEnter: (_) => setState(() => _isHovered = true), onExit: (_) => setState(() => _isHovered = false), child: button, ); } return button; } } /// 텍스트 링크 스타일의 버튼 /// 간단한 액션이나 링크에 사용됩니다. class TextLinkButton extends StatefulWidget { final String text; final VoidCallback? onPressed; final IconData? icon; final Color? color; final double fontSize; final bool enableHoverEffect; const TextLinkButton({ super.key, required this.text, this.onPressed, this.icon, this.color, this.fontSize = 14, this.enableHoverEffect = true, }); @override State createState() => _TextLinkButtonState(); } class _TextLinkButtonState extends State { bool _isHovered = false; @override Widget build(BuildContext context) { final theme = Theme.of(context); final effectiveColor = widget.color ?? AppColors.primaryColor; Widget button = AnimatedContainer( duration: const Duration(milliseconds: 200), decoration: BoxDecoration( color: _isHovered ? theme.colorScheme.onSurface.withValues(alpha: 0.05) : Colors.transparent, borderRadius: BorderRadius.circular(8), ), child: TextButton( onPressed: widget.onPressed, style: TextButton.styleFrom( foregroundColor: effectiveColor, padding: const EdgeInsets.symmetric( horizontal: 10, vertical: 6, ), minimumSize: Size.zero, tapTargetSize: MaterialTapTargetSize.shrinkWrap, ), child: Row( mainAxisSize: MainAxisSize.min, children: [ if (widget.icon != null) ...[ Icon( widget.icon, size: 18, color: effectiveColor, ), const SizedBox(width: 6), ], Text( widget.text, style: TextStyle( fontSize: widget.fontSize, fontWeight: FontWeight.w500, color: effectiveColor, decoration: _isHovered ? TextDecoration.underline : TextDecoration.none, ), ), ], ), ), ); if (widget.enableHoverEffect) { return MouseRegion( onEnter: (_) => setState(() => _isHovered = true), onExit: (_) => setState(() => _isHovered = false), child: button, ); } return button; } }