diff --git a/src/components/button/README.md b/src/components/button/README.md index 5e6161961e9c..3dc9923f6183 100644 --- a/src/components/button/README.md +++ b/src/components/button/README.md @@ -112,3 +112,4 @@ Properties: | --- | --- | --- | | `color` | `"primary"|"accent"|"warn"` | The color palette of the button | `disabled` | boolean | Whether or not the button is disabled +| `disableRipple` | boolean | Whether the ripple effect when the button is clicked should be disabled diff --git a/src/components/button/button.html b/src/components/button/button.html index 4e3df0e22666..a1636be45494 100644 --- a/src/components/button/button.html +++ b/src/components/button/button.html @@ -1 +1,6 @@
diff --git a/src/components/button/button.scss b/src/components/button/button.scss index 2d5e366a549b..ff0eb85ed88b 100644 --- a/src/components/button/button.scss +++ b/src/components/button/button.scss @@ -43,6 +43,23 @@ } } +// The ripple container should match the bounds of the entire button. +.md-button-ripple { + position: absolute; + top: 0; + left: 0; + bottom: 0; + right: 0; +} + +// For round buttons, the ripple container should clip child ripples to a circle. +.md-button-ripple-round { + border-radius: 50%; + // z-index needed to make clipping to border-radius work correctly. + // http://stackoverflow.com/questions/20001515/chrome-bug-border-radius-not-clipping-contents-when-combined-with-css-transiti + z-index: 1; +} + // Only flat buttons and icon buttons (not raised or fabs) have a hover style. [md-button]:hover, [md-icon-button]:hover { // Use the same visual treatment for hover as for focus. diff --git a/src/components/button/button.spec.ts b/src/components/button/button.spec.ts index 6c69dc744a84..3de21aaf3f24 100644 --- a/src/components/button/button.spec.ts +++ b/src/components/button/button.spec.ts @@ -1,4 +1,4 @@ -import {inject} from '@angular/core/testing'; +import {async, inject} from '@angular/core/testing'; import {TestComponentBuilder} from '@angular/compiler/testing'; import {Component} from '@angular/core'; import {By} from '@angular/platform-browser'; @@ -130,6 +130,23 @@ describe('MdButton', () => { }); }); + + // Ripple tests. + describe('button ripples', () => { + it('should remove ripple if md-ripple-disabled input is set', async(() => { + builder.createAsync(TestApp).then(fixture => { + let testComponent = fixture.debugElement.componentInstance; + let buttonDebugElement = fixture.debugElement.query(By.css('button')); + + fixture.detectChanges(); + expect(buttonDebugElement.nativeElement.querySelectorAll('[md-ripple]').length).toBe(1); + + testComponent.rippleDisabled = true; + fixture.detectChanges(); + expect(buttonDebugElement.nativeElement.querySelectorAll('[md-ripple]').length).toBe(0); + }); + })); + }); }); /** Test component that contains an MdButton. */ @@ -137,7 +154,7 @@ describe('MdButton', () => { selector: 'test-app', template: ` Link @@ -147,6 +164,7 @@ describe('MdButton', () => { class TestApp { clickCount: number = 0; isDisabled: boolean = false; + rippleDisabled: boolean = false; increment() { this.clickCount++; diff --git a/src/components/button/button.ts b/src/components/button/button.ts index 495d687758dc..57d904dc6cdf 100644 --- a/src/components/button/button.ts +++ b/src/components/button/button.ts @@ -8,8 +8,9 @@ import { Renderer, Type, } from '@angular/core'; +import {MD_RIPPLE_DIRECTIVES} from '@angular2-material/core/core'; +import {BooleanFieldValue} from '@angular2-material/core/annotations/field-value'; -// TODO(jelbourn): Ink ripples. // TODO(jelbourn): Make the `isMouseDown` stuff done with one global listener. // TODO(kara): Convert attribute selectors to classes when attr maps become available @@ -27,6 +28,7 @@ import { }, templateUrl: 'button.html', styleUrls: ['button.css'], + directives: [MD_RIPPLE_DIRECTIVES], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, }) @@ -39,6 +41,9 @@ export class MdButton { /** Whether a mousedown has occurred on this element in the last 100ms. */ _isMouseDown: boolean = false; + /** Whether the ripple effect on click should be disabled. */ + @Input() @BooleanFieldValue() disableRipple: boolean = false; + constructor(private _elementRef: ElementRef, private _renderer: Renderer) { } get color(): string { @@ -82,6 +87,21 @@ export class MdButton { focus() { this._elementRef.nativeElement.focus(); } + + getHostElement() { + return this._elementRef.nativeElement; + } + + isRoundButton() { + const el = this._elementRef.nativeElement; + return el.hasAttribute('md-icon-button') || + el.hasAttribute('md-fab') || + el.hasAttribute('md-mini-fab'); + } + + isRippleEnabled() { + return !this.disableRipple; + } } @Component({ @@ -97,6 +117,7 @@ export class MdButton { }, templateUrl: 'button.html', styleUrls: ['button.css'], + directives: [MD_RIPPLE_DIRECTIVES], encapsulation: ViewEncapsulation.None }) export class MdAnchor extends MdButton { diff --git a/src/demo-app/ripple/ripple-demo.html b/src/demo-app/ripple/ripple-demo.html index 9f09de717d09..f658df015350 100644 --- a/src/demo-app/ripple/ripple-demo.html +++ b/src/demo-app/ripple/ripple-demo.html @@ -1,12 +1,13 @@ +