Skip to content

Commit

Permalink
Merge pull request #126 from github/kendallg/allow-no-results
Browse files Browse the repository at this point in the history
Allow a no-results option with role=presentation
  • Loading branch information
kendallgassner authored Feb 13, 2025
2 parents fa1e349 + 749c264 commit 49d5f01
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 3 deletions.
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,14 @@ item whose display text needs to be different:
<li role="option" data-autocomplete-value="bb8">BB-8 (astromech)</li>
```
Use `data-no-result-found="true"` to show a no results message inside the autocomplete popover. Be sure to add `role="presentation"`
to this element so that screen readers do not mistake this as an auto-complete option. The auto-complete-element has built in functionality that
handles aria-live announcing number of search results so this should be purely decorative.
```html
<li role="presentation" aria-hidden="true" disabled data-no-result-found="true">No results found!</li>
```
### A Note on Clear button
While `input type="search"` comes with an `x` that clears the content of the field and refocuses it on many browsers, the implementation for this control is not keyboard accessible, and so we've opted to enable a customizable clear button so that your keyboard users will be able to interact with it.
Expand Down
11 changes: 9 additions & 2 deletions examples/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,15 @@
<div id="custom-fetching-items-popup-feedback" class="sr-only"></div>
</auto-complete>
<button type="submit">Save</button>
</form>
</form>
<script>
window.fetch = () => Promise.resolve(new Response(robotsList));
window.fetch = (url) => {
const query = url.split('?q=')[1]
if (query === 'none') {
return Promise.resolve(new Response('<li role="presentation" aria-hidden="true" data-no-result-found="true">No results found!</li>'))
}
return Promise.resolve(new Response(robotsList));
}
// fetchResult must be a function that return a Promise of string and that accepts as parameters an element and an URL
document.querySelector("auto-complete#custom-fetching-method").fetchResult = async (el, url) => (await fetch(url)).text();
</script>
Expand All @@ -123,3 +129,4 @@
<script type="module" src="https://unpkg.com/@github/auto-complete-element@latest/dist/bundle.js"></script>
</body>
</html>

4 changes: 3 additions & 1 deletion src/autocomplete.ts
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,9 @@ export default class Autocomplete {
this.identifyOptions()
this.combobox.indicateDefaultOption()
const allNewOptions = this.results.querySelectorAll('[role="option"]')
const hasResults = !!allNewOptions.length

const hasResults =
!!allNewOptions.length || !!this.results.querySelectorAll('[data-no-result-found="true"]').length
const numOptions = allNewOptions.length

const [firstOption] = allNewOptions
Expand Down
25 changes: 25 additions & 0 deletions test/auto-complete-element.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,31 @@ import {AutoCompleteElement} from '../src/index.ts'
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms))

describe('auto-complete element', function () {
describe('no results', () => {
beforeEach(function () {
document.body.innerHTML = `
<div id="mocha-fixture">
<auto-complete src="/noresults" for="popup">
<input type="text">
<ul id="popup"></ul>
<div id="popup-feedback"></div>
</auto-complete>
</div>
`
})

it('checks that no results is displayed', async () => {
const container = document.querySelector('auto-complete')
const input = container.querySelector('input')
const popup = container.querySelector('#popup')

triggerInput(input, 'none')
await once(container, 'loadend')
assert.isTrue(container.open)
assert.equal(1, popup.children.length)
})
})

describe('element creation', function () {
it('creates from document.createElement', function () {
const el = document.createElement('auto-complete')
Expand Down
5 changes: 5 additions & 0 deletions web-test-runner.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ export default {
<li role="option" aria-disabled="true"><span>fourth</span></li>
<li><a role="option" href="#hash">link</a></li>
`
} else if (method === 'GET' && url.startsWith('/noresults?q=none')) {
response.status = 200
response.body = `
<li role="presentation" aria-hidden="true" disabled data-no-result-found="true">No results found!</li>
`
}
await next()
},
Expand Down

0 comments on commit 49d5f01

Please sign in to comment.