You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
cloudsolutions-atoms/lib/common_widgets/stapper_widget/custom_stepper.dart

272 lines
9.1 KiB
Dart

library easy_stepper;
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:test_sa/new_views/app_style/app_color.dart';
import 'components/base_step.dart';
import 'components/custom_line.dart';
class CustomStepper extends StatefulWidget {
final List<StepModel> steps;
final OnStepReached ?onStepReached;
final Color ?unreachedStepBackgroundColor;
final Color ?unreachedStepTextColor;
final Color ?unreachedStepIconColor;
final Color ?unreachedStepBorderColor;
final BorderType ?unreachedStepBorderType;
final Color activeStepBackgroundColor;
final Color? activeStepTextColor;
final Color activeStepIconColor;
final Color activeStepBorderColor;
final BorderType ?activeStepBorderType;
final Color finishedStepBackgroundColor;
final Color ?finishedStepBorderColor;
final Color ?finishedStepTextColor;
final Color ?finishedStepIconColor;
final BorderType ?finishedStepBorderType;
final double stepRadius;
final int activeStep;
final int ?maxReachedStep;
final Set<int>? reachedSteps;
final AlignmentGeometry alignment;
final double internalPadding;
final EdgeInsetsGeometry padding;
final bool titlesAreLargerThanSteps;
final Curve stepAnimationCurve;
final Duration stepAnimationDuration;
final double borderThickness;
final StepShape stepShape;
final double ?stepBorderRadius;
final bool showStepBorder;
final bool showScrollbar;
final bool fitWidth;
final LineStyle ?lineStyle;
const CustomStepper({
Key? key,
required this.activeStep,
required this.steps,
this.reachedSteps,
this.maxReachedStep,
this.onStepReached,
this.unreachedStepBackgroundColor,
this.unreachedStepTextColor,
this.unreachedStepIconColor,
this.unreachedStepBorderColor,
this.activeStepTextColor,
this.activeStepIconColor=AppColor.primary10,
this.activeStepBackgroundColor=AppColor.primary10,
this.activeStepBorderColor=AppColor.primary10,
this.finishedStepBackgroundColor=AppColor.primary10,
this.finishedStepBorderColor,
this.finishedStepIconColor,
this.stepRadius = 20,
this.alignment = Alignment.center,
this.fitWidth = true,
this.showScrollbar = false,
this.padding=EdgeInsetsDirectional.zero,
this.titlesAreLargerThanSteps = false,
this.internalPadding = 8,
this.stepAnimationCurve = Curves.linear,
this.stepAnimationDuration = const Duration(seconds: 1),
this.borderThickness = 1,
this.stepShape = StepShape.circle,
this.stepBorderRadius,
this.unreachedStepBorderType,
this.activeStepBorderType,
this.finishedStepBorderType,
this.showStepBorder = false,
this.lineStyle, this.finishedStepTextColor,
}) : assert(maxReachedStep == null || reachedSteps == null,
'only "maxReachedStep" or "reachedSteps" allowed'),
super(key: key);
@override
State<CustomStepper> createState() => _CustomStepperState();
}
class _CustomStepperState extends State<CustomStepper> {
late ScrollController _scrollController;
int ?_selectedIndex;
LineStyle? lineStyle;
EdgeInsetsGeometry? _padding;
@override
void initState() {
lineStyle = widget.lineStyle ?? const LineStyle();
_selectedIndex = widget.activeStep;
_scrollController = ScrollController();
_padding = const EdgeInsetsDirectional.all(10);
if (widget.steps.any((element) => element.topTitle??false)) {
_padding = _padding!.add(const EdgeInsetsDirectional.only(top: 45));
}
if (widget.titlesAreLargerThanSteps) {
_padding = _padding!.add(EdgeInsetsDirectional.symmetric(
horizontal: lineStyle!.lineLength / 2));
}
_padding!.add(widget.padding);
super.initState();
}
@override
void didUpdateWidget(CustomStepper oldWidget) {
super.didUpdateWidget(oldWidget);
// Verify that the active step falls within a valid range.
if (widget.activeStep >= 0 && widget.activeStep < widget.steps.length) {
_selectedIndex = widget.activeStep;
}
}
@override
void dispose() {
_scrollController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
lineStyle = widget.lineStyle ?? const LineStyle();
return Align(
alignment: widget.alignment,
child: NotificationListener<OverscrollIndicatorNotification>(
onNotification: (OverscrollIndicatorNotification overscroll) {
overscroll.disallowIndicator();
return false;
},
child: FittedBox(
fit: widget.fitWidth ? BoxFit.fitWidth : BoxFit.none,
child: Row(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: _buildEasySteps(),
),
)
),
);
}
List<Widget> _buildEasySteps() {
return List.generate(widget.steps.length, (index) {
return Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
_buildStep(index),
_buildLine(index, Axis.horizontal),
],
);
});
}
BaseStep _buildStep(int index) {
final step = widget.steps[index];
return BaseStep(
step: step,
radius: widget.stepRadius,
isActive: index == widget.activeStep,
isFinished: widget.reachedSteps != null
? index < widget.activeStep && widget.reachedSteps!.contains(index)
: index < widget.activeStep,
isUnreached: index > widget.activeStep,
isAlreadyReached: widget.reachedSteps != null
? widget.reachedSteps!.contains(index)
: widget.maxReachedStep != null
? index <= widget.maxReachedStep!
: false,
activeStepBackgroundColor: widget.activeStepBackgroundColor,
activeStepBorderColor: widget.activeStepBorderColor,
activeTextColor: widget.activeStepTextColor??AppColor.neutral100,
activeIconColor: widget.activeStepIconColor,
unreachedBackgroundColor: widget.unreachedStepBackgroundColor??AppColor.white10,
unreachedBorderColor: widget.unreachedStepBorderColor??AppColor.neutral100,
unreachedTextColor: widget.unreachedStepTextColor??AppColor.neutral100,
unreachedIconColor: widget.unreachedStepIconColor??AppColor.neutral100,
padding: max(widget.internalPadding, 0),
stepRadius: widget.stepBorderRadius??10,
showStepBorder: widget.showStepBorder,
lineLength: lineStyle!.lineLength,
enabled: widget.steps[index].enabled??false,
);
}
// BorderType _handleBorderType(int index) {
// if (index == widget.activeStep) {
// //Active Step
// return widget.activeStepBorderType ?? widget.defaultStepBorderType;
// } else if (index > widget.activeStep) {
// //Unreached Step
// return widget.unreachedStepBorderType ?? widget.defaultStepBorderType;
// } else if (index < widget.activeStep) {
// //Finished Step
// return widget.finishedStepBorderType ?? widget.defaultStepBorderType;
// } else {
// return widget.defaultStepBorderType;
// }
// }
Color _getLineColor(int index) {
Color ?preferredColor;
if (index == widget.activeStep) {
//Active Step
preferredColor = lineStyle!.activeLineColor??AppColor.primary10;
} else if (index > widget.activeStep) {
//Unreached Step
preferredColor = lineStyle!.unreachedLineColor??AppColor.primary10;
} else if (index < widget.activeStep) {
//Finished Step
preferredColor = lineStyle!.finishedLineColor??AppColor.primary10;
}
return preferredColor ??
lineStyle!.defaultLineColor ??
Theme.of(context).colorScheme.primary;
}
Widget _buildLine(int index, Axis axis) {
return index < widget.steps.length - 1
? Column(
children: [
Padding(
padding: EdgeInsets.only(
top: axis == Axis.horizontal
? (widget.stepRadius - lineStyle!.lineThickness)
: 0,
),
child: _buildBaseLine(index, axis),
),
if (axis == Axis.horizontal) ...[
const SizedBox(height: 5),
SizedBox(
width: lineStyle!.lineLength,
child: widget.steps[index].customLineWidget ??
Text(
widget.steps[index].lineText??'',
maxLines: 3,
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.labelSmall,
),
),
],
],
)
: const Offstage();
}
EasyLine _buildBaseLine(int index, Axis axis) {
return EasyLine(
length: lineStyle!.lineLength,
color: _getLineColor(index),
thickness: lineStyle!.lineThickness,
spacing: lineStyle!.lineSpace,
width: lineStyle!.lineWidth,
axis: axis,
lineType:
index > widget.activeStep - 1 && lineStyle!.unreachedLineType != null
? lineStyle!.unreachedLineType
: lineStyle!.lineType,
);
}
}