import 'package:flutter/material.dart'; /// 주요 액션에 사용되는 Primary 버튼 /// 저장, 추가, 확인 등의 주요 액션에 사용됩니다. class PrimaryButton extends StatefulWidget { final String text; final VoidCallback? onPressed; final bool isLoading; final IconData? icon; final double? width; final double height; final Color? backgroundColor; final Color? foregroundColor; final double fontSize; final EdgeInsetsGeometry? padding; final double borderRadius; final bool enableHoverEffect; const PrimaryButton({ super.key, required this.text, this.onPressed, this.isLoading = false, this.icon, this.width, this.height = 60, this.backgroundColor, this.foregroundColor, this.fontSize = 18, this.padding, this.borderRadius = 16, this.enableHoverEffect = true, }); @override State createState() => _PrimaryButtonState(); } class _PrimaryButtonState extends State { bool _isHovered = false; @override Widget build(BuildContext context) { final theme = Theme.of(context); final effectiveBackgroundColor = widget.backgroundColor ?? theme.colorScheme.primary; final effectiveForegroundColor = widget.foregroundColor ?? theme.colorScheme.onPrimary; Widget button = AnimatedContainer( duration: const Duration(milliseconds: 200), width: widget.width ?? double.infinity, height: widget.height, transform: widget.enableHoverEffect && _isHovered ? Matrix4.diagonal3Values(1.02, 1.02, 1.0) : Matrix4.identity(), child: ElevatedButton( onPressed: widget.isLoading ? null : widget.onPressed, style: ElevatedButton.styleFrom( backgroundColor: effectiveBackgroundColor, foregroundColor: effectiveForegroundColor, // 고정 높이와 텍스트 잘림 방지를 위해 최소 사이즈 지정 minimumSize: Size.fromHeight(widget.height), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(widget.borderRadius), ), // 컨테이너에서 높이를 관리하므로 수직 패딩은 0으로 두고 // 수평 여백만 부여하여 작은 높이(예: 48)에서 글자 잘림 방지 padding: widget.padding ?? const EdgeInsets.symmetric(horizontal: 16), elevation: widget.enableHoverEffect && _isHovered ? 2 : 0, shadowColor: Colors.black.withValues(alpha: 0.08), disabledBackgroundColor: effectiveBackgroundColor.withValues(alpha: 0.6), ), child: widget.isLoading ? SizedBox( width: 24, height: 24, child: CircularProgressIndicator( strokeWidth: 2.5, color: effectiveForegroundColor, ), ) : Row( mainAxisAlignment: MainAxisAlignment.center, mainAxisSize: MainAxisSize.min, children: [ if (widget.icon != null) ...[ Icon( widget.icon, color: effectiveForegroundColor, size: _isHovered ? 24 : 20, ), const SizedBox(width: 8), ], Text( widget.text, style: TextStyle( fontSize: widget.fontSize, fontWeight: FontWeight.w600, color: effectiveForegroundColor, ), ), ], ), ), ); if (widget.enableHoverEffect) { return MouseRegion( onEnter: (_) => setState(() => _isHovered = true), onExit: (_) => setState(() => _isHovered = false), child: button, ); } return button; } }