diff --git a/src/lib/button-toggle/button-toggle.html b/src/lib/button-toggle/button-toggle.html
index face84340cfa..2f73348c495d 100644
--- a/src/lib/button-toggle/button-toggle.html
+++ b/src/lib/button-toggle/button-toggle.html
@@ -5,6 +5,8 @@
[checked]="checked"
[disabled]="disabled"
[name]="name"
+ (blur)="_onInputBlur()"
+ (focus)="_onInputFocus()"
(change)="_onInputChange($event)"
(click)="_onInputClick($event)">
@@ -12,3 +14,5 @@
+
+
diff --git a/src/lib/button-toggle/button-toggle.scss b/src/lib/button-toggle/button-toggle.scss
index 78a54939c765..7185f4a58ca1 100644
--- a/src/lib/button-toggle/button-toggle.scss
+++ b/src/lib/button-toggle/button-toggle.scss
@@ -1,4 +1,5 @@
@import '../core/style/elevation';
+@import '../core/a11y/a11y';
$mat-button-toggle-padding: 0 16px !default;
$mat-button-toggle-line-height: 36px !default;
@@ -34,6 +35,11 @@ $mat-button-toggle-border-radius: 2px !default;
.mat-button-toggle {
white-space: nowrap;
font-family: $mat-font-family;
+ position: relative;
+}
+
+.mat-button-toggle.mat-button-toggle-focus .mat-button-toggle-focus-overlay {
+ opacity: 1;
}
.mat-button-toggle-label-content {
@@ -47,3 +53,27 @@ $mat-button-toggle-border-radius: 2px !default;
.mat-button-toggle-label-content > * {
vertical-align: middle;
}
+
+// Overlay to be used as a tint. Note that the same effect can be achieved by using a pseudo
+// element, however we use a proper DOM element in order to be able to disable the default
+// touch action. This makes the buttons more responsive on touch devices.
+.mat-button-toggle-focus-overlay {
+ // The button spec calls for focus on raised buttons (and FABs) to be indicated with a
+ // black, 12% opacity shade over the normal color (for both light and dark themes).
+ background-color: rgba(black, 0.12);
+ border-radius: inherit;
+ pointer-events: none;
+ opacity: 0;
+ position: absolute;
+ top: 0;
+ left: 0;
+ bottom: 0;
+ right: 0;
+
+ @include cdk-high-contrast {
+ // Note that IE will render this in the same way, no
+ // matter whether the theme is light or dark. This helps
+ // with the readability of focused buttons.
+ background-color: rgba(white, 0.5);
+ }
+}
diff --git a/src/lib/button-toggle/button-toggle.ts b/src/lib/button-toggle/button-toggle.ts
index a34cbb15134b..56e99f45d7f1 100644
--- a/src/lib/button-toggle/button-toggle.ts
+++ b/src/lib/button-toggle/button-toggle.ts
@@ -276,7 +276,6 @@ export class MdButtonToggleGroupMultiple {
set vertical(value) {
this._vertical = coerceBooleanProperty(value);
}
-
}
/** Single button inside of a toggle group. */
@@ -287,13 +286,21 @@ export class MdButtonToggleGroupMultiple {
styleUrls: ['button-toggle.css'],
encapsulation: ViewEncapsulation.None,
host: {
- '[class.mat-button-toggle]': 'true'
+ '[class.mat-button-toggle-focus]': '_hasFocus',
+ '[class.mat-button-toggle]': 'true',
+ '(mousedown)': '_setMousedown()',
}
})
export class MdButtonToggle implements OnInit {
/** Whether or not this button toggle is checked. */
private _checked: boolean = false;
+ /** Whether the button has focus. Used for class binding. */
+ _hasFocus: boolean = false;
+
+ /** Whether a mousedown has occurred on this element in the last 100ms. */
+ _isMouseDown: boolean = false;
+
/** Type of the button toggle. Either 'radio' or 'checkbox'. */
_type: ToggleType;
@@ -461,10 +468,31 @@ export class MdButtonToggle implements OnInit {
event.stopPropagation();
}
+ _onInputFocus() {
+ // Only show the focus / ripple indicator when the focus was not triggered by a mouse
+ // interaction on the component.
+ if (!this._isMouseDown) {
+ this._hasFocus = true;
+ }
+ }
+
+ _onInputBlur() {
+ this._hasFocus = false;
+ }
+
/** Focuses the button. */
focus() {
this._renderer.invokeElementMethod(this._inputElement.nativeElement, 'focus');
}
+
+ _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;
+ setTimeout(() => { this._isMouseDown = false; }, 100);
+ }
}