From 62265cc87f4b10612d1ee15da0dcb24db2a5e9c1 Mon Sep 17 00:00:00 2001 From: DevVersion Date: Fri, 18 Mar 2016 18:08:07 +0100 Subject: [PATCH] fix(button): apply color classes correctly. Fixes #75. Closes #89 Closes #195 --- src/components/button/button.spec.ts | 24 +++++++++++++++++++ src/components/button/button.ts | 32 ++++++++++++++++++++++---- src/components/toolbar/toolbar.spec.ts | 2 ++ src/components/toolbar/toolbar.ts | 14 +++++------ 4 files changed, 61 insertions(+), 11 deletions(-) diff --git a/src/components/button/button.spec.ts b/src/components/button/button.spec.ts index 0a053314061f..5db1309dcb2a 100644 --- a/src/components/button/button.spec.ts +++ b/src/components/button/button.spec.ts @@ -43,6 +43,30 @@ export function main() { }); }); + it('should should not clear previous defined classes', (done: () => void) => { + return builder.createAsync(TestApp).then((fixture) => { + let testComponent = fixture.debugElement.componentInstance; + let buttonDebugElement = fixture.debugElement.query(By.css('button')); + + buttonDebugElement.nativeElement.classList.add('custom-class'); + + testComponent.buttonColor = 'primary'; + fixture.detectChanges(); + + expect(buttonDebugElement.nativeElement.classList.contains('md-primary')).toBe(true); + expect(buttonDebugElement.nativeElement.classList.contains('custom-class')).toBe(true); + + testComponent.buttonColor = 'accent'; + fixture.detectChanges(); + + expect(buttonDebugElement.nativeElement.classList.contains('md-primary')).toBe(false); + expect(buttonDebugElement.nativeElement.classList.contains('md-accent')).toBe(true); + expect(buttonDebugElement.nativeElement.classList.contains('custom-class')).toBe(true); + + done(); + }); + }); + // Regular button tests describe('button[md-button]', () => { it('should handle a click on the button', (done: () => void) => { diff --git a/src/components/button/button.ts b/src/components/button/button.ts index 8f65d1613062..84cc2d5fd2e7 100644 --- a/src/components/button/button.ts +++ b/src/components/button/button.ts @@ -5,6 +5,8 @@ import { HostBinding, HostListener, ChangeDetectionStrategy, + ElementRef, + Renderer, } from 'angular2/core'; import {TimerWrapper} from 'angular2/src/facade/async'; @@ -18,7 +20,6 @@ import {TimerWrapper} from 'angular2/src/facade/async'; inputs: ['color'], host: { '[class.md-button-focus]': 'isKeyboardFocused', - '[class]': 'setClassList()', '(mousedown)': 'setMousedown()', '(focus)': 'setKeyboardFocus()', '(blur)': 'removeKeyboardFocus()' @@ -29,7 +30,7 @@ import {TimerWrapper} from 'angular2/src/facade/async'; changeDetection: ChangeDetectionStrategy.OnPush, }) export class MdButton { - color: string; + private _color: string; /** Whether the button has focus from the keyboard (not the mouse). Used for class binding. */ isKeyboardFocused: boolean = false; @@ -37,7 +38,15 @@ export class MdButton { /** Whether a mousedown has occurred on this element in the last 100ms. */ isMouseDown: boolean = false; - setClassList() { return `md-${this.color}`; } + constructor(private elementRef: ElementRef, private renderer: Renderer) { } + + get color(): string { + return this._color; + } + + set color(value: string) { + this._updateColor(value); + } setMousedown() { // We only *show* the focus style when focus has come to the button via the keyboard. @@ -48,6 +57,18 @@ export class MdButton { TimerWrapper.setTimeout(() => { this.isMouseDown = false; }, 100); } + _updateColor(newColor: string) { + this._setElementColor(this._color, false); + this._setElementColor(newColor, true); + this._color = newColor; + } + + _setElementColor(color: string, isAdd: boolean) { + if (color != null && color != '') { + this.renderer.setElementClass(this.elementRef.nativeElement, `md-${color}`, isAdd); + } + } + setKeyboardFocus($event: any) { this.isKeyboardFocused = !this.isMouseDown; } @@ -62,7 +83,6 @@ export class MdButton { inputs: ['color'], host: { '[class.md-button-focus]': 'isKeyboardFocused', - '[class]': 'setClassList()', '(mousedown)': 'setMousedown()', '(focus)': 'setKeyboardFocus()', '(blur)': 'removeKeyboardFocus()' @@ -74,6 +94,10 @@ export class MdButton { export class MdAnchor extends MdButton { _disabled: boolean = null; + constructor(elementRef: ElementRef, renderer: Renderer) { + super(elementRef, renderer); + } + @HostBinding('tabIndex') get tabIndex(): number { return this.disabled ? -1 : 0; diff --git a/src/components/toolbar/toolbar.spec.ts b/src/components/toolbar/toolbar.spec.ts index a3f6dfb5b6fa..29a555365ab9 100644 --- a/src/components/toolbar/toolbar.spec.ts +++ b/src/components/toolbar/toolbar.spec.ts @@ -36,11 +36,13 @@ export function main() { testComponent.toolbarColor = 'accent'; fixture.detectChanges(); + expect(toolbarDebugElement.nativeElement.classList.contains('md-primary')).toBe(false); expect(toolbarDebugElement.nativeElement.classList.contains('md-accent')).toBe(true); testComponent.toolbarColor = 'warn'; fixture.detectChanges(); + expect(toolbarDebugElement.nativeElement.classList.contains('md-accent')).toBe(false); expect(toolbarDebugElement.nativeElement.classList.contains('md-warn')).toBe(true); done(); diff --git a/src/components/toolbar/toolbar.ts b/src/components/toolbar/toolbar.ts index 6c97ce740778..fa36e3f357b3 100644 --- a/src/components/toolbar/toolbar.ts +++ b/src/components/toolbar/toolbar.ts @@ -28,15 +28,15 @@ export class MdToolbar { } _updateColor(newColor: string) { - if (this._color != null && this._color != '') { - this.renderer.setElementClass(this.elementRef.nativeElement, `md-${newColor}`, false); - } + this._setElementColor(this._color, false); + this._setElementColor(newColor, true); + this._color = newColor; + } - if (newColor != null && newColor != '') { - this.renderer.setElementClass(this.elementRef.nativeElement, `md-${newColor}`, true); + _setElementColor(color: string, isAdd: boolean) { + if (color != null && color != '') { + this.renderer.setElementClass(this.elementRef.nativeElement, `md-${color}`, isAdd); } - - this._color = newColor; } }