import 'package:flutter/material.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; class FlutterFlowIconButton extends StatefulWidget { const FlutterFlowIconButton({ super.key, required this.icon, this.borderColor, this.borderRadius, this.borderWidth, this.buttonSize, this.fillColor, this.disabledColor, this.disabledIconColor, this.hoverColor, this.hoverIconColor, this.onPressed, this.showLoadingIndicator = false, }); final Widget icon; final double? borderRadius; final double? buttonSize; final Color? fillColor; final Color? disabledColor; final Color? disabledIconColor; final Color? hoverColor; final Color? hoverIconColor; final Color? borderColor; final double? borderWidth; final bool showLoadingIndicator; final Function()? onPressed; @override State createState() => _FlutterFlowIconButtonState(); } class _FlutterFlowIconButtonState extends State { bool loading = false; late double? iconSize; late Color? iconColor; late Widget effectiveIcon; @override void initState() { super.initState(); _updateIcon(); } @override void didUpdateWidget(FlutterFlowIconButton oldWidget) { super.didUpdateWidget(oldWidget); _updateIcon(); } void _updateIcon() { final isFontAwesome = widget.icon is FaIcon; if (isFontAwesome) { FaIcon icon = widget.icon as FaIcon; effectiveIcon = FaIcon( icon.icon, size: icon.size, ); iconSize = icon.size; iconColor = icon.color; } else { Icon icon = widget.icon as Icon; effectiveIcon = Icon( icon.icon, size: icon.size, ); iconSize = icon.size; iconColor = icon.color; } } @override Widget build(BuildContext context) { ButtonStyle style = ButtonStyle( shape: WidgetStateProperty.resolveWith( (states) { return RoundedRectangleBorder( borderRadius: BorderRadius.circular(widget.borderRadius ?? 0), side: BorderSide( color: widget.borderColor ?? Colors.transparent, width: widget.borderWidth ?? 0, ), ); }, ), iconColor: WidgetStateProperty.resolveWith( (states) { if (states.contains(WidgetState.disabled) && widget.disabledIconColor != null) { return widget.disabledIconColor; } if (states.contains(WidgetState.hovered) && widget.hoverIconColor != null) { return widget.hoverIconColor; } return iconColor; }, ), backgroundColor: WidgetStateProperty.resolveWith( (states) { if (states.contains(WidgetState.disabled) && widget.disabledColor != null) { return widget.disabledColor; } if (states.contains(WidgetState.hovered) && widget.hoverColor != null) { return widget.hoverColor; } return widget.fillColor; }, ), overlayColor: WidgetStateProperty.resolveWith((states) { if (states.contains(WidgetState.pressed)) { return null; } return widget.hoverColor == null ? null : Colors.transparent; }), ); return SizedBox( width: widget.buttonSize, height: widget.buttonSize, child: Theme( data: ThemeData.from( colorScheme: Theme.of(context).colorScheme, useMaterial3: true, ), child: IgnorePointer( ignoring: (widget.showLoadingIndicator && loading), child: IconButton( icon: (widget.showLoadingIndicator && loading) ? SizedBox( width: iconSize, height: iconSize, child: CircularProgressIndicator( valueColor: AlwaysStoppedAnimation( iconColor ?? Colors.white, ), ), ) : effectiveIcon, onPressed: widget.onPressed == null ? null : () async { if (loading) { return; } setState(() => loading = true); try { await widget.onPressed!(); } finally { if (mounted) { setState(() => loading = false); } } }, splashRadius: widget.buttonSize, style: style, ), ), ), ); } }