diff --git a/src/components/checkbox/checkbox.ts b/src/components/checkbox/checkbox.ts index 10b7e5ff0e74..374b1ff9d444 100644 --- a/src/components/checkbox/checkbox.ts +++ b/src/components/checkbox/checkbox.ts @@ -127,7 +127,7 @@ export class MdCheckbox implements AfterContentInit, ControlValueAccessor { private _indeterminate: boolean = false; - private _changeSubscription: {unsubscribe: () => any} = null; + private _controlValueAccessorChangeFn: (value: any) => void = (value) => {}; hasFocus: boolean = false; @@ -195,11 +195,8 @@ export class MdCheckbox implements AfterContentInit, ControlValueAccessor { * Implemented as part of ControlValueAccessor. * TODO: internal */ - registerOnChange(fn: any) { - if (this._changeSubscription) { - this._changeSubscription.unsubscribe(); - } - this._changeSubscription = <{unsubscribe: () => any}>this.change.subscribe(fn); + registerOnChange(fn: (value: any) => void) { + this._controlValueAccessorChangeFn = fn; } /** @@ -236,6 +233,7 @@ export class MdCheckbox implements AfterContentInit, ControlValueAccessor { event.source = this; event.checked = this.checked; + this._controlValueAccessorChangeFn(this.checked); this.change.emit(event); } diff --git a/src/components/radio/radio.html b/src/components/radio/radio.html index 249e35f67b43..7a205d7f7a5e 100644 --- a/src/components/radio/radio.html +++ b/src/components/radio/radio.html @@ -20,7 +20,7 @@ (blur)="onInputBlur()" /> -
+
diff --git a/src/components/radio/radio.scss b/src/components/radio/radio.scss index 24d66cc2cf78..703b9ef4ecd7 100644 --- a/src/components/radio/radio.scss +++ b/src/components/radio/radio.scss @@ -13,7 +13,8 @@ md-radio-button { // Enables focus by click. .md-radio-label { cursor: pointer; - display: block; + display: inline-flex; + align-items: baseline; white-space: nowrap; } @@ -23,8 +24,8 @@ md-radio-button { display: inline-block; height: $md-radio-size; position: relative; - top: 2px; width: $md-radio-size; + top: 2px; } // The outer circle for the radio, always present. @@ -74,19 +75,29 @@ md-radio-button { // Text label next to radio. .md-radio-label-content { display: inline-block; - float: right; - line-height: 24px; + order: 0; + line-height: inherit; padding-left: $md-toggle-padding; - position: relative; - vertical-align: top; + padding-right: 0; [dir='rtl'] & { - float: left; padding-right: $md-toggle-padding; padding-left: 0; } } +// Alignment. +.md-radio-label-content.md-radio-align-end { + order: -1; + padding-left: 0; + padding-right: $md-toggle-padding; + + [dir='rtl'] & { + padding-right: 0; + padding-left: $md-toggle-padding; + } +} + // Underlying native input element. // Visually hidden but still able to respond to focus. .md-radio-input { diff --git a/src/components/radio/radio.spec.ts b/src/components/radio/radio.spec.ts index 96405e80976c..42e10572d17c 100644 --- a/src/components/radio/radio.spec.ts +++ b/src/components/radio/radio.spec.ts @@ -75,6 +75,22 @@ describe('MdRadio', () => { expect(radioInstances[0].checked).toBe(false); }); + it('should set alignment based on the group alignment', () => { + testComponent.alignment = 'end'; + fixture.detectChanges(); + + for (let radio of radioInstances) { + expect(radio.align).toBe('end'); + } + + testComponent.alignment = 'start'; + fixture.detectChanges(); + + for (let radio of radioInstances) { + expect(radio.align).toBe('start'); + } + }); + it('should disable each individual radio when the group is disabled', () => { testComponent.isGroupDisabled = true; fixture.detectChanges(); @@ -452,7 +468,10 @@ describe('MdRadio', () => { @Component({ directives: [MD_RADIO_DIRECTIVES], template: ` - + Charmander Squirtle Bulbasaur @@ -460,6 +479,7 @@ describe('MdRadio', () => { ` }) class RadiosInsideRadioGroup { + alignment: string; isGroupDisabled: boolean = false; groupValue: string = null; } diff --git a/src/components/radio/radio.ts b/src/components/radio/radio.ts index 94114db1f717..9c15fb3a01ac 100644 --- a/src/components/radio/radio.ts +++ b/src/components/radio/radio.ts @@ -108,6 +108,8 @@ export class MdRadioGroup implements AfterContentInit, ControlValueAccessor { this._updateRadioButtonNames(); } + @Input() align: 'start' | 'end'; + @Input() get disabled(): boolean { return this._disabled; @@ -333,6 +335,17 @@ export class MdRadioButton implements OnInit { } } + private _align: 'start' | 'end'; + + @Input() + get align(): 'start' | 'end' { + return this._align || (this.radioGroup != null && this.radioGroup.align) || 'start'; + } + + set align(value: 'start' | 'end') { + this._align = value; + } + @HostBinding('class.md-radio-disabled') @Input() get disabled(): boolean { diff --git a/src/demo-app/baseline/baseline-demo.html b/src/demo-app/baseline/baseline-demo.html new file mode 100644 index 000000000000..f745b02f22cd --- /dev/null +++ b/src/demo-app/baseline/baseline-demo.html @@ -0,0 +1,35 @@ + + Basic Forms + + Text Before | + Checkbox Label + | Text 1 | + Radio 1 + | Text 2 | + Radio 2 + | Text 3 | + Radio 3 + | Text 4 | + Label + | Text After + + + + + Headers + +

+ Text Before | + Checkbox Label + | Text 1 | + Radio 1 + | Text 2 | + Radio 2 + | Text 3 | + Radio 3 + | Text 4 | + Label + | Text After +

+
+
diff --git a/src/demo-app/baseline/baseline-demo.scss b/src/demo-app/baseline/baseline-demo.scss new file mode 100644 index 000000000000..4ec33a506a96 --- /dev/null +++ b/src/demo-app/baseline/baseline-demo.scss @@ -0,0 +1,30 @@ +@import 'default-theme'; +@import 'variables'; + +.demo-basic { + padding: 0; +} +.demo-basic md-card-content { + padding: 16px; +} +.demo-full-width { + width: 100%; +} + +.demo-icons { + font-size: 100%; + height: inherit; + vertical-align: top; + width: inherit; +} + +.demo-transform { + transition: color $swift-ease-out-duration $swift-ease-out-timing-function; +} +.demo-primary { + color: md-color($md-primary); +} + +.demo-card { + margin: 16px; +} diff --git a/src/demo-app/baseline/baseline-demo.ts b/src/demo-app/baseline/baseline-demo.ts new file mode 100644 index 000000000000..76666c077399 --- /dev/null +++ b/src/demo-app/baseline/baseline-demo.ts @@ -0,0 +1,33 @@ +import {Component} from '@angular/core'; +import {MD_INPUT_DIRECTIVES} from '@angular2-material/input/input'; +import {MD_BUTTON_DIRECTIVES} from '@angular2-material/button/button'; +import {MD_CARD_DIRECTIVES} from '@angular2-material/card/card'; +import {MD_CHECKBOX_DIRECTIVES} from '@angular2-material/checkbox/checkbox'; +import {MD_RADIO_DIRECTIVES} from '@angular2-material/radio/radio'; +import {MdIcon} from '@angular2-material/icon/icon'; +import {MdToolbar} from '@angular2-material/toolbar/toolbar'; + +import { + MdUniqueSelectionDispatcher +} from '@angular2-material/core/coordination/unique-selection-dispatcher'; + + +@Component({ + moduleId: module.id, + selector: 'baseline-demo', + templateUrl: 'baseline-demo.html', + styleUrls: ['baseline-demo.css'], + providers: [MdUniqueSelectionDispatcher], + directives: [ + MD_BUTTON_DIRECTIVES, + MD_CARD_DIRECTIVES, + MD_CHECKBOX_DIRECTIVES, + MD_RADIO_DIRECTIVES, + MD_INPUT_DIRECTIVES, + MdIcon, + MdToolbar + ] +}) +export class BaselineDemo { + name: string; +} diff --git a/src/demo-app/demo-app/demo-app.html b/src/demo-app/demo-app/demo-app.html index b3219d41312c..b7ec903b17f0 100644 --- a/src/demo-app/demo-app/demo-app.html +++ b/src/demo-app/demo-app/demo-app.html @@ -20,6 +20,8 @@ Slide Toggle Toolbar Tabs +
+ Baseline diff --git a/src/demo-app/demo-app/demo-app.ts b/src/demo-app/demo-app/demo-app.ts index f7320965c4b0..50c07f4298c9 100644 --- a/src/demo-app/demo-app/demo-app.ts +++ b/src/demo-app/demo-app/demo-app.ts @@ -9,6 +9,7 @@ import {MdIcon} from '@angular2-material/icon/icon'; import {MdToolbar} from '@angular2-material/toolbar/toolbar'; import {CardDemo} from '../card/card-demo'; +import {BaselineDemo} from '../baseline/baseline-demo'; import {ButtonDemo} from '../button/button-demo'; import {IconDemo} from '../icon/icon-demo'; import {RadioDemo} from '../radio/radio-demo'; @@ -75,5 +76,7 @@ export class Home {} new Route({path: '/grid-list', component: GridListDemo}), new Route({path: '/tabs', component: TabsDemo}), new Route({path: '/button-toggle', component: ButtonToggleDemo}), + + new Route({path: '/baseline', component: BaselineDemo}) ]) export class DemoApp { } diff --git a/src/demo-app/radio/radio-demo.html b/src/demo-app/radio/radio-demo.html index 802d0070a149..341c6735013c 100644 --- a/src/demo-app/radio/radio-demo.html +++ b/src/demo-app/radio/radio-demo.html @@ -12,7 +12,10 @@

Dynamic Example

Disable buttons
- +
+ Align end +
+ Option 1 Option 2 Option 3 diff --git a/src/demo-app/radio/radio-demo.ts b/src/demo-app/radio/radio-demo.ts index 278058af1ff7..910683caeefb 100644 --- a/src/demo-app/radio/radio-demo.ts +++ b/src/demo-app/radio/radio-demo.ts @@ -1,4 +1,5 @@ import {Component} from '@angular/core'; +import {MdCheckbox} from '@angular2-material/checkbox/checkbox'; import {MdRadioButton, MdRadioGroup} from '@angular2-material/radio/radio'; import { MdUniqueSelectionDispatcher @@ -10,10 +11,11 @@ import { templateUrl: 'radio-demo.html', styleUrls: ['radio-demo.css'], providers: [MdUniqueSelectionDispatcher], - directives: [MdRadioButton, MdRadioGroup] + directives: [MdCheckbox, MdRadioButton, MdRadioGroup] }) export class RadioDemo { isDisabled: boolean = false; + isAlignEnd: boolean = false; favoriteSeason: string = 'Autumn'; seasonOptions = [ 'Winter',