Skip to content

Commit c31c7fe

Browse files
committed
fix(cdk/stepper): emitting interacted event when item has not changed (#30579)
Fixes that the stepper was marking an item as interacted and emitting an event whenever the `selectedIndex` is assigned, even if it's the same. Fixes #30540. (cherry picked from commit 4f3c931)
1 parent 6a087fd commit c31c7fe

File tree

2 files changed

+35
-10
lines changed

2 files changed

+35
-10
lines changed

src/cdk/stepper/stepper.ts

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -284,20 +284,21 @@ export class CdkStepper implements AfterContentInit, AfterViewInit, OnDestroy {
284284
return this._selectedIndex;
285285
}
286286
set selectedIndex(index: number) {
287-
if (this.steps && this._steps) {
287+
if (this._steps) {
288288
// Ensure that the index can't be out of bounds.
289289
if (!this._isValidIndex(index) && (typeof ngDevMode === 'undefined' || ngDevMode)) {
290290
throw Error('cdkStepper: Cannot assign out-of-bounds value to `selectedIndex`.');
291291
}
292292

293-
this.selected?._markAsInteracted();
293+
if (this._selectedIndex !== index) {
294+
this.selected?._markAsInteracted();
294295

295-
if (
296-
this._selectedIndex !== index &&
297-
!this._anyControlsInvalidOrPending(index) &&
298-
(index >= this._selectedIndex || this.steps.toArray()[index].editable)
299-
) {
300-
this._updateSelectedItemIndex(index);
296+
if (
297+
!this._anyControlsInvalidOrPending(index) &&
298+
(index >= this._selectedIndex || this.steps.toArray()[index].editable)
299+
) {
300+
this._updateSelectedItemIndex(index);
301+
}
301302
}
302303
} else {
303304
this._selectedIndex = index;

src/material/stepper/stepper.spec.ts

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1213,7 +1213,7 @@ describe('MatStepper', () => {
12131213
fixture.detectChanges();
12141214
expect(stepper.steps.map(step => step.interacted)).toEqual([true, true, false]);
12151215

1216-
stepper.next();
1216+
stepper.previous();
12171217
fixture.detectChanges();
12181218
expect(stepper.steps.map(step => step.interacted)).toEqual([true, true, true]);
12191219
});
@@ -1240,12 +1240,36 @@ describe('MatStepper', () => {
12401240
fixture.detectChanges();
12411241
expect(interactedSteps).toEqual([0, 1]);
12421242

1243-
stepper.next();
1243+
stepper.previous();
12441244
fixture.detectChanges();
12451245
expect(interactedSteps).toEqual([0, 1, 2]);
12461246
subscription.unsubscribe();
12471247
});
12481248

1249+
it('should not emit interacted event if selectedIndex does not change', () => {
1250+
const fixture = createComponent(SimpleMatHorizontalStepperApp);
1251+
fixture.detectChanges();
1252+
1253+
const stepper: MatStepper = fixture.debugElement.query(
1254+
By.directive(MatStepper),
1255+
).componentInstance;
1256+
const interactedSteps: number[] = [];
1257+
const subscription = merge(...stepper.steps.map(step => step.interactedStream)).subscribe(
1258+
step => interactedSteps.push(stepper.steps.toArray().indexOf(step as MatStep)),
1259+
);
1260+
1261+
expect(interactedSteps).toEqual([]);
1262+
1263+
stepper.next();
1264+
fixture.detectChanges();
1265+
expect(interactedSteps).toEqual([0]);
1266+
1267+
stepper.selectedIndex = 1;
1268+
fixture.detectChanges();
1269+
expect(interactedSteps).toEqual([0]);
1270+
subscription.unsubscribe();
1271+
});
1272+
12491273
it('should set a class on the host if the header is positioned at the bottom', () => {
12501274
const fixture = createComponent(SimpleMatHorizontalStepperApp);
12511275
fixture.detectChanges();

0 commit comments

Comments
 (0)