Skip to content

Commit

Permalink
Latest code
Browse files Browse the repository at this point in the history
  • Loading branch information
camertron committed Feb 22, 2024
1 parent 3935fba commit a6a233b
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 56 deletions.
14 changes: 7 additions & 7 deletions examples/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,10 @@
<input name="robot" type="text" aria-labelledby="robots-label" autofocus />
<!-- if a clear button is passed in, recommended to be *before* UL elements to avoid conflicting with their blur logic -->
<button id="robot-clear">x</button>
<ul popover id="items-popup"></ul>
<ul id="items-popup"></ul>
<!-- For built-in screen-reader announcements:
- Note the ID is the same as the <ul> with "feedback" appended
- Also note that aria attributes will be added programmatically if they aren't set correctly
- Also note that aria attributes will be added programmatically if they aren't set correctly
-->
<div id="items-popup-feedback" class="sr-only"></div>
</auto-complete>
Expand All @@ -64,10 +64,10 @@
<input id="robot-a" name="robot-a" type="text" aria-labelledby="robots-a-label" autofocus />
<!-- if a clear button is passed in, recommended to be *before* UL elements to avoid conflicting with their blur logic -->
<button id="robot-a-clear">x</button>
<ul popover id="items-a-popup"></ul>
<ul id="items-a-popup"></ul>
<!-- For built-in screen-reader announcements:
- Note the ID is the same as the <ul> with "feedback" appended
- Also note that aria attributes will be added programmatically if they aren't set correctly
- Also note that aria attributes will be added programmatically if they aren't set correctly
-->
<div id="items-a-popup-feedback" class="sr-only"></div>
</auto-complete>
Expand All @@ -79,7 +79,7 @@
<label id="robots-2-label" for="robot-2">Robots (without autoselect on enter)</label>
<auto-complete src="/demo" for="items-2-popup" aria-labelledby="robots-2-label">
<input name="robot-2" type="text" aria-labelledby="robots-2-label" autofocus />
<ul popover id="items-2-popup"></ul>
<ul id="items-2-popup"></ul>
<div id="items-2-popup-feedback" class="sr-only"></div>
</auto-complete>
<button type="submit">Save</button>
Expand All @@ -96,7 +96,7 @@
data-autoselect="true"
>
<input name="custom-fetching-robot" type="text" aria-labelledby="custom-fetching-robots-label" autofocus />
<ul popover id="custom-fetching-items-popup"></ul>
<ul id="custom-fetching-items-popup"></ul>
<div id="custom-fetching-items-popup-feedback" class="sr-only"></div>
</auto-complete>
<button type="submit">Save</button>
Expand All @@ -113,7 +113,7 @@
<auto-complete src="/demo" for="fetch-on-empty-items-popup" aria-labelledby="fetch-on-empty-robots-label" fetch-on-empty>
<input name="fetch-on-empty-robot" type="text" aria-labelledby="fetch-on-empty-robots-label" autofocus />
<button id="fetch-on-empty-robot-clear">x</button>
<ul popover id="fetch-on-empty-items-popup"></ul>
<ul id="fetch-on-empty-items-popup"></ul>
<div id="fetch-on-empty-items-popup-feedback" class="sr-only"></div>
</auto-complete>
<button type="submit">Save</button>
Expand Down
26 changes: 14 additions & 12 deletions src/autocomplete.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,42 +112,40 @@ export default class Autocomplete {
this.container.value = ''
this.input.focus()
this.input.dispatchEvent(new Event('change'))
this.container.open = false
this.close()
}

onKeydown(event: KeyboardEvent): void {
if (event.key === 'Escape' && this.container.open) {
this.container.open = false
this.close()
event.stopPropagation()
event.preventDefault()
} else if (event.altKey && event.key === 'ArrowUp' && this.container.open) {
this.container.open = false
this.close()
event.stopPropagation()
event.preventDefault()
} else if (event.altKey && event.key === 'ArrowDown' && !this.container.open) {
if (!this.input.value.trim()) return
this.container.open = true
this.open()
event.stopPropagation()
event.preventDefault()
}
}

onInputFocus(): void {
if (this.interactingWithList) return
this.fetchResults()
}

