Skip to content

Commit ef8bc2d

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 4e4c6a6 commit ef8bc2d

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} 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} from './index';
3+
import {MdRipple, MdRippleModule, MD_RIPPLES_DISABLE} 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,
@@ -272,6 +272,50 @@ describe('MdRipple', () => {
272272

273273
});
274274

275+
describe('with ripples disabled', () => {
276+
let rippleDirective: MdRipple;
277+
278+
beforeEach(() => {
279+
// Reset the previously configured testing module to be able to disable ripples globally.
280+
// The testing module has been initialized in the root describe group for the ripples.
281+
TestBed.resetTestingModule();
282+
TestBed.configureTestingModule({
283+
imports: [MdRippleModule],
284+
declarations: [BasicRippleContainer],
285+
providers: [{ provide: MD_RIPPLES_DISABLE, useValue: true }]
286+
});
287+
});
288+
289+
beforeEach(() => {
290+
fixture = TestBed.createComponent(BasicRippleContainer);
291+
fixture.detectChanges();
292+
293+
rippleTarget = fixture.nativeElement.querySelector('[mat-ripple]');
294+
rippleDirective = fixture.componentInstance.ripple;
295+
});
296+
297+
it('should not show any ripples on mousedown', () => {
298+
dispatchMouseEvent(rippleTarget, 'mousedown');
299+
dispatchMouseEvent(rippleTarget, 'mouseup');
300+
301+
expect(rippleTarget.querySelectorAll('.mat-ripple-element').length).toBe(0);
302+
303+
dispatchMouseEvent(rippleTarget, 'mousedown');
304+
dispatchMouseEvent(rippleTarget, 'mouseup');
305+
306+
expect(rippleTarget.querySelectorAll('.mat-ripple-element').length).toBe(0);
307+
});
308+
309+
it('should still allow manual ripples', () => {
310+
expect(rippleTarget.querySelectorAll('.mat-ripple-element').length).toBe(0);
311+
312+
rippleDirective.launch(0, 0);
313+
314+
expect(rippleTarget.querySelectorAll('.mat-ripple-element').length).toBe(1);
315+
});
316+
317+
});
318+
275319
describe('configuring behavior', () => {
276320
let controller: RippleContainerWithInputBindings;
277321
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)