Skip to content

Commit f66852f

Browse files
authored
feat: add new labelId option for accessibility (#254)
1 parent 5443ff9 commit f66852f

File tree

7 files changed

+87
-0
lines changed

7 files changed

+87
-0
lines changed

packages/demo/src/app-routing.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ import Options35 from './options/options35';
6767
import Options36 from './options/options36';
6868
import Options37 from './options/options37';
6969
import Options38 from './options/options38';
70+
import Options39 from './options/options39';
7071

7172
export const navbarRouting = [
7273
{ name: 'getting-started', view: '/src/getting-started.html', viewModel: GettingStarted, title: 'Getting Started' },
@@ -136,6 +137,7 @@ export const exampleRouting = [
136137
{ name: 'options36', view: '/src/options/options36.html', viewModel: Options36, title: 'Infinite Scroll' },
137138
{ name: 'options37', view: '/src/options/options37.html', viewModel: Options37, title: 'Navigation Highlight' },
138139
{ name: 'options38', view: '/src/options/options38.html', viewModel: Options38, title: 'Dark Mode' },
140+
{ name: 'options39', view: '/src/options/options39.html', viewModel: Options39, title: 'Label Id (aria-labelledby)' },
139141
],
140142
},
141143
{
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<div class="row mb-2">
2+
<div class="col-md-12 title-desc">
3+
<h2 class="bd-title">
4+
Label Id <small>(for accessibility)</small>
5+
<span class="float-end links">
6+
Code <span class="fa fa-link"></span>
7+
<span class="small">
8+
<a
9+
target="_blank"
10+
href="https://github.com/ghiscoding/multiple-select-vanilla/blob/main/packages/demo/src/options/options03.html"
11+
>html</a
12+
>
13+
|
14+
<a target="_blank" href="https://github.com/ghiscoding/multiple-select-vanilla/blob/main/packages/demo/src/options/options03.ts"
15+
>ts</a
16+
>
17+
</span>
18+
</span>
19+
</h2>
20+
<div class="demo-subtitle">
21+
In order for the select to be accessible, it should be linked to a label, use <code>labelId</code> option
22+
to associate your label to the select button (the label must be created by yourself and linked via the <code>for</code> attribute).
23+
Using this option will link the <code>id</code> and <code>aria-labelledby</code> of the <code>.ms-choice</code> select button with your custom label.
24+
</div>
25+
<div class="demo-subtitle">
26+
Clicking the label will open the select dropdown.
27+
</div>
28+
</div>
29+
</div>
30+
31+
<div>
32+
<div class="mb-10">
33+
<label class="mb-2" for="custom-label">My Select Label</label>
34+
</div>
35+
<div class="mb-10">
36+
<select class="col-sm-8">
37+
<option value="1">First</option>
38+
<option value="2">Second</option>
39+
<option value="3">Third</option>
40+
<option value="4">Fourth</option>
41+
</select>
42+
</div>
43+
</div>
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { type MultipleSelectInstance, multipleSelect } from 'multiple-select-vanilla';
2+
3+
export default class Example {
4+
ms1?: MultipleSelectInstance;
5+
6+
mount() {
7+
this.ms1 = multipleSelect('select', {
8+
labelId: 'custom-label',
9+
}) as MultipleSelectInstance;
10+
}
11+
12+
unmount() {
13+
// destroy ms instance(s) to avoid DOM leaks
14+
this.ms1?.destroy();
15+
this.ms1 = undefined;
16+
}
17+
}

packages/demo/src/style.scss

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,9 @@ h2 .links {
9090
.content-text section {
9191
margin-bottom: 30px;
9292
}
93+
label {
94+
font-weight: 500;
95+
}
9396

9497
/** Sidebar (left) and Content (right) */
9598
@media (min-width: 1200px) {

packages/multiple-select-vanilla/src/MultipleSelectInstance.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,11 @@ export class MultipleSelectInstance {
200200

201201
this.choiceElm = createDomElement('button', { className: 'ms-choice', type: 'button' }, this.parentElm);
202202

203+
if (this.options.labelId) {
204+
this.choiceElm.id = this.options.labelId;
205+
this.choiceElm.setAttribute('aria-labelledby', this.options.labelId);
206+
}
207+
203208
this.choiceElm.appendChild(createDomElement('span', { className: 'ms-placeholder', textContent: this.options.placeholder }));
204209

205210
if (this.options.showClear) {

packages/multiple-select-vanilla/src/interfaces/multipleSelectOption.interface.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,12 @@ export interface MultipleSelectOption extends MultipleSelectLocale {
100100
/** Keep the select dropdown always open.By default this option is set to false. */
101101
keepOpen?: boolean;
102102

103+
/**
104+
* For accessibility, you can provide a Label Id to be associated to the select button element (`.ms-choice`).
105+
* An example can be `labelId: "custom-label"` which will be assigned to `id` and `aria-labelledby` attributes of the `.ms-choice` button.
106+
*/
107+
labelId?: string;
108+
103109
/** Optional Locale */
104110
locale?: LocaleKey | MultipleSelectLocale;
105111

playwright/e2e/options39.spec.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { test, expect } from '@playwright/test';
2+
3+
test.describe('Options 39 - Label ID', () => {
4+
test('adding a Label id to the select button', async ({ page }) => {
5+
await page.goto('#/options39');
6+
7+
const msChoice = await page.locator('.ms-choice');
8+
await expect(msChoice).toHaveAttribute('id', 'custom-label');
9+
await expect(msChoice).toHaveAttribute('aria-labelledby', 'custom-label');
10+
});
11+
});

0 commit comments

Comments
 (0)