Skip to content

Commit 58dacef

Browse files
committed
feat(ripple): add way to globally disable ripples
* Currently ripples can be only disable component-wise. This isn't very elegant if users want to disable ripples for all components. * This commit introduces a new `OpaqueToken`/ `InjectionToken` that can be used to globally disable all ripples. * Makes the `tab-nav-bar` ripple directive more clean. Since Angular v2.3.0 (as we recently upgraded) the inherited metadata can be used. For upcoming accessibility features (focus indicators) we don't want to allow developers to disable programmatic ripples.
1 parent 94adecd commit 58dacef

File tree

4 files changed

+57
-13
lines changed

4 files changed

+57
-13
lines changed

src/lib/core/ripple/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import {CompatibilityModule} from '../compatibility/compatibility';
44
import {VIEWPORT_RULER_PROVIDER} from '../overlay/position/viewport-ruler';
55
import {SCROLL_DISPATCHER_PROVIDER} from '../overlay/scroll/scroll-dispatcher';
66

7-
export {MdRipple} from './ripple';
7+
export {MdRipple, MD_RIPPLES_DISABLE} from './ripple';
88
export {RippleRef, RippleState} from './ripple-ref';
99
export {RippleConfig} from './ripple-renderer';
1010

src/lib/core/ripple/ripple.spec.ts

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import {TestBed, ComponentFixture, fakeAsync, tick, inject} from '@angular/core/testing';
22
import {Component, ViewChild} from '@angular/core';
3-
import {MdRipple, MdRippleModule, RippleState} from './index';
3+
import {MdRipple, MdRippleModule, MD_RIPPLES_DISABLE, RippleState} from './index';
44
import {ViewportRuler} from '../overlay/position/viewport-ruler';
55
import {RIPPLE_FADE_OUT_DURATION, RIPPLE_FADE_IN_DURATION} from './ripple-renderer';
66
import {dispatchMouseEvent} from '../testing/dispatch-events';
@@ -18,7 +18,7 @@ describe('MdRipple', () => {
1818

1919
beforeEach(() => {
2020
TestBed.configureTestingModule({
21-
imports: [MdRippleModule.forRoot()],
21+
imports: [MdRippleModule],
2222
declarations: [
2323
BasicRippleContainer,
2424
RippleContainerWithInputBindings,
@@ -346,6 +346,50 @@ describe('MdRipple', () => {
346346

347347
});
348348

349+
describe('with ripples disabled', () => {
350+
let rippleDirective: MdRipple;
351+
352+
beforeEach(() => {
353+
// Reset the previously configured testing module to be able to disable ripples globally.
354+
// The testing module has been initialized in the root describe group for the ripples.
355+
TestBed.resetTestingModule();
356+
TestBed.configureTestingModule({
357+
imports: [MdRippleModule],
358+
declarations: [BasicRippleContainer],
359+
providers: [{ provide: MD_RIPPLES_DISABLE, useValue: true }]
360+
});
361+
});
362+
363+
beforeEach(() => {
364+
fixture = TestBed.createComponent(BasicRippleContainer);
365+
fixture.detectChanges();
366+
367+
rippleTarget = fixture.nativeElement.querySelector('[mat-ripple]');
368+
rippleDirective = fixture.componentInstance.ripple;
369+
});
370+
371+
it('should not show any ripples on mousedown', () => {
372+
dispatchMouseEvent(rippleTarget, 'mousedown');
373+
dispatchMouseEvent(rippleTarget, 'mouseup');
374+
375+
expect(rippleTarget.querySelectorAll('.mat-ripple-element').length).toBe(0);
376+
377+
dispatchMouseEvent(rippleTarget, 'mousedown');
378+
dispatchMouseEvent(rippleTarget, 'mouseup');
379+
380+
expect(rippleTarget.querySelectorAll('.mat-ripple-element').length).toBe(0);
381+
});
382+
383+
it('should still allow manual ripples', () => {
384+
expect(rippleTarget.querySelectorAll('.mat-ripple-element').length).toBe(0);
385+
386+
rippleDirective.launch(0, 0);
387+
388+
expect(rippleTarget.querySelectorAll('.mat-ripple-element').length).toBe(1);
389+
});
390+
391+
});
392+
349393
describe('configuring behavior', () => {
350394
let controller: RippleContainerWithInputBindings;
351395
let rippleComponent: MdRipple;

src/lib/core/ripple/ripple.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,20 @@ import {
22
Directive,
33
ElementRef,
44
Input,
5+
Inject,
56
NgZone,
67
OnChanges,
78
SimpleChanges,
89
OnDestroy,
10+
OpaqueToken,
11+
Optional,
912
} from '@angular/core';
1013
import {RippleConfig, RippleRenderer} from './ripple-renderer';
1114
import {ViewportRuler} from '../overlay/position/viewport-ruler';
1215
import {RippleRef} from './ripple-ref';
1316

17+
/** OpaqueToken that can be used to globally disable all ripples. Except programmatic ones. */
18+
export const MD_RIPPLES_DISABLE = new OpaqueToken('md-ripples-disable');
1419

1520
@Directive({
1621
selector: '[md-ripple], [mat-ripple]',
@@ -65,7 +70,9 @@ export class MdRipple implements OnChanges, OnDestroy {
6570
/** Renderer for the ripple DOM manipulations. */
6671
private _rippleRenderer: RippleRenderer;
6772

68-
constructor(elementRef: ElementRef, ngZone: NgZone, ruler: ViewportRuler) {
73+
constructor(elementRef: ElementRef, ngZone: NgZone, ruler: ViewportRuler,
74+
@Optional() @Inject(MD_RIPPLES_DISABLE) private _forceDisableRipples: boolean) {
75+
6976
this._rippleRenderer = new RippleRenderer(elementRef, ngZone, ruler);
7077
}
7178

@@ -74,7 +81,7 @@ export class MdRipple implements OnChanges, OnDestroy {
7481
this._rippleRenderer.setTriggerElement(this.trigger);
7582
}
7683

77-
this._rippleRenderer.rippleDisabled = this.disabled;
84+
this._rippleRenderer.rippleDisabled = this._forceDisableRipples || this.disabled;
7885
this._rippleRenderer.rippleConfig = this.rippleConfig;
7986
}
8087

src/lib/tabs/tab-nav-bar/tab-nav-bar.ts

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,9 @@ import {
55
ElementRef,
66
ViewEncapsulation,
77
Directive,
8-
NgZone,
98
} from '@angular/core';
109
import {MdInkBar} from '../ink-bar';
1110
import {MdRipple} from '../../core/ripple/index';
12-
import {ViewportRuler} from '../../core/overlay/position/viewport-ruler';
1311

1412
/**
1513
* Navigation component matching the styles of the tab group header.
@@ -81,9 +79,4 @@ export class MdTabLink {
8179
'[class.mat-tab-link]': 'true',
8280
},
8381
})
84-
export class MdTabLinkRipple extends MdRipple {
85-
constructor(elementRef: ElementRef, ngZone: NgZone, ruler: ViewportRuler) {
86-
super(elementRef, ngZone, ruler);
87-
}
88-
89-
}
82+
export class MdTabLinkRipple extends MdRipple {}

0 commit comments

Comments
 (0)