mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
feat(ripple): support for global ripple options (#3463)
* feat(ripple): add option to change global speedFactor * Refactors the `MD_DISABLE_RIPPLES` token to a configuration object, that can also include options like a global `baseSpeedFactor`. * Fix Angular issue
This commit is contained in:
committed by
tinayuangao
parent
17bf5e5759
commit
fb75a136e7
@@ -4,7 +4,7 @@ import {CompatibilityModule} from '../compatibility/compatibility';
|
||||
import {VIEWPORT_RULER_PROVIDER} from '../overlay/position/viewport-ruler';
|
||||
import {SCROLL_DISPATCHER_PROVIDER} from '../overlay/scroll/scroll-dispatcher';
|
||||
|
||||
export {MdRipple, MD_DISABLE_RIPPLES} from './ripple';
|
||||
export {MdRipple, RippleGlobalOptions, MD_RIPPLE_GLOBAL_OPTIONS} from './ripple';
|
||||
export {RippleRef, RippleState} from './ripple-ref';
|
||||
export {RippleConfig} from './ripple-renderer';
|
||||
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import {TestBed, ComponentFixture, fakeAsync, tick, inject} from '@angular/core/testing';
|
||||
import {Component, ViewChild} from '@angular/core';
|
||||
import {MdRipple, MdRippleModule, MD_DISABLE_RIPPLES, RippleState} from './index';
|
||||
import {ViewportRuler} from '../overlay/position/viewport-ruler';
|
||||
import {RIPPLE_FADE_OUT_DURATION, RIPPLE_FADE_IN_DURATION} from './ripple-renderer';
|
||||
import {dispatchMouseEvent} from '../testing/dispatch-events';
|
||||
import {
|
||||
MdRipple, MdRippleModule, MD_RIPPLE_GLOBAL_OPTIONS, RippleState, RippleGlobalOptions
|
||||
} from './index';
|
||||
|
||||
/** Extracts the numeric value of a pixel size string like '123px'. */
|
||||
const pxStringToFloat = (s: string) => {
|
||||
@@ -346,29 +348,29 @@ describe('MdRipple', () => {
|
||||
|
||||
});
|
||||
|
||||
describe('with ripples disabled', () => {
|
||||
describe('global ripple options', () => {
|
||||
let rippleDirective: MdRipple;
|
||||
|
||||
beforeEach(() => {
|
||||
// Reset the previously configured testing module to be able to disable ripples globally.
|
||||
function createTestComponent(rippleConfig: RippleGlobalOptions) {
|
||||
// Reset the previously configured testing module to be able set new providers.
|
||||
// The testing module has been initialized in the root describe group for the ripples.
|
||||
TestBed.resetTestingModule();
|
||||
TestBed.configureTestingModule({
|
||||
imports: [MdRippleModule],
|
||||
declarations: [BasicRippleContainer],
|
||||
providers: [{ provide: MD_DISABLE_RIPPLES, useValue: true }]
|
||||
providers: [{ provide: MD_RIPPLE_GLOBAL_OPTIONS, useValue: rippleConfig }]
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(BasicRippleContainer);
|
||||
fixture.detectChanges();
|
||||
|
||||
rippleTarget = fixture.nativeElement.querySelector('[mat-ripple]');
|
||||
rippleDirective = fixture.componentInstance.ripple;
|
||||
});
|
||||
}
|
||||
|
||||
it('when disabled should not show any ripples on mousedown', () => {
|
||||
createTestComponent({ disabled: true });
|
||||
|
||||
it('should not show any ripples on mousedown', () => {
|
||||
dispatchMouseEvent(rippleTarget, 'mousedown');
|
||||
dispatchMouseEvent(rippleTarget, 'mouseup');
|
||||
|
||||
@@ -380,7 +382,9 @@ describe('MdRipple', () => {
|
||||
expect(rippleTarget.querySelectorAll('.mat-ripple-element').length).toBe(0);
|
||||
});
|
||||
|
||||
it('should still allow manual ripples', () => {
|
||||
it('when disabled should still allow manual ripples', () => {
|
||||
createTestComponent({ disabled: true });
|
||||
|
||||
expect(rippleTarget.querySelectorAll('.mat-ripple-element').length).toBe(0);
|
||||
|
||||
rippleDirective.launch(0, 0);
|
||||
@@ -388,6 +392,41 @@ describe('MdRipple', () => {
|
||||
expect(rippleTarget.querySelectorAll('.mat-ripple-element').length).toBe(1);
|
||||
});
|
||||
|
||||
it('should support changing the baseSpeedFactor', fakeAsync(() => {
|
||||
createTestComponent({ baseSpeedFactor: 0.5 });
|
||||
|
||||
dispatchMouseEvent(rippleTarget, 'mousedown');
|
||||
dispatchMouseEvent(rippleTarget, 'mouseup');
|
||||
|
||||
expect(rippleTarget.querySelectorAll('.mat-ripple-element').length).toBe(1);
|
||||
|
||||
// Calculates the speedFactor for the duration. Those factors needs to be inverted, because
|
||||
// a lower speed factor, will make the duration longer. For example: 0.5 => 2x duration.
|
||||
let fadeInFactor = 1 / 0.5;
|
||||
|
||||
// Calculates the duration for fading-in and fading-out the ripple.
|
||||
tick(RIPPLE_FADE_IN_DURATION * fadeInFactor + RIPPLE_FADE_OUT_DURATION);
|
||||
|
||||
expect(rippleTarget.querySelectorAll('.mat-ripple-element').length).toBe(0);
|
||||
}));
|
||||
|
||||
it('should combine individual speed factor with baseSpeedFactor', fakeAsync(() => {
|
||||
createTestComponent({ baseSpeedFactor: 0.5 });
|
||||
|
||||
rippleDirective.launch(0, 0, { speedFactor: 1.5 });
|
||||
|
||||
expect(rippleTarget.querySelectorAll('.mat-ripple-element').length).toBe(1);
|
||||
|
||||
// Calculates the speedFactor for the duration. Those factors needs to be inverted, because
|
||||
// a lower speed factor, will make the duration longer. For example: 0.5 => 2x duration.
|
||||
let fadeInFactor = 1 / (0.5 * 1.5);
|
||||
|
||||
// Calculates the duration for fading-in and fading-out the ripple.
|
||||
tick(RIPPLE_FADE_IN_DURATION * fadeInFactor + RIPPLE_FADE_OUT_DURATION);
|
||||
|
||||
expect(rippleTarget.querySelectorAll('.mat-ripple-element').length).toBe(0);
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
describe('configuring behavior', () => {
|
||||
|
||||
@@ -14,8 +14,13 @@ import {RippleConfig, RippleRenderer} from './ripple-renderer';
|
||||
import {ViewportRuler} from '../overlay/position/viewport-ruler';
|
||||
import {RippleRef} from './ripple-ref';
|
||||
|
||||
/** OpaqueToken that can be used to globally disable all ripples. Except programmatic ones. */
|
||||
export const MD_DISABLE_RIPPLES = new OpaqueToken('md-disable-ripples');
|
||||
/** OpaqueToken that can be used to specify the global ripple options. */
|
||||
export const MD_RIPPLE_GLOBAL_OPTIONS = new OpaqueToken('md-ripple-global-options');
|
||||
|
||||
export type RippleGlobalOptions = {
|
||||
disabled?: boolean;
|
||||
baseSpeedFactor?: number;
|
||||
};
|
||||
|
||||
@Directive({
|
||||
selector: '[md-ripple], [mat-ripple], [mdRipple], [matRipple]',
|
||||
@@ -70,10 +75,18 @@ export class MdRipple implements OnChanges, OnDestroy {
|
||||
/** Renderer for the ripple DOM manipulations. */
|
||||
private _rippleRenderer: RippleRenderer;
|
||||
|
||||
constructor(elementRef: ElementRef, ngZone: NgZone, ruler: ViewportRuler,
|
||||
@Optional() @Inject(MD_DISABLE_RIPPLES) private _forceDisableRipples: boolean) {
|
||||
/** Options that are set globally for all ripples. */
|
||||
private _globalOptions: RippleGlobalOptions;
|
||||
|
||||
constructor(
|
||||
elementRef: ElementRef,
|
||||
ngZone: NgZone,
|
||||
ruler: ViewportRuler,
|
||||
// Type needs to be `any` because of https://github.com/angular/angular/issues/12631
|
||||
@Optional() @Inject(MD_RIPPLE_GLOBAL_OPTIONS) globalOptions: any
|
||||
) {
|
||||
this._rippleRenderer = new RippleRenderer(elementRef, ngZone, ruler);
|
||||
this._globalOptions = globalOptions ? globalOptions : {};
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges) {
|
||||
@@ -81,7 +94,7 @@ export class MdRipple implements OnChanges, OnDestroy {
|
||||
this._rippleRenderer.setTriggerElement(this.trigger);
|
||||
}
|
||||
|
||||
this._rippleRenderer.rippleDisabled = this._forceDisableRipples || this.disabled;
|
||||
this._rippleRenderer.rippleDisabled = this._globalOptions.disabled || this.disabled;
|
||||
this._rippleRenderer.rippleConfig = this.rippleConfig;
|
||||
}
|
||||
|
||||
@@ -104,7 +117,7 @@ export class MdRipple implements OnChanges, OnDestroy {
|
||||
get rippleConfig(): RippleConfig {
|
||||
return {
|
||||
centered: this.centered,
|
||||
speedFactor: this.speedFactor,
|
||||
speedFactor: this.speedFactor * (this._globalOptions.baseSpeedFactor || 1),
|
||||
radius: this.radius,
|
||||
color: this.color
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user