import 'package:flutter/material.dart'; import 'package:mobile_monitoring/core/constants/colors.dart'; import 'package:mobile_monitoring/core/constants/app_settings.dart'; /// Custom Button - Berbagai jenis button yang reusable class CustomButton extends StatelessWidget { final String text; final VoidCallback? onPressed; final bool isLoading; final ButtonType type; final ButtonSize size; final IconData? icon; final Color? backgroundColor; final Color? textColor; final double? width; final double? height; const CustomButton({ super.key, required this.text, this.onPressed, this.isLoading = false, this.type = ButtonType.primary, this.size = ButtonSize.medium, this.icon, this.backgroundColor, this.textColor, this.width, this.height, }); @override Widget build(BuildContext context) { final isDisabled = onPressed == null || isLoading; return SizedBox( width: width, height: height ?? _getHeight(), child: _buildButton(context, isDisabled), ); } Widget _buildButton(BuildContext context, bool isDisabled) { switch (type) { case ButtonType.primary: return ElevatedButton( onPressed: isDisabled ? null : onPressed, style: ElevatedButton.styleFrom( backgroundColor: backgroundColor ?? AppColors.primary, foregroundColor: textColor ?? AppColors.white, padding: _getPadding(), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(AppSettings.defaultBorderRadius), ), elevation: 2, ), child: _buildContent(), ); case ButtonType.secondary: return OutlinedButton( onPressed: isDisabled ? null : onPressed, style: OutlinedButton.styleFrom( foregroundColor: backgroundColor ?? AppColors.primary, side: BorderSide( color: backgroundColor ?? AppColors.primary, width: 1.5, ), padding: _getPadding(), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(AppSettings.defaultBorderRadius), ), ), child: _buildContent(), ); case ButtonType.text: return TextButton( onPressed: isDisabled ? null : onPressed, style: TextButton.styleFrom( foregroundColor: backgroundColor ?? AppColors.primary, padding: _getPadding(), ), child: _buildContent(), ); case ButtonType.danger: return ElevatedButton( onPressed: isDisabled ? null : onPressed, style: ElevatedButton.styleFrom( backgroundColor: AppColors.error, foregroundColor: AppColors.white, padding: _getPadding(), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(AppSettings.defaultBorderRadius), ), elevation: 2, ), child: _buildContent(), ); } } Widget _buildContent() { if (isLoading) { return SizedBox( height: _getIndicatorSize(), width: _getIndicatorSize(), child: CircularProgressIndicator( strokeWidth: 2, valueColor: AlwaysStoppedAnimation( type == ButtonType.primary || type == ButtonType.danger ? AppColors.white : AppColors.primary, ), ), ); } if (icon != null) { return Row( mainAxisSize: MainAxisSize.min, children: [ Icon(icon, size: _getIconSize()), const SizedBox(width: 8), Text(text, style: TextStyle(fontSize: _getFontSize())), ], ); } return Text(text, style: TextStyle(fontSize: _getFontSize())); } double _getHeight() { switch (size) { case ButtonSize.small: return 36; case ButtonSize.medium: return 48; case ButtonSize.large: return 56; } } EdgeInsets _getPadding() { switch (size) { case ButtonSize.small: return const EdgeInsets.symmetric(horizontal: 16, vertical: 8); case ButtonSize.medium: return const EdgeInsets.symmetric(horizontal: 24, vertical: 12); case ButtonSize.large: return const EdgeInsets.symmetric(horizontal: 32, vertical: 16); } } double _getFontSize() { switch (size) { case ButtonSize.small: return 14; case ButtonSize.medium: return 16; case ButtonSize.large: return 18; } } double _getIconSize() { switch (size) { case ButtonSize.small: return 18; case ButtonSize.medium: return 20; case ButtonSize.large: return 24; } } double _getIndicatorSize() { switch (size) { case ButtonSize.small: return 16; case ButtonSize.medium: return 20; case ButtonSize.large: return 24; } } } enum ButtonType { primary, secondary, text, danger } enum ButtonSize { small, medium, large }