state_button 1.0.0
state_button: ^1.0.0 copied to clipboard
Flutter button with loading, success, and failure states with smooth animations
state_button #
An animated Flutter button that transitions through idle → loading → success / failure → idle with zero boilerplate.
Features #
- 🎯 Four phases:
idle,loading,success,failure - ✨ Animated tick (✓) and cross (✗) drawn with
CustomPainter - 🔒 Tap-lock during loading – no double-submission guard needed
- 🔄 Auto-resets to idle after success or failure
- 🎨 Fully customisable: colours, radius, shadow, size, duration
- 📦 Zero external dependencies beyond Flutter itself
Installation #
Run this command:
flutter pub add state_button
Or add manually to pubspec.yaml:
dependencies:
state_button: ^latest-version
Then run flutter pub get and import:
import 'package:state_button/state_button.dart';
Previews #
1 · Primary filled button #
Solid indigo fill, white label. Demonstrates a failure flow.
StateButton(
controller: _ctrl,
width: double.infinity,
onPressed: () async {
_ctrl.setLoading();
await Future.delayed(const Duration(seconds: 2));
_ctrl.setFailure();
},
child: const Text(
'Submit',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.w600,
fontSize: 16,
),
),
)
2 · Outlined / custom decoration button #
White background with a coloured border. Success and failure icons use matching brand colours instead of white.
StateButton(
controller: _ctrl,
width: double.infinity,
backgroundColor: Colors.white,
successColor: const Color(0xFF22C55E),
failureColor: const Color(0xFFEF4444),
successIconColor: const Color(0xFF22C55E),
failureIconColor: const Color(0xFFEF4444),
loadingColor: const Color(0xFF6366F1),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(12),
border: Border.all(color: const Color(0xFF6366F1), width: 1.5),
),
boxShadow: [
BoxShadow(
color: Colors.black.withValues(alpha: 0.06),
blurRadius: 8,
offset: const Offset(0, 3),
),
],
onPressed: () async {
_ctrl.setLoading();
await Future.delayed(const Duration(seconds: 2));
_ctrl.setSuccess();
},
child: const Text(
'Upload File',
style: TextStyle(color: Color(0xFF6366F1), fontSize: 15),
),
)
3 · Button with icon + label #
Fully rounded pill shape with a dark background and an icon-label row child. Demonstrates a success flow with a custom
autoResetDuration.
StateButton(
controller: _ctrl,
borderRadius: 999,
padding: const EdgeInsets.symmetric(horizontal: 32, vertical: 14),
backgroundColor: const Color(0xFF0F172A),
autoResetDuration: const Duration(seconds: 2),
boxShadow: [
BoxShadow(
color: const Color(0xFF0F172A).withValues(alpha: 0.35),
blurRadius: 16,
offset: const Offset(0, 6),
),
],
onPressed: () async {
_ctrl.setLoading();
await Future.delayed(const Duration(milliseconds: 1500));
_ctrl.setSuccess();
},
child: const Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(Icons.rocket_launch_rounded, color: Colors.white, size: 18),
SizedBox(width: 8),
Text(
'Deploy',
style: TextStyle(color: Colors.white, fontSize: 15),
),
],
),
)
API Reference #
SbController #
| Member | Type | Description |
|---|---|---|
phase |
SbPhase |
Current phase (read-only) |
setIdle() |
void |
Reset to tappable idle state |
setLoading() |
void |
Show spinner, block taps |
setSuccess() |
void |
Show animated ✓, then auto-reset |
setFailure() |
void |
Show animated ✗, then auto-reset |
dispose() |
void |
Release resources — call in dispose() |
SbPhase #
enum SbPhase { idle, loading, success, failure }
StateButton parameters #
| Parameter | Type | Default | Description |
|---|---|---|---|
controller |
SbController |
required | Drives phase transitions |
onPressed |
VoidCallback |
required | Called on tap (idle phase only) |
child |
Widget |
Text('Submit') |
Widget shown in idle phase |
width |
double? |
null |
Fixed width; null = stretch |
height |
double |
52 |
Fixed height in logical pixels |
padding |
EdgeInsetsGeometry |
h:24 v:12 |
Inner padding |
margin |
EdgeInsetsGeometry |
zero |
Outer margin |
borderRadius |
double |
12 |
Corner radius; use 999 for pill |
backgroundColor |
Color |
#6366F1 |
Fill colour in idle phase |
successColor |
Color |
#22C55E |
Fill colour in success phase |
failureColor |
Color |
#EF4444 |
Fill colour in failure phase |
splashColor |
Color? |
white 15% | Ink splash on tap |
highlightColor |
Color? |
white 8% | Ink highlight on long-press |
decoration |
BoxDecoration? |
null |
Overrides all container decoration |
boxShadow |
List<BoxShadow>? |
null |
Drop shadows (ignored if decoration set) |
indicatorSize |
double |
26 |
Diameter of spinner / tick / cross |
loadingColor |
Color |
white |
Spinner colour |
successIconColor |
Color |
white |
Tick + circle stroke colour |
failureIconColor |
Color |
white |
Cross + circle stroke colour |
autoResetDuration |
Duration |
1 800 ms |
Time before auto-reset to idle |
animationDuration |
Duration |
300 ms |
Colour fade + content crossfade speed |