Skip to content

Commit b3d2e78

Browse files
devversionjelbourn
authored andcommitted
feat(stepper): add proper type to stepper buttons (#9401)
* Automatically adds the proper button type for the StepperPrevious and StepperNext buttons.
1 parent 4ad7cc8 commit b3d2e78

File tree

4 files changed

+65
-22
lines changed

4 files changed

+65
-22
lines changed

src/cdk/stepper/stepper-button.ts

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,23 +6,35 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9-
import {Directive} from '@angular/core';
9+
import {Directive, Input} from '@angular/core';
1010
import {CdkStepper} from './stepper';
1111

1212
/** Button that moves to the next step in a stepper workflow. */
1313
@Directive({
1414
selector: 'button[cdkStepperNext]',
15-
host: {'(click)': '_stepper.next()'}
15+
host: {
16+
'(click)': '_stepper.next()',
17+
'[type]': 'type',
18+
}
1619
})
1720
export class CdkStepperNext {
18-
constructor(public _stepper: CdkStepper) { }
21+
/** Type of the next button. Defaults to "submit" if not specified. */
22+
@Input() type: string = 'submit';
23+
24+
constructor(public _stepper: CdkStepper) {}
1925
}
2026

2127
/** Button that moves to the previous step in a stepper workflow. */
2228
@Directive({
2329
selector: 'button[cdkStepperPrevious]',
24-
host: {'(click)': '_stepper.previous()'}
30+
host: {
31+
'(click)': '_stepper.previous()',
32+
'[type]': 'type',
33+
}
2534
})
2635
export class CdkStepperPrevious {
27-
constructor(public _stepper: CdkStepper) { }
36+
/** Type of the previous button. Defaults to "button" if not specified. */
37+
@Input() type: string = 'button';
38+
39+
constructor(public _stepper: CdkStepper) {}
2840
}

src/demo-app/stepper/stepper-demo.html

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ <h3>Linear Vertical Stepper Demo using a single form</h3>
1515
<mat-error>This field is required</mat-error>
1616
</mat-form-field>
1717
<div>
18-
<button mat-button matStepperNext type="button">Next</button>
18+
<button mat-button matStepperNext>Next</button>
1919
</div>
2020
</mat-step>
2121

@@ -28,8 +28,8 @@ <h3>Linear Vertical Stepper Demo using a single form</h3>
2828
<mat-error>The input is invalid.</mat-error>
2929
</mat-form-field>
3030
<div>
31-
<button mat-button matStepperPrevious type="button">Back</button>
32-
<button mat-button matStepperNext type="button">Next</button>
31+
<button mat-button matStepperPrevious>Back</button>
32+
<button mat-button matStepperNext>Next</button>
3333
</div>
3434
</mat-step>
3535

@@ -102,7 +102,7 @@ <h3>Vertical Stepper Demo</h3>
102102
<input matInput placeholder="Last Name">
103103
</mat-form-field>
104104
<div>
105-
<button mat-button matStepperNext type="button">Next</button>
105+
<button mat-button matStepperNext>Next</button>
106106
</div>
107107
</mat-step>
108108

@@ -114,8 +114,8 @@ <h3>Vertical Stepper Demo</h3>
114114
<input matInput placeholder="Phone number">
115115
</mat-form-field>
116116
<div>
117-
<button mat-button matStepperPrevious type="button">Back</button>
118-
<button mat-button matStepperNext type="button">Next</button>
117+
<button mat-button matStepperPrevious>Back</button>
118+
<button mat-button matStepperNext>Next</button>
119119
</div>
120120
</mat-step>
121121

@@ -127,8 +127,8 @@ <h3>Vertical Stepper Demo</h3>
127127
<input matInput placeholder="Address">
128128
</mat-form-field>
129129
<div>
130-
<button mat-button matStepperPrevious type="button">Back</button>
131-
<button mat-button matStepperNext type="button">Next</button>
130+
<button mat-button matStepperPrevious>Back</button>
131+
<button mat-button matStepperNext>Next</button>
132132
</div>
133133
</mat-step>
134134

@@ -152,7 +152,7 @@ <h3>Horizontal Stepper Demo with Text Label</h3>
152152
<input matInput placeholder="Last Name">
153153
</mat-form-field>
154154
<div>
155-
<button mat-button matStepperNext type="button">Next</button>
155+
<button mat-button matStepperNext>Next</button>
156156
</div>
157157
</mat-step>
158158

@@ -161,8 +161,8 @@ <h3>Horizontal Stepper Demo with Text Label</h3>
161161
<input matInput placeholder="Phone number">
162162
</mat-form-field>
163163
<div>
164-
<button mat-button matStepperPrevious type="button">Back</button>
165-
<button mat-button matStepperNext type="button">Next</button>
164+
<button mat-button matStepperPrevious>Back</button>
165+
<button mat-button matStepperNext>Next</button>
166166
</div>
167167
</mat-step>
168168

@@ -171,8 +171,8 @@ <h3>Horizontal Stepper Demo with Text Label</h3>
171171
<input matInput placeholder="Address">
172172
</mat-form-field>
173173
<div>
174-
<button mat-button matStepperPrevious type="button">Back</button>
175-
<button mat-button matStepperNext type="button">Next</button>
174+
<button mat-button matStepperPrevious>Back</button>
175+
<button mat-button matStepperNext>Next</button>
176176
</div>
177177
</mat-step>
178178

src/lib/stepper/stepper-button.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,23 @@ import {MatStepper} from './stepper';
1313
/** Button that moves to the next step in a stepper workflow. */
1414
@Directive({
1515
selector: 'button[matStepperNext]',
16-
host: {'(click)': '_stepper.next()'},
16+
host: {
17+
'(click)': '_stepper.next()',
18+
'[type]': 'type',
19+
},
20+
inputs: ['type'],
1721
providers: [{provide: CdkStepper, useExisting: MatStepper}]
1822
})
19-
export class MatStepperNext extends CdkStepperNext { }
23+
export class MatStepperNext extends CdkStepperNext {}
2024

2125
/** Button that moves to the previous step in a stepper workflow. */
2226
@Directive({
2327
selector: 'button[matStepperPrevious]',
24-
host: {'(click)': '_stepper.previous()'},
28+
host: {
29+
'(click)': '_stepper.previous()',
30+
'[type]': 'type',
31+
},
32+
inputs: ['type'],
2533
providers: [{provide: CdkStepper, useExisting: MatStepper}]
2634
})
27-
export class MatStepperPrevious extends CdkStepperPrevious { }
35+
export class MatStepperPrevious extends CdkStepperPrevious {}

src/lib/stepper/stepper.spec.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,18 @@ describe('MatHorizontalStepper', () => {
8282
assertNextStepperButtonClick(fixture);
8383
});
8484

85+
it('should set the next stepper button type to "submit"', () => {
86+
assertStepperButtonType(fixture, MatStepperNext, 'submit');
87+
});
88+
8589
it('should go to previous available step when the previous button is clicked', () => {
8690
assertPreviousStepperButtonClick(fixture);
8791
});
8892

93+
it('should set the previous stepper button type to "button"', () => {
94+
assertStepperButtonType(fixture, MatStepperPrevious, 'button');
95+
});
96+
8997
it('should set the correct step position for animation', () => {
9098
assertCorrectStepAnimationDirection(fixture);
9199
});
@@ -318,10 +326,18 @@ describe('MatVerticalStepper', () => {
318326
assertNextStepperButtonClick(fixture);
319327
});
320328

329+
it('should set the next stepper button type to "submit"', () => {
330+
assertStepperButtonType(fixture, MatStepperNext, 'submit');
331+
});
332+
321333
it('should go to previous available step when the previous button is clicked', () => {
322334
assertPreviousStepperButtonClick(fixture);
323335
});
324336

337+
it('should set the previous stepper button type to "button"', () => {
338+
assertStepperButtonType(fixture, MatStepperPrevious, 'button');
339+
});
340+
325341
it('should set the correct step position for animation', () => {
326342
assertCorrectStepAnimationDirection(fixture);
327343
});
@@ -511,6 +527,13 @@ function assertNextStepperButtonClick(fixture: ComponentFixture<any>) {
511527
expect(stepperComponent.selectedIndex).toBe(2);
512528
}
513529

530+
/** Asserts that the specified type of stepper button has the given type. */
531+
function assertStepperButtonType(fixture: ComponentFixture<any>, stepperClass: any, type: string) {
532+
const buttonElement = fixture.debugElement.query(By.directive(stepperClass)).nativeElement;
533+
534+
expect(buttonElement.type).toBe(type, `Expected the button to have "${type}" set as type.`);
535+
}
536+
514537
/** Asserts that clicking on MatStepperPrevious button updates `selectedIndex` correctly. */
515538
function assertPreviousStepperButtonClick(fixture: ComponentFixture<any>) {
516539
let stepperComponent = fixture.debugElement.query(By.directive(MatStepper)).componentInstance;

0 commit comments

Comments
 (0)