import 'package:flutter/material.dart'; /// 위험한 액션에 사용되는 Danger 버튼 /// 삭제, 취소, 종료 등의 위험한 액션에 사용됩니다. class DangerButton extends StatefulWidget { final String text; final VoidCallback? onPressed; final bool requireConfirmation; final String? confirmationTitle; final String? confirmationMessage; final IconData? icon; final double? width; final double height; final double fontSize; final EdgeInsetsGeometry? padding; final double borderRadius; final bool enableHoverEffect; const DangerButton({ super.key, required this.text, this.onPressed, this.requireConfirmation = false, this.confirmationTitle, this.confirmationMessage, this.icon, this.width, this.height = 60, this.fontSize = 18, this.padding, this.borderRadius = 16, this.enableHoverEffect = true, }); @override State createState() => _DangerButtonState(); } class _DangerButtonState extends State { bool _isHovered = false; static const Color _dangerColor = Color(0xFFDC2626); Future _handlePress() async { if (widget.requireConfirmation) { final confirmed = await showDialog( context: context, builder: (context) => AlertDialog( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(20), ), title: Text( widget.confirmationTitle ?? widget.text, style: const TextStyle( fontWeight: FontWeight.bold, fontSize: 20, ), ), content: Column( mainAxisSize: MainAxisSize.min, children: [ Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: _dangerColor.withOpacity(0.1), borderRadius: BorderRadius.circular(12), ), child: Icon( widget.icon ?? Icons.warning_amber_rounded, color: _dangerColor, size: 48, ), ), const SizedBox(height: 16), Text( widget.confirmationMessage ?? '이 작업은 되돌릴 수 없습니다.\n계속하시겠습니까?', textAlign: TextAlign.center, style: const TextStyle( fontSize: 16, height: 1.5, ), ), ], ), actions: [ TextButton( onPressed: () => Navigator.of(context).pop(false), child: const Text('취소'), ), ElevatedButton( onPressed: () => Navigator.of(context).pop(true), style: ElevatedButton.styleFrom( backgroundColor: _dangerColor, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), ), ), child: Text( widget.text, style: const TextStyle(color: Colors.white), ), ), ], ), ); if (confirmed == true) { widget.onPressed?.call(); } } else { widget.onPressed?.call(); } } @override Widget build(BuildContext context) { Widget button = AnimatedContainer( duration: const Duration(milliseconds: 200), width: widget.width ?? double.infinity, height: widget.height, transform: widget.enableHoverEffect && _isHovered ? (Matrix4.identity()..scale(1.02)) : Matrix4.identity(), child: ElevatedButton( onPressed: widget.onPressed != null ? _handlePress : null, style: ElevatedButton.styleFrom( backgroundColor: _dangerColor, foregroundColor: Colors.white, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(widget.borderRadius), ), padding: widget.padding ?? const EdgeInsets.symmetric(vertical: 16), elevation: widget.enableHoverEffect && _isHovered ? 8 : 4, shadowColor: _dangerColor.withOpacity(0.5), disabledBackgroundColor: _dangerColor.withOpacity(0.6), ), child: Row( mainAxisAlignment: MainAxisAlignment.center, mainAxisSize: MainAxisSize.min, children: [ if (widget.icon != null) ...[ Icon( widget.icon, color: Colors.white, size: _isHovered ? 24 : 20, ), const SizedBox(width: 8), ], Text( widget.text, style: TextStyle( fontSize: widget.fontSize, fontWeight: FontWeight.w600, color: Colors.white, ), ), ], ), ), ); if (widget.enableHoverEffect) { return MouseRegion( onEnter: (_) => setState(() => _isHovered = true), onExit: (_) => setState(() => _isHovered = false), child: button, ); } return button; } }