import 'package:flutter/material.dart'; typedef VoidFutureCallBack = Future Function(); class FutureTextButton extends StatefulWidget { const FutureTextButton({ Key? key, this.onLongPress, this.onHover, this.onFocusChange, this.style, this.focusNode, this.autofocus = false, this.clipBehavior = Clip.none, required this.child, required this.onPressed, }) : super(key: key); final VoidFutureCallBack? onPressed; final VoidCallback? onLongPress; final ValueChanged? onHover; final ValueChanged? onFocusChange; final ButtonStyle? style; final Clip clipBehavior; final FocusNode? focusNode; final bool autofocus; final Widget child; @override State createState() => _FutureTextButtonState(); } class _FutureTextButtonState extends State { bool _isBusy = false; Future onPressed() async { if (_isBusy) return; setState(() => _isBusy = true); try { await widget.onPressed?.call(); } catch (e) { rethrow; } finally { if (mounted) setState(() => _isBusy = false); } } @override Widget build(BuildContext context) { return TextButton( key: widget.key, onPressed: _isBusy || widget.onPressed == null ? null : () => onPressed(), onLongPress: widget.onLongPress, onHover: widget.onHover, onFocusChange: widget.onFocusChange, style: widget.style, focusNode: widget.focusNode, autofocus: widget.autofocus, clipBehavior: widget.clipBehavior, child: widget.child, ); } }