Skip to content

Commit

Permalink
feat: add new labelId option for accessibility (#254)
Browse files Browse the repository at this point in the history
  • Loading branch information
ghiscoding authored Mar 20, 2024
1 parent 5443ff9 commit f66852f
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 0 deletions.
2 changes: 2 additions & 0 deletions packages/demo/src/app-routing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ import Options35 from './options/options35';
import Options36 from './options/options36';
import Options37 from './options/options37';
import Options38 from './options/options38';
import Options39 from './options/options39';

export const navbarRouting = [
{ name: 'getting-started', view: '/src/getting-started.html', viewModel: GettingStarted, title: 'Getting Started' },
Expand Down Expand Up @@ -136,6 +137,7 @@ export const exampleRouting = [
{ name: 'options36', view: '/src/options/options36.html', viewModel: Options36, title: 'Infinite Scroll' },
{ name: 'options37', view: '/src/options/options37.html', viewModel: Options37, title: 'Navigation Highlight' },
{ name: 'options38', view: '/src/options/options38.html', viewModel: Options38, title: 'Dark Mode' },
{ name: 'options39', view: '/src/options/options39.html', viewModel: Options39, title: 'Label Id (aria-labelledby)' },
],
},
{
Expand Down
43 changes: 43 additions & 0 deletions packages/demo/src/options/options39.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<div class="row mb-2">
<div class="col-md-12 title-desc">
<h2 class="bd-title">
Label Id <small>(for accessibility)</small>
<span class="float-end links">
Code <span class="fa fa-link"></span>
<span class="small">
<a
target="_blank"
href="https://github.com/ghiscoding/multiple-select-vanilla/blob/main/packages/demo/src/options/options03.html"
>html</a
>
|
<a target="_blank" href="https://github.com/ghiscoding/multiple-select-vanilla/blob/main/packages/demo/src/options/options03.ts"
>ts</a
>
</span>
</span>
</h2>
<div class="demo-subtitle">
In order for the select to be accessible, it should be linked to a label, use <code>labelId</code> option
to associate your label to the select button (the label must be created by yourself and linked via the <code>for</code> attribute).
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.
</div>
<div class="demo-subtitle">
Clicking the label will open the select dropdown.
</div>
</div>
</div>

<div>
<div class="mb-10">
<label class="mb-2" for="custom-label">My Select Label</label>
</div>
<div class="mb-10">
<select class="col-sm-8">
<option value="1">First</option>
<option value="2">Second</option>
<option value="3">Third</option>
<option value="4">Fourth</option>
</select>
</div>
</div>
17 changes: 17 additions & 0 deletions packages/demo/src/options/options39.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { type MultipleSelectInstance, multipleSelect } from 'multiple-select-vanilla';

export default class Example {
ms1?: MultipleSelectInstance;

mount() {
this.ms1 = multipleSelect('select', {
labelId: 'custom-label',
}) as MultipleSelectInstance;
}

unmount() {
// destroy ms instance(s) to avoid DOM leaks
this.ms1?.destroy();
this.ms1 = undefined;
}
}
3 changes: 3 additions & 0 deletions packages/demo/src/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,9 @@ h2 .links {
.content-text section {
margin-bottom: 30px;
}
label {
font-weight: 500;
}

/** Sidebar (left) and Content (right) */
@media (min-width: 1200px) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,11 @@ export class MultipleSelectInstance {

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

if (this.options.labelId) {
this.choiceElm.id = this.options.labelId;
this.choiceElm.setAttribute('aria-labelledby', this.options.labelId);
}

this.choiceElm.appendChild(createDomElement('span', { className: 'ms-placeholder', textContent: this.options.placeholder }));

if (this.options.showClear) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,12 @@ export interface MultipleSelectOption extends MultipleSelectLocale {
/** Keep the select dropdown always open.By default this option is set to false. */
keepOpen?: boolean;

/**
* For accessibility, you can provide a Label Id to be associated to the select button element (`.ms-choice`).
* An example can be `labelId: "custom-label"` which will be assigned to `id` and `aria-labelledby` attributes of the `.ms-choice` button.
*/
labelId?: string;

/** Optional Locale */
locale?: LocaleKey | MultipleSelectLocale;

Expand Down
11 changes: 11 additions & 0 deletions playwright/e2e/options39.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { test, expect } from '@playwright/test';

test.describe('Options 39 - Label ID', () => {
test('adding a Label id to the select button', async ({ page }) => {
await page.goto('#/options39');

const msChoice = await page.locator('.ms-choice');
await expect(msChoice).toHaveAttribute('id', 'custom-label');
await expect(msChoice).toHaveAttribute('aria-labelledby', 'custom-label');
});
});

0 comments on commit f66852f

Please sign in to comment.