Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading