apptomate_custom_stepper 0.0.1
apptomate_custom_stepper: ^0.0.1 copied to clipboard
An enhanced, fully customizable stepper widget for Flutter that provides a multi-step form workflow with validation support, customizable colors, and button labels.
example/lib/main.dart
import 'package:apptomate_custom_stepper/apptomate_custom_stepper.dart';
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key});
@override
_SignupStepperExampleState createState() => _SignupStepperExampleState();
}
class _SignupStepperExampleState extends State<MyHomePage> {
int _currentStep = 0;
final _formKey1 = GlobalKey<FormState>();
final _formKey2 = GlobalKey<FormState>();
String _name = '';
String _email = '';
String _phone = '';
void _onStepContinue() {
if (_currentStep == 0) {
if (_formKey1.currentState!.validate()) {
setState(() => _currentStep++);
}
} else if (_currentStep == 1) {
if (_formKey2.currentState!.validate()) {
setState(() => _currentStep++);
}
} else if (_currentStep == 2) {
// Submit or Finalize
_submitForm();
}
}
void _onStepCancel() {
if (_currentStep > 0) {
setState(() => _currentStep--);
}
}
void _submitForm() {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Signup Complete for $_name')),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Custom Stepper')),
body: CustomStepper(
currentStep: _currentStep,
nextBtnName: "Continue",
onStepTapped: (step) {
setState(() {
_currentStep = step;
});
},
onStepContinue: _onStepContinue,
onStepCancel: _onStepCancel,
activeColor: Colors.blue,
completedColor: Colors.green,
inactiveColor: Colors.grey,
steps: [
// Step 1: Personal Details
Step(
title: const Text('Personal Details'),
content: Form(
key: _formKey1,
child: Column(
children: [
TextFormField(
decoration: const InputDecoration(labelText: 'Name'),
onChanged: (value) => _name = value,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter your name';
}
return null;
},
),
],
),
),
isActive: _currentStep == 0,
),
// Step 2: Contact Details
Step(
title: const Text('Contact Details'),
content: Form(
key: _formKey2,
child: Column(
children: [
TextFormField(
decoration: const InputDecoration(labelText: 'Email'),
onChanged: (value) => _email = value,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter your email';
}
if (!RegExp(r'\S+@\S+\.\S+').hasMatch(value)) {
return 'Enter a valid email';
}
return null;
},
),
const SizedBox(height: 12),
TextFormField(
decoration: const InputDecoration(labelText: 'Phone'),
onChanged: (value) => _phone = value,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter your phone number';
}
if (!RegExp(r'^[0-9]{10}$').hasMatch(value)) {
return 'Enter a valid 10-digit phone number';
}
return null;
},
),
],
),
),
isActive: _currentStep == 1,
),
// Step 3: Confirmation
Step(
title: const Text('Confirmation'),
content: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Name: $_name'),
Text('Email: $_email'),
Text('Phone: $_phone'),
],
),
isActive: _currentStep == 2,
),
],
),
);
}
}