From 1693f5b721d9a3d7f6cfec0c6d95d8ddd9236c6e Mon Sep 17 00:00:00 2001 From: Craig Kochis Date: Wed, 12 Jun 2024 22:33:19 -0400 Subject: [PATCH 1/5] add more aria role support for autocomplete widget --- src/ui/autocomplete.ts | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/src/ui/autocomplete.ts b/src/ui/autocomplete.ts index 17c1de80..26fd869e 100644 --- a/src/ui/autocomplete.ts +++ b/src/ui/autocomplete.ts @@ -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 @@ -136,6 +132,8 @@ class AutocompleteUI { // result list element this.resultsList = document.createElement('ul'); this.resultsList.classList.add(CLASSNAMES.RESULTS_LIST); + this.resultsList.setAttribute('role', 'listbox'); + this.resultsList.setAttribute('aria-live', 'polite'); setHeight(this.resultsList, this.config); if (containerEL.nodeName === 'INPUT') { @@ -168,6 +166,13 @@ class AutocompleteUI { this.container.appendChild(this.wrapper); } + // set aria roles + this.inputField.setAttribute('aria-expanded', 'false'); + this.inputField.setAttribute('aria-control', 'autocomplete-list'); + 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)); @@ -275,6 +280,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', `item-${index}`); // construct result with bolded label let listContent; @@ -336,7 +343,7 @@ class AutocompleteUI { return; } - this.wrapper.setAttribute(ARIA.EXPANDED, 'true'); + this.inputField.setAttribute('aria-expanded', 'true'); this.resultsList.removeAttribute('hidden'); this.isOpen = true; } @@ -350,7 +357,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; @@ -380,6 +388,9 @@ 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', `item-${index}`); + this.highlightedIndex = index; } From 4d5222650fb5daec71a2f0026df44b5f3c5499ec Mon Sep 17 00:00:00 2001 From: Craig Kochis Date: Wed, 12 Jun 2024 22:34:34 -0400 Subject: [PATCH 2/5] bump version --- README.md | 14 +++++++------- package-lock.json | 2 +- package.json | 2 +- src/version.ts | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index b313fceb..c6e9cceb 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,7 @@ Radar.initialize('prj_test_pk_...', { /* options */ }); Add the following script in your `html` file ```html - + ``` Then initialize the Radar SDK @@ -73,8 +73,8 @@ To create a map, first initialize the Radar SDK with your publishable key. Then ```html - - + + @@ -98,8 +98,8 @@ To create an autocomplete input, first initialize the Radar SDK with your publis ```html - - + + @@ -130,8 +130,8 @@ To power [geofencing](https://radar.com/documentation/geofencing/overview) exper ```html - - + + diff --git a/package-lock.json b/package-lock.json index 918f7cba..90e2c9b7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "radar-sdk-js", - "version": "4.3.0", + "version": "4.3.1-beta.0", "lockfileVersion": 3, "requires": true, "packages": { diff --git a/package.json b/package.json index dca0231f..f41a5c5f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "radar-sdk-js", - "version": "4.3.0", + "version": "4.3.1-beta.0", "description": "Web Javascript SDK for Radar, location infrastructure for mobile and web apps.", "homepage": "https://radar.com", "type": "module", diff --git a/src/version.ts b/src/version.ts index 0601e528..d0ff53db 100644 --- a/src/version.ts +++ b/src/version.ts @@ -1 +1 @@ -export default '4.3.0'; +export default '4.3.1-beta.0'; From 648f22a28d2da37be684c7fafacd142a03a414f9 Mon Sep 17 00:00:00 2001 From: Craig Kochis Date: Wed, 12 Jun 2024 22:40:24 -0400 Subject: [PATCH 3/5] use event.key instead of event.code --- README.md | 14 +++++++------- package-lock.json | 2 +- package.json | 2 +- src/ui/autocomplete.ts | 9 ++------- src/version.ts | 2 +- 5 files changed, 12 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index c6e9cceb..84a4dbf1 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,7 @@ Radar.initialize('prj_test_pk_...', { /* options */ }); Add the following script in your `html` file ```html - + ``` Then initialize the Radar SDK @@ -73,8 +73,8 @@ To create a map, first initialize the Radar SDK with your publishable key. Then ```html - - + + @@ -98,8 +98,8 @@ To create an autocomplete input, first initialize the Radar SDK with your publis ```html - - + + @@ -130,8 +130,8 @@ To power [geofencing](https://radar.com/documentation/geofencing/overview) exper ```html - - + + diff --git a/package-lock.json b/package-lock.json index 90e2c9b7..3a7fd1e9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "radar-sdk-js", - "version": "4.3.1-beta.0", + "version": "4.3.1-beta.1", "lockfileVersion": 3, "requires": true, "packages": { diff --git a/package.json b/package.json index f41a5c5f..01ee691d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "radar-sdk-js", - "version": "4.3.1-beta.0", + "version": "4.3.1-beta.1", "description": "Web Javascript SDK for Radar, location infrastructure for mobile and web apps.", "homepage": "https://radar.com", "type": "module", diff --git a/src/ui/autocomplete.ts b/src/ui/autocomplete.ts index 26fd869e..2b204976 100644 --- a/src/ui/autocomplete.ts +++ b/src/ui/autocomplete.ts @@ -395,39 +395,34 @@ class AutocompleteUI { } 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; } diff --git a/src/version.ts b/src/version.ts index d0ff53db..5ee20e61 100644 --- a/src/version.ts +++ b/src/version.ts @@ -1 +1 @@ -export default '4.3.1-beta.0'; +export default '4.3.1-beta.1'; From 829d82b9fd262c4a060b49b225e5eb257a75fd0d Mon Sep 17 00:00:00 2001 From: Craig Kochis Date: Wed, 12 Jun 2024 23:11:50 -0400 Subject: [PATCH 4/5] fix aria labels --- README.md | 14 +++++++------- package-lock.json | 2 +- package.json | 2 +- src/ui/autocomplete.ts | 5 ++++- src/version.ts | 2 +- 5 files changed, 14 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 84a4dbf1..29bd18e0 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,7 @@ Radar.initialize('prj_test_pk_...', { /* options */ }); Add the following script in your `html` file ```html - + ``` Then initialize the Radar SDK @@ -73,8 +73,8 @@ To create a map, first initialize the Radar SDK with your publishable key. Then ```html - - + + @@ -98,8 +98,8 @@ To create an autocomplete input, first initialize the Radar SDK with your publis ```html - - + + @@ -130,8 +130,8 @@ To power [geofencing](https://radar.com/documentation/geofencing/overview) exper ```html - - + + diff --git a/package-lock.json b/package-lock.json index 3a7fd1e9..b4fa2844 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "radar-sdk-js", - "version": "4.3.1-beta.1", + "version": "4.3.1-beta.2", "lockfileVersion": 3, "requires": true, "packages": { diff --git a/package.json b/package.json index 01ee691d..a2a8c792 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "radar-sdk-js", - "version": "4.3.1-beta.1", + "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", diff --git a/src/ui/autocomplete.ts b/src/ui/autocomplete.ts index 2b204976..51613adf 100644 --- a/src/ui/autocomplete.ts +++ b/src/ui/autocomplete.ts @@ -132,8 +132,10 @@ class AutocompleteUI { // result list element this.resultsList = document.createElement('ul'); this.resultsList.classList.add(CLASSNAMES.RESULTS_LIST); + this.resultsList.classList.add('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') { @@ -167,8 +169,9 @@ class AutocompleteUI { } // 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-control', 'autocomplete-list'); this.inputField.setAttribute('aria-haspopup', 'listbox'); this.inputField.setAttribute('aria-autocomplete', 'list'); this.inputField.setAttribute('aria-activedescendant', ''); diff --git a/src/version.ts b/src/version.ts index 5ee20e61..3d4f9ba8 100644 --- a/src/version.ts +++ b/src/version.ts @@ -1 +1 @@ -export default '4.3.1-beta.1'; +export default '4.3.1-beta.2'; From ee499ba04e0582a62aa871063ba1d04ab382c7df Mon Sep 17 00:00:00 2001 From: Craig Kochis Date: Thu, 27 Jun 2024 16:04:38 -0400 Subject: [PATCH 5/5] PR comments --- src/ui/autocomplete.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ui/autocomplete.ts b/src/ui/autocomplete.ts index 51613adf..4e316ed9 100644 --- a/src/ui/autocomplete.ts +++ b/src/ui/autocomplete.ts @@ -132,7 +132,7 @@ class AutocompleteUI { // result list element this.resultsList = document.createElement('ul'); this.resultsList.classList.add(CLASSNAMES.RESULTS_LIST); - this.resultsList.classList.add('id', 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'); @@ -284,7 +284,7 @@ class AutocompleteUI { const li = document.createElement('li'); li.classList.add(CLASSNAMES.RESULTS_ITEM); li.setAttribute('role', 'option'); - li.setAttribute('id', `item-${index}`); + li.setAttribute('id', `${CLASSNAMES.RESULTS_ITEM}}-${index}`); // construct result with bolded label let listContent; @@ -392,7 +392,7 @@ class AutocompleteUI { resultItems[index].classList.add(CLASSNAMES.SELECTED_ITEM); // set aria active descendant - this.inputField.setAttribute('aria-activedescendant', `item-${index}`); + this.inputField.setAttribute('aria-activedescendant', `${CLASSNAMES.RESULTS_ITEM}-${index}`); this.highlightedIndex = index; }