Skip to content

Commit

Permalink
feat(number-stepper): add inputs for aria-labels (#49)
Browse files Browse the repository at this point in the history
* feat(number-stepper): add aria-label inputs

* fix(number-stepper): tests for aria inputs and aria for text field

* feat(number-stepper): add input for input aria label + tests

* fix: linting

* fix: add missing docs sentence

* Update projects/ng-aquila/documentation/examples/number-stepper-localize/number-stepper-localize-example.html

* Update projects/ng-aquila/src/number-stepper/number-stepper.md

Co-Authored-By: Silvia Milde <[email protected]>

* Update projects/ng-aquila/src/number-stepper/number-stepper.component.spec.ts

Co-Authored-By: Silvia Milde <[email protected]>

* Update projects/ng-aquila/src/number-stepper/number-stepper.component.ts

Co-Authored-By: Silvia Milde <[email protected]>

* Update projects/ng-aquila/src/number-stepper/number-stepper.component.ts

Co-Authored-By: Silvia Milde <[email protected]>

* Update projects/ng-aquila/src/number-stepper/number-stepper.component.ts

Co-Authored-By: Silvia Milde <[email protected]>

* Update projects/ng-aquila/src/number-stepper/number-stepper.component.ts

Co-Authored-By: Silvia Milde <[email protected]>

* fix: linter

* fix(number-stepper): add a11y example

* fix: forgot to add files

Co-authored-by: Silvia Milde <[email protected]>
  • Loading branch information
2 people authored and GitHub Enterprise committed Sep 28, 2020
1 parent 4feb209 commit 90adcc7
Show file tree
Hide file tree
Showing 8 changed files with 139 additions and 37 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<nx-number-stepper
inputAriaLabel="Number of travellers"
incrementAriaLabel="Increase number of travellers"
decrementAriaLabel="Decrease number of travellers"
>
<label>Number of travellers</label>
</nx-number-stepper>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { Component } from '@angular/core';

/**
* @title Number Stepper Accessiblity Example
*/
@Component({
templateUrl: './number-stepper-a11y-example.html'
})
export class NumberStepperAccessibilityExampleComponent {}
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<nx-number-stepper></nx-number-stepper>
<nx-number-stepper></nx-number-stepper>
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
</div>
<div class="nx-stepper__input-container">
<button
[attr.aria-label]="_intl.decrementAriaLabel"
[attr.aria-label]="decrementAriaLabel || _intl.decrementAriaLabel"
[nxButton]="_buttonType"
class="nx-stepper__down nx-stepper__control"
(click)="decrementOnClick()"
Expand All @@ -23,6 +23,7 @@
<input type="number"
[nxAutoResize]="resize"
[attr.aria-describedby]="ariaDescribedBy"
[attr.aria-label]="inputAriaLabel"
[id]="inputId" [ngClass]="inputClassNames"
(input)="onInputChange($event)"
(blur)="onTouchedCallback()"
Expand All @@ -39,7 +40,7 @@
</div>

<button
[attr.aria-label]="_intl.incrementAriaLabel"
[attr.aria-label]="incrementAriaLabel || _intl.incrementAriaLabel"
[nxButton]="_buttonType"
class="nx-stepper__up nx-stepper__control"
(click)="incrementOnClick()"
Expand Down
110 changes: 78 additions & 32 deletions projects/ng-aquila/src/number-stepper/number-stepper.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,13 @@ abstract class NumberStepperTest {
negative: boolean = false;
leadingZero: boolean = true;
disabled: boolean = false;
inputAriaLabel: string = 'input label';
incrementAriaLabel: string = 'increase number';
decrementAriaLabel: string = 'decrease number';
testForm: FormGroup = new FormBuilder().group({ stepper: 3 });
@ViewChild(NxNumberStepperComponent) stepperInstance: NxNumberStepperComponent;

onSubmit() {}
onSubmit() { }
}

describe('NxNumberStepperComponent', () => {
Expand All @@ -48,10 +51,10 @@ describe('NxNumberStepperComponent', () => {
fixture.detectChanges();
testInstance = fixture.componentInstance;
stepperInstance = testInstance.stepperInstance;
upButton = <HTMLButtonElement>fixture.nativeElement.querySelector('button.nx-stepper__up');
downButton = <HTMLButtonElement>fixture.nativeElement.querySelector('button.nx-stepper__down');
inputElement = <HTMLInputElement>fixture.nativeElement.querySelector('input');
label = <HTMLLabelElement>fixture.nativeElement.querySelector('label');
upButton = fixture.nativeElement.querySelector('button.nx-stepper__up') as HTMLButtonElement;
downButton = fixture.nativeElement.querySelector('button.nx-stepper__down') as HTMLButtonElement;
inputElement = fixture.nativeElement.querySelector('input') as HTMLInputElement;
label = fixture.nativeElement.querySelector('label') as HTMLLabelElement;
stepperDebugElement = fixture.debugElement.query(By.directive(NxNumberStepperComponent));
stepperNativeElement = stepperDebugElement.nativeElement;
}
Expand All @@ -64,7 +67,7 @@ describe('NxNumberStepperComponent', () => {
ReactiveFormsModule
],
providers: [
{provide: NxNumberStepperIntl, useClass: MyIntl},
{ provide: NxNumberStepperIntl, useClass: MyIntl },
],
declarations: [
BasicStepper,
Expand Down Expand Up @@ -115,14 +118,14 @@ describe('NxNumberStepperComponent', () => {
expect(label).not.toBeNull();
});

it('should count up by 1 by default', fakeAsync( () => {
it('should count up by 1 by default', fakeAsync(() => {
createTestComponent(BasicStepper);
clickUp();
expect(stepperInstance.value).toBe(1);
assertInputValue('01');
}));

it('should have min = 0 by default and not decrement', fakeAsync( () => {
it('should have min = 0 by default and not decrement', fakeAsync(() => {
createTestComponent(BasicStepper);
clickDown();
expect(downButton.disabled).toBe(true);
Expand All @@ -142,7 +145,7 @@ describe('NxNumberStepperComponent', () => {
});

describe('button disabling', () => {
it('should disable the down button on min', fakeAsync( () => {
it('should disable the down button on min', fakeAsync(() => {
createTestComponent(ConfigurableStepper);
testInstance.min = -2;
testInstance.max = 2;
Expand All @@ -152,15 +155,15 @@ describe('NxNumberStepperComponent', () => {
expect(downButton.disabled).toBe(true);
}));

it('should not disable the down button for correct values', fakeAsync( () => {
it('should not disable the down button for correct values', fakeAsync(() => {
createTestComponent(ConfigurableStepper);
testInstance.min = -10;
fixture.detectChanges();
clickDown();
expect(downButton.disabled).toBe(false);
}));

it('should disable the up button on max', fakeAsync( () => {
it('should disable the up button on max', fakeAsync(() => {
createTestComponent(ConfigurableStepper);
testInstance.min = -2;
testInstance.max = 2;
Expand All @@ -170,7 +173,7 @@ describe('NxNumberStepperComponent', () => {
expect(upButton.disabled).toBe(true);
}));

it('should not disable the up button for correct values', fakeAsync( () => {
it('should not disable the up button for correct values', fakeAsync(() => {
createTestComponent(ConfigurableStepper);
clickUp();
expect(upButton.disabled).toBe(false);
Expand All @@ -188,7 +191,7 @@ describe('NxNumberStepperComponent', () => {
expect(downButton.disabled).toBe(false);
}));

it('should disable the down button if user input is below the minimum', fakeAsync( () => {
it('should disable the down button if user input is below the minimum', fakeAsync(() => {
createTestComponent(ConfigurableStepper);
testInstance.min = -2;
testInstance.max = 2;
Expand All @@ -200,7 +203,7 @@ describe('NxNumberStepperComponent', () => {
expect(downButton.disabled).toBe(true);
}));

it('should disable the up button if user input is over the maximum', fakeAsync( () => {
it('should disable the up button if user input is over the maximum', fakeAsync(() => {
createTestComponent(ConfigurableStepper);
testInstance.min = -2;
testInstance.max = 2;
Expand All @@ -226,7 +229,7 @@ describe('NxNumberStepperComponent', () => {
});

describe('min/max', () => {
it('should not count over the maximum', fakeAsync( () => {
it('should not count over the maximum', fakeAsync(() => {
createTestComponent(ConfigurableStepper);
testInstance.max = 2;
testInstance.step = 2;
Expand All @@ -237,7 +240,7 @@ describe('NxNumberStepperComponent', () => {
assertInputValue('02');
}));

it('should not count below the minimum', fakeAsync( () => {
it('should not count below the minimum', fakeAsync(() => {
createTestComponent(ConfigurableStepper);
testInstance.min = -2;
testInstance.step = 2;
Expand Down Expand Up @@ -278,7 +281,7 @@ describe('NxNumberStepperComponent', () => {
assertInputValue('-1');
}));

it('should count up by custom stepsize 2', fakeAsync( () => {
it('should count up by custom stepsize 2', fakeAsync(() => {
createTestComponent(ConfigurableStepper);
testInstance.step = 2;
fixture.detectChanges();
Expand All @@ -287,7 +290,7 @@ describe('NxNumberStepperComponent', () => {
assertInputValue('02');
}));

it('should count down by custom stepsize 2', fakeAsync( () => {
it('should count down by custom stepsize 2', fakeAsync(() => {
createTestComponent(ConfigurableStepper);
testInstance.min = -2;
testInstance.step = 2;
Expand Down Expand Up @@ -453,7 +456,7 @@ describe('NxNumberStepperComponent', () => {
describe('reactive', () => {
it('should not submit form on buttons click', fakeAsync(() => {
createTestComponent(ReactiveFormStepper);
const submitButton = <HTMLButtonElement>fixture.nativeElement.querySelector('#submit-button');
const submitButton = fixture.nativeElement.querySelector('#submit-button') as HTMLButtonElement;
spyOn(testInstance, 'onSubmit');

clickUp();
Expand All @@ -479,7 +482,7 @@ describe('NxNumberStepperComponent', () => {
expect(testInstance.testForm.get('count').value)
.toEqual(2, 'Expected value to change once control is blurred.');
}));
});
});

describe('with onPush', () => {

Expand Down Expand Up @@ -573,6 +576,43 @@ describe('NxNumberStepperComponent', () => {
}
));

it('should use inputs for button aria-labels', () => {
createTestComponent(ConfigurableStepper);
expect(downButton.getAttribute('aria-label')).toBe('decrease number');
expect(upButton.getAttribute('aria-label')).toBe('increase number');
});

it('should set the aria-label of the input via input', () => {
createTestComponent(ConfigurableStepper);
expect(inputElement.getAttribute('aria-label')).toBe('input label');
});

it('should react on change of inputs for aria-labels', () => {
createTestComponent(ConfigurableStepper);
expect(downButton.getAttribute('aria-label')).toBe('decrease number');
expect(upButton.getAttribute('aria-label')).toBe('increase number');
expect(inputElement.getAttribute('aria-label')).toBe('input label');

fixture.componentInstance.incrementAriaLabel = 'new increase';
fixture.componentInstance.decrementAriaLabel = 'new decrease';
fixture.componentInstance.inputAriaLabel = 'new input label';

fixture.detectChanges();

expect(downButton.getAttribute('aria-label')).toBe('new decrease');
expect(upButton.getAttribute('aria-label')).toBe('new increase');
expect(inputElement.getAttribute('aria-label')).toBe('new input label');
});

it('should give precedence to inputs and not injected attributes for aria-labels', inject([NxNumberStepperIntl],
(intl: NxNumberStepperIntl) => {
createTestComponent(ConfigurableStepper);
expect(downButton.getAttribute('aria-label')).toBe('decrease number');
expect(upButton.getAttribute('aria-label')).toBe('increase number');
expect(inputElement.getAttribute('aria-label')).toBe('input label');
}
));

it('should rerender when the i18n aria labels change', inject([NxNumberStepperIntl],
(intl: NxNumberStepperIntl) => {
createTestComponent(BasicStepper);
Expand All @@ -583,10 +623,10 @@ describe('NxNumberStepperComponent', () => {
}
));

it('has no accessibility violations', function(done) {
it('has no accessibility violations', function (done) {
createTestComponent(BasicStepper);

axe.run(fixture.nativeElement, {}, (error: Error, results: axe.AxeResults) => {
axe.run(fixture.nativeElement, {}, (error: Error, results: axe.AxeResults) => {
expect(results.violations.length).toBe(0);
const violationMessages = results.violations.map(item => item.description);
done();
Expand All @@ -600,14 +640,14 @@ describe('NxNumberStepperComponent', () => {
<nx-number-stepper nxLabel="Test"></nx-number-stepper>
`
})
class BasicStepper extends NumberStepperTest {}
class BasicStepper extends NumberStepperTest { }

@Component({
template: `
<nx-number-stepper [(nxValue)]="value"></nx-number-stepper>
`
})
class SimpleBindingStepper extends NumberStepperTest {}
class SimpleBindingStepper extends NumberStepperTest { }

@Component({
template: `
Expand All @@ -633,29 +673,35 @@ class ResizeOnInitTestOnPush extends NumberStepperTest {
<nx-number-stepper [(ngModel)]="value"></nx-number-stepper>
`
})
class NgModelStepper extends NumberStepperTest {}
class NgModelStepper extends NumberStepperTest { }

@Component({
template: `
<nx-number-stepper [nxMin]="min" [nxMax]="max" [nxStep]="step" [negative]="negative" [leadingZero]="leadingZero"></nx-number-stepper>
<nx-number-stepper [nxMin]="min"
[nxMax]="max" [nxStep]="step"
[negative]="negative"
[leadingZero]="leadingZero"
[inputAriaLabel]="inputAriaLabel"
[incrementAriaLabel]="incrementAriaLabel"
[decrementAriaLabel]="decrementAriaLabel"></nx-number-stepper>
`
})
class ConfigurableStepper extends NumberStepperTest {}
class ConfigurableStepper extends NumberStepperTest { }

@Component({
template: `
<nx-number-stepper [nxDisabled]="disabled" [nxMin]="-10"></nx-number-stepper>
`
})
class DisableableStepper extends NumberStepperTest {}
class DisableableStepper extends NumberStepperTest { }

@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<nx-number-stepper [negative]="negative"></nx-number-stepper>
`
})
class StepperOnPush extends NumberStepperTest {}
class StepperOnPush extends NumberStepperTest { }

@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
Expand All @@ -666,7 +712,7 @@ class StepperOnPush extends NumberStepperTest {}
</nx-number-stepper>
`
})
class DirectivesStepper extends NumberStepperTest {}
class DirectivesStepper extends NumberStepperTest { }

@Component({
template: `
Expand All @@ -676,7 +722,7 @@ class DirectivesStepper extends NumberStepperTest {}
</form>
`
})
class ReactiveFormStepper extends NumberStepperTest {}
class ReactiveFormStepper extends NumberStepperTest { }

@Component({
template: `
Expand All @@ -690,6 +736,6 @@ class ReactiveFormOnBlurStepper extends NumberStepperTest {
super();
this.testForm = this.fb.group({
count: 0
}, {updateOn: 'blur'});
}, { updateOn: 'blur' });
}
}
33 changes: 33 additions & 0 deletions projects/ng-aquila/src/number-stepper/number-stepper.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ export class NxNumberStepperComponent extends MappedStyles
private _max: number = 100;
private _value: number = 0;
private _label = null;
private _incrementAriaLabel = '';
private _decrementAriaLabel = '';
private _inputAriaLabel = '';
private _resize: boolean = false;
private _intlSubscription: Subscription;
private _negative: boolean = false;
Expand Down Expand Up @@ -128,6 +131,36 @@ export class NxNumberStepperComponent extends MappedStyles
}
}

/** Sets the aria-label for the increment button. */
@Input()
set incrementAriaLabel(value: string) {
this._incrementAriaLabel = value;
}

get incrementAriaLabel(): string {
return this._incrementAriaLabel;
}

/** Sets the aria-label for the decrement button. */
@Input()
set decrementAriaLabel(value: string) {
this._decrementAriaLabel = value;
}

get decrementAriaLabel(): string {
return this._decrementAriaLabel;
}

/** Sets the aria-label for the input of the number stepper. */
@Input()
set inputAriaLabel(value: string) {
this._inputAriaLabel = value;
}

get inputAriaLabel(): string {
return this._inputAriaLabel;
}

/** Sets the step size. Default: 1 */
@Input('nxStep')
set step(value: number) {
Expand Down
Loading

0 comments on commit 90adcc7

Please sign in to comment.