Commit ee157d57 authored by Jason Gill's avatar Jason Gill Committed by Valentin Hervieu

fix(options): add labelling options for a11y

Provides the option to label slider(s) for screen readers using either a direct label via
`aria-label` or as a reference using `aria-labelledby`.

fixes issue #492
parent 3ba812d5
......@@ -249,7 +249,11 @@ The default options are:
logScale: false,
customValueToPosition: null,
customPositionToValue: null,
selectionBarGradient: null
selectionBarGradient: null,
ariaLabel: null,
ariaLabelledBy: null,
ariaLabelHigh: null,
ariaLabelledByHigh: null
}
````
......@@ -404,6 +408,10 @@ For custom scales:
**selectionBarGradient** - _Object (default to null)_: Use to display the selection bar as a gradient. The given object must contain `from` and `to` properties which are colors.
**ariaLabel and ariaLabelHigh** - _String (default to null)_: Use to add a label directly to the slider(s) for accessibility. Adds the `aria-label` attribute.
**ariaLabelledBy and ariaLabelledByHigh** - _String (default to null)_: Use instead of ariaLabel and ariaLabelHigh to reference the id of an element which will be used to label the slider(s). Adds the `aria-labelledby` attribute.
## Change default options
If you want the change the default options for all the sliders displayed in your application, you can set them using the `RzSliderOptions.options()` method:
```js
......
This diff is collapsed.
/*! angularjs-slider - v6.0.2 -
(c) Rafal Zajac <rzajac@gmail.com>, Valentin Hervieu <valentin@hervieu.me>, Jussi Saarivirta <jusasi@gmail.com>, Angelin Sirbu <angelin.sirbu@gmail.com> -
https://github.com/angular-slider/angularjs-slider -
2017-03-02 */
2017-03-05 */
/*jslint unparam: true */
/*global angular: false, console: false, define, module */
(function(root, factory) {
......@@ -81,7 +81,11 @@
logScale: false,
customValueToPosition: null,
customPositionToValue: null,
selectionBarGradient: null
selectionBarGradient: null,
ariaLabel: null,
ariaLabelledBy: null,
ariaLabelHigh: null,
ariaLabelledByHigh: null
};
var globalOptions = {};
......@@ -893,6 +897,10 @@
this.minH.attr('tabindex', '');
if (this.options.vertical)
this.minH.attr('aria-orientation', 'vertical');
if (this.options.ariaLabel)
this.minH.attr('aria-label', this.options.ariaLabel);
else if (this.options.ariaLabelledBy)
this.minH.attr('aria-labelledby', this.options.ariaLabelledBy);
if (this.range) {
this.maxH.attr('role', 'slider');
......@@ -902,6 +910,10 @@
this.maxH.attr('tabindex', '');
if (this.options.vertical)
this.maxH.attr('aria-orientation', 'vertical');
if (this.options.ariaLabelHigh)
this.maxH.attr('aria-label', this.options.ariaLabelHigh);
else if (this.options.ariaLabelledByHigh)
this.maxH.attr('aria-labelledby', this.options.ariaLabelledByHigh);
}
},
......
/*! angularjs-slider - v6.0.2 - (c) Rafal Zajac <rzajac@gmail.com>, Valentin Hervieu <valentin@hervieu.me>, Jussi Saarivirta <jusasi@gmail.com>, Angelin Sirbu <angelin.sirbu@gmail.com> - https://github.com/angular-slider/angularjs-slider - 2017-03-02 */
/*! angularjs-slider - v6.0.2 - (c) Rafal Zajac <rzajac@gmail.com>, Valentin Hervieu <valentin@hervieu.me>, Jussi Saarivirta <jusasi@gmail.com>, Angelin Sirbu <angelin.sirbu@gmail.com> - https://github.com/angular-slider/angularjs-slider - 2017-03-05 */
.rzslider{position:relative;display:inline-block;width:100%;height:4px;margin:35px 0 15px 0;vertical-align:middle;user-select:none}.rzslider.with-legend{margin-bottom:40px}.rzslider[disabled]{cursor:not-allowed}.rzslider[disabled] .rz-pointer{cursor:not-allowed;background-color:#d8e0f3}.rzslider[disabled] .rz-draggable{cursor:not-allowed}.rzslider[disabled] .rz-selection{background:#8b91a2}.rzslider[disabled] .rz-tick{cursor:not-allowed}.rzslider[disabled] .rz-tick.rz-selected{background:#8b91a2}.rzslider span{position:absolute;display:inline-block;white-space:nowrap}.rzslider .rz-base{width:100%;height:100%;padding:0}.rzslider .rz-bar-wrapper{left:0;z-index:1;width:100%;height:32px;padding-top:16px;margin-top:-16px;box-sizing:border-box}.rzslider .rz-draggable{cursor:move}.rzslider .rz-bar{left:0;z-index:1;width:100%;height:4px;background:#d8e0f3;-webkit-border-radius:2px;-moz-border-radius:2px;border-radius:2px}.rzslider .rz-selection{z-index:2;background:#0db9f0;-webkit-border-radius:2px;-moz-border-radius:2px;border-radius:2px}.rzslider .rz-pointer{top:-14px;z-index:3;width:32px;height:32px;cursor:pointer;background-color:#0db9f0;-webkit-border-radius:16px;-moz-border-radius:16px;border-radius:16px}.rzslider .rz-pointer:after{position:absolute;top:12px;left:12px;width:8px;height:8px;background:#fff;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;content:''}.rzslider .rz-pointer:hover:after{background-color:#fff}.rzslider .rz-pointer.rz-active{z-index:4}.rzslider .rz-pointer.rz-active:after{background-color:#451aff}.rzslider .rz-bubble{bottom:16px;padding:1px 3px;color:#55637d;cursor:default}.rzslider .rz-bubble.rz-limit{color:#55637d}.rzslider .rz-ticks{position:absolute;top:-3px;left:0;z-index:1;width:100%;height:0;margin:0;list-style:none;box-sizing:border-box}.rzslider .rz-ticks-values-under .rz-tick-value{top:initial;bottom:-32px}.rzslider .rz-tick{position:absolute;top:0;left:0;width:10px;height:10px;margin-left:11px;text-align:center;cursor:pointer;background:#d8e0f3;border-radius:50%}.rzslider .rz-tick.rz-selected{background:#0db9f0}.rzslider .rz-tick-value{position:absolute;top:-30px;transform:translate(-50%,0)}.rzslider .rz-tick-legend{position:absolute;top:24px;max-width:50px;white-space:normal;transform:translate(-50%,0)}.rzslider.rz-vertical{position:relative;width:4px;height:100%;padding:0;margin:0 20px;vertical-align:baseline}.rzslider.rz-vertical .rz-base{width:100%;height:100%;padding:0}.rzslider.rz-vertical .rz-bar-wrapper{top:auto;left:0;width:32px;height:100%;padding:0 0 0 16px;margin:0 0 0 -16px}.rzslider.rz-vertical .rz-bar{bottom:0;left:auto;width:4px;height:100%}.rzslider.rz-vertical .rz-pointer{top:auto;bottom:0;left:-14px!important}.rzslider.rz-vertical .rz-bubble{bottom:0;left:16px!important;margin-left:3px}.rzslider.rz-vertical .rz-ticks{top:0;left:-3px;z-index:1;width:0;height:100%}.rzslider.rz-vertical .rz-tick{margin-top:11px;margin-left:auto;vertical-align:middle}.rzslider.rz-vertical .rz-tick-value{top:initial;left:24px;transform:translate(0,-28%)}.rzslider.rz-vertical .rz-tick-legend{top:initial;right:24px;max-width:none;white-space:nowrap;transform:translate(0,-28%)}.rzslider.rz-vertical .rz-ticks-values-under .rz-tick-value{right:24px;bottom:initial;left:initial}
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
......@@ -85,7 +85,11 @@
logScale: false,
customValueToPosition: null,
customPositionToValue: null,
selectionBarGradient: null
selectionBarGradient: null,
ariaLabel: null,
ariaLabelledBy: null,
ariaLabelHigh: null,
ariaLabelledByHigh: null
};
var globalOptions = {};
......@@ -897,6 +901,10 @@
this.minH.attr('tabindex', '');
if (this.options.vertical)
this.minH.attr('aria-orientation', 'vertical');
if (this.options.ariaLabel)
this.minH.attr('aria-label', this.options.ariaLabel);
else if (this.options.ariaLabelledBy)
this.minH.attr('aria-labelledby', this.options.ariaLabelledBy);
if (this.range) {
this.maxH.attr('role', 'slider');
......@@ -906,6 +914,10 @@
this.maxH.attr('tabindex', '');
if (this.options.vertical)
this.maxH.attr('aria-orientation', 'vertical');
if (this.options.ariaLabelHigh)
this.maxH.attr('aria-label', this.options.ariaLabelHigh);
else if (this.options.ariaLabelledByHigh)
this.maxH.attr('aria-labelledby', this.options.ariaLabelledByHigh);
}
},
......
......@@ -243,6 +243,105 @@
expect(helper.slider.minH.attr('aria-valuenow')).to.equal('2');
expect(helper.slider.minH.attr('aria-valuetext')).to.equal('C');
});
it('should have labelled single slider when option is set', function() {
var sliderConf = {
value: 10,
options: {
floor: 0,
ceil: 100,
step: 10,
ariaLabel: "test label"
}
};
helper.createSlider(sliderConf);
expect(helper.slider.minH.attr('aria-label')).to.equal('test label');
});
it('should have labelled range slider when option is set', function() {
var sliderConf = {
min: 10,
max: 90,
options: {
floor: 0,
ceil: 100,
step: 10,
ariaLabel: "test label",
ariaLabelHigh: "test label high"
}
};
helper.createRangeSlider(sliderConf);
expect(helper.slider.minH.attr('aria-label')).to.equal('test label');
expect(helper.slider.maxH.attr('aria-label')).to.equal('test label high');
});
it('should have labelled by id on single slider when option is set', function() {
var sliderConf = {
value: 10,
options: {
floor: 0,
ceil: 100,
step: 10,
ariaLabelledBy: "testId"
}
};
helper.createSlider(sliderConf);
expect(helper.slider.minH.attr('aria-labelledby')).to.equal('testId');
});
it('should have labelled by id on range slider when option is set', function() {
var sliderConf = {
min: 10,
max: 90,
options: {
floor: 0,
ceil: 100,
step: 10,
ariaLabelledBy: "testId",
ariaLabelledByHigh: "testIdHigh"
}
};
helper.createRangeSlider(sliderConf);
expect(helper.slider.minH.attr('aria-labelledby')).to.equal('testId');
expect(helper.slider.maxH.attr('aria-labelledby')).to.equal('testIdHigh');
});
it('should not have labelled by id on single slider when both options set', function() {
var sliderConf = {
value: 10,
options: {
floor: 0,
ceil: 100,
step: 10,
ariaLabel: "test label",
ariaLabelledBy: "testId"
}
};
helper.createSlider(sliderConf);
expect(helper.slider.minH.attr('aria-label')).to.equal('test label');
expect(helper.slider.minH.attr('aria-labelledby')).to.equal(undefined);
});
it('should not have labelled by id on range slider when both options set', function() {
var sliderConf = {
min: 10,
max: 90,
options: {
floor: 0,
ceil: 100,
step: 10,
ariaLabel: "test label",
ariaLabelHigh: "test label high",
ariaLabelledBy: "testId",
ariaLabelledByHigh: "testIdHigh"
}
};
helper.createRangeSlider(sliderConf);
expect(helper.slider.minH.attr('aria-label')).to.equal('test label');
expect(helper.slider.maxH.attr('aria-label')).to.equal('test label high');
expect(helper.slider.minH.attr('aria-labelledby')).to.equal(undefined);
expect(helper.slider.maxH.attr('aria-labelledby')).to.equal(undefined);
});
});
}());
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment