Skip to content

Commit 5f03195

Browse files
mike doornenbalFreek van de Ven
authored andcommitted
feat: add option to always use dashedline
1 parent 634c710 commit 5f03195

5 files changed

Lines changed: 125 additions & 54 deletions

File tree

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
## [2.3.0]
2+
3+
- Added lastBuilder to the StepIndicatorTheme to allow for custom last step indicator.
4+
- Added useDashedLine to always use a dashed line for the stepper.
5+
- Added activeLineColor to the StepIndicatorTheme to allow for custom active line color.
6+
- Added hideStepWhenDone to the StepIndicatorTheme to scroll the stepper when the step is done.
7+
18
## [2.2.0] - 4 March 2024
29

310
- Added optional `lineHeight` to the `StepperTheme` to allow for custom line height.

lib/src/models/step_indicator_theme.dart

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import 'package:flutter/material.dart';
77
class StepIndicatorTheme {
88
const StepIndicatorTheme({
99
this.builder,
10+
this.lastBuilder,
1011
this.completedBackgroundColor,
1112
this.completedBorder,
1213
this.completedTextStyle,
@@ -22,6 +23,10 @@ class StepIndicatorTheme {
2223
/// and current index.
2324
final Widget Function(int stepIndex, int? currentIndex)? builder;
2425

26+
/// A function that defines custom widget builders based on the step index
27+
/// and current index for the last step.
28+
final Widget Function(int stepIndex, int? currentIndex)? lastBuilder;
29+
2530
/// The background color for active steps.
2631
final Color? activeBackgroundColor;
2732

lib/src/models/stepper_theme.dart

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ class StepperTheme {
2222
this.paddingTopForCenterContent = 10,
2323
this.useIndicator = false,
2424
this.lineHeight = 0,
25+
this.useDashedLine = false,
26+
this.activeLineColor,
27+
this.hideStepWhenDone = false,
2528
});
2629

2730
/// The padding between the start of the line and the stepper indicator.
@@ -66,4 +69,13 @@ class StepperTheme {
6669

6770
/// The height of the line between the steps when all steps are shown
6871
final double? lineHeight;
72+
73+
/// Always use a dashedline
74+
final bool useDashedLine;
75+
76+
/// The color of the line coming from the current step
77+
final Color? activeLineColor;
78+
79+
/// scroll the completed steps up
80+
final bool hideStepWhenDone;
6981
}

lib/src/stepper.dart

Lines changed: 100 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -106,27 +106,34 @@ class _StepContent extends StatelessWidget {
106106
required this.steps,
107107
required this.index,
108108
required this.showOnlyCurrentStep,
109+
required this.lineHeight,
110+
required this.currentStep,
109111
});
110112

111113
final StepperTheme stepperTheme;
112114
final List<MultiViewStep> steps;
113115
final bool showOnlyCurrentStep;
114116
final int index;
117+
final double lineHeight;
118+
final int currentStep;
115119

116120
@override
117121
Widget build(BuildContext context) {
118122
var step = steps[index];
123+
if (currentStep - 1 > index && stepperTheme.hideStepWhenDone) {
124+
return SizedBox(height: stepperTheme.linePadding);
125+
}
119126
return Column(
120127
crossAxisAlignment: CrossAxisAlignment.start,
121128
children: [
122129
SizedBox(height: stepperTheme.linePadding),
123130
if (showOnlyCurrentStep) ...[
124131
SizedBox(
125-
height: index == steps.length - 1 ? 0 : stepperTheme.emptyHeight,
132+
height: index == steps.length - 1 ? 0 : lineHeight,
126133
),
127134
] else if (step.hidden) ...[
128135
SizedBox(
129-
height: index == steps.length - 1 ? 0 : stepperTheme.emptyHeight,
136+
height: index == steps.length - 1 ? 0 : lineHeight,
130137
width: stepperTheme.emptyWidth,
131138
),
132139
] else if (step.size != null) ...[
@@ -228,68 +235,109 @@ class _SinglePageStepper extends StatelessWidget {
228235
Widget build(BuildContext context) {
229236
Widget expandIndicators(Widget child) =>
230237
!showOnlyCurrentStep ? Expanded(child: child) : child;
238+
Widget dashedLine(Color lineColor) => Expanded(
239+
child: CustomPaint(
240+
painter: VerticalDashedLinePainter(
241+
dashColor: lineColor,
242+
dashHeight: stepperTheme.lineDashLength,
243+
dashSpace: stepperTheme.lineDashGapLength,
244+
strokeWidth: stepperTheme.lineWidth,
245+
),
246+
),
247+
);
231248

249+
Widget solidLine(Color lineColor) => Expanded(
250+
child: Container(
251+
height: stepperTheme.lineHeight,
252+
width: stepperTheme.lineWidth,
253+
color: lineColor,
254+
),
255+
);
232256
return Row(
233257
crossAxisAlignment: CrossAxisAlignment.start,
234258
children: [
235259
expandIndicators(
236260
Column(
237261
children: List.generate(
238262
steps.length,
239-
(index) => IntrinsicHeight(
240-
child: Row(
241-
crossAxisAlignment: CrossAxisAlignment.stretch,
242-
children: [
243-
Padding(
244-
padding: linePadding,
245-
child: Column(
246-
children: [
247-
GestureDetector(
248-
onTap: () {},
249-
child: stepperTheme.stepIndicatorTheme.builder
250-
?.call(index, currentIndex) ??
251-
_StepIndicator(
252-
step: index,
253-
isZeroIndexed: isZeroIndexed,
254-
stepperTheme: stepperTheme,
255-
currentIndex: currentIndex,
256-
indicator: steps[index].indicator,
257-
),
258-
),
259-
if (index < currentIndex) ...[
260-
Expanded(
261-
child: Container(
262-
height: stepperTheme.lineHeight,
263-
width: stepperTheme.lineWidth,
264-
color: stepperTheme.lineColor,
265-
),
266-
),
267-
] else ...[
268-
Expanded(
269-
child: CustomPaint(
270-
painter: VerticalDashedLinePainter(
271-
dashColor: stepperTheme.lineColor,
272-
dashHeight: stepperTheme.lineDashLength,
273-
dashSpace: stepperTheme.lineDashGapLength,
274-
strokeWidth: stepperTheme.lineWidth,
275-
),
276-
),
263+
(index) {
264+
var lineColor = stepperTheme.activeLineColor != null
265+
? currentIndex == index
266+
? stepperTheme.activeLineColor!
267+
: stepperTheme.lineColor
268+
: stepperTheme.lineColor;
269+
Widget stepIndicator;
270+
stepIndicator = stepperTheme.stepIndicatorTheme.builder
271+
?.call(index, currentIndex) ??
272+
_StepIndicator(
273+
step: index,
274+
isZeroIndexed: isZeroIndexed,
275+
stepperTheme: stepperTheme,
276+
currentIndex: currentIndex,
277+
indicator: steps[index].indicator,
278+
);
279+
if (currentIndex > index && stepperTheme.hideStepWhenDone) {
280+
stepIndicator = const SizedBox.shrink();
281+
}
282+
283+
if (steps.length - 1 == index) {
284+
stepIndicator = stepperTheme.stepIndicatorTheme.lastBuilder
285+
?.call(index, currentIndex) ??
286+
_StepIndicator(
287+
step: index,
288+
isZeroIndexed: isZeroIndexed,
289+
stepperTheme: stepperTheme,
290+
currentIndex: currentIndex,
291+
indicator: steps[index].indicator,
292+
);
293+
}
294+
Widget line;
295+
296+
if (currentIndex < index) {
297+
line = stepperTheme.useDashedLine
298+
? dashedLine(lineColor)
299+
: solidLine(lineColor);
300+
} else {
301+
line = dashedLine(lineColor);
302+
}
303+
304+
if (currentIndex - 1 > index && stepperTheme.hideStepWhenDone) {
305+
line = const SizedBox.shrink();
306+
}
307+
308+
return IntrinsicHeight(
309+
child: Row(
310+
crossAxisAlignment: CrossAxisAlignment.stretch,
311+
children: [
312+
Padding(
313+
padding: linePadding,
314+
child: Column(
315+
children: [
316+
GestureDetector(
317+
onTap: () {},
318+
child: stepIndicator,
277319
),
320+
line,
278321
],
279-
],
322+
),
280323
),
281-
),
282-
expandIndicators(
283-
_StepContent(
284-
stepperTheme: stepperTheme,
285-
showOnlyCurrentStep: showOnlyCurrentStep,
286-
steps: steps,
287-
index: index,
324+
expandIndicators(
325+
_StepContent(
326+
stepperTheme: stepperTheme,
327+
showOnlyCurrentStep: showOnlyCurrentStep,
328+
steps: steps,
329+
index: index,
330+
currentStep: currentIndex,
331+
lineHeight: currentIndex > index &&
332+
stepperTheme.hideStepWhenDone
333+
? 40
334+
: stepperTheme.emptyHeight,
335+
),
288336
),
289-
),
290-
],
291-
),
292-
),
337+
],
338+
),
339+
);
340+
},
293341
),
294342
),
295343
),
@@ -344,7 +392,6 @@ class _StepIndicator extends StatelessWidget {
344392
color = indicatorTheme.inactiveBackgroundColor ?? color;
345393
textStyle = indicatorTheme.inactiveTextStyle ?? textStyle;
346394
}
347-
348395
var indicator = this.indicator ??
349396
Text(
350397
isZeroIndexed ? '$step' : '${step + 1}',

pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name: flutter_stepper
22
description: Flutter package to create a Stepper widget that can be used to display a sequence of steps with a line between each step.
3-
version: 2.2.0
3+
version: 2.3.0
44
homepage: https://github.com/Iconica-Development/stepper
55

66
environment:

0 commit comments

Comments
 (0)