s_future_button 1.0.0
s_future_button: ^1.0.0 copied to clipboard
A Flutter package for future_button functionality
SFutureButton #
A powerful Flutter package that provides a customizable SFutureButton widget for handling asynchronous operations with automatic state management. It elegantly handles loading, success, error, and reset states with smooth animations.
Demo #

Features #
β¨ Automatic State Management
- Seamlessly handles loading, success, error, and reset states
- Smart result interpretation based on Future return values
- Smooth animations for all state transitions
π¨ Fully Customizable UI
- Configurable dimensions (height and width)
- Custom colors for background and icons
- Adjustable border radius
- Toggle between elevated and flat button styles
- Optional error message display
β‘ Advanced Async Handling
- Returns
trueβ Shows success animation with green checkmark - Returns
falseβ Shows validation error with message - Returns
nullβ Silent dismissal without animation - Throws exception β Shows error state with exception message
π― Rich Callbacks
onPostSuccess- Called after successful operation completiononPostError- Called after error state display with error messageonTap- Main async operation handler returningFuture<bool?>
βΏ Accessibility
- FocusNode support for keyboard navigation
- Focus change callbacks
- Proper disabled state handling
π¬ Beautiful Animations
- Squeeze animation when tapped
- Loading spinner with configurable size
- Bounce effect for success/error states
- Auto-reset after error display (1.5 seconds)
πΎ State Persistence
- Button state survives hot reload during development
Installation #
Add this to your package's pubspec.yaml file:
dependencies:
s_future_button: ^1.0.0
Then run:
flutter pub get
Usage #
Import the package #
import 'package:s_future_button/s_future_button.dart';
Basic Example #
The simplest way to use SFutureButton:
SFutureButton(
onTap: () async {
// Perform your async operation here
final success = await loginUser();
return success; // true = success, false = validation error, null = silent dismiss
},
label: 'Login',
onPostSuccess: () {
print('Login successful!');
},
)
Success Operation #
SFutureButton(
onTap: () async {
// Simulate network request
await Future.delayed(const Duration(seconds: 2));
return true; // Shows success animation
},
label: 'Submit',
bgColor: Colors.blue.shade700,
onPostSuccess: () {
Navigator.pop(context);
},
)
Validation Failure #
SFutureButton(
onTap: () async {
final isValid = validateForm();
if (!isValid) {
return false; // Shows validation error message
}
await submitForm();
return true;
},
label: 'Register',
onPostError: (errorMessage) {
// Handle error (e.g., show snackbar, log error)
print('Validation error: $errorMessage');
},
)
Exception Handling #
SFutureButton(
onTap: () async {
try {
final response = await fetchData();
return true;
} catch (e) {
throw Exception('Failed to load data: ${e.toString()}');
}
},
label: 'Fetch Data',
onPostError: (errorMessage) {
print('Error: $errorMessage');
},
)
Silent Dismissal #
SFutureButton(
onTap: () async {
// Check if user cancelled the operation
final shouldProceed = await showDialog(...);
if (!shouldProceed) {
return null; // Silent dismissal - no animation
}
await processData();
return true;
},
label: 'Process',
showErrorMessage: false,
)
Custom Styling #
SFutureButton(
onTap: () async {
await uploadFile();
return true;
},
label: 'Upload',
height: 56,
width: 200,
borderRadius: 12,
bgColor: Colors.green.shade600,
iconColor: Colors.white,
isElevatedButton: true,
showErrorMessage: true,
)
Icon Button #
SFutureButton(
onTap: () async {
await saveData();
return true;
},
icon: const Icon(
Icons.check,
color: Colors.white,
size: 24,
),
height: 50,
width: 50,
borderRadius: 25,
bgColor: Colors.blue,
onPostSuccess: () {
print('Data saved!');
},
)
With Focus Support #
final focusNode = FocusNode();
SFutureButton(
onTap: () async {
await submitForm();
return true;
},
label: 'Submit',
focusNode: focusNode,
onFocusChange: (isFocused) {
if (isFocused) {
print('Button is focused');
}
},
)
Advanced Configuration #
SFutureButton(
onTap: _performAsyncTask,
label: 'Advanced',
// Dimensions
height: 48,
width: 300,
// Styling
bgColor: Colors.blue.shade700,
iconColor: Colors.white,
borderRadius: 8,
isElevatedButton: true,
// State
isEnabled: true,
showErrorMessage: true,
// Loading indicator
loadingCircleSize: 24,
// Callbacks
onPostSuccess: () {
print('Success!');
},
onPostError: (error) {
print('Error: $error');
},
// Focus management
focusNode: _focusNode,
onFocusChange: (isFocused) {
setState(() {
_isButtonFocused = isFocused;
});
},
)
API Reference #
SFutureButton Constructor Parameters #
| Parameter | Type | Default | Description |
|---|---|---|---|
onTap |
Future<bool?> Function()? |
null |
Async callback that returns Future result |
label |
String? |
null |
Button text label |
icon |
Widget? |
null |
Custom icon widget (overrides label) |
height |
double? |
70 |
Button height |
width |
double? |
150 |
Button width |
bgColor |
Color? |
Colors.blue.shade800 |
Background color |
iconColor |
Color? |
Colors.white |
Icon/text color |
borderRadius |
double? |
35 |
Border radius |
isElevatedButton |
bool |
true |
Whether button has elevation shadow |
isEnabled |
bool |
true |
Whether button is interactive |
showErrorMessage |
bool |
true |
Show error message below button |
loadingCircleSize |
double? |
24 |
Loading indicator size |
onPostSuccess |
VoidCallback? |
null |
Callback after success |
onPostError |
ValueChanged<String>? |
null |
Callback after error with message |
focusNode |
FocusNode? |
null |
Custom focus node |
onFocusChange |
void Function(bool)? |
null |
Focus change callback |
Return Value Handling #
The onTap callback should return a Future<bool?>:
| Return Value | Behavior |
|---|---|
true |
Shows success animation (green checkmark), calls onPostSuccess |
false |
Shows error state with "Validation failed" message, calls onPostError |
null |
Silent reset - no animation or callback |
| Exception | Shows error state with exception message, calls onPostError |
State Flow Diagram #
Idle
β (tap) β Loading (squeeze animation)
β
Success/Error (bounce animation)
β (after 1.5s delay)
β (callback execution)
β
Reset to Idle
Complete Example App #
A full example application demonstrating all features is available in the example/ directory. Run it with:
cd example
flutter run
The example demonstrates:
- β Basic success operations
- β Validation failures
- π¨ Exception handling
- π€« Silent dismissal
- π¨ Custom styling
- πΌοΈ Icon buttons
- β¨οΈ Focus management
- βΏ Disabled states
Dependencies #
- Flutter: >=3.0.0
- Dart: >=3.0.0
- assorted_layout_widgets: ^11.0.0
- nb_utils: ^7.1.8
- soundsliced_dart_extensions: ^1.0.1
- s_disabled: ^1.0.0
- states_rebuilder_extended: ^1.0.3
- rxdart: ^0.28.0
- ticker_free_circular_progress_indicator: ^1.0.0
- soundsliced_tween_animation_builder: ^1.2.0
Contributing #
Contributions are welcome! Please feel free to submit pull requests or open issues on GitHub.
License #
This project is licensed under the MIT License - see the LICENSE file for details.
Support #
For issues, questions, or suggestions, please visit the issue tracker.
Built with β€οΈ by SoundSliced