Skip to content

Commit 5d6920d

Browse files
mmalerbatinayuangao
authored andcommitted
fix(button): use FocusOriginMonitor for focus styles (#3294)
* use FocusOriginMonitor for md-button focus styles * format imports * fix tests * export style module * remove style module import in test * don't re-export StylModule * clean up imports * add back stopImmediatePropagation
1 parent dcc8576 commit 5d6920d

File tree

5 files changed

+37
-56
lines changed

5 files changed

+37
-56
lines changed

src/lib/button/_button-base.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ $mat-mini-fab-padding: 8px !default;
5555
cursor: default;
5656
}
5757

58-
&.mat-button-focus {
58+
&.cdk-keyboard-focused {
5959
.mat-button-focus-overlay {
6060
opacity: 1;
6161
}

src/lib/button/_button-theme.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@
5454
$foreground: map-get($theme, foreground);
5555

5656
.mat-button, .mat-icon-button, .mat-raised-button, .mat-fab, .mat-mini-fab {
57-
&.mat-button-focus {
57+
&.cdk-keyboard-focused {
5858
@include _mat-button-focus-color($theme);
5959
}
6060
}

src/lib/button/button.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {async, TestBed, ComponentFixture} from '@angular/core/testing';
1+
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
22
import {Component} from '@angular/core';
33
import {By} from '@angular/platform-browser';
44
import {MdButtonModule} from './index';

src/lib/button/button.ts

Lines changed: 18 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
import {
2-
Component,
3-
ViewEncapsulation,
4-
Input,
5-
HostBinding,
62
ChangeDetectionStrategy,
3+
Component,
4+
Directive,
75
ElementRef,
6+
HostBinding,
7+
Input,
8+
OnDestroy,
89
Renderer,
9-
Directive,
10+
ViewEncapsulation
1011
} from '@angular/core';
11-
import {coerceBooleanProperty} from '../core';
12+
import {coerceBooleanProperty, FocusOriginMonitor} from '../core';
1213

1314

14-
// TODO(jelbourn): Make the `isMouseDown` stuff done with one global listener.
1515
// TODO(kara): Convert attribute selectors to classes when attr maps become available
1616

1717

@@ -90,25 +90,15 @@ export class MdMiniFabCssMatStyler {}
9090
'button[mat-fab], button[mat-mini-fab]',
9191
host: {
9292
'[disabled]': 'disabled',
93-
'[class.mat-button-focus]': '_isKeyboardFocused',
94-
'(mousedown)': '_setMousedown()',
95-
'(focus)': '_setKeyboardFocus()',
96-
'(blur)': '_removeKeyboardFocus()',
9793
},
9894
templateUrl: 'button.html',
9995
styleUrls: ['button.css'],
10096
encapsulation: ViewEncapsulation.None,
10197
changeDetection: ChangeDetectionStrategy.OnPush,
10298
})
103-
export class MdButton {
99+
export class MdButton implements OnDestroy {
104100
private _color: string;
105101

106-
/** Whether the button has focus from the keyboard (not the mouse). Used for class binding. */
107-
_isKeyboardFocused: boolean = false;
108-
109-
/** Whether a mousedown has occurred on this element in the last 100ms. */
110-
_isMouseDown: boolean = false;
111-
112102
/** Whether the button is round. */
113103
_isRoundButton: boolean = ['icon-button', 'fab', 'mini-fab'].some(suffix => {
114104
let el = this._getHostElement();
@@ -129,22 +119,20 @@ export class MdButton {
129119
get disabled() { return this._disabled; }
130120
set disabled(value: boolean) { this._disabled = coerceBooleanProperty(value) ? true : null; }
131121

132-
constructor(private _elementRef: ElementRef, private _renderer: Renderer) { }
122+
constructor(private _elementRef: ElementRef, private _renderer: Renderer,
123+
private _focusOriginMonitor: FocusOriginMonitor) {
124+
this._focusOriginMonitor.monitor(this._elementRef.nativeElement, this._renderer, true);
125+
}
126+
127+
ngOnDestroy() {
128+
this._focusOriginMonitor.unmonitor(this._elementRef.nativeElement);
129+
}
133130

134131
/** The color of the button. Can be `primary`, `accent`, or `warn`. */
135132
@Input()
136133
get color(): string { return this._color; }
137134
set color(value: string) { this._updateColor(value); }
138135

139-
_setMousedown() {
140-
// We only *show* the focus style when focus has come to the button via the keyboard.
141-
// The Material Design spec is silent on this topic, and without doing this, the
142-
// button continues to look :active after clicking.
143-
// @see http://marcysutton.com/button-focus-hell/
144-
this._isMouseDown = true;
145-
setTimeout(() => { this._isMouseDown = false; }, 100);
146-
}
147-
148136
_updateColor(newColor: string) {
149137
this._setElementColor(this._color, false);
150138
this._setElementColor(newColor, true);
@@ -157,14 +145,6 @@ export class MdButton {
157145
}
158146
}
159147

160-
_setKeyboardFocus() {
161-
this._isKeyboardFocused = !this._isMouseDown;
162-
}
163-
164-
_removeKeyboardFocus() {
165-
this._isKeyboardFocused = false;
166-
}
167-
168148
/** Focuses the button. */
169149
focus(): void {
170150
this._renderer.invokeElementMethod(this._getHostElement(), 'focus');
@@ -189,19 +169,15 @@ export class MdButton {
189169
host: {
190170
'[attr.disabled]': 'disabled',
191171
'[attr.aria-disabled]': '_isAriaDisabled',
192-
'[class.mat-button-focus]': '_isKeyboardFocused',
193-
'(mousedown)': '_setMousedown()',
194-
'(focus)': '_setKeyboardFocus()',
195-
'(blur)': '_removeKeyboardFocus()',
196172
'(click)': '_haltDisabledEvents($event)',
197173
},
198174
templateUrl: 'button.html',
199175
styleUrls: ['button.css'],
200176
encapsulation: ViewEncapsulation.None
201177
})
202178
export class MdAnchor extends MdButton {
203-
constructor(elementRef: ElementRef, renderer: Renderer) {
204-
super(elementRef, renderer);
179+
constructor(elementRef: ElementRef, renderer: Renderer, focusOriginMonitor: FocusOriginMonitor) {
180+
super(elementRef, renderer, focusOriginMonitor);
205181
}
206182

207183
/** @docs-private */

src/lib/button/index.ts

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,27 @@
1-
import {NgModule, ModuleWithProviders} from '@angular/core';
1+
import {ModuleWithProviders, NgModule} from '@angular/core';
22
import {CommonModule} from '@angular/common';
3-
import {MdRippleModule, CompatibilityModule} from '../core';
3+
import {CompatibilityModule, MdRippleModule, StyleModule} from '../core';
44
import {
5-
MdButton,
65
MdAnchor,
6+
MdButton,
77
MdButtonCssMatStyler,
8-
MdRaisedButtonCssMatStyler,
9-
MdIconButtonCssMatStyler,
108
MdFabCssMatStyler,
9+
MdIconButtonCssMatStyler,
1110
MdMiniFabCssMatStyler,
11+
MdRaisedButtonCssMatStyler
1212
} from './button';
1313

1414

15+
export * from './button';
16+
17+
1518
@NgModule({
16-
imports: [CommonModule, MdRippleModule, CompatibilityModule],
19+
imports: [
20+
CommonModule,
21+
MdRippleModule,
22+
CompatibilityModule,
23+
StyleModule,
24+
],
1725
exports: [
1826
MdButton,
1927
MdAnchor,
@@ -22,7 +30,7 @@ import {
2230
MdRaisedButtonCssMatStyler,
2331
MdIconButtonCssMatStyler,
2432
MdFabCssMatStyler,
25-
MdMiniFabCssMatStyler
33+
MdMiniFabCssMatStyler,
2634
],
2735
declarations: [
2836
MdButton,
@@ -31,7 +39,7 @@ import {
3139
MdRaisedButtonCssMatStyler,
3240
MdIconButtonCssMatStyler,
3341
MdFabCssMatStyler,
34-
MdMiniFabCssMatStyler
42+
MdMiniFabCssMatStyler,
3543
],
3644
})
3745
export class MdButtonModule {
@@ -43,6 +51,3 @@ export class MdButtonModule {
4351
};
4452
}
4553
}
46-
47-
48-
export * from './button';

0 commit comments

Comments
 (0)