Skip to content

Commit a4868a9

Browse files
committed
Add a11y improvements
1 parent 283bbbf commit a4868a9

4 files changed

Lines changed: 50 additions & 19 deletions

File tree

dev/vscode-single-select/basic-example.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
<body>
2727
<main>
2828
<vscode-demo>
29-
<vscode-single-select>
29+
<vscode-single-select label="Single Select example">
3030
<vscode-option>Lorem</vscode-option>
3131
<vscode-option>Ipsum</vscode-option>
3232
<vscode-option>Dolor</vscode-option>

src/includes/vscode-select/vscode-select-base.ts

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,6 @@ export const OPT_HEIGHT = 22;
2727
* @cssprop --dropdown-z-index - workaround for dropdown z-index issues
2828
*/
2929
export class VscodeSelectBase extends VscElement {
30-
/** @internal */
31-
@property({type: String, reflect: true, attribute: 'aria-expanded'})
32-
override ariaExpanded = 'false';
33-
3430
@property({type: Boolean, reflect: true})
3531
creatable = false;
3632

@@ -40,6 +36,13 @@ export class VscodeSelectBase extends VscElement {
4036
@property({type: Boolean, reflect: true})
4137
combobox = false;
4238

39+
/**
40+
* Accessible label for screen readers. When a `<vscode-label>` is connected
41+
* to the component, it will be filled automatically.
42+
*/
43+
@property({reflect: true})
44+
label = '';
45+
4346
/**
4447
* The element cannot be used and is not focusable.
4548
*/
@@ -671,6 +674,8 @@ export class VscodeSelectBase extends VscElement {
671674
return html`
672675
<ul
673676
class="options"
677+
id=${`${this._multiple ? 'ms' : 'ss'}-listbox`}
678+
role="listbox"
674679
@click=${this._onOptionClick}
675680
@mouseover=${this._onOptionMouseOver}
676681
@scroll=${this._onOptionListScroll}
@@ -680,8 +685,11 @@ export class VscodeSelectBase extends VscElement {
680685
list,
681686
(op) => op.index,
682687
(op, index) => {
688+
const active = op.index === this._activeIndex && !op.disabled;
689+
const selected = this._selectedIndex === op.index;
690+
683691
const optionClasses = {
684-
active: index === this._activeIndex && !op.disabled,
692+
active,
685693
disabled: op.disabled,
686694
option: true,
687695
selected: op.selected,
@@ -699,9 +707,12 @@ export class VscodeSelectBase extends VscElement {
699707
700708
return html`
701709
<li
710+
aria-selected=${selected ? 'true' : 'false'}
702711
class=${classMap(optionClasses)}
703712
data-index=${op.index}
704713
data-filtered-index=${index}
714+
id=${`op-${op.index}`}
715+
role="option"
705716
>
706717
${this._multiple
707718
? html`<span class=${classMap(checkboxClasses)}></span
@@ -818,7 +829,7 @@ export class VscodeSelectBase extends VscElement {
818829
return html`${nothing}`;
819830
}
820831

821-
private _renderDropdown() {
832+
protected _renderDropdown() {
822833
const classes = {
823834
dropdown: true,
824835
multiple: this._multiple,
@@ -833,12 +844,4 @@ export class VscodeSelectBase extends VscElement {
833844
</div>
834845
`;
835846
}
836-
837-
override render(): TemplateResult {
838-
return html`
839-
<slot class="main-slot" @slotchange=${this._onSlotChange}></slot>
840-
${this.combobox ? this._renderComboboxFace() : this._renderSelectFace()}
841-
${this._renderDropdown()}
842-
`;
843-
}
844847
}

src/vscode-multi-select/vscode-multi-select.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,16 @@ export class VscodeMultiSelect
412412
`
413413
: html`${nothing}`;
414414
}
415+
416+
override render(): TemplateResult {
417+
return html`
418+
<div class="multi-select">
419+
<slot class="main-slot" @slotchange=${this._onSlotChange}></slot>
420+
${this.combobox ? this._renderComboboxFace() : this._renderSelectFace()}
421+
${this._renderDropdown()}
422+
</div>
423+
`;
424+
}
415425
}
416426

417427
declare global {

src/vscode-single-select/vscode-single-select.ts

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
findNextSelectableOptionIndex,
1414
findPrevSelectableOptionIndex,
1515
} from '../includes/vscode-select/helpers.js';
16+
import {ifDefined} from 'lit/directives/if-defined.js';
1617

1718
export type VscSingleSelectCreateOptionEvent = CustomEvent<{value: string}>;
1819

@@ -81,10 +82,6 @@ export class VscodeSingleSelect
8182
@property({attribute: 'default-value'})
8283
defaultValue = '';
8384

84-
/** @internal */
85-
@property({type: String, attribute: true, reflect: true})
86-
override role = 'listbox';
87-
8885
@property({reflect: true})
8986
name: string | undefined = undefined;
9087

@@ -107,6 +104,10 @@ export class VscodeSingleSelect
107104
return this._selectedIndex;
108105
}
109106

107+
/** @internal */
108+
@property({reflect: true, type: Number})
109+
override tabIndex: number = 0;
110+
110111
@property({type: String})
111112
set value(val: string) {
112113
if (this._options[this._selectedIndex]) {
@@ -397,17 +398,34 @@ export class VscodeSingleSelect
397398

398399
protected override _renderSelectFace(): TemplateResult {
399400
const label = this._options[this._selectedIndex]?.label ?? '';
401+
const activeDescendant = `op-${this._activeIndex < 0 ? this._selectedIndex : this._activeIndex}`;
400402

401403
return html`
402404
<div
405+
aria-activedescendant=${activeDescendant}
406+
aria-controls="ss-listbox"
407+
aria-expanded=${this.open ? 'true' : 'false'}
408+
aria-haspopup="listbox"
409+
aria-label=${ifDefined(this.label)}
403410
class="select-face face"
404411
@click=${this._onFaceClick}
412+
role="combobox"
405413
tabindex=${this.tabIndex > -1 ? 0 : -1}
406414
>
407415
<span class="text">${label}</span> ${chevronDownIcon}
408416
</div>
409417
`;
410418
}
419+
420+
override render(): TemplateResult {
421+
return html`
422+
<div class="single-select">
423+
<slot class="main-slot" @slotchange=${this._onSlotChange}></slot>
424+
${this.combobox ? this._renderComboboxFace() : this._renderSelectFace()}
425+
${this._renderDropdown()}
426+
</div>
427+
`;
428+
}
411429
}
412430

413431
declare global {

0 commit comments

Comments
 (0)