Skip to content

Commit 9710a77

Browse files
committed
refactor(stepper): modify the linear disabled steps calculation and add comments
1 parent b7e414b commit 9710a77

File tree

3 files changed

+67
-43
lines changed

3 files changed

+67
-43
lines changed

projects/igniteui-angular/src/lib/stepper/step/step.component.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ let NEXT_ID = 0;
1919
* The IgxStepComponent is used within the `igx-stepper` element and it holds the content of each step.
2020
* It also supports custom indicators, title and subtitle.
2121
*
22+
* @igxModule IgxStepperModule
23+
*
2224
* @igxKeywords step
2325
*
2426
* @example

projects/igniteui-angular/src/lib/stepper/stepper.component.ts

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -166,13 +166,9 @@ export class IgxStepperComponent extends IgxCarouselComponentBase implements Igx
166166
public set linear(value: boolean) {
167167
this._linear = value;
168168
if (this._linear) {
169-
this.steps.forEach(step => {
170-
if (step.index <= this.stepperService.activeStep.index) {
171-
this.stepperService.visitedSteps.add(step);
172-
} else {
173-
this.stepperService.visitedSteps.delete(step);
174-
}
175-
});
169+
// when the stepper is in linear mode we should calculate which steps should be disabled
170+
// and which are visited i.e. their validity should be correctly displayed.
171+
this.stepperService.calculateVisitedSteps();
176172
this.stepperService.calculateLinearDisabledSteps();
177173
} else {
178174
this.stepperService.linearDisabledSteps.clear();

projects/igniteui-angular/src/lib/stepper/stepper.service.ts

Lines changed: 62 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import { IgxStepComponent } from './step/step.component';
55
/** @hidden @internal */
66
@Injectable()
77
export class IgxStepperService {
8-
98
public activeStep: IgxStepComponent;
109
public previousActiveStep: IgxStepComponent;
1110
public focusedStep: IgxStepComponent;
@@ -20,46 +19,45 @@ export class IgxStepperService {
2019
}
2120

2221
/**
23-
* Adds the step to the `expandedSteps` set and fires the steps change event
24-
*
25-
* @param step target step
26-
* @param uiTrigger is the event triggered by a ui interraction (so we know if we should animate)
27-
* @returns void
22+
* Activates the step, fires the steps change event and plays animations.
2823
*/
2924
public expand(step: IgxStepComponent): void {
3025
if (this.activeStep === step) {
3126
return;
3227
}
3328

34-
const argsCanceled = this.emitActivatingEvent(step);
35-
36-
if (!argsCanceled) {
37-
this.collapsingSteps.delete(step);
29+
const cancel = this.emitActivatingEvent(step);
30+
if (cancel) {
31+
return;
32+
}
3833

39-
this.previousActiveStep = this.activeStep;
40-
this.activeStep = step;
41-
this.activeStep.activeChange.emit(true);
34+
this.collapsingSteps.delete(step);
4235

43-
this.collapsingSteps.add(this.previousActiveStep);
44-
this.visitedSteps.add(this.activeStep);
36+
this.previousActiveStep = this.activeStep;
37+
this.activeStep = step;
38+
this.activeStep.activeChange.emit(true);
4539

46-
if (this.stepper.orientation === IgxStepperOrienatation.Vertical) {
47-
this.previousActiveStep.playCloseAnimation(
48-
this.previousActiveStep.contentContainer
49-
);
50-
this.activeStep.cdr.detectChanges();
40+
this.collapsingSteps.add(this.previousActiveStep);
41+
this.visitedSteps.add(this.activeStep);
5142

52-
this.activeStep.playOpenAnimation(
53-
this.activeStep.contentContainer
54-
);
55-
} else {
56-
this.activeStep.cdr.detectChanges();
57-
this.stepper.playHorizontalAnimations();
58-
}
43+
if (this.stepper.orientation === IgxStepperOrienatation.Vertical) {
44+
this.previousActiveStep.playCloseAnimation(
45+
this.previousActiveStep.contentContainer
46+
);
47+
this.activeStep.cdr.detectChanges();
5948

49+
this.activeStep.playOpenAnimation(
50+
this.activeStep.contentContainer
51+
);
52+
} else {
53+
this.activeStep.cdr.detectChanges();
54+
this.stepper.playHorizontalAnimations();
6055
}
6156
}
6257

58+
/**
59+
* Activates the step and fires the steps change event without playing animations.
60+
*/
6361
public expandThroughApi(step: IgxStepComponent): void {
6462
if (this.activeStep === step) {
6563
return;
@@ -83,6 +81,9 @@ export class IgxStepperService {
8381
this.previousActiveStep?.activeChange.emit(false);
8482
}
8583

84+
/**
85+
* Collapses the currently active step and fires the change event.
86+
*/
8687
public collapse(step: IgxStepComponent): void {
8788
if (this.activeStep === step) {
8889
return;
@@ -91,19 +92,27 @@ export class IgxStepperService {
9192
this.collapsingSteps.delete(step);
9293
}
9394

95+
/**
96+
* Determines the steps that should be marked as visited based on the active step.
97+
*/
98+
public calculateVisitedSteps(): void {
99+
this.stepper.steps.forEach(step => {
100+
if (step.index <= this.activeStep.index) {
101+
this.visitedSteps.add(step);
102+
} else {
103+
this.visitedSteps.delete(step);
104+
}
105+
});
106+
}
107+
108+
/**
109+
* Determines the steps that should be disabled in linear mode based on the validity of the active step.
110+
*/
94111
public calculateLinearDisabledSteps(): void {
95112
if (this.activeStep.isValid) {
96113
const firstRequiredIndex = this.getNextRequiredStep();
97114
if (firstRequiredIndex !== -1) {
98-
this.stepper.steps.forEach(s => {
99-
if (s.index > this.activeStep.index) {
100-
if (s.index <= firstRequiredIndex) {
101-
this.linearDisabledSteps.delete(s);
102-
} else {
103-
this.linearDisabledSteps.add(s);
104-
}
105-
}
106-
});
115+
this.updateLinearDisabledSteps(firstRequiredIndex);
107116
} else {
108117
this.linearDisabledSteps.clear();
109118
}
@@ -128,6 +137,23 @@ export class IgxStepperService {
128137
return args.cancel;
129138
}
130139

140+
/**
141+
* Updates the linearDisabled steps from the current active step to the next required invalid step.
142+
*
143+
* @param toIndex the index of the last step that should be enabled.
144+
*/
145+
private updateLinearDisabledSteps(toIndex: number): void {
146+
this.stepper.steps.forEach(s => {
147+
if (s.index > this.activeStep.index) {
148+
if (s.index <= toIndex) {
149+
this.linearDisabledSteps.delete(s);
150+
} else {
151+
this.linearDisabledSteps.add(s);
152+
}
153+
}
154+
});
155+
}
156+
131157
private getNextRequiredStep(): number {
132158
return this.stepper.steps.findIndex(s => s.index > this.activeStep.index && !s.optional && !s.disabled && !s.isValid);
133159
}

0 commit comments

Comments
 (0)