feat(button): add ripple to md-button

This commit is contained in:
Brian Nenninger
2016-07-25 23:50:14 -04:00
committed by Jeremy Elbourn
parent ca351b2a52
commit 32aa4614dd
7 changed files with 71 additions and 6 deletions
+1
View File
@@ -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
+5
View File
@@ -1 +1,6 @@
<span class="md-button-wrapper"><ng-content></ng-content></span>
<div md-ripple *ngIf="isRippleEnabled()" class="md-button-ripple"
[class.md-button-ripple-round]="isRoundButton()"
[md-ripple-trigger]="getHostElement()"
[md-ripple-color]="isRoundButton() ? 'rgba(255, 255, 255, 0.2)' : ''"
md-ripple-background-color="rgba(0, 0, 0, 0)"></div>
+17
View File
@@ -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.
+19 -1
View File
@@ -143,6 +143,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. */
@@ -150,7 +167,7 @@ describe('MdButton', () => {
selector: 'test-app',
template: `
<button md-button type="button" (click)="increment()"
[disabled]="isDisabled" [color]="buttonColor">
[disabled]="isDisabled" [color]="buttonColor" [disableRipple]="rippleDisabled">
Go
</button>
<a href="http://www.google.com" md-button [disabled]="isDisabled" [color]="buttonColor">Link</a>
@@ -159,6 +176,7 @@ describe('MdButton', () => {
class TestApp {
clickCount: number = 0;
isDisabled: boolean = false;
rippleDisabled: boolean = false;
increment() {
this.clickCount++;
+22 -1
View File
@@ -9,8 +9,9 @@ import {
Type,
NgModule,
} 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
@@ -28,6 +29,7 @@ import {
},
templateUrl: 'button.html',
styleUrls: ['button.css'],
directives: [MD_RIPPLE_DIRECTIVES],
encapsulation: ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.OnPush,
})
@@ -40,6 +42,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 {
@@ -83,6 +88,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({
@@ -98,6 +118,7 @@ export class MdButton {
},
templateUrl: 'button.html',
styleUrls: ['button.css'],
directives: [MD_RIPPLE_DIRECTIVES],
encapsulation: ViewEncapsulation.None
})
export class MdAnchor extends MdButton {
+5 -4
View File
@@ -1,12 +1,13 @@
<!-- Use <md-card>? -->
<div class="demo-ripple">
<section>
<button md-button>flat</button>
<button md-raised-button>raised</button>
<button md-fab>
<md-checkbox [(ngModel)]="disableButtonRipples">Disable button ripples</md-checkbox>
<button md-button [disableRipple]="disableButtonRipples">flat</button>
<button md-raised-button [disableRipple]="disableButtonRipples">raised</button>
<button md-fab [disableRipple]="disableButtonRipples">
<md-icon>check</md-icon>
</button>
<button md-mini-fab>
<button md-mini-fab [disableRipple]="disableButtonRipples">
<md-icon>check</md-icon>
</button>
</section>
+2
View File
@@ -20,6 +20,8 @@ export class RippleDemo {
rippleColor = '';
rippleBackgroundColor = '';
disableButtonRipples = false;
doManualRipple() {
if (this.manualRipple) {
window.setTimeout(() => this.manualRipple.start(), 10);