Skip to content

Commit

Permalink
fix(radio): support aria-label(ledby) on md-radio (#586) (#596)
Browse files Browse the repository at this point in the history
  • Loading branch information
MartinMa authored and jelbourn committed Jun 2, 2016
1 parent b24d321 commit 8ccc49b
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 2 deletions.
5 changes: 4 additions & 1 deletion src/components/radio/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,16 @@ The `md-radio-group` component has no button initially selected.
## `<md-radio-button>`
### Properties

| Name | Type | Description |
| Name (attribute) | Type | Description |
| --- | --- | --- |
| `id` | `string` | The unique ID of this radio button. |
| `name` | `string` | Group name, defaults to parent radio group if present. |
| `value` | `any` | The value of this radio button. |
| `checked` | `boolean` | Whether the radio is checked. |
| `disabled` | `boolean` | Whether the radio is disabled. |
| `aria-label` | `string` | Used to set the `aria-label` attribute of the underlying input element. |
| `aria-labelledby` | `string` | Used to set the `aria-labelledby` attribute of the underlying input element.
If provided, this attribute takes precedence as the element's text alternative. |

When checked, an event is emitted from the `change` EventEmitter property.

Expand Down
2 changes: 2 additions & 0 deletions src/components/radio/radio.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
[checked]="checked"
[disabled]="disabled"
[name]="name"
[attr.aria-label]="ariaLabel"
[attr.aria-labelledby]="ariaLabelledby"
(change)="onInputChange($event)"
(focus)="onInputFocus()"
(blur)="onInputBlur()" />
Expand Down
55 changes: 55 additions & 0 deletions src/components/radio/radio.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -345,10 +345,14 @@ describe('MdRadio', () => {
let radioDebugElements: DebugElement[];
let seasonRadioInstances: MdRadioButton[];
let weatherRadioInstances: MdRadioButton[];
let fruitRadioInstances: MdRadioButton[];
let fruitRadioNativeInputs: HTMLElement[];
let testComponent: StandaloneRadioButtons;

beforeEach(async(() => {
builder.createAsync(StandaloneRadioButtons).then(f => {
let fruitRadioNativeElements: HTMLElement[];

fixture = f;
fixture.detectChanges();

Expand All @@ -361,6 +365,18 @@ describe('MdRadio', () => {
weatherRadioInstances = radioDebugElements
.filter(debugEl => debugEl.componentInstance.name == 'weather')
.map(debugEl => debugEl.componentInstance);
fruitRadioInstances = radioDebugElements
.filter(debugEl => debugEl.componentInstance.name == 'fruit')
.map(debugEl => debugEl.componentInstance);

fruitRadioNativeElements = radioDebugElements
.filter(debugEl => debugEl.componentInstance.name == 'fruit')
.map(debugEl => debugEl.nativeElement);

fruitRadioNativeInputs = [];
for (let element of fruitRadioNativeElements) {
fruitRadioNativeInputs.push(<HTMLElement> element.querySelector('input'));
}
});
}));

Expand Down Expand Up @@ -393,6 +409,40 @@ describe('MdRadio', () => {
expect(weatherRadioInstances[1].checked).toBe(false);
expect(weatherRadioInstances[2].checked).toBe(true);
});

it('should add aria-label attribute to the underlying input element if defined', () => {
expect(fruitRadioNativeInputs[0].getAttribute('aria-label')).toBe('Banana');
});

it('should not add aria-label attribute if not defined', () => {
expect(fruitRadioNativeInputs[1].hasAttribute('aria-label')).toBeFalsy();
});

it('should change aria-label attribute if property is changed at runtime', () => {
expect(fruitRadioNativeInputs[0].getAttribute('aria-label')).toBe('Banana');

fruitRadioInstances[0].ariaLabel = 'Pineapple';
fixture.detectChanges();

expect(fruitRadioNativeInputs[0].getAttribute('aria-label')).toBe('Pineapple');
});

it('should add aria-labelledby attribute to the underlying input element if defined', () => {
expect(fruitRadioNativeInputs[0].getAttribute('aria-labelledby')).toBe('xyz');
});

it('should not add aria-labelledby attribute if not defined', () => {
expect(fruitRadioNativeInputs[1].hasAttribute('aria-labelledby')).toBeFalsy();
});

it('should change aria-labelledby attribute if property is changed at runtime', () => {
expect(fruitRadioNativeInputs[0].getAttribute('aria-labelledby')).toBe('xyz');

fruitRadioInstances[0].ariaLabelledby = 'uvw';
fixture.detectChanges();

expect(fruitRadioNativeInputs[0].getAttribute('aria-labelledby')).toBe('uvw');
});
});
});

Expand Down Expand Up @@ -423,6 +473,11 @@ class RadiosInsideRadioGroup {
<md-radio-button name="weather" value="warm">Spring</md-radio-button>
<md-radio-button name="weather" value="hot">Summer</md-radio-button>
<md-radio-button name="weather" value="cool">Autumn</md-radio-button>
<span id="xyz">Baby Banana<span>
<md-radio-button name="fruit" value="banana" aria-label="Banana" aria-labelledby="xyz">
</md-radio-button>
<md-radio-button name="fruit" value="raspberry">Raspberry</md-radio-button>
`
})
class StandaloneRadioButtons { }
Expand Down
6 changes: 6 additions & 0 deletions src/components/radio/radio.ts
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,12 @@ export class MdRadioButton implements OnInit {
@Input()
name: string;

/** Used to set the 'aria-label' attribute on the underlying input element. */
@Input('aria-label') ariaLabel: string;

/** The 'aria-labelledby' attribute takes precedence as the element's text alternative. */
@Input('aria-labelledby') ariaLabelledby: string;

/** Whether this radio is disabled. */
private _disabled: boolean;

Expand Down
2 changes: 1 addition & 1 deletion src/demo-app/radio/radio-demo.scss
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@
md-radio-button {
margin: 8px;
}
}
}

0 comments on commit 8ccc49b

Please sign in to comment.