Skip to content

feat(stepper): allow disabling ripples of headers #14972

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions src/dev-app/stepper/stepper-demo.html
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
<mat-checkbox [(ngModel)]="isNonLinear">Disable linear mode</mat-checkbox>
<mat-checkbox [(ngModel)]="disableRipple">Disable header ripple</mat-checkbox>

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

<h3>Linear Horizontal Stepper Demo using a different form for each step</h3>
<mat-horizontal-stepper #linearHorizontalStepper="matHorizontalStepper" [linear]="!isNonLinear">
<mat-horizontal-stepper #linearHorizontalStepper="matHorizontalStepper" [linear]="!isNonLinear"
[disableRipple]="disableRipple">
<mat-step [stepControl]="nameFormGroup">
<form [formGroup]="nameFormGroup">
<ng-template matStepLabel>Fill out your name</ng-template>
Expand Down
1 change: 1 addition & 0 deletions src/dev-app/stepper/stepper-demo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export class StepperDemo implements OnInit {
formGroup: FormGroup;
isNonLinear = false;
isNonEditable = false;
disableRipple = false;

nameFormGroup: FormGroup;
emailFormGroup: FormGroup;
Expand Down
1 change: 1 addition & 0 deletions src/lib/stepper/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ ng_test_library(
"//src/cdk/testing",
"//src/lib/form-field",
"//src/lib/input",
"//src/lib/core",
":stepper",
]
)
Expand Down
5 changes: 4 additions & 1 deletion src/lib/stepper/step-header.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
<div class="mat-step-header-ripple" mat-ripple [matRippleTrigger]="_getHostElement()"></div>
<div class="mat-step-header-ripple" matRipple
[matRippleTrigger]="_getHostElement()"
[matRippleDisabled]="disableRipple"></div>

<div class="mat-step-icon-state-{{state}} mat-step-icon" [class.mat-step-icon-selected]="selected">
<div class="mat-step-icon-content" [ngSwitch]="!!(iconOverrides && iconOverrides[state])">
<ng-container
Expand Down
3 changes: 3 additions & 0 deletions src/lib/stepper/step-header.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ export class MatStepHeader extends CdkStepHeader implements OnDestroy {
/** Whether the given step is optional. */
@Input() optional: boolean;

/** Whether the ripple should be disabled. */
@Input() disableRipple: boolean;

constructor(
public _intl: MatStepperIntl,
private _focusMonitor: FocusMonitor,
Expand Down
5 changes: 3 additions & 2 deletions src/lib/stepper/stepper-horizontal.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<div class="mat-horizontal-stepper-header-container">
<ng-container *ngFor="let step of steps; let i = index; let isLast = last">
<mat-step-header class="mat-horizontal-stepper-header"
<mat-step-header class="mat-horizontal-stepper-header"
(click)="step.select()"
(keydown)="_onKeydown($event)"
[tabIndex]="_getFocusIndex() === i ? 0 : -1"
Expand All @@ -18,7 +18,8 @@
[active]="step.completed || selectedIndex === i || !linear"
[optional]="step.optional"
[errorMessage]="step.errorMessage"
[iconOverrides]="_iconOverrides">
[iconOverrides]="_iconOverrides"
[disableRipple]="disableRipple">
</mat-step-header>
<div *ngIf="!isLast" class="mat-stepper-horizontal-line"></div>
</ng-container>
Expand Down
5 changes: 3 additions & 2 deletions src/lib/stepper/stepper-vertical.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<div class="mat-step" *ngFor="let step of steps; let i = index; let isLast = last">
<mat-step-header class="mat-vertical-stepper-header"
<mat-step-header class="mat-vertical-stepper-header"
(click)="step.select()"
(keydown)="_onKeydown($event)"
[tabIndex]="_getFocusIndex() == i ? 0 : -1"
Expand All @@ -17,7 +17,8 @@
[active]="step.completed || selectedIndex === i || !linear"
[optional]="step.optional"
[errorMessage]="step.errorMessage"
[iconOverrides]="_iconOverrides">
[iconOverrides]="_iconOverrides"
[disableRipple]="disableRipple">
</mat-step-header>

<div class="mat-vertical-content-container" [class.mat-stepper-vertical-line]="!isLast">
Expand Down
41 changes: 38 additions & 3 deletions src/lib/stepper/stepper.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,12 @@ import {
Validators,
FormBuilder
} from '@angular/forms';
import {MatRipple} from '@angular/material/core';
import {By} from '@angular/platform-browser';
import {NoopAnimationsModule} from '@angular/platform-browser/animations';
import {Observable, Subject} from 'rxjs';
import {map, take} from 'rxjs/operators';
import {MatStepperModule} from './index';
import {MatStepHeader, MatStepperModule} from './index';
import {MatHorizontalStepper, MatStep, MatStepper, MatVerticalStepper} from './stepper';
import {MatStepperNext, MatStepperPrevious} from './stepper-button';
import {MatStepperIntl} from './stepper-intl';
Expand Down Expand Up @@ -795,6 +796,22 @@ describe('MatStepper', () => {
let stepHeaders = fixture.debugElement.queryAll(By.css('.mat-vertical-stepper-header'));
assertArrowKeyInteractionInRtl(fixture, stepHeaders);
});

it('should be able to disable ripples', () => {
const fixture = createComponent(SimpleMatVerticalStepperApp);
fixture.detectChanges();

const stepHeaders = fixture.debugElement.queryAll(By.directive(MatStepHeader));
const headerRipples = stepHeaders.map(headerDebugEl =>
headerDebugEl.query(By.directive(MatRipple)).injector.get(MatRipple));

expect(headerRipples.every(ripple => ripple.disabled)).toBe(false);

fixture.componentInstance.disableRipple = true;
fixture.detectChanges();

expect(headerRipples.every(ripple => ripple.disabled)).toBe(true);
});
});

