Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add option labelId to improve a11y #971

Merged
merged 4 commits into from
Jan 18, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Add option labelId to improve a11y
  • Loading branch information
Josua Vogel committed Oct 22, 2021
commit 9624b66d39401f5308d603c0fe64b1e1eebe8c18
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ Or include Choices directly:
fuseOptions: {
include: 'score'
},
labelId: '',
callbackOnInit: null,
callbackOnCreateTemplates: null
});
Expand Down Expand Up @@ -573,6 +574,14 @@ const example = new Choices(element, {
};
```

### labelId

**Type:** `String` **Default:** ``

**Input types affected:** `select-one`, `select-multiple`

**Usage:** The labelId improves accessibility. If set, it will add aria-labeledby to the choices element.

### classNames

**Type:** `Object` **Default:**
Expand Down
14 changes: 10 additions & 4 deletions public/assets/scripts/choices.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/*! choices.js v9.0.1 | © 2019 Josh Johnson | https://github.com/jshjohnson/Choices#readme */
/*! choices.js v9.0.1 | © 2021 Josh Johnson | https://github.com/jshjohnson/Choices#readme */
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
Expand Down Expand Up @@ -184,6 +184,7 @@ exports.DEFAULT_CONFIG = {
fuseOptions: {
includeScore: true
},
labelId: '',
callbackOnInit: null,
callbackOnCreateTemplates: null,
classNames: exports.DEFAULT_CLASSNAMES
Expand Down Expand Up @@ -3318,7 +3319,7 @@ function () {

Choices.prototype._createElements = function () {
this.containerOuter = new components_1.Container({
element: this._getTemplate('containerOuter', this._direction, this._isSelectElement, this._isSelectOneElement, this.config.searchEnabled, this.passedElement.element.type),
element: this._getTemplate('containerOuter', this._direction, this._isSelectElement, this._isSelectOneElement, this.config.searchEnabled, this.passedElement.element.type, this.config.labelId),
classNames: this.config.classNames,
type: this.passedElement.element.type,
position: this.config.position
Expand Down Expand Up @@ -3577,7 +3578,7 @@ function () {
};

Choices.prototype._generatePlaceholderValue = function () {
if (this._isSelectElement) {
if (this._isSelectElement && this.passedElement.placeholderOption) {
var placeholderOption = this.passedElement.placeholderOption;
return placeholderOption ? placeholderOption.text : null;
}
Expand Down Expand Up @@ -5122,7 +5123,7 @@ Object.defineProperty(exports, "__esModule", {
*/

var templates = {
containerOuter: function containerOuter(_a, dir, isSelectElement, isSelectOneElement, searchEnabled, passedElementType) {
containerOuter: function containerOuter(_a, dir, isSelectElement, isSelectOneElement, searchEnabled, passedElementType, labelId) {
var containerOuter = _a.containerOuter;
var div = Object.assign(document.createElement('div'), {
className: containerOuter
Expand All @@ -5147,6 +5148,11 @@ var templates = {

div.setAttribute('aria-haspopup', 'true');
div.setAttribute('aria-expanded', 'false');

if (labelId) {
div.setAttribute('aria-labeledby', labelId);
}

return div;
},
containerInner: function containerInner(_a) {
Expand Down
6 changes: 3 additions & 3 deletions public/assets/scripts/choices.min.js

Large diffs are not rendered by default.

11 changes: 9 additions & 2 deletions public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,9 @@ <h2>Multiple select input</h2>
<hr />

<h2>Single select input</h2>
<label for="choices-single-default">Default</label>
<label id="choices-single-default-label" for="choices-single-default"
>Default</label
>
<select
class="form-control"
data-trigger
Expand Down Expand Up @@ -433,7 +435,11 @@ <h2>Single select input</h2>
>
</select>

<label for="choices-single-no-sorting">Options without sorting</label>
<label
id="choices-single-no-sorting-label"
for="choices-single-no-sorting"
>Options without sorting</label
>
<select
class="form-control"
name="choices-single-no-sorting"
Expand Down Expand Up @@ -783,6 +789,7 @@ <h2>Form interaction</h2>

var singleNoSorting = new Choices('#choices-single-no-sorting', {
shouldSort: false,
labelId: 'choices-single-no-sorting-label',
});

var cities = new Choices(document.getElementById('cities'));
Expand Down
1 change: 1 addition & 0 deletions src/scripts/choices.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2107,6 +2107,7 @@ class Choices {
this._isSelectOneElement,
this.config.searchEnabled,
this.passedElement.element.type,
this.config.labelId,
),
classNames: this.config.classNames,
type: this.passedElement.element.type as PassedElement['type'],
Expand Down
1 change: 1 addition & 0 deletions src/scripts/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ export const DEFAULT_CONFIG: Options = {
fuseOptions: {
includeScore: true,
},
labelId: '',
callbackOnInit: null,
callbackOnCreateTemplates: null,
classNames: DEFAULT_CLASSNAMES,
Expand Down
5 changes: 5 additions & 0 deletions src/scripts/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -692,6 +692,11 @@ export interface Options {
*/
fuseOptions: FuseOptions<Choice>;

/**
* ID of the connected label to improve a11y. If set, aria-labeledby will be added.
*/
labelId: string;

/**
* Function to run once Choices initialises.
*
Expand Down
8 changes: 8 additions & 0 deletions src/scripts/templates.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ describe('templates', () => {
const isSelectOneElement = false;
const searchEnabled = true;
const passedElementType = 'select-multiple';
const labelId = '';

const expectedOutput = strToEl(`
<div
Expand All @@ -55,6 +56,7 @@ describe('templates', () => {
isSelectOneElement,
searchEnabled,
passedElementType,
labelId,
);
expectEqualElements(actualOutput, expectedOutput);
});
Expand All @@ -66,6 +68,7 @@ describe('templates', () => {
const isSelectOneElement = false;
const searchEnabled = false;
const passedElementType = 'select-multiple';
const labelId = '';

const expectedOutput = strToEl(`
<div
Expand All @@ -85,6 +88,7 @@ describe('templates', () => {
isSelectOneElement,
searchEnabled,
passedElementType,
labelId,
);

expectEqualElements(actualOutput, expectedOutput);
Expand All @@ -97,6 +101,7 @@ describe('templates', () => {
const isSelectOneElement = true;
const searchEnabled = false;
const passedElementType = 'select-one';
const labelId = '';

const expectedOutput = strToEl(`
<div
Expand All @@ -117,6 +122,7 @@ describe('templates', () => {
isSelectOneElement,
searchEnabled,
passedElementType,
labelId,
);

expectEqualElements(actualOutput, expectedOutput);
Expand All @@ -130,6 +136,7 @@ describe('templates', () => {
const isSelectOneElement = false;
const searchEnabled = false;
const passedElementType = 'text';
const labelId = '';

const expectedOutput = strToEl(`
<div
Expand All @@ -148,6 +155,7 @@ describe('templates', () => {
isSelectOneElement,
searchEnabled,
passedElementType,
labelId,
);

expectEqualElements(actualOutput, expectedOutput);
Expand Down
4 changes: 4 additions & 0 deletions src/scripts/templates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ const templates = {
isSelectOneElement: boolean,
searchEnabled: boolean,
passedElementType: PassedElement['type'],
labelId: string,
): HTMLDivElement {
const div = Object.assign(document.createElement('div'), {
className: containerOuter,
Expand All @@ -37,6 +38,9 @@ const templates = {

div.setAttribute('aria-haspopup', 'true');
div.setAttribute('aria-expanded', 'false');
if (labelId) {
div.setAttribute('aria-labeledby', labelId);
}

return div;
},
Expand Down