feat(ripple): expose ripple directive in template (#3165)

* When programmatically calling `launch` on the ripple element the developer can specifiy a configuration object.
  Since the `launch` method is part of the directive and all the associated `@Input`s. The given configuration should be used as default.

 * Exposes the ripple component instance to the Angular template.
This commit is contained in:
Paul Gschwendtner
2017-02-21 20:19:12 +01:00
committed by mmalerba
parent b939cd870b
commit 6595ad87c2
2 changed files with 28 additions and 11 deletions
+22 -6
View File
@@ -75,6 +75,7 @@ describe('MdRipple', () => {
}
describe('basic ripple', () => {
let rippleDirective: MdRipple;
const TARGET_HEIGHT = 200;
const TARGET_WIDTH = 300;
@@ -83,7 +84,8 @@ describe('MdRipple', () => {
fixture = TestBed.createComponent(BasicRippleContainer);
fixture.detectChanges();
rippleTarget = fixture.debugElement.nativeElement.querySelector('[mat-ripple]');
rippleTarget = fixture.nativeElement.querySelector('[mat-ripple]');
rippleDirective = fixture.componentInstance.ripple;
});
it('creates ripple on mousedown', () => {
@@ -111,15 +113,29 @@ describe('MdRipple', () => {
}));
it('creates ripples when manually triggered', () => {
let rippleComponent = fixture.debugElement.componentInstance.ripple as MdRipple;
expect(rippleTarget.querySelectorAll('.mat-ripple-element').length).toBe(0);
rippleComponent.launch(0, 0);
rippleDirective.launch(0, 0);
expect(rippleTarget.querySelectorAll('.mat-ripple-element').length).toBe(1);
});
it('creates manual ripples with the default ripple config', () => {
expect(rippleTarget.querySelectorAll('.mat-ripple-element').length).toBe(0);
// Calculate the diagonal distance and divide it by two for the center radius.
let radius = Math.sqrt(TARGET_HEIGHT * TARGET_HEIGHT + TARGET_WIDTH * TARGET_WIDTH) / 2;
rippleDirective.centered = true;
rippleDirective.launch(0, 0);
let rippleElement = rippleTarget.querySelector('.mat-ripple-element') as HTMLElement;
expect(rippleElement).toBeTruthy();
expect(parseFloat(rippleElement.style.left)).toBeCloseTo(TARGET_WIDTH / 2 - radius, 1);
expect(parseFloat(rippleElement.style.top)).toBeCloseTo(TARGET_HEIGHT / 2 - radius, 1);
});
it('sizes ripple to cover element', () => {
let elementRect = rippleTarget.getBoundingClientRect();
@@ -382,13 +398,13 @@ describe('MdRipple', () => {
@Component({
template: `
<div id="container" mat-ripple [mdRippleSpeedFactor]="0"
<div id="container" #ripple="mdRipple" mat-ripple [mdRippleSpeedFactor]="0"
style="position: relative; width:300px; height:200px;">
</div>
`,
})
class BasicRippleContainer {
@ViewChild(MdRipple) ripple: MdRipple;
@ViewChild('ripple') ripple: MdRipple;
}
@Component({
+6 -5
View File
@@ -17,6 +17,7 @@ import {SCROLL_DISPATCHER_PROVIDER} from '../overlay/scroll/scroll-dispatcher';
@Directive({
selector: '[md-ripple], [mat-ripple]',
exportAs: 'mdRipple',
host: {
'[class.mat-ripple]': 'true',
'[class.mat-ripple-unbounded]': 'unbounded'
@@ -77,7 +78,7 @@ export class MdRipple implements OnChanges, OnDestroy {
}
this._rippleRenderer.rippleDisabled = this.disabled;
this._updateRippleConfig();
this._rippleRenderer.rippleConfig = this.rippleConfig;
}
ngOnDestroy() {
@@ -86,13 +87,13 @@ export class MdRipple implements OnChanges, OnDestroy {
}
/** Launches a manual ripple at the specified position. */
launch(pageX: number, pageY: number, config?: RippleConfig) {
launch(pageX: number, pageY: number, config = this.rippleConfig) {
this._rippleRenderer.fadeInRipple(pageX, pageY, config);
}
/** Updates the ripple configuration with the input values. */
private _updateRippleConfig() {
this._rippleRenderer.rippleConfig = {
/** Ripple configuration from the directive's input values. */
get rippleConfig(): RippleConfig {
return {
centered: this.centered,
speedFactor: this.speedFactor,
radius: this.radius,