Skip to content
This repository has been archived by the owner on Dec 8, 2022. It is now read-only.

Commit

Permalink
Added watches for when radio buttons change and the ability to set an…
Browse files Browse the repository at this point in the history
… aria label (#26)

* Added watches for when radio buttons change and the ability to set an aria label

* Code review changes
  • Loading branch information
Blackbaud-TrevorBurch committed Mar 19, 2019
1 parent 4d6ac4c commit 1fd2798
Show file tree
Hide file tree
Showing 5 changed files with 133 additions and 8 deletions.
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
<form [formGroup]="radioForm">
<sky-radio-group
ariaLabelledBy="radio-group-label"
class="form-group radio"
formControlName="option"
name="option"
[ariaLabel]="ariaLabel"
[ariaLabelledBy]="ariaLabelledBy"
[tabIndex]="tabIndex"
>
<legend
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ export class SkyRadioGroupTestComponent {
public radioForm: FormGroup;

public tabIndex: number;

public ariaLabelledBy: string = 'radio-group-label';

public ariaLabel: string;

public options = [
{ name: 'Lillith Corharvest', disabled: false },
{ name: 'Harima Kenji', disabled: false },
Expand All @@ -38,4 +43,13 @@ export class SkyRadioGroupTestComponent {
option: new FormControl(this.options[0])
});
}

public changeOptions(): void {
this.options = [
{ name: 'Lillith Corharvest', disabled: false },
{ name: 'Hank Salizar', disabled: false },
{ name: 'Harima Kenji', disabled: false },
{ name: 'Harry Mckenzie', disabled: false }
];
}
}
1 change: 1 addition & 0 deletions src/app/public/modules/radio/radio-group.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
class="sky-radio-group"
role="radiogroup"
[attr.aria-labelledby]="ariaLabelledBy"
[attr.aria-label]="ariaLabel"
>
<ng-content></ng-content>
</div>
82 changes: 82 additions & 0 deletions src/app/public/modules/radio/radio-group.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,46 @@ describe('Radio group component', function () {
}
}));

it('should maintain tabIndex when options change', fakeAsync(function () {
componentInstance.tabIndex = 2;
fixture.detectChanges();
tick();
fixture.detectChanges();

componentInstance.changeOptions();
fixture.detectChanges();
tick();
fixture.detectChanges();

const radios = fixture.nativeElement.querySelectorAll('input');
for (let element of radios) {
expect(element.getAttribute('tabindex')).toBe('2');
}
}));

it('should set the radio name properties correctly', fakeAsync(() => {
fixture.detectChanges();
tick();
const radios = fixture.nativeElement.querySelectorAll('input');
for (let element of radios) {
expect(element.getAttribute('name')).toBe('option');
}
}));

it('should set the radio name properties correctly when options change', fakeAsync(() => {
fixture.detectChanges();
tick();

componentInstance.changeOptions();
fixture.detectChanges();
tick();

const radios = fixture.nativeElement.querySelectorAll('input');
for (let element of radios) {
expect(element.getAttribute('name')).toBe('option');
}
}));

it('should maintain checked state when value is changed', fakeAsync(function () {
fixture.detectChanges();

Expand Down Expand Up @@ -133,6 +173,48 @@ describe('Radio group component', function () {
expect(radioDebugElement.componentInstance.checked).toBeTruthy();
}));

it('should maintain checked state when options are changed', fakeAsync(function () {
fixture.detectChanges();

let newValue = {
name: 'Jerry Salmonella',
disabled: false
};

let radioDebugElement = fixture.debugElement.query(By.css('sky-radio'));
radioDebugElement.componentInstance.value = newValue;
fixture.detectChanges();
tick();

expect(radioDebugElement.componentInstance.checked).toBeTruthy();

componentInstance.changeOptions();

fixture.detectChanges();
tick();

expect(radioDebugElement.componentInstance.checked).toBeTruthy();
}));

it('should set the aria-labeledby property correctly', fakeAsync(() => {
fixture.detectChanges();
tick();

const radioGroupDiv = fixture.nativeElement.querySelector('.sky-radio-group');
expect(radioGroupDiv.getAttribute('aria-labelledby')).toBe('radio-group-label');
}));

it('should set the aria-label property correctly', fakeAsync(() => {
componentInstance.ariaLabel = 'radio-group-label-manual';
componentInstance.ariaLabelledBy = undefined;

fixture.detectChanges();
tick();

const radioGroupDiv = fixture.nativeElement.querySelector('.sky-radio-group');
expect(radioGroupDiv.getAttribute('aria-label')).toBe('radio-group-label-manual');
}));

it('should pass accessibility', async(() => {
fixture.detectChanges();
fixture.whenStable().then(() => {
Expand Down
41 changes: 34 additions & 7 deletions src/app/public/modules/radio/radio-group.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
ContentChildren,
forwardRef,
Input,
OnDestroy,
QueryList
} from '@angular/core';

Expand All @@ -13,6 +14,10 @@ import {
NG_VALUE_ACCESSOR
} from '@angular/forms';

import {
Subject
} from 'rxjs/Subject';

import {
SkyRadioChange
} from './types';
Expand All @@ -38,10 +43,13 @@ const SKY_RADIO_GROUP_CONTROL_VALUE_ACCESSOR: any = {
SKY_RADIO_GROUP_CONTROL_VALUE_ACCESSOR
]
})
export class SkyRadioGroupComponent implements AfterContentInit, ControlValueAccessor {
export class SkyRadioGroupComponent implements AfterContentInit, ControlValueAccessor, OnDestroy {
@Input()
public ariaLabelledBy: string;

@Input()
public ariaLabel: string;

@Input()
public set name(value: string) {
this._name = value;
Expand Down Expand Up @@ -82,21 +90,34 @@ export class SkyRadioGroupComponent implements AfterContentInit, ControlValueAcc
@ContentChildren(SkyRadioComponent, { descendants: true })
private radios: QueryList<SkyRadioComponent>;

private ngUnsubscribe = new Subject();

private _name = `sky-radio-group-${nextUniqueId++}`;
private _value: any;
private _tabIndex: number;

public ngAfterContentInit(): void {
this.updateCheckedRadioFromValue();
this.updateRadioButtonNames();
this.updateRadioButtonTabIndexes();
this.resetRadioButtons();

// Watch for radio selections.
this.radios.forEach((radio) => {
radio.change.subscribe((change: SkyRadioChange) => {
this.writeValue(change.value);
});
radio.change
.takeUntil(this.ngUnsubscribe)
.subscribe((change: SkyRadioChange) => {
this.writeValue(change.value);
});
});

this.radios.changes
.takeUntil(this.ngUnsubscribe)
.subscribe(() => {
this.resetRadioButtons();
});
}

public ngOnDestroy() {
this.ngUnsubscribe.next();
this.ngUnsubscribe.complete();
}

public writeValue(value: any): void {
Expand Down Expand Up @@ -145,4 +166,10 @@ export class SkyRadioGroupComponent implements AfterContentInit, ControlValueAcc
}
});
}

private resetRadioButtons(): void {
this.updateCheckedRadioFromValue();
this.updateRadioButtonNames();
this.updateRadioButtonTabIndexes();
}
}

0 comments on commit 1fd2798

Please sign in to comment.