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

☕ Support #


🌐 Connect #

        

5
likes
160
points
88
downloads

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