state_button 1.1.0
state_button: ^1.1.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
- ๐ Six built-in loader styles โ from classic iOS spinner to modern animated dots
- ๐ฆ 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),
),
],
),
)
Loader Types #
state_button ships with six built-in loading indicators via SbLoaderType. Pass the desired style to the loaderType parameter โ it defaults to cupertinoSpinner for full backward compatibility.
StateButton(
controller: _ctrl,
loaderType: SbLoaderType.spinningArc, // โ pick any style
onPressed: () async {
_ctrl.setLoading();
await Future.delayed(const Duration(seconds: 2));
_ctrl.setSuccess();
},
child: const Text('Submit'),
)
| Loader | SbLoaderType value |
Description |
|---|---|---|
| iOS-style spinner | cupertinoSpinner (default) |
Uses CupertinoActivityIndicator โ preserves original behaviour |
| Circular progress | circular |
Continuously rotating full-circle stroke via CircularProgressIndicator |
| Wave dots | dotsWave |
Three dots animated in a smooth sine-based wave with phase shifts |
| Pulse dots | dotsPulse |
Three dots that scale in and out sequentially โ a rhythmic "breathing" effect |
| Progressive dots | progressiveDots |
Four dots shifting right-to-left; leading dot fades out as a new one appears |
| Spinning arc | spinningArc |
A partial arc with a rounded cap that rotates โ modern and minimal |
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 }
SbLoaderType #
enum SbLoaderType {
cupertinoSpinner, // default
circular,
dotsWave,
dotsPulse,
progressiveDots,
spinningArc,
}
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 |
loaderType |
SbLoaderType |
cupertinoSpinner |
Style of loading indicator shown during loading 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 |
