Skip to content
This repository has been archived by the owner on Jan 3, 2024. It is now read-only.

Commit

Permalink
Improve accessibility of ocAutocomplete
Browse files Browse the repository at this point in the history
  • Loading branch information
marcus-herrmann committed Dec 2, 2019
1 parent 4a97e7c commit a1a4d69
Showing 1 changed file with 55 additions and 1 deletion.
56 changes: 55 additions & 1 deletion src/patterns/OcAutocomplete.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,21 @@
<div class="oc-autocomplete">
<input
class="oc-autocomplete-input"
autocomplete="off"
role="combobox"
aria-autocomplete="list"
:aria-expanded="ariaExpanded.toString()"
:aria-owns="$_ocAutocomplete_listboxId"
:aria-activedescendant="$_ocAutocomplete_optionId(highlighted)"
:aria-label="ariaLabel"
v-model="input"
:placeholder="placeholder"
:disabled="disabled"
ref="$_ocAutocompleteInput"
@keydown.up.prevent="highlighted--"
@keydown.down.prevent="highlighted++"
@keydown.enter="$_ocAutocomplete_selectSuggestion"
@keydown.esc="$_ocAutocomplete_dropdown.hide"
/>
<div hidden :id="$_ocAutocomplete_boundryId" />
<div
Expand All @@ -18,9 +26,15 @@
:uk-drop="'mode:click;delay-hide:0;toggle:#' + $_ocAutocomplete_boundryId"
:id="$_ocAutocomplete_dropdownId"
>
<ul class="oc-autocomplete-suggestion-list">
<ul class="oc-autocomplete-suggestion-list" role="listbox" :id="$_ocAutocomplete_listboxId">
<template v-for="(item, i) in $_ocAutocomplete_matchesShown">
<li
role="option"
:id="$_ocAutocomplete_optionId(i)"
:aria-posinset="i + 1"
:aria-setsize="$_ocAutocomplete_matchesShown.length"
:aria-selected="i === highlighted"
:aria-describedby="$_ocAutocomplete_descriptionId"
:class="[
'oc-autocomplete-suggestion',
{ 'oc-autocomplete-suggestion-selected': i === highlighted },
Expand Down Expand Up @@ -48,6 +62,7 @@
</li>
</ul>
</div>
<div hidden :id="$_ocAutocomplete_descriptionId" v-text="ariaDescription" />
</div>
</template>
<script>
Expand All @@ -62,6 +77,11 @@ import { uniqueId as _uniqueId } from "lodash"
* and presenting the user a list of possible matches to the entered search term.
*
* The component supports single select only at the moment.
*
* ## Accessibility
* This component is built based on the [WAI-ARIA 1.1 Authoring Practice](https://www.w3.org/TR/wai-aria-practices/examples/combobox/aria1.1pattern/grid-combo.html) and [GOV.UK's implementation](https://alphagov.github.io/accessible-autocomplete/examples/) (their frontend team is considered an authority in accessibility community).
*
* Please provide at least an accessible name via the `ariaLabel` prop. By default this component comes with a description to screen reader users on how to use this component (it is a thin line of when it is good to supply help text for screen reader users and [when it's just too verbose](https://adrianroselli.com/2019/10/stop-giving-control-hints-to-screen-readers.html)). This description text is `When autocomplete results are available use up and down arrows to review and enter to select. Touch device users, explore by touch or with swipe gestures.` but can be overridden with the `ariaDescription` prop.
*/
export default {
name: "oc-autocomplete",
Expand All @@ -76,6 +96,22 @@ export default {
type: String,
required: false,
},
/**
* Label (accessible name) of the input
*/
ariaLabel: {
type: String,
required: true,
},
/**
* Add a description of how to use this (complex) widget for screen reader users
*/
ariaDescription: {
type: String,
required: false,
default:
"When autocomplete results are available use up and down arrows to review and enter to select. Touch device users, explore by touch or with swipe gestures.",
},
/**
* Informative text displayed right next to the spinner while loading data
*/
Expand Down Expand Up @@ -145,6 +181,8 @@ export default {
input: "",
highlighted: 0,
expanded: false,
ariaExpanded: false,
activeDescendant: "",
overflowingMatches: this.$_ocAutocomplete_matchesOverflowing,
}
},
Expand All @@ -155,6 +193,11 @@ export default {
maxHeight = `calc(100vh - ${ddOffsetTop}px )`
dd.style.maxHeight = maxHeight
this.ariaExpanded = true
})
UiKit.util.on(`#${this.$_ocAutocomplete_dropdownId}`, "hide", () => {
this.ariaExpanded = false
})
},
computed: {
Expand All @@ -179,6 +222,12 @@ export default {
$_ocAutocomplete_dropdownId() {
return _uniqueId("oc-autocomplete-dropdown-")
},
$_ocAutocomplete_listboxId() {
return _uniqueId("oc-autocomplete-listbox-")
},
$_ocAutocomplete_descriptionId() {
return _uniqueId("oc-autocomplete-description-")
},
$_ocAutocomplete_boundryId() {
return _uniqueId("oc-autocomplete-boundry-")
},
Expand Down Expand Up @@ -234,6 +283,11 @@ export default {
this.expanded = false
}
},
$_ocAutocomplete_optionId(i) {
const activeDescendantId = `oc-autocomplete-option-${i}`
this.activeDescendant = activeDescendantId
return this.ariaExpanded ? activeDescendantId : ""
},
focus() {
this.$refs.$_ocAutocompleteInput.focus()
},
Expand Down

0 comments on commit a1a4d69

Please sign in to comment.