Skip to content

ma7moud3osman/easy_stepper

Repository files navigation

Easy Stepper

About

Pub Version GitHub Stars GitHub opened issues GitHub closed issues GitHub last commit GitHub code size in bytes GitHub forks License

Guide users, step by step. A fully customizable, beautiful and easy-to-use stepper widget with different variations.

Description

Easy Stepper guides your users through a flow one step at a time — showing progress or collecting information in clear, organized steps.

Horizontal checkout Vertical order tracking Delivery status Onboarding

Install

In the pubspec.yaml of your flutter project, add the following dependency:

dependencies:
  easy_stepper: <latest_version>

In your library add the following import:

import 'package:easy_stepper/easy_stepper.dart';

Getting started

  • Simply import package:easy_stepper/easy_stepper.dart.

  • Important: The direction argument controls whether the stepper is displayed horizontally or vertically. A horizontal Stepper can be wrapped within a Column with no issues. However, if wrapped within a row, it must also be wrapped within the built-in Expanded widget. The same applies to the vertical Stepper.

  • Validation: To enable validation before the next step is reached, set the steppingEnabled property to an appropriate value in a StatefulWidget.

  • Controlling Steppers: All steppers are controlled using the activeStep property. You can control a stepper by tapping individual steps.

    • See examples here.
  • To customize the color, border, etc., wrap a stepper widget inside a Container and specify it's decoration argument.

🎬 Stepper types

EasyStepper is one widget with many looks. The app mockups above show these types inside real screens — below, each type lists the variations you can produce, with a collapsible code snippet.


🧭 Horizontal

Icons or custom content in a row, with titles above/below/none and dotted or solid connectors — the everyday wizard.

Variations

Titles below · dotted
Titles below · dotted

No titles · solid
No titles · solid

Rounded rectangle
Rounded rectangle

Line text
Line text

View example code  ·  25 lines
EasyStepper(
  activeStep: activeStep,
  stepRadius: 28,
  showLoadingAnimation: false,
  stepBorderRadius: 15,
  finishedStepBackgroundColor: const Color(0xFF7C3AED),
  activeStepBackgroundColor: const Color(0xFF7C3AED),
  finishedStepTextColor: const Color(0xFF7C3AED),
  lineStyle: const LineStyle(
    lineLength: 60,
    lineType: LineType.normal,
    lineThickness: 3,
    unreachedLineType: LineType.dashed,
    defaultLineColor: Color(0xFFDCD7E8),
    finishedLineColor: Color(0xFF7C3AED),
  ),
  steps: const [
    EasyStep(icon: Icon(Icons.shopping_cart), title: 'Cart'),
    EasyStep(icon: Icon(Icons.person), title: 'Address'),
    EasyStep(icon: Icon(Icons.receipt_long), title: 'Checkout'),
    EasyStep(icon: Icon(Icons.star), title: 'Review'),
    EasyStep(icon: Icon(Icons.check_circle), title: 'Done'),
  ],
  onStepReached: (index) => setState(() => activeStep = index),
)

🧵 Vertical

Set direction: Axis.vertical for timelines and tracking screens.

Variation

Vertical icons with titles beside

View example code  ·  20 lines
EasyStepper(
  activeStep: activeStep,
  direction: Axis.vertical,
  showTitle: true,
  stepRadius: 26,
  finishedStepBackgroundColor: const Color(0xFF7C3AED),
  activeStepBackgroundColor: const Color(0xFF7C3AED),
  lineStyle: const LineStyle(
    lineType: LineType.dotted,
    unreachedLineType: LineType.dashed,
  ),
  steps: const [
    EasyStep(icon: Icon(Icons.shopping_cart), title: 'Order placed'),
    EasyStep(icon: Icon(Icons.verified), title: 'Confirmed'),
    EasyStep(icon: Icon(Icons.inventory_2), title: 'Preparing'),
    EasyStep(icon: Icon(Icons.local_shipping), title: 'Shipped'),
    EasyStep(icon: Icon(Icons.home), title: 'Delivered'),
  ],
  onStepReached: (index) => setState(() => activeStep = index),
)

Title placement

For vertical steppers you can control where each step title is rendered using verticalTitlePlacement:

  • VerticalTitlePlacement.side (default) — title beside the icon (left/right depending on text direction and placeTitleAtStart).
  • VerticalTitlePlacement.belowIcon — title below the icon.

When using VerticalTitlePlacement.belowIcon, add extra spacing around the connecting line via LineStyle.verticalLinePadding:

EasyStepper(
  direction: Axis.vertical,
  verticalTitlePlacement: VerticalTitlePlacement.belowIcon,
  lineStyle: const LineStyle(
    verticalLinePadding: EdgeInsets.symmetric(vertical: 8),
  ),
  // ...
)

Horizontal alignment

Use verticalAlignment to align the steps to the leading edge, center, or trailing edge of a vertical stepper (defaults to centered):

EasyStepper(
  direction: Axis.vertical,
  verticalAlignment: CrossAxisAlignment.start, // .center (default) / .end
  // ...
)

⚪ Dots · top & bottom titles

Minimal dots with titles alternating above and below the line — great for compact status bars.

Variation

Alternating top and bottom titles

View example code  ·  31 lines
EasyStepper(
  activeStep: activeStep,
  stepRadius: 8,
  showStepBorder: false,
  showLoadingAnimation: false,
  titlesAreLargerThanSteps: true,
  lineStyle: const LineStyle(
    lineLength: 70,
    lineType: LineType.normal,
    finishedLineColor: Color(0xFF7C3AED),
  ),
  steps: [
    EasyStep(
      customStep: CircleAvatar(
        radius: 8,
        backgroundColor: activeStep >= 0 ? violet : grey,
      ),
      title: 'Waiting',
    ),
    EasyStep(
      customStep: CircleAvatar(
        radius: 8,
        backgroundColor: activeStep >= 1 ? violet : grey,
      ),
      title: 'Received',
      placeTitleAtStart: true,
    ),
    // ...remaining steps
  ],
  onStepReached: (index) => setState(() => activeStep = index),
)

🖼️ Custom image

Any widget can be a step via customStep — here, images make an onboarding flow.

Variation

Circular image steps

View example code  ·  28 lines
EasyStepper(
  activeStep: activeStep,
  stepShape: StepShape.rRectangle,
  stepBorderRadius: 15,
  stepRadius: 28,
  borderThickness: 2,
  finishedStepBackgroundColor: const Color(0xFF7C3AED),
  activeStepIconColor: const Color(0xFF7C3AED),
  lineStyle: const LineStyle(
    lineLength: 50,
    lineType: LineType.normal,
    unreachedLineType: LineType.dashed,
  ),
  steps: [
    for (int i = 0; i < 5; i++)
      EasyStep(
        customStep: ClipRRect(
          borderRadius: BorderRadius.circular(15),
          child: Opacity(
            opacity: activeStep >= i ? 1 : 0.3,
            child: Image.asset('assets/${i + 1}.png'),
          ),
        ),
        customTitle: Text('Dash ${i + 1}', textAlign: TextAlign.center),
      ),
  ],
  onStepReached: (index) => setState(() => activeStep = index),
)

Contributions

Feel free to contribute to this project.

If you find a bug or want a feature, but don't know how to fix/implement it, please fill an issue.
If you fixed a bug or implemented a feature, please send a pull request.

Made with contrib.rocks.

Connect with me

GitHub LinkedIn Twitter

Support

  • Please Like to support!

  • Buy Me A Coffee

Built with

Flutter Dart

Love

About

Flutter Package help you to build easy stepper widget with several customization

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Used by

Contributors

Languages