state_button 1.1.0 copy "state_button: ^1.1.0" to clipboard
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

โ˜• Support #


๐ŸŒ Connect #

        

5
likes
160
points
87
downloads
screenshot

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Flutter button with loading, success, and failure states with smooth animations

Repository (GitHub)
View/report issues

Topics

#button #loading #animation #ui #async

License

MIT (license)

Dependencies

flutter

More

Packages that depend on state_button