diff --git a/examples/index.html b/examples/index.html
index 4702cf9..2b90b7d 100644
--- a/examples/index.html
+++ b/examples/index.html
@@ -46,10 +46,10 @@
-
+
@@ -64,10 +64,10 @@
-
+
@@ -79,7 +79,7 @@
-
+
@@ -96,7 +96,7 @@
data-autoselect="true"
>
-
+
@@ -113,7 +113,7 @@
-
+
diff --git a/package-lock.json b/package-lock.json
index f7bf61e..ffdb9c7 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -4846,9 +4846,9 @@
"dev": true
},
"node_modules/follow-redirects": {
- "version": "1.15.3",
- "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz",
- "integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==",
+ "version": "1.15.4",
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz",
+ "integrity": "sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw==",
"dev": true,
"funding": [
{
@@ -5423,9 +5423,9 @@
}
},
"node_modules/ip": {
- "version": "1.1.8",
- "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.8.tgz",
- "integrity": "sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg==",
+ "version": "1.1.9",
+ "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.9.tgz",
+ "integrity": "sha512-cyRxvOEpNHNtchU3Ln9KC/auJgup87llfQpQ+t5ghoC/UhL16SWzbueiCsdTnWmqAWl7LadfuwhlqmtOaqMHdQ==",
"dev": true
},
"node_modules/is-array-buffer": {
diff --git a/src/autocomplete.ts b/src/autocomplete.ts
index 7008de3..13126dc 100644
--- a/src/autocomplete.ts
+++ b/src/autocomplete.ts
@@ -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): 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.`)
@@ -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
}
@@ -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'))
})
@@ -246,6 +244,8 @@ export default class Autocomplete {
this.results.hidden = false
}
}
+ this.container.open = true
+ this.interactingWithList = true
}
close(): void {
@@ -258,5 +258,7 @@ export default class Autocomplete {
this.results.hidden = true
}
}
+ this.container.open = false
+ this.interactingWithList = false
}
}
diff --git a/test/auto-complete-element.js b/test/auto-complete-element.js
index 74cd5bf..7d1827f 100644
--- a/test/auto-complete-element.js
+++ b/test/auto-complete-element.js
@@ -18,19 +18,8 @@ describe('auto-complete element', function () {
})
})
- describe('requesting server results', function () {
- beforeEach(function () {
- document.body.innerHTML = `
-
- `
- })
-
+ // 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')
@@ -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')
@@ -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 () {
@@ -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 () => {
@@ -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 = `
+
+ `
+ })
+
+ serverResponseExamples()
+ })
+
+ describe('requesting server results (popover)', function () {
+ beforeEach(function () {
+ document.body.innerHTML = `
+
+ `
+ })
+
+ serverResponseExamples()
})
describe('clear button provided', () => {