Skip to content

Commit 31f0c7f

Browse files
hansljelbourn
authored andcommitted
fix(radio): fix the baseline of radio buttons (#642)
1 parent 3c3bf0d commit 31f0c7f

File tree

12 files changed

+167
-17
lines changed

12 files changed

+167
-17
lines changed

src/components/checkbox/checkbox.ts

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ export class MdCheckbox implements AfterContentInit, ControlValueAccessor {
127127

128128
private _indeterminate: boolean = false;
129129

130-
private _changeSubscription: {unsubscribe: () => any} = null;
130+
private _controlValueAccessorChangeFn: (value: any) => void = (value) => {};
131131

132132
hasFocus: boolean = false;
133133

@@ -195,11 +195,8 @@ export class MdCheckbox implements AfterContentInit, ControlValueAccessor {
195195
* Implemented as part of ControlValueAccessor.
196196
* TODO: internal
197197
*/
198-
registerOnChange(fn: any) {
199-
if (this._changeSubscription) {
200-
this._changeSubscription.unsubscribe();
201-
}
202-
this._changeSubscription = <{unsubscribe: () => any}>this.change.subscribe(fn);
198+
registerOnChange(fn: (value: any) => void) {
199+
this._controlValueAccessorChangeFn = fn;
203200
}
204201

205202
/**
@@ -236,6 +233,7 @@ export class MdCheckbox implements AfterContentInit, ControlValueAccessor {
236233
event.source = this;
237234
event.checked = this.checked;
238235

236+
this._controlValueAccessorChangeFn(this.checked);
239237
this.change.emit(event);
240238
}
241239

src/components/radio/radio.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
(blur)="onInputBlur()" />
2121

2222
<!-- The label content for radio control. -->
23-
<div class="md-radio-label-content">
23+
<div class="md-radio-label-content" [class.md-radio-align-end]="align == 'end'">
2424
<ng-content></ng-content>
2525
</div>
2626
</label>

src/components/radio/radio.scss

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ md-radio-button {
1313
// Enables focus by click.
1414
.md-radio-label {
1515
cursor: pointer;
16-
display: block;
16+
display: inline-flex;
17+
align-items: baseline;
1718
white-space: nowrap;
1819
}
1920

@@ -23,8 +24,8 @@ md-radio-button {
2324
display: inline-block;
2425
height: $md-radio-size;
2526
position: relative;
26-
top: 2px;
2727
width: $md-radio-size;
28+
top: 2px;
2829
}
2930

3031
// The outer circle for the radio, always present.
@@ -74,19 +75,29 @@ md-radio-button {
7475
// Text label next to radio.
7576
.md-radio-label-content {
7677
display: inline-block;
77-
float: right;
78-
line-height: 24px;
78+
order: 0;
79+
line-height: inherit;
7980
padding-left: $md-toggle-padding;
80-
position: relative;
81-
vertical-align: top;
81+
padding-right: 0;
8282

8383
[dir='rtl'] & {
84-
float: left;
8584
padding-right: $md-toggle-padding;
8685
padding-left: 0;
8786
}
8887
}
8988

89+
// Alignment.
90+
.md-radio-label-content.md-radio-align-end {
91+
order: -1;
92+
padding-left: 0;
93+
padding-right: $md-toggle-padding;
94+
95+
[dir='rtl'] & {
96+
padding-right: 0;
97+
padding-left: $md-toggle-padding;
98+
}
99+
}
100+
90101
// Underlying native input element.
91102
// Visually hidden but still able to respond to focus.
92103
.md-radio-input {

src/components/radio/radio.spec.ts

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,22 @@ describe('MdRadio', () => {
7575
expect(radioInstances[0].checked).toBe(false);
7676
});
7777

78+
it('should set alignment based on the group alignment', () => {
79+
testComponent.alignment = 'end';
80+
fixture.detectChanges();
81+
82+
for (let radio of radioInstances) {
83+
expect(radio.align).toBe('end');
84+
}
85+
86+
testComponent.alignment = 'start';
87+
fixture.detectChanges();
88+
89+
for (let radio of radioInstances) {
90+
expect(radio.align).toBe('start');
91+
}
92+
});
93+
7894
it('should disable each individual radio when the group is disabled', () => {
7995
testComponent.isGroupDisabled = true;
8096
fixture.detectChanges();
@@ -452,14 +468,18 @@ describe('MdRadio', () => {
452468
@Component({
453469
directives: [MD_RADIO_DIRECTIVES],
454470
template: `
455-
<md-radio-group [disabled]="isGroupDisabled" [value]="groupValue" name="test-name">
471+
<md-radio-group [disabled]="isGroupDisabled"
472+
[align]="alignment"
473+
[value]="groupValue"
474+
name="test-name">
456475
<md-radio-button value="fire">Charmander</md-radio-button>
457476
<md-radio-button value="water">Squirtle</md-radio-button>
458477
<md-radio-button value="leaf">Bulbasaur</md-radio-button>
459478
</md-radio-group>
460479
`
461480
})
462481
class RadiosInsideRadioGroup {
482+
alignment: string;
463483
isGroupDisabled: boolean = false;
464484
groupValue: string = null;
465485
}

src/components/radio/radio.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,8 @@ export class MdRadioGroup implements AfterContentInit, ControlValueAccessor {
108108
this._updateRadioButtonNames();
109109
}
110110

111+
@Input() align: 'start' | 'end';
112+
111113
@Input()
112114
get disabled(): boolean {
113115
return this._disabled;
@@ -333,6 +335,17 @@ export class MdRadioButton implements OnInit {
333335
}
334336
}
335337

338+
private _align: 'start' | 'end';
339+
340+
@Input()
341+
get align(): 'start' | 'end' {
342+
return this._align || (this.radioGroup != null && this.radioGroup.align) || 'start';
343+
}
344+
345+
set align(value: 'start' | 'end') {
346+
this._align = value;
347+
}
348+
336349
@HostBinding('class.md-radio-disabled')
337350
@Input()
338351
get disabled(): boolean {
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<md-card class="demo-card demo-basic">
2+
<md-toolbar color="primary">Basic Forms</md-toolbar>
3+
<md-card-content>
4+
Text Before |
5+
<md-checkbox>Checkbox Label</md-checkbox>
6+
| Text 1 |
7+
<md-radio-button value="option_1">Radio 1</md-radio-button>
8+
| Text 2 |
9+
<md-radio-button value="option_2">Radio 2</md-radio-button>
10+
| Text 3 |
11+
<md-radio-button value="option_3">Radio 3</md-radio-button>
12+
| Text 4 |
13+
<md-input>Label</md-input>
14+
| Text After
15+
</md-card-content>
16+
</md-card>
17+
18+
<md-card class="demo-card demo-basic">
19+
<md-toolbar color="primary">Headers</md-toolbar>
20+
<md-card-content>
21+
<h1>
22+
Text Before |
23+
<md-checkbox>Checkbox Label</md-checkbox>
24+
| Text 1 |
25+
<md-radio-button value="option_1">Radio 1</md-radio-button>
26+
| Text 2 |
27+
<md-radio-button value="option_2">Radio 2</md-radio-button>
28+
| Text 3 |
29+
<md-radio-button value="option_3">Radio 3</md-radio-button>
30+
| Text 4 |
31+
<md-input>Label</md-input>
32+
| Text After
33+
</h1>
34+
</md-card-content>
35+
</md-card>
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
@import 'default-theme';
2+
@import 'variables';
3+
4+
.demo-basic {
5+
padding: 0;
6+
}
7+
.demo-basic md-card-content {
8+
padding: 16px;
9+
}
10+
.demo-full-width {
11+
width: 100%;
12+
}
13+
14+
.demo-icons {
15+
font-size: 100%;
16+
height: inherit;
17+
vertical-align: top;
18+
width: inherit;
19+
}
20+
21+
.demo-transform {
22+
transition: color $swift-ease-out-duration $swift-ease-out-timing-function;
23+
}
24+
.demo-primary {
25+
color: md-color($md-primary);
26+
}
27+
28+
.demo-card {
29+
margin: 16px;
30+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import {Component} from '@angular/core';
2+
import {MD_INPUT_DIRECTIVES} from '@angular2-material/input/input';
3+
import {MD_BUTTON_DIRECTIVES} from '@angular2-material/button/button';
4+
import {MD_CARD_DIRECTIVES} from '@angular2-material/card/card';
5+
import {MD_CHECKBOX_DIRECTIVES} from '@angular2-material/checkbox/checkbox';
6+
import {MD_RADIO_DIRECTIVES} from '@angular2-material/radio/radio';
7+
import {MdIcon} from '@angular2-material/icon/icon';
8+
import {MdToolbar} from '@angular2-material/toolbar/toolbar';
9+
10+
import {
11+
MdUniqueSelectionDispatcher
12+
} from '@angular2-material/core/coordination/unique-selection-dispatcher';
13+
14+
15+
@Component({
16+
moduleId: module.id,
17+
selector: 'baseline-demo',
18+
templateUrl: 'baseline-demo.html',
19+
styleUrls: ['baseline-demo.css'],
20+
providers: [MdUniqueSelectionDispatcher],
21+
directives: [
22+
MD_BUTTON_DIRECTIVES,
23+
MD_CARD_DIRECTIVES,
24+
MD_CHECKBOX_DIRECTIVES,
25+
MD_RADIO_DIRECTIVES,
26+
MD_INPUT_DIRECTIVES,
27+
MdIcon,
28+
MdToolbar
29+
]
30+
})
31+
export class BaselineDemo {
32+
name: string;
33+
}

src/demo-app/demo-app/demo-app.html

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
<a md-list-item [routerLink]="['slide-toggle']">Slide Toggle</a>
2121
<a md-list-item [routerLink]="['toolbar']">Toolbar</a>
2222
<a md-list-item [routerLink]="['tabs']">Tabs</a>
23+
<hr>
24+
<a md-list-item [routerLink]="['baseline']">Baseline</a>
2325
</md-nav-list>
2426
<button md-button (click)="start.close()">CLOSE</button>
2527
</md-sidenav>

src/demo-app/demo-app/demo-app.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {MdIcon} from '@angular2-material/icon/icon';
99
import {MdToolbar} from '@angular2-material/toolbar/toolbar';
1010

1111
import {CardDemo} from '../card/card-demo';
12+
import {BaselineDemo} from '../baseline/baseline-demo';
1213
import {ButtonDemo} from '../button/button-demo';
1314
import {IconDemo} from '../icon/icon-demo';
1415
import {RadioDemo} from '../radio/radio-demo';
@@ -75,5 +76,7 @@ export class Home {}
7576
new Route({path: '/grid-list', component: GridListDemo}),
7677
new Route({path: '/tabs', component: TabsDemo}),
7778
new Route({path: '/button-toggle', component: ButtonToggleDemo}),
79+
80+
new Route({path: '/baseline', component: BaselineDemo})
7881
])
7982
export class DemoApp { }

src/demo-app/radio/radio-demo.html

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@ <h1>Dynamic Example</h1>
1212
Disable buttons
1313
</button>
1414
</div>
15-
<md-radio-group name="my_options" [disabled]="isDisabled">
15+
<div>
16+
<span><md-checkbox [(ngModel)]="isAlignEnd">Align end</md-checkbox></span>
17+
</div>
18+
<md-radio-group name="my_options" [disabled]="isDisabled" [align]="isAlignEnd ? 'end' : 'start'">
1619
<md-radio-button value="option_1">Option 1</md-radio-button>
1720
<md-radio-button value="option_2">Option 2</md-radio-button>
1821
<md-radio-button value="option_3">Option 3</md-radio-button>

src/demo-app/radio/radio-demo.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import {Component} from '@angular/core';
2+
import {MdCheckbox} from '@angular2-material/checkbox/checkbox';
23
import {MdRadioButton, MdRadioGroup} from '@angular2-material/radio/radio';
34
import {
45
MdUniqueSelectionDispatcher
@@ -10,10 +11,11 @@ import {
1011
templateUrl: 'radio-demo.html',
1112
styleUrls: ['radio-demo.css'],
1213
providers: [MdUniqueSelectionDispatcher],
13-
directives: [MdRadioButton, MdRadioGroup]
14+
directives: [MdCheckbox, MdRadioButton, MdRadioGroup]
1415
})
1516
export class RadioDemo {
1617
isDisabled: boolean = false;
18+
isAlignEnd: boolean = false;
1719
favoriteSeason: string = 'Autumn';
1820
seasonOptions = [
1921
'Winter',

0 commit comments

Comments
 (0)