-
Notifications
You must be signed in to change notification settings - Fork 6.8k
Fix #75: md-button attaches class "md-undefined" to host element when on color provided #89
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,14 @@ | ||
import { | ||
Component, | ||
ElementRef, | ||
ViewEncapsulation, | ||
Input, | ||
HostBinding, | ||
HostListener, | ||
ChangeDetectionStrategy, | ||
Renderer, | ||
} from 'angular2/core'; | ||
|
||
import {TimerWrapper} from 'angular2/src/facade/async'; | ||
|
||
// TODO(jelbourn): Ink ripples. | ||
|
@@ -18,7 +21,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,23 +31,47 @@ import {TimerWrapper} from 'angular2/src/facade/async'; | |
changeDetection: ChangeDetectionStrategy.OnPush, | ||
}) | ||
export class MdButton { | ||
color: string; | ||
private color_: string; | ||
|
||
// Setting the class when a color property is provided | ||
// cannot be done through [ngClass] on host or [class] = 'getClassList()' | ||
// @see http://stackoverflow.com/questions/35506395 | ||
@Input() | ||
set color(value: string) { | ||
// Remove the previous color if one provided | ||
if (this.color_ != null) { | ||
this.renderer.setElementClass(this.elementRef, 'md-' + this.color_, false); | ||
} | ||
|
||
this.color_ = value; | ||
|
||
if (value != null) { | ||
this.renderer.setElementClass(this.elementRef, 'md-' + this.color_, true); | ||
} | ||
} | ||
|
||
get color(): string { | ||
return this.color_; | ||
} | ||
|
||
constructor(public elementRef: ElementRef, public renderer: Renderer) { | ||
} | ||
|
||
/** Whether the button has focus from the keyboard (not the mouse). Used for class binding. */ | ||
isKeyboardFocused: boolean = false; | ||
|
||
/** Whether a mousedown has occurred on this element in the last 100ms. */ | ||
isMouseDown: boolean = false; | ||
|
||
setClassList() {return `md-${this.color}`;} | ||
|
||
setMousedown() { | ||
// We only *show* the focus style when focus has come to the button via the keyboard. | ||
// The Material Design spec is silent on this topic, and without doing this, the | ||
// button continues to look :active after clicking. | ||
// @see http://marcysutton.com/button-focus-hell/ | ||
this.isMouseDown = true; | ||
TimerWrapper.setTimeout(() => { this.isMouseDown = false; }, 100); | ||
TimerWrapper.setTimeout(() => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why aren't you using the lambda expression instead? TimeWrapper.setTimeout(() => this.isMouseDown = false, 100); There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You need brackets for ts2dart to work as expected. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @hansl Ah well, thanks for the information :) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is because There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks great!, indeed - just saw, lambda will always return the expression. |
||
this.isMouseDown = false; | ||
}, 100); | ||
} | ||
|
||
setKeyboardFocus($event: any) { | ||
|
@@ -62,7 +88,6 @@ export class MdButton { | |
inputs: ['color'], | ||
host: { | ||
'[class.md-button-focus]': 'isKeyboardFocused', | ||
'[class]': 'setClassList()', | ||
'(mousedown)': 'setMousedown()', | ||
'(focus)': 'setKeyboardFocus()', | ||
'(blur)': 'removeKeyboardFocus()' | ||
|
@@ -74,8 +99,12 @@ export class MdButton { | |
export class MdAnchor extends MdButton { | ||
disabled_: boolean = null; | ||
|
||
constructor(elementRef_: ElementRef, renderer_: Renderer) { | ||
super(elementRef_, renderer_); | ||
} | ||
|
||
@HostBinding('tabIndex') | ||
get tabIndex():number { | ||
get tabIndex(): number { | ||
return this.disabled ? -1 : 0; | ||
} | ||
|
||
|
@@ -87,7 +116,9 @@ export class MdAnchor extends MdButton { | |
|
||
@HostBinding('attr.disabled') | ||
@Input('disabled') | ||
get disabled() { return this.disabled_; } | ||
get disabled() { | ||
return this.disabled_; | ||
} | ||
|
||
set disabled(value: boolean) { | ||
// The presence of *any* disabled value makes the component disabled, *except* for false. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why can this fix not be something like:
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
<button md-button class="myClass" color="warn">Submit</button>
results in
<button md-button class="md-warn">Submit</button>
It should be
<button md-button class="myClass md-warn">Submit</button>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I chatted with Misko and he agreed that this is an issue in Angular: angular/angular#7289
In the meantime I would be okay with the renderer approach.