Skip to content

Commit

Permalink
Fix autocomplete keyboard control on Windows/Edge (#170)
Browse files Browse the repository at this point in the history
* add more aria role support for autocomplete widget

* bump version

* use event.key instead of event.code

* fix aria labels

* PR comments
  • Loading branch information
kochis authored Jun 27, 2024
1 parent be6c07c commit 94e267e
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 23 deletions.
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ Radar.initialize('prj_test_pk_...', { /* options */ });
Add the following script in your `html` file
```html
<script src="https://js.radar.com/v4.3.0/radar.min.js"></script>
<script src="https://js.radar.com/v4.3.1-beta.2/radar.min.js"></script>
```

Then initialize the Radar SDK
Expand All @@ -73,8 +73,8 @@ To create a map, first initialize the Radar SDK with your publishable key. Then
```html
<html>
<head>
<link href="https://js.radar.com/v4.3.0/radar.css" rel="stylesheet">
<script src="https://js.radar.com/v4.3.0/radar.min.js"></script>
<link href="https://js.radar.com/v4.3.1-beta.2/radar.css" rel="stylesheet">
<script src="https://js.radar.com/v4.3.1-beta.2/radar.min.js"></script>
</head>

<body>
Expand All @@ -98,8 +98,8 @@ To create an autocomplete input, first initialize the Radar SDK with your publis
```html
<html>
<head>
<link href="https://js.radar.com/v4.3.0/radar.css" rel="stylesheet">
<script src="https://js.radar.com/v4.3.0/radar.min.js"></script>
<link href="https://js.radar.com/v4.3.1-beta.2/radar.css" rel="stylesheet">
<script src="https://js.radar.com/v4.3.1-beta.2/radar.min.js"></script>
</head>

<body>
Expand Down Expand Up @@ -130,8 +130,8 @@ To power [geofencing](https://radar.com/documentation/geofencing/overview) exper
```html
<html>
<head>
<link href="https://js.radar.com/v4.3.0/radar.css" rel="stylesheet">
<script src="https://js.radar.com/v4.3.0/radar.min.js"></script>
<link href="https://js.radar.com/v4.3.1-beta.2/radar.css" rel="stylesheet">
<script src="https://js.radar.com/v4.3.1-beta.2/radar.min.js"></script>
</head>

<body>
Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "radar-sdk-js",
"version": "4.3.0",
"version": "4.3.1-beta.2",
"description": "Web Javascript SDK for Radar, location infrastructure for mobile and web apps.",
"homepage": "https://radar.com",
"type": "module",
Expand Down
35 changes: 22 additions & 13 deletions src/ui/autocomplete.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,6 @@ const CLASSNAMES = {
NO_RESULTS: 'radar-no-results',
};

const ARIA = {
EXPANDED: 'aria-expanded',
};

const defaultAutocompleteOptions: RadarAutocompleteUIOptions = {
container: 'autocomplete',
debounceMS: 200, // Debounce time in milliseconds
Expand Down Expand Up @@ -136,6 +132,10 @@ class AutocompleteUI {
// result list element
this.resultsList = document.createElement('ul');
this.resultsList.classList.add(CLASSNAMES.RESULTS_LIST);
this.resultsList.setAttribute('id', CLASSNAMES.RESULTS_LIST);
this.resultsList.setAttribute('role', 'listbox');
this.resultsList.setAttribute('aria-live', 'polite');
this.resultsList.setAttribute('aria-label', 'Search results');
setHeight(this.resultsList, this.config);

if (containerEL.nodeName === 'INPUT') {
Expand Down Expand Up @@ -168,6 +168,14 @@ class AutocompleteUI {
this.container.appendChild(this.wrapper);
}

// set aria roles
this.inputField.setAttribute('role', 'combobox');
this.inputField.setAttribute('aria-controls', CLASSNAMES.RESULTS_LIST);
this.inputField.setAttribute('aria-expanded', 'false');
this.inputField.setAttribute('aria-haspopup', 'listbox');
this.inputField.setAttribute('aria-autocomplete', 'list');
this.inputField.setAttribute('aria-activedescendant', '');

// setup event listeners
this.inputField.addEventListener('input', this.handleInput.bind(this));
this.inputField.addEventListener('keydown', this.handleKeyboardNavigation.bind(this));
Expand Down Expand Up @@ -275,6 +283,8 @@ class AutocompleteUI {
results.forEach((result, index) => {
const li = document.createElement('li');
li.classList.add(CLASSNAMES.RESULTS_ITEM);
li.setAttribute('role', 'option');
li.setAttribute('id', `${CLASSNAMES.RESULTS_ITEM}}-${index}`);

// construct result with bolded label
let listContent;
Expand Down Expand Up @@ -336,7 +346,7 @@ class AutocompleteUI {
return;
}

this.wrapper.setAttribute(ARIA.EXPANDED, 'true');
this.inputField.setAttribute('aria-expanded', 'true');
this.resultsList.removeAttribute('hidden');
this.isOpen = true;
}
Expand All @@ -350,7 +360,8 @@ class AutocompleteUI {
// (add 100ms delay if closed from link click)
const linkClick = e && (e.relatedTarget === this.poweredByLink);
setTimeout(() => {
this.wrapper.removeAttribute(ARIA.EXPANDED);
this.inputField.setAttribute('aria-expanded', 'false');
this.inputField.setAttribute('aria-activedescendant', '');
this.resultsList.setAttribute('hidden', '');
this.highlightedIndex = -1;
this.isOpen = false;
Expand Down Expand Up @@ -380,43 +391,41 @@ class AutocompleteUI {
// add class name to newly highlighted item
resultItems[index].classList.add(CLASSNAMES.SELECTED_ITEM);

// set aria active descendant
this.inputField.setAttribute('aria-activedescendant', `${CLASSNAMES.RESULTS_ITEM}-${index}`);

this.highlightedIndex = index;
}

public handleKeyboardNavigation(event: KeyboardEvent) {
// fallback to deprecated "keyCode" if event.code not set
const code = event.code !== undefined ? event.code : event.keyCode;
const key = event.key;

// allow event to propagate if result list is not open
if (!this.isOpen) {
return;
}

switch (code) {
switch (key) {
// Next item
case 'Tab':
case 'ArrowDown':
case 40:
event.preventDefault();
this.goTo(this.highlightedIndex + 1);
break;

// Prev item
case 'ArrowUp':
case 38:
event.preventDefault();
this.goTo(this.highlightedIndex - 1);
break;

// Select
case 'Enter':
case 13:
this.select(this.highlightedIndex);
break;

// Close
case 'Esc':
case 27:
this.close();
break;
}
Expand Down
2 changes: 1 addition & 1 deletion src/version.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export default '4.3.0';
export default '4.3.1-beta.2';

0 comments on commit 94e267e

Please sign in to comment.