awesome_stepper 1.1.0
awesome_stepper: ^1.1.0 copied to clipboard
Beautiful, customizable Flutter stepper with animated progress headers, step validation, a controller and foldable-ready large-screen layout.

awesome_stepper #
The beautiful Flutter stepper for multi-step forms, onboarding, checkout and wizard flows: an animated step progress indicator, sliding pages, form validation per step, a controller, and a side-by-side layout on tablets and foldables. Material 3, dark mode, no dependencies.
🏆 Award-winning: awesome_stepper won 1st place in the Autumn Flutter Package Development Challenge (2021), organized by Levent Kantaroğlu. Version 1.0 is a full redesign.

Live demo: monsware.com/awesome-stepper
Features of this Flutter stepper widget #
- 4 header styles: the classic progress circle, a progress bar, dots, numbered steps — plus a vertical stepper layout.
- Standalone step progress indicator:
AwesomeStepIndicatorwithout pages. - Material 3: colors come from your theme; light and dark mode out of the box.
- Smooth motion: pages slide and fade, the title cross-fades, the progress animates.
- Validation:
canContinueper step (sync or async) keeps the user on an invalid step and marks it red. - Step states: completed ✓, error !, locked 🔒 (disabled steps are skipped).
- Controller:
next(),back(),jumpTo(), listen tocurrentStep. - Large screens & foldables: from 840 px the
circleandnumberedheaders become a side list; on foldables (Galaxy Z Fold, Pixel Fold, iPhone Duo) the split follows the fold. - Accessible: screen reader announces "Step 2 of 5: Payment", 48 px buttons, RTL, arrow keys, swipe, haptics.
- No dependencies besides Flutter.
Install #
dependencies:
awesome_stepper: ^1.1.0
Usage: a multi-step form in Flutter #
import 'package:awesome_stepper/awesome_stepper.dart';
AwesomeStepper(
onCompleted: () => print('done'),
steps: [
AwesomeStepperItem(
label: 'Address',
subtitle: 'Where should we deliver?',
content: AddressForm(key: formKey),
canContinue: () => formKey.currentState!.validate(),
),
const AwesomeStepperItem(label: 'Payment', content: PaymentPage()),
const AwesomeStepperItem(label: 'Review', content: ReviewPage()),
],
)
Header styles #
AwesomeStepper(headerType: AwesomeStepperHeader.numbered, steps: steps)
// circle (default) · bar · dots · numbered
Controller #
final controller = AwesomeStepperController();
AwesomeStepper(controller: controller, steps: steps);
await controller.next(); // runs canContinue first
await controller.jumpTo(3);
controller.addListener(() => print(controller.currentStep));
Custom controls #
AwesomeStepper(
steps: steps,
controlBuilder: (onNext, onBack) => Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
IconButton(onPressed: onBack, icon: const Icon(Icons.arrow_back)),
IconButton(onPressed: onNext, icon: const Icon(Icons.arrow_forward)),
],
),
)
Vertical stepper #
AwesomeStepper(
layout: AwesomeStepperLayout.vertical,
lineStyle: AwesomeStepperLineStyle.dashed,
steps: steps, // content must size itself: Column, not ListView
)
Optional steps, completed screen, restoration #
AwesomeStepper(
restorationId: 'checkout', // survives app restarts
completedBuilder: (_) => const ThankYouPage(),
steps: [
AwesomeStepperItem(label: 'Extras', optional: true, content: extras), // Skip button
...
],
)
Just the indicator: AwesomeStepIndicator #
AwesomeStepIndicator(
type: AwesomeStepperHeader.bar, // circle · bar · dots · numbered
currentStep: 1, // 0-based
labels: const ['Cart', 'Address', 'Payment'],
)
Coming from step_progress_indicator? StepProgressIndicator(totalSteps: 5, currentStep: 2)
becomes AwesomeStepIndicator(totalSteps: 5, currentStep: 1) — currentStep is the 0-based index
of the active step. You get labels, numbered steps, animations, dark mode and accessibility for free.
Theme for the whole app #
ThemeData(extensions: const [
AwesomeStepperTheme(accentColor: Colors.teal, buttonHeight: 52),
])
Translations #
AwesomeStepper(
nextLabel: 'Weiter',
backLabel: 'Zurück',
finishLabel: 'Fertig',
semanticsLabel: (step, total, label) => 'Schritt $step von $total: $label',
steps: steps,
)
Options #
| Parameter | Default | |
|---|---|---|
headerType |
circle |
circle, bar, dots, numbered |
headerColor / progressColor |
theme | header background / accent |
headerStyle / progressStyle |
theme | title / counter text styles |
headerHeight / controllerHeight |
72 (88 numbered) / 48 | |
contentAnimationDuration |
300 ms | page slide |
headerAnimationDuration / progressBarAnimationDuration |
250 ms / 1 s | |
swipeEnabled / keyboardEnabled / hapticsEnabled |
true |
|
sideBySideMinWidth |
840 | null = never side by side |
sideListWidth |
300 | when there is no fold |
contentMaxWidth |
720 | page, buttons and header column on wide windows |
layout |
horizontal |
horizontal, vertical |
transition |
slide |
slide, fade, scale, none |
lineStyle |
solid |
solid, dotted, dashed |
skipLabel |
Skip | shown on optional steps |
allowHeaderJump |
true |
jump forward from the header |
completedBuilder |
— | screen after the last step |
restorationId |
— | keep the step across app restarts |
Upgrading from 0.x #
Existing code keeps working. The default look is now Material 3 (theme colors instead of
white / red / green); pass headerColor and progressColor to keep your colors.
AwesomeStepperItem is const, onStepChanged is ValueChanged<int>.
Keywords #
Flutter stepper · step progress indicator · vertical stepper · horizontal stepper · wizard · multi-step form · onboarding flow · checkout flow · form validation · progress bar · Material 3 stepper.
Issues and ideas: GitHub.
About the author #
Made with ❤️ by Muhammed Şamil Demir, Flutter & iOS developer and founder of Monsware. Free and open source (see LICENSE).
- 🌐 Website: monsware.com · GitHub: @msaadev
- 📱 Apps by Monsware: Triangle Calculator · Circle Calculator
- 📦 More Flutter packages: awesome_stepper · regex_ui · fold_kit
- 💼 Need a Flutter or iOS app built? Get in touch
If this package saves you time, a ⭐ on GitHub and a 👍 on pub.dev help a lot.
