diff --git a/README.md b/README.md index 63b9db6cd2be..7a5b8ec63172 100644 --- a/README.md +++ b/README.md @@ -38,16 +38,16 @@ and which pieces are blocked) and make a comment. Also see our [`Good for community contribution`](https://github.com/angular/material2/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+for+community+contribution%22) label. -High level items planned for January 2017: - -* Initial version of md-autocomplete -* Prototyping for data-table -* Improvements to https://material.angular.io -* Continued expanding e2e test coverage -* More work on scroll / resize handling for overlays -* Screenshot tests -* Better development automation +High level items planned for next few months: +- Initial version of datepicker +- Initial version of data table +- Initial version of tree +- Select improvements (multi-select, etc) +- Screenshot test improvements +- Docs site improvements +- A11y audit +- Various bug fixes #### Feature status: @@ -76,7 +76,7 @@ High level items planned for January 2017: | snackbar / toast | Available | [README][21] | [#115][0115] | | select | Available | [README][23] | [#118][0118] | | textarea | Available | [README][5] | - | -| autocomplete | In-progress | - | [#117][0117] | +| autocomplete | Initial version, features evolving | [README][24] | [#117][0117] | | chips | Initial version, features evolving | - | [#120][0120] | | theming | Available, need guidance overlays | [Guide][20] | - | | docs site | UX design and tooling in progress | - | - | @@ -86,36 +86,37 @@ High level items planned for January 2017: | bottom-sheet | Not started | - | - | | bottom-nav | Not started | - | [#408][0408] | | virtual-repeat | Not started | - | [#823][0823] | -| datepicker | Not started | - | [#675][0675] | +| datepicker | In progress | - | [#675][0675] | | data-table | Design in-progress | - | [#581][0581] | | stepper | Not started | - | [#508][0508] | | layout | See [angular/flex-layout][lay_rp] | [Wiki][0] | - | [lay_rp]: https://github.com/angular/flex-layout [0]: https://github.com/angular/flex-layout/wiki - [1]: https://github.com/angular/material2/blob/master/src/lib/button/README.md - [2]: https://github.com/angular/material2/blob/master/src/lib/card/README.md - [3]: https://github.com/angular/material2/blob/master/src/lib/checkbox/README.md - [4]: https://github.com/angular/material2/blob/master/src/lib/radio/README.md - [5]: https://github.com/angular/material2/blob/master/src/lib/input/README.md - [6]: https://github.com/angular/material2/blob/master/src/lib/sidenav/README.md - [7]: https://github.com/angular/material2/blob/master/src/lib/toolbar/README.md - [8]: https://github.com/angular/material2/blob/master/src/lib/list/README.md - [9]: https://github.com/angular/material2/blob/master/src/lib/grid-list/README.md -[10]: https://github.com/angular/material2/blob/master/src/lib/icon/README.md -[11]: https://github.com/angular/material2/blob/master/src/lib/progress-spinner/README.md -[12]: https://github.com/angular/material2/blob/master/src/lib/progress-bar/README.md -[13]: https://github.com/angular/material2/blob/master/src/lib/tabs/README.md -[14]: https://github.com/angular/material2/blob/master/src/lib/slide-toggle/README.md -[15]: https://github.com/angular/material2/blob/master/src/lib/button-toggle/README.md -[16]: https://github.com/angular/material2/blob/master/src/lib/slider/README.md -[17]: https://github.com/angular/material2/blob/master/src/lib/menu/README.md -[18]: https://github.com/angular/material2/blob/master/src/lib/tooltip/README.md + [1]: https://material.angular.io/components/component/button + [2]: https://material.angular.io/components/component/card + [3]: https://material.angular.io/components/component/checkbox + [4]: https://material.angular.io/components/component/radio + [5]: https://material.angular.io/components/component/input + [6]: https://material.angular.io/components/component/sidenav + [7]: https://material.angular.io/components/component/toolbar + [8]: https://material.angular.io/components/component/list + [9]: https://material.angular.io/components/component/grid-list +[10]: https://material.angular.io/components/component/icon +[11]: https://material.angular.io/components/component/progress-spinner +[12]: https://material.angular.io/components/component/progress-bar +[13]: https://material.angular.io/components/component/tabs +[14]: https://material.angular.io/components/component/slide-toggle +[15]: https://material.angular.io/components/component/button-toggle +[16]: https://material.angular.io/components/component/slider +[17]: https://material.angular.io/components/component/menu +[18]: https://material.angular.io/components/component/tooltip [19]: https://github.com/angular/material2/blob/master/src/lib/core/ripple/README.md [20]: https://github.com/angular/material2/blob/master/guides/theming.md -[21]: https://github.com/angular/material2/blob/master/src/lib/snack-bar/README.md -[22]: https://github.com/angular/material2/blob/master/src/lib/dialog/README.md -[23]: https://github.com/angular/material2/blob/master/src/lib/select/README.md +[21]: https://material.angular.io/components/component/snack-bar +[22]: https://material.angular.io/components/component/dialog +[23]: https://material.angular.io/components/component/select +[24]: https://material.angular.io/components/component/autocomplete [0107]: https://github.com/angular/material2/issues/107 [0119]: https://github.com/angular/material2/issues/119 diff --git a/e2e/components/slide-toggle/slide-toggle.e2e.ts b/e2e/components/slide-toggle/slide-toggle.e2e.ts index c681c093942f..38808fed43c4 100644 --- a/e2e/components/slide-toggle/slide-toggle.e2e.ts +++ b/e2e/components/slide-toggle/slide-toggle.e2e.ts @@ -1,4 +1,4 @@ -import {browser, element, by, Key} from 'protractor'; +import {browser, element, by, Key, ExpectedConditions} from 'protractor'; import {expectToExist} from '../../util/asserts'; import {screenshot} from '../../screenshot'; @@ -21,7 +21,9 @@ describe('slide-toggle', () => { getNormalToggle().click(); expect(inputEl.getAttribute('checked')).toBeTruthy('Expect slide-toggle to be checked'); - screenshot(); + browser.wait(ExpectedConditions.not( + ExpectedConditions.presenceOf(element(by.css('div.mat-ripple-element'))))) + .then(() => screenshot()); }); it('should change the checked state on click', () => { @@ -32,7 +34,9 @@ describe('slide-toggle', () => { getNormalToggle().click(); expect(inputEl.getAttribute('checked')).toBeTruthy('Expect slide-toggle to be checked'); - screenshot(); + browser.wait(ExpectedConditions.not( + ExpectedConditions.presenceOf(element(by.css('div.mat-ripple-element'))))) + .then(() => screenshot()); }); it('should not change the checked state on click when disabled', () => { @@ -43,7 +47,9 @@ describe('slide-toggle', () => { element(by.css('#disabled-slide-toggle')).click(); expect(inputEl.getAttribute('checked')).toBeFalsy('Expect slide-toggle to be unchecked'); - screenshot(); + browser.wait(ExpectedConditions.not( + ExpectedConditions.presenceOf(element(by.css('div.mat-ripple-element'))))) + .then(() => screenshot()); }); it('should move the thumb on state change', () => { @@ -57,7 +63,9 @@ describe('slide-toggle', () => { let newX = thumbEl.getLocation().then(pos => pos.x); expect(previousX).not.toBe(newX); - screenshot(); + browser.wait(ExpectedConditions.not( + ExpectedConditions.presenceOf(element(by.css('div.mat-ripple-element'))))) + .then(() => screenshot()); }); it('should toggle the slide-toggle on space key', () => { diff --git a/e2e/screenshot.ts b/e2e/screenshot.ts index e5df95c695d0..f6a2d5af0901 100644 --- a/e2e/screenshot.ts +++ b/e2e/screenshot.ts @@ -3,11 +3,14 @@ import * as path from 'path'; import {browser} from 'protractor'; const OUTPUT_DIR = './screenshots/'; +const HEIGHT = 768; +const WIDTH = 1024; let currentJasmineSpecName = ''; /** Adds a custom jasmine reporter that simply keeps track of the current test name. */ function initializeEnvironment(jasmine: any) { + browser.manage().window().setSize(WIDTH, HEIGHT); let reporter = new jasmine.JsApiReporter({}); reporter.specStarted = function(result: any) { currentJasmineSpecName = result.fullName; diff --git a/guides/theming-your-components.md b/guides/theming-your-components.md index 91750546d8e8..6922749b1b29 100644 --- a/guides/theming-your-components.md +++ b/guides/theming-your-components.md @@ -22,7 +22,7 @@ All you need is to create a `@mixin` function in the custom-component-theme.scss $primary: map-get($theme, primary); $accent: map-get($theme, accent); - // Use md-color to extract individual colors from a palette as necessary. + // Use mat-color to extract individual colors from a palette as necessary. .candy-carousel { background-color: mat-color($primary); border-color: mat-color($accent, A400); diff --git a/package.json b/package.json index 427b8a5f5ff1..302cdd0297bc 100644 --- a/package.json +++ b/package.json @@ -41,6 +41,7 @@ "@angular/platform-browser-dynamic": "^2.3.0", "@angular/platform-server": "^2.3.0", "@angular/router": "^3.3.0", + "@types/fs-extra": "0.0.37", "@types/glob": "^5.0.30", "@types/gulp": "^3.8.32", "@types/hammerjs": "^2.0.34", @@ -59,6 +60,7 @@ "firebase-tools": "^2.2.1", "fs-extra": "^2.0.0", "glob": "^7.1.1", + "google-cloud": "^0.45.1", "gulp": "^3.9.1", "gulp-autoprefixer": "^3.1.1", "gulp-better-rollup": "^1.0.2", @@ -77,6 +79,7 @@ "gulp-transform": "^1.1.0", "hammerjs": "^2.0.8", "highlight.js": "^9.9.0", + "image-diff": "^1.6.3", "jasmine-core": "^2.5.2", "karma": "^1.4.1", "karma-browserstack-launcher": "^1.2.0", diff --git a/src/demo-app/checkbox/checkbox-demo.html b/src/demo-app/checkbox/checkbox-demo.html index 713f8b008d4c..73fdfc6e2c91 100644 --- a/src/demo-app/checkbox/checkbox-demo.html +++ b/src/demo-app/checkbox/checkbox-demo.html @@ -43,5 +43,15 @@

md-checkbox: Basic Example

+

Pseudo checkboxes

+ + + + + + + + +

Nested Checklist

diff --git a/src/demo-app/demo-app-module.ts b/src/demo-app/demo-app-module.ts index 9f66cf8016ba..0263eff112fc 100644 --- a/src/demo-app/demo-app-module.ts +++ b/src/demo-app/demo-app-module.ts @@ -4,7 +4,12 @@ import {HttpModule} from '@angular/http'; import {FormsModule, ReactiveFormsModule} from '@angular/forms'; import {DemoApp, Home} from './demo-app/demo-app'; import {RouterModule} from '@angular/router'; -import {MaterialModule, OverlayContainer, FullscreenOverlayContainer} from '@angular/material'; +import { + MaterialModule, + OverlayContainer, + FullscreenOverlayContainer, + MdSelectionModule, +} from '@angular/material'; import {DEMO_APP_ROUTES} from './demo-app/routes'; import {ProgressBarDemo} from './progress-bar/progress-bar-demo'; import {JazzDialog, ContentElementDialog, DialogDemo, IFrameDialog} from './dialog/dialog-demo'; @@ -47,6 +52,7 @@ import {StyleDemo} from './style/style-demo'; ReactiveFormsModule, RouterModule.forRoot(DEMO_APP_ROUTES), MaterialModule.forRoot(), + MdSelectionModule, ], declarations: [ AutocompleteDemo, @@ -93,7 +99,7 @@ import {StyleDemo} from './style/style-demo'; SunnyTabContent, RainyTabContent, FoggyTabContent, - PlatformDemo + PlatformDemo, ], providers: [ {provide: OverlayContainer, useClass: FullscreenOverlayContainer} diff --git a/src/demo-app/select/select-demo.html b/src/demo-app/select/select-demo.html index 4471ebc92c54..821934b4b59f 100644 --- a/src/demo-app/select/select-demo.html +++ b/src/demo-app/select/select-demo.html @@ -18,7 +18,7 @@ + [floatPlaceholder]="floatPlaceholder" #drinkControl="ngModel"> {{ drink.viewValue }} @@ -27,6 +27,15 @@

Touched: {{ drinkControl.touched }}

Dirty: {{ drinkControl.dirty }}

Status: {{ drinkControl.control?.status }}

+

+ + +

+ diff --git a/src/demo-app/select/select-demo.ts b/src/demo-app/select/select-demo.ts index 0b369e0c137b..b731087b5624 100644 --- a/src/demo-app/select/select-demo.ts +++ b/src/demo-app/select/select-demo.ts @@ -14,6 +14,7 @@ export class SelectDemo { showSelect = false; currentDrink: string; latestChangeEvent: MdSelectChange; + floatPlaceholder: string = 'auto'; foodControl = new FormControl('pizza-1'); foods = [ diff --git a/src/lib/autocomplete/autocomplete-trigger.ts b/src/lib/autocomplete/autocomplete-trigger.ts index b6e841046605..2368cdcd1e01 100644 --- a/src/lib/autocomplete/autocomplete-trigger.ts +++ b/src/lib/autocomplete/autocomplete-trigger.ts @@ -61,7 +61,7 @@ export const MD_AUTOCOMPLETE_VALUE_ACCESSOR: any = { '[attr.aria-owns]': 'autocomplete?.id', '(focus)': 'openPanel()', '(blur)': '_handleBlur($event.relatedTarget?.tagName)', - '(input)': '_handleInput($event.target.value)', + '(input)': '_handleInput($event)', '(keydown)': '_handleKeydown($event)', }, providers: [MD_AUTOCOMPLETE_VALUE_ACCESSOR] @@ -153,15 +153,15 @@ export class MdAutocompleteTrigger implements AfterContentInit, ControlValueAcce */ get panelClosingActions(): Observable { return Observable.merge( - ...this.optionSelections, + this.optionSelections, this._blurStream.asObservable(), this._keyManager.tabOut ); } /** Stream of autocomplete option selections. */ - get optionSelections(): Observable[] { - return this.autocomplete.options.map(option => option.onSelect); + get optionSelections(): Observable { + return Observable.merge(...this.autocomplete.options.map(option => option.onSelect)); } /** The currently active option, coerced to MdOption type. */ @@ -213,9 +213,14 @@ export class MdAutocompleteTrigger implements AfterContentInit, ControlValueAcce } } - _handleInput(value: string): void { - this._onChange(value); - this.openPanel(); + _handleInput(event: KeyboardEvent): void { + // We need to ensure that the input is focused, because IE will fire the `input` + // event on focus/blur/load if the input has a placeholder. See: + // https://connect.microsoft.com/IE/feedback/details/885747/ + if (document.activeElement === event.target) { + this._onChange((event.target as HTMLInputElement).value); + this.openPanel(); + } } _handleBlur(newlyFocusedTag: string): void { diff --git a/src/lib/autocomplete/autocomplete.spec.ts b/src/lib/autocomplete/autocomplete.spec.ts index e533ae34704c..5baee70ad18e 100644 --- a/src/lib/autocomplete/autocomplete.spec.ts +++ b/src/lib/autocomplete/autocomplete.spec.ts @@ -124,8 +124,7 @@ describe('MdAutocomplete', () => { fixture.whenStable().then(() => { // Filter down the option list to a subset of original options ('Alabama', 'California') - input.value = 'al'; - dispatchEvent('input', input); + typeInElement('al', input); fixture.detectChanges(); let options = @@ -134,8 +133,7 @@ describe('MdAutocomplete', () => { // Changing value from 'Alabama' to 'al' to re-populate the option list, // ensuring that 'California' is created new. - input.value = 'al'; - dispatchEvent('input', input); + typeInElement('al', input); fixture.detectChanges(); fixture.whenStable().then(() => { @@ -177,8 +175,7 @@ describe('MdAutocomplete', () => { .toContain('mat-autocomplete-visible', `Expected panel to start out visible.`); // Filter down the option list such that no options match the value - input.value = 'af'; - dispatchEvent('input', input); + typeInElement('af', input); fixture.detectChanges(); fixture.whenStable().then(() => { @@ -210,6 +207,18 @@ describe('MdAutocomplete', () => { }); })); + it('should not open the panel when the `input` event is invoked on a non-focused input', () => { + expect(fixture.componentInstance.trigger.panelOpen) + .toBe(false, `Expected panel state to start out closed.`); + + input.value = 'Alabama'; + dispatchEvent('input', input); + fixture.detectChanges(); + + expect(fixture.componentInstance.trigger.panelOpen) + .toBe(false, `Expected panel state to stay closed.`); + }); + }); it('should have the correct text direction in RTL', () => { @@ -241,15 +250,13 @@ describe('MdAutocomplete', () => { fixture.componentInstance.trigger.openPanel(); fixture.detectChanges(); - input.value = 'a'; - dispatchEvent('input', input); + typeInElement('a', input); fixture.detectChanges(); expect(fixture.componentInstance.stateCtrl.value) .toEqual('a', 'Expected control value to be updated as user types.'); - input.value = 'al'; - dispatchEvent('input', input); + typeInElement('al', input); fixture.detectChanges(); expect(fixture.componentInstance.stateCtrl.value) @@ -282,8 +289,7 @@ describe('MdAutocomplete', () => { options[1].click(); fixture.detectChanges(); - input.value = 'Californi'; - dispatchEvent('input', input); + typeInElement('Californi', input); fixture.detectChanges(); expect(fixture.componentInstance.stateCtrl.value) @@ -339,8 +345,7 @@ describe('MdAutocomplete', () => { })); it('should clear the text field if value is reset programmatically', async(() => { - input.value = 'Alabama'; - dispatchEvent('input', input); + typeInElement('Alabama', input); fixture.detectChanges(); fixture.whenStable().then(() => { @@ -376,8 +381,7 @@ describe('MdAutocomplete', () => { expect(fixture.componentInstance.stateCtrl.dirty) .toBe(false, `Expected control to start out pristine.`); - input.value = 'a'; - dispatchEvent('input', input); + typeInElement('a', input); fixture.detectChanges(); expect(fixture.componentInstance.stateCtrl.dirty) @@ -531,8 +535,7 @@ describe('MdAutocomplete', () => { fixture.detectChanges(); fixture.whenStable().then(() => { - input.value = 'o'; - dispatchEvent('input', input); + typeInElement('o', input); fixture.detectChanges(); fixture.componentInstance.trigger._handleKeydown(DOWN_ARROW_EVENT); @@ -565,8 +568,7 @@ describe('MdAutocomplete', () => { it('should fill the text field, not select an option, when SPACE is entered', async(() => { fixture.whenStable().then(() => { - input.value = 'New'; - dispatchEvent('input', input); + typeInElement('New', input); fixture.detectChanges(); const SPACE_EVENT = new FakeKeyboardEvent(SPACE) as KeyboardEvent; @@ -604,8 +606,7 @@ describe('MdAutocomplete', () => { expect(overlayContainerElement.textContent) .toEqual('', `Expected panel to close after ENTER key.`); - input.value = 'Alabam'; - dispatchEvent('input', input); + typeInElement('Alabama', input); fixture.detectChanges(); expect(fixture.componentInstance.trigger.panelOpen) @@ -782,8 +783,7 @@ describe('MdAutocomplete', () => { fixture.detectChanges(); fixture.whenStable().then(() => { - input.value = 'f'; - dispatchEvent('input', input); + typeInElement('f', input); fixture.detectChanges(); const inputTop = input.getBoundingClientRect().top; @@ -808,8 +808,7 @@ describe('MdAutocomplete', () => { fixture.detectChanges(); const input = fixture.debugElement.query(By.css('input')).nativeElement; - input.value = 'd'; - dispatchEvent('input', input); + typeInElement('d', input); fixture.detectChanges(); const options = @@ -826,7 +825,7 @@ describe('MdAutocomplete', () => { - + {{ state.code }}: {{ state.name }} @@ -881,10 +880,10 @@ class SimpleAutocomplete implements OnDestroy { @Component({ template: ` - - + {{ state }} @@ -920,6 +919,19 @@ function dispatchEvent(eventName: string, element: HTMLElement): void { element.dispatchEvent(event); } + +/** + * Focuses an input, sets its value and dispatches + * the `input` event, simulating the user typing. + * @param value Value to be set on the input. + * @param element Element onto which to set the value. + */ +function typeInElement(value: string, element: HTMLInputElement) { + element.focus(); + element.value = value; + dispatchEvent('input', element); +} + /** This is a mock keyboard event to test keyboard events in the autocomplete. */ class FakeKeyboardEvent { constructor(public keyCode: number) {} diff --git a/src/lib/button-toggle/_button-toggle-theme.scss b/src/lib/button-toggle/_button-toggle-theme.scss index 4b7f6c9309f3..912ade1b3428 100644 --- a/src/lib/button-toggle/_button-toggle-theme.scss +++ b/src/lib/button-toggle/_button-toggle-theme.scss @@ -1,6 +1,14 @@ @import '../core/theming/palette'; @import '../core/theming/theming'; +// Applies a focus style to an md-button-toggle element for each of the supported palettes. +@mixin _mat-button-toggle-focus-color($theme) { + $background: map-get($theme, background); + + .mat-button-toggle-focus-overlay { + background-color: mat-color($background, focused-button); + } +} @mixin mat-button-toggle-theme($theme) { $foreground: map-get($theme, foreground); @@ -8,6 +16,10 @@ .mat-button-toggle { color: mat-color($foreground, hint-text); + + &.cdk-focused { + @include _mat-button-toggle-focus-color($theme); + } } .mat-button-toggle-checked { diff --git a/src/lib/button-toggle/button-toggle.html b/src/lib/button-toggle/button-toggle.html index face84340cfa..fffdfa7c3e25 100644 --- a/src/lib/button-toggle/button-toggle.html +++ b/src/lib/button-toggle/button-toggle.html @@ -12,3 +12,5 @@ + +
diff --git a/src/lib/button-toggle/button-toggle.scss b/src/lib/button-toggle/button-toggle.scss index 78a54939c765..eea47e3edaab 100644 --- a/src/lib/button-toggle/button-toggle.scss +++ b/src/lib/button-toggle/button-toggle.scss @@ -1,4 +1,6 @@ +@import '../core/a11y/a11y'; @import '../core/style/elevation'; +@import '../core/style/layout-common'; $mat-button-toggle-padding: 0 16px !default; $mat-button-toggle-line-height: 36px !default; @@ -34,6 +36,11 @@ $mat-button-toggle-border-radius: 2px !default; .mat-button-toggle { white-space: nowrap; font-family: $mat-font-family; + position: relative; +} + +.mat-button-toggle.cdk-keyboard-focused .mat-button-toggle-focus-overlay { + opacity: 1; } .mat-button-toggle-label-content { @@ -47,3 +54,13 @@ $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 { + border-radius: inherit; + pointer-events: none; + opacity: 0; + @include mat-fill; +} diff --git a/src/lib/button-toggle/button-toggle.ts b/src/lib/button-toggle/button-toggle.ts index a34cbb15134b..7bc964988040 100644 --- a/src/lib/button-toggle/button-toggle.ts +++ b/src/lib/button-toggle/button-toggle.ts @@ -21,6 +21,7 @@ import { import {NG_VALUE_ACCESSOR, ControlValueAccessor, FormsModule} from '@angular/forms'; import {Observable} from 'rxjs/Observable'; import { + FocusOriginMonitor, UniqueSelectionDispatcher, coerceBooleanProperty, UNIQUE_SELECTION_DISPATCHER_PROVIDER, @@ -276,7 +277,6 @@ export class MdButtonToggleGroupMultiple { set vertical(value) { this._vertical = coerceBooleanProperty(value); } - } /** Single button inside of a toggle group. */ @@ -332,7 +332,9 @@ export class MdButtonToggle implements OnInit { constructor(@Optional() toggleGroup: MdButtonToggleGroup, @Optional() toggleGroupMultiple: MdButtonToggleGroupMultiple, public buttonToggleDispatcher: UniqueSelectionDispatcher, - private _renderer: Renderer) { + private _renderer: Renderer, + private _elementRef: ElementRef, + private _focusOriginMonitor: FocusOriginMonitor) { this.buttonToggleGroup = toggleGroup; this.buttonToggleGroupMultiple = toggleGroupMultiple; @@ -363,6 +365,7 @@ export class MdButtonToggle implements OnInit { if (this.buttonToggleGroup && this._value == this.buttonToggleGroup.value) { this._checked = true; } + this._focusOriginMonitor.monitor(this._elementRef.nativeElement, this._renderer, true); } /** Unique ID for the underlying `input` element. */ @@ -477,7 +480,7 @@ export class MdButtonToggle implements OnInit { CompatibilityModule, ], declarations: [MdButtonToggleGroup, MdButtonToggleGroupMultiple, MdButtonToggle], - providers: [UNIQUE_SELECTION_DISPATCHER_PROVIDER] + providers: [UNIQUE_SELECTION_DISPATCHER_PROVIDER, FocusOriginMonitor] }) export class MdButtonToggleModule { /** @deprecated */ diff --git a/src/lib/button/button.html b/src/lib/button/button.html index d13ade40bef4..d29f2dc600a4 100644 --- a/src/lib/button/button.html +++ b/src/lib/button/button.html @@ -1,6 +1,6 @@
diff --git a/src/lib/button/button.ts b/src/lib/button/button.ts index 29a12d1d3173..029e152a12dc 100644 --- a/src/lib/button/button.ts +++ b/src/lib/button/button.ts @@ -106,6 +106,12 @@ export class MdButton { /** Whether a mousedown has occurred on this element in the last 100ms. */ _isMouseDown: boolean = false; + /** Whether the button is round. */ + _isRoundButton: boolean = ['icon-button', 'fab', 'mini-fab'].some(suffix => { + let el = this._getHostElement(); + return el.hasAttribute('md-' + suffix) || el.hasAttribute('mat-' + suffix); + }); + /** Whether the ripple effect on click should be disabled. */ private _disableRipple: boolean = false; private _disabled: boolean = null; @@ -165,13 +171,6 @@ export class MdButton { return this._elementRef.nativeElement; } - _isRoundButton() { - const el = this._getHostElement(); - return el.hasAttribute('md-icon-button') || - el.hasAttribute('md-fab') || - el.hasAttribute('md-mini-fab'); - } - _isRippleDisabled() { return this.disableRipple || this.disabled; } diff --git a/src/lib/checkbox/_checkbox-theme.scss b/src/lib/checkbox/_checkbox-theme.scss index cf025e1a0b37..b36d64526f67 100644 --- a/src/lib/checkbox/_checkbox-theme.scss +++ b/src/lib/checkbox/_checkbox-theme.scss @@ -9,9 +9,6 @@ $background: map-get($theme, background); - // The color of the checkbox border. - $checkbox-border-color: if($is-dark-theme, rgba(white, 0.7), rgba(black, 0.54)) !default; - // The color of the checkbox's checkmark / mixedmark. $checkbox-mark-color: mat-color($background, background); @@ -23,7 +20,7 @@ $disabled-color: if($is-dark-theme, $white-30pct-opacity-on-dark, $black-26pct-opacity-on-light); .mat-checkbox-frame { - border-color: $checkbox-border-color; + border-color: mat-color(map-get($theme, foreground), secondary-text); } .mat-checkbox-checkmark { diff --git a/src/lib/checkbox/checkbox.html b/src/lib/checkbox/checkbox.html index d9dc0a5a2120..185e28b16ea9 100644 --- a/src/lib/checkbox/checkbox.html +++ b/src/lib/checkbox/checkbox.html @@ -1,4 +1,4 @@ -