onInputBlur(): void {
if (this.interactingWithList) {
this.interactingWithList = false
return
}
this.container.open = false
if (this.interactingWithList) return
this.close()
}

onCommit({target}: Pick<Event, 'target'>): void {
const selected = target
if (!(selected instanceof HTMLElement)) return
this.container.open = false
this.close()
if (selected instanceof HTMLAnchorElement) return
const value = selected.getAttribute('data-autocomplete-value') || selected.textContent!
this.updateFeedbackForScreenReaders(`${selected.textContent || ''} selected.`)
Expand Down Expand Up @@ -189,7 +187,7 @@ export default class Autocomplete {
fetchResults(): void {
const query = this.input.value.trim()
if (!query && !this.container.fetchOnEmpty) {
this.container.open = false
this.close()
return
}

Expand Down Expand Up @@ -225,7 +223,7 @@ export default class Autocomplete {
this.updateFeedbackForScreenReaders(`${numOptions || 'No'} results.`)
}

this.container.open = hasResults
hasResults ? this.open() : this.close()
this.container.dispatchEvent(new CustomEvent('load'))
this.container.dispatchEvent(new CustomEvent('loadend'))
})
Expand All @@ -246,6 +244,8 @@ export default class Autocomplete {
this.results.hidden = false
}
}
this.container.open = true
this.interactingWithList = true
}

close(): void {
Expand All @@ -258,5 +258,7 @@ export default class Autocomplete {
this.results.hidden = true
}
}
this.container.open = false
this.interactingWithList = false
}
}
76 changes: 39 additions & 37 deletions test/auto-complete-element.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,8 @@ describe('auto-complete element', function () {
})
})

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

// eslint-disable-next-line func-style
const serverResponseExamples = function () {
it('requests html fragment', async function () {
const container = document.querySelector('auto-complete')
const input = container.querySelector('input')
Expand Down Expand Up @@ -147,25 +136,6 @@ describe('auto-complete element', function () {
assert.isFalse(container.open)
})

it('does not close on blur after mousedown', async function () {
const container = document.querySelector('auto-complete')
const input = container.querySelector('input')

triggerInput(input, 'hub')
await once(container, 'loadend')

const link = container.querySelector('a[role=option]')

assert.equal('', container.value)
link.dispatchEvent(new MouseEvent('mousedown', {bubbles: true}))
input.dispatchEvent(new Event('blur'))
assert(container.open)

await sleep(100)
input.dispatchEvent(new Event('blur'))
assert.isFalse(container.open)
})

it('closes on Escape', async function () {
const container = document.querySelector('auto-complete')
const input = container.querySelector('input')
Expand All @@ -175,10 +145,10 @@ describe('auto-complete element', function () {
await once(container, 'loadend')

assert.isTrue(container.open)
assert.isFalse(popup.hidden)
if (!popup.popover) assert.isFalse(popup.hidden)
assert.isFalse(keydown(input, 'Escape'))
assert.isFalse(container.open)
assert.isTrue(popup.hidden)
if (!popup.popover) assert.isTrue(popup.hidden)
})

it('opens and closes on alt + ArrowDown and alt + ArrowUp', async function () {
Expand All @@ -190,15 +160,15 @@ describe('auto-complete element', function () {
await once(container, 'loadend')

assert.isTrue(container.open)
assert.isFalse(popup.hidden)
if (!popup.popover) assert.isFalse(popup.hidden)

assert.isFalse(keydown(input, 'ArrowUp', true))
assert.isFalse(container.open)
assert.isTrue(popup.hidden)
if (!popup.popover) assert.isTrue(popup.hidden)

assert.isFalse(keydown(input, 'ArrowDown', true))
assert.isTrue(container.open)
assert.isFalse(popup.hidden)
if (!popup.popover) assert.isFalse(popup.hidden)
})

it('allows providing a custom fetch method', async () => {
Expand All @@ -216,6 +186,38 @@ describe('auto-complete element', function () {
assert.equal(2, popup.children.length)
assert.equal(popup.querySelector('li').textContent, 'Mock Custom Fetch Result 1')
})
}

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

serverResponseExamples()
})

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

serverResponseExamples()
})

describe('clear button provided', () => {
Expand Down

0 comments on commit a6a233b

Please sign in to comment.