Skip to content

Commit a6cc98f

Browse files
devversionmmalerba
authored andcommitted
feat(stepper): allow disabling ripples of headers (#14972)
* Adds a way for developers to disable ripples of the `MatStepHeader`. This is useful because currently developers have no way of specifically disabling ripples for a stepper (only disabling globally is possible) Closes #14940.
1 parent cd72c9d commit a6cc98f

File tree

10 files changed

+63
-10
lines changed

10 files changed

+63
-10
lines changed

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
<mat-checkbox [(ngModel)]="isNonLinear">Disable linear mode</mat-checkbox>
2+
<mat-checkbox [(ngModel)]="disableRipple">Disable header ripple</mat-checkbox>
23

34
<h3>Linear Vertical Stepper Demo using a single form</h3>
45
<form [formGroup]="formGroup">
5-
<mat-vertical-stepper #linearVerticalStepper="matVerticalStepper" formArrayName="formArray" [linear]="!isNonLinear">
6+
<mat-vertical-stepper #linearVerticalStepper="matVerticalStepper" formArrayName="formArray"
7+
[linear]="!isNonLinear" [disableRipple]="disableRipple">
68
<mat-step formGroupName="0" [stepControl]="formArray?.get([0])">
79
<ng-template matStepLabel>Fill out your name</ng-template>
810
<mat-form-field>
@@ -48,7 +50,8 @@ <h3>Linear Vertical Stepper Demo using a single form</h3>
4850
</form>
4951

5052
<h3>Linear Horizontal Stepper Demo using a different form for each step</h3>
51-
<mat-horizontal-stepper #linearHorizontalStepper="matHorizontalStepper" [linear]="!isNonLinear">
53+
<mat-horizontal-stepper #linearHorizontalStepper="matHorizontalStepper" [linear]="!isNonLinear"
54+
[disableRipple]="disableRipple">
5255
<mat-step [stepControl]="nameFormGroup">
5356
<form [formGroup]="nameFormGroup">
5457
<ng-template matStepLabel>Fill out your name</ng-template>

src/dev-app/stepper/stepper-demo.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export class StepperDemo implements OnInit {
1919
formGroup: FormGroup;
2020
isNonLinear = false;
2121
isNonEditable = false;
22+
disableRipple = false;
2223

2324
nameFormGroup: FormGroup;
2425
emailFormGroup: FormGroup;

src/lib/stepper/BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ ng_test_library(
6262
"//src/cdk/testing",
6363
"//src/lib/form-field",
6464
"//src/lib/input",
65+
"//src/lib/core",
6566
":stepper",
6667
]
6768
)

src/lib/stepper/step-header.html

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
<div class="mat-step-header-ripple" mat-ripple [matRippleTrigger]="_getHostElement()"></div>
1+
<div class="mat-step-header-ripple" matRipple
2+
[matRippleTrigger]="_getHostElement()"
3+
[matRippleDisabled]="disableRipple"></div>
4+
25
<div class="mat-step-icon-state-{{state}} mat-step-icon" [class.mat-step-icon-selected]="selected">
36
<div class="mat-step-icon-content" [ngSwitch]="!!(iconOverrides && iconOverrides[state])">
47
<ng-container

src/lib/stepper/step-header.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ export class MatStepHeader extends CdkStepHeader implements OnDestroy {
6363
/** Whether the given step is optional. */
6464
@Input() optional: boolean;
6565

66+
/** Whether the ripple should be disabled. */
67+
@Input() disableRipple: boolean;
68+
6669
constructor(
6770
public _intl: MatStepperIntl,
6871
private _focusMonitor: FocusMonitor,

src/lib/stepper/stepper-horizontal.html

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<div class="mat-horizontal-stepper-header-container">
22
<ng-container *ngFor="let step of steps; let i = index; let isLast = last">
3-
<mat-step-header class="mat-horizontal-stepper-header"
3+
<mat-step-header class="mat-horizontal-stepper-header"
44
(click)="step.select()"
55
(keydown)="_onKeydown($event)"
66
[tabIndex]="_getFocusIndex() === i ? 0 : -1"
@@ -18,7 +18,8 @@
1818
[active]="step.completed || selectedIndex === i || !linear"
1919
[optional]="step.optional"
2020
[errorMessage]="step.errorMessage"
21-
[iconOverrides]="_iconOverrides">
21+
[iconOverrides]="_iconOverrides"
22+
[disableRipple]="disableRipple">
2223
</mat-step-header>
2324
<div *ngIf="!isLast" class="mat-stepper-horizontal-line"></div>
2425
</ng-container>

src/lib/stepper/stepper-vertical.html

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<div class="mat-step" *ngFor="let step of steps; let i = index; let isLast = last">
2-
<mat-step-header class="mat-vertical-stepper-header"
2+
<mat-step-header class="mat-vertical-stepper-header"
33
(click)="step.select()"
44
(keydown)="_onKeydown($event)"
55
[tabIndex]="_getFocusIndex() == i ? 0 : -1"
@@ -17,7 +17,8 @@
1717
[active]="step.completed || selectedIndex === i || !linear"
1818
[optional]="step.optional"
1919
[errorMessage]="step.errorMessage"
20-
[iconOverrides]="_iconOverrides">
20+
[iconOverrides]="_iconOverrides"
21+
[disableRipple]="disableRipple">
2122
</mat-step-header>
2223

2324
<div class="mat-vertical-content-container" [class.mat-stepper-vertical-line]="!isLast">

src/lib/stepper/stepper.spec.ts

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,12 @@ import {
2828
Validators,
2929
FormBuilder
3030
} from '@angular/forms';
31+
import {MatRipple} from '@angular/material/core';
3132
import {By} from '@angular/platform-browser';
3233
import {NoopAnimationsModule} from '@angular/platform-browser/animations';
3334
import {Observable, Subject} from 'rxjs';
3435
import {map, take} from 'rxjs/operators';
35-
import {MatStepperModule} from './index';
36+
import {MatStepHeader, MatStepperModule} from './index';
3637
import {MatHorizontalStepper, MatStep, MatStepper, MatVerticalStepper} from './stepper';
3738
import {MatStepperNext, MatStepperPrevious} from './stepper-button';
3839
import {MatStepperIntl} from './stepper-intl';
@@ -795,6 +796,22 @@ describe('MatStepper', () => {
795796
let stepHeaders = fixture.debugElement.queryAll(By.css('.mat-vertical-stepper-header'));
796797
assertArrowKeyInteractionInRtl(fixture, stepHeaders);
797798
});
799+
800+
it('should be able to disable ripples', () => {
801+
const fixture = createComponent(SimpleMatVerticalStepperApp);
802+
fixture.detectChanges();
803+
804+
const stepHeaders = fixture.debugElement.queryAll(By.directive(MatStepHeader));
805+
const headerRipples = stepHeaders.map(headerDebugEl =>
806+
headerDebugEl.query(By.directive(MatRipple)).injector.get(MatRipple));
807+
808+
expect(headerRipples.every(ripple => ripple.disabled)).toBe(false);
809+
810+
fixture.componentInstance.disableRipple = true;
811+
fixture.detectChanges();
812+
813+
expect(headerRipples.every(ripple => ripple.disabled)).toBe(true);
814+
});
798815
});
799816

800817
describe('horizontal stepper', () => {
@@ -836,6 +853,22 @@ describe('MatStepper', () => {
836853

837854
assertArrowKeyInteractionInRtl(fixture, stepHeaders);
838855
});
856+
857+
it('should be able to disable ripples', () => {
858+
const fixture = createComponent(SimpleMatHorizontalStepperApp);
859+
fixture.detectChanges();
860+
861+
const stepHeaders = fixture.debugElement.queryAll(By.directive(MatStepHeader));
862+
const headerRipples = stepHeaders.map(headerDebugEl =>
863+
headerDebugEl.query(By.directive(MatRipple)).injector.get(MatRipple));
864+
865+
expect(headerRipples.every(ripple => ripple.disabled)).toBe(false);
866+
867+
fixture.componentInstance.disableRipple = true;
868+
fixture.detectChanges();
869+
870+
expect(headerRipples.every(ripple => ripple.disabled)).toBe(true);
871+
});
839872
});
840873

841874
describe('linear stepper with valid step', () => {
@@ -1200,7 +1233,7 @@ class MatHorizontalStepperWithErrorsApp implements OnInit {
12001233

12011234
@Component({
12021235
template: `
1203-
<mat-horizontal-stepper>
1236+
<mat-horizontal-stepper [disableRipple]="disableRipple">
12041237
<mat-step>
12051238
<ng-template matStepLabel>Step 1</ng-template>
12061239
Content 1
@@ -1229,11 +1262,12 @@ class MatHorizontalStepperWithErrorsApp implements OnInit {
12291262
})
12301263
class SimpleMatHorizontalStepperApp {
12311264
inputLabel = 'Step 3';
1265+
disableRipple = false;
12321266
}
12331267

12341268
@Component({
12351269
template: `
1236-
<mat-vertical-stepper>
1270+
<mat-vertical-stepper [disableRipple]="disableRipple">
12371271
<mat-step>
12381272
<ng-template matStepLabel>Step 1</ng-template>
12391273
Content 1
@@ -1263,6 +1297,7 @@ class SimpleMatHorizontalStepperApp {
12631297
class SimpleMatVerticalStepperApp {
12641298
inputLabel = 'Step 3';
12651299
showStepTwo = true;
1300+
disableRipple = false;
12661301
}
12671302

12681303
@Component({

src/lib/stepper/stepper.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,9 @@ export class MatStepper extends CdkStepper implements AfterContentInit {
9797
/** Event emitted when the current step is done transitioning in. */
9898
@Output() readonly animationDone: EventEmitter<void> = new EventEmitter<void>();
9999

100+
/** Whether ripples should be disabled for the step headers. */
101+
@Input() disableRipple: boolean;
102+
100103
/** Consumer-specified template-refs to be used to override the header icons. */
101104
_iconOverrides: {[key: string]: TemplateRef<MatStepperIconContext>} = {};
102105

tools/public_api_guard/lib/stepper.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export declare class MatStep extends CdkStep implements ErrorStateMatcher {
1919
export declare class MatStepHeader extends CdkStepHeader implements OnDestroy {
2020
_intl: MatStepperIntl;
2121
active: boolean;
22+
disableRipple: boolean;
2223
errorMessage: string;
2324
iconOverrides: {
2425
[key: string]: TemplateRef<MatStepperIconContext>;
@@ -49,6 +50,7 @@ export declare class MatStepper extends CdkStepper implements AfterContentInit {
4950
_stepHeader: QueryList<MatStepHeader>;
5051
_steps: QueryList<MatStep>;
5152
readonly animationDone: EventEmitter<void>;
53+
disableRipple: boolean;
5254
ngAfterContentInit(): void;
5355
}
5456

0 commit comments

Comments
 (0)