describe('horizontal stepper', () => {
Expand Down Expand Up @@ -836,6 +853,22 @@ describe('MatStepper', () => {

assertArrowKeyInteractionInRtl(fixture, stepHeaders);
});

it('should be able to disable ripples', () => {
const fixture = createComponent(SimpleMatHorizontalStepperApp);
fixture.detectChanges();

const stepHeaders = fixture.debugElement.queryAll(By.directive(MatStepHeader));
const headerRipples = stepHeaders.map(headerDebugEl =>
headerDebugEl.query(By.directive(MatRipple)).injector.get(MatRipple));

expect(headerRipples.every(ripple => ripple.disabled)).toBe(false);

fixture.componentInstance.disableRipple = true;
fixture.detectChanges();

expect(headerRipples.every(ripple => ripple.disabled)).toBe(true);
});
});

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

@Component({
template: `
<mat-horizontal-stepper>
<mat-horizontal-stepper [disableRipple]="disableRipple">
<mat-step>
<ng-template matStepLabel>Step 1</ng-template>
Content 1
Expand Down Expand Up @@ -1229,11 +1262,12 @@ class MatHorizontalStepperWithErrorsApp implements OnInit {
})
class SimpleMatHorizontalStepperApp {
inputLabel = 'Step 3';
disableRipple = false;
}

@Component({
template: `
<mat-vertical-stepper>
<mat-vertical-stepper [disableRipple]="disableRipple">
<mat-step>
<ng-template matStepLabel>Step 1</ng-template>
Content 1
Expand Down Expand Up @@ -1263,6 +1297,7 @@ class SimpleMatHorizontalStepperApp {
class SimpleMatVerticalStepperApp {
inputLabel = 'Step 3';
showStepTwo = true;
disableRipple = false;
}

@Component({
Expand Down
3 changes: 3 additions & 0 deletions src/lib/stepper/stepper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,9 @@ export class MatStepper extends CdkStepper implements AfterContentInit {
/** Event emitted when the current step is done transitioning in. */
@Output() readonly animationDone: EventEmitter<void> = new EventEmitter<void>();

/** Whether ripples should be disabled for the step headers. */
@Input() disableRipple: boolean;

/** Consumer-specified template-refs to be used to override the header icons. */
_iconOverrides: {[key: string]: TemplateRef<MatStepperIconContext>} = {};

Expand Down
2 changes: 2 additions & 0 deletions tools/public_api_guard/lib/stepper.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export declare class MatStep extends CdkStep implements ErrorStateMatcher {
export declare class MatStepHeader extends CdkStepHeader implements OnDestroy {
_intl: MatStepperIntl;
active: boolean;
disableRipple: boolean;
errorMessage: string;
iconOverrides: {
[key: string]: TemplateRef<MatStepperIconContext>;
Expand Down Expand Up @@ -49,6 +50,7 @@ export declare class MatStepper extends CdkStepper implements AfterContentInit {
_stepHeader: QueryList<MatStepHeader>;
_steps: QueryList<MatStep>;
readonly animationDone: EventEmitter<void>;
disableRipple: boolean;
ngAfterContentInit(): void;
}

Expand Down