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.
This commit is contained in:
Paul Gschwendtner
2019-01-30 23:00:35 +01:00
committed by mmalerba
parent cd72c9dc85
commit a6cc98fa6e
10 changed files with 63 additions and 10 deletions
+5 -2
View File
@@ -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>
@@ -48,7 +50,8 @@
</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>
+1
View File
@@ -19,6 +19,7 @@ export class StepperDemo implements OnInit {
formGroup: FormGroup;
isNonLinear = false;
isNonEditable = false;
disableRipple = false;
nameFormGroup: FormGroup;
emailFormGroup: FormGroup;
+1
View File
@@ -62,6 +62,7 @@ ng_test_library(
"//src/cdk/testing",
"//src/lib/form-field",
"//src/lib/input",
"//src/lib/core",
":stepper",
]
)
+4 -1
View File
@@ -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
+3
View File
@@ -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,
+3 -2
View File
@@ -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"
@@ -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>
+3 -2
View File
@@ -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"
@@ -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">
+38 -3
View File
@@ -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';
@@ -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', () => {
@@ -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', () => {
@@ -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
@@ -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
@@ -1263,6 +1297,7 @@ class SimpleMatHorizontalStepperApp {
class SimpleMatVerticalStepperApp {
inputLabel = 'Step 3';
showStepTwo = true;
disableRipple = false;
}
@Component({
+3
View File
@@ -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>} = {};
+2
View File
@@ -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>;
@@ -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;
}