Skip to content

Commit a6a233b

Browse files
committed
Latest code
1 parent 3935fba commit a6a233b

3 files changed

Lines changed: 60 additions & 56 deletions

File tree

examples/index.html

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,10 @@
4646
<input name="robot" type="text" aria-labelledby="robots-label" autofocus />
4747
<!-- if a clear button is passed in, recommended to be *before* UL elements to avoid conflicting with their blur logic -->
4848
<button id="robot-clear">x</button>
49-
<ul popover id="items-popup"></ul>
49+
<ul id="items-popup"></ul>
5050
<!-- For built-in screen-reader announcements:
5151
- Note the ID is the same as the <ul> with "feedback" appended
52-
- Also note that aria attributes will be added programmatically if they aren't set correctly
52+
- Also note that aria attributes will be added programmatically if they aren't set correctly
5353
-->
5454
<div id="items-popup-feedback" class="sr-only"></div>
5555
</auto-complete>
@@ -64,10 +64,10 @@
6464
<input id="robot-a" name="robot-a" type="text" aria-labelledby="robots-a-label" autofocus />
6565
<!-- if a clear button is passed in, recommended to be *before* UL elements to avoid conflicting with their blur logic -->
6666
<button id="robot-a-clear">x</button>
67-
<ul popover id="items-a-popup"></ul>
67+
<ul id="items-a-popup"></ul>
6868
<!-- For built-in screen-reader announcements:
6969
- Note the ID is the same as the <ul> with "feedback" appended
70-
- Also note that aria attributes will be added programmatically if they aren't set correctly
70+
- Also note that aria attributes will be added programmatically if they aren't set correctly
7171
-->
7272
<div id="items-a-popup-feedback" class="sr-only"></div>
7373
</auto-complete>
@@ -79,7 +79,7 @@
7979
<label id="robots-2-label" for="robot-2">Robots (without autoselect on enter)</label>
8080
<auto-complete src="/demo" for="items-2-popup" aria-labelledby="robots-2-label">
8181
<input name="robot-2" type="text" aria-labelledby="robots-2-label" autofocus />
82-
<ul popover id="items-2-popup"></ul>
82+
<ul id="items-2-popup"></ul>
8383
<div id="items-2-popup-feedback" class="sr-only"></div>
8484
</auto-complete>
8585
<button type="submit">Save</button>
@@ -96,7 +96,7 @@
9696
data-autoselect="true"
9797
>
9898
<input name="custom-fetching-robot" type="text" aria-labelledby="custom-fetching-robots-label" autofocus />
99-
<ul popover id="custom-fetching-items-popup"></ul>
99+
<ul id="custom-fetching-items-popup"></ul>
100100
<div id="custom-fetching-items-popup-feedback" class="sr-only"></div>
101101
</auto-complete>
102102
<button type="submit">Save</button>
@@ -113,7 +113,7 @@
113113
<auto-complete src="/demo" for="fetch-on-empty-items-popup" aria-labelledby="fetch-on-empty-robots-label" fetch-on-empty>
114114
<input name="fetch-on-empty-robot" type="text" aria-labelledby="fetch-on-empty-robots-label" autofocus />
115115
<button id="fetch-on-empty-robot-clear">x</button>
116-
<ul popover id="fetch-on-empty-items-popup"></ul>
116+
<ul id="fetch-on-empty-items-popup"></ul>
117117
<div id="fetch-on-empty-items-popup-feedback" class="sr-only"></div>
118118
</auto-complete>
119119
<button type="submit">Save</button>

src/autocomplete.ts

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -112,42 +112,40 @@ export default class Autocomplete {
112112
this.container.value = ''
113113
this.input.focus()
114114
this.input.dispatchEvent(new Event('change'))
115-
this.container.open = false
115+
this.close()
116116
}
117117

118118
onKeydown(event: KeyboardEvent): void {
119119
if (event.key === 'Escape' && this.container.open) {
120-
this.container.open = false
120+
this.close()
121121
event.stopPropagation()
122122
event.preventDefault()
123123
} else if (event.altKey && event.key === 'ArrowUp' && this.container.open) {
124-
this.container.open = false
124+
this.close()
125125
event.stopPropagation()
126126
event.preventDefault()
127127
} else if (event.altKey && event.key === 'ArrowDown' && !this.container.open) {
128128
if (!this.input.value.trim()) return
129-
this.container.open = true
129+
this.open()
130130
event.stopPropagation()
131131
event.preventDefault()
132132
}
133133
}
134134

135135
onInputFocus(): void {
136+
if (this.interactingWithList) return
136137
this.fetchResults()
137138
}
138139

139140
onInputBlur(): void {
140-
if (this.interactingWithList) {
141-
this.interactingWithList = false
142-
return
143-
}
144-
this.container.open = false
141+
if (this.interactingWithList) return
142+
this.close()
145143
}
146144

147145
onCommit({target}: Pick<Event, 'target'>): void {
148146
const selected = target
149147
if (!(selected instanceof HTMLElement)) return
150-
this.container.open = false
148+
this.close()
151149
if (selected instanceof HTMLAnchorElement) return
152150
const value = selected.getAttribute('data-autocomplete-value') || selected.textContent!
153151
this.updateFeedbackForScreenReaders(`${selected.textContent || ''} selected.`)
@@ -189,7 +187,7 @@ export default class Autocomplete {
189187
fetchResults(): void {
190188
const query = this.input.value.trim()
191189
if (!query && !this.container.fetchOnEmpty) {
192-
this.container.open = false
190+
this.close()
193191
return
194192
}
195193

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

228-
this.container.open = hasResults
226+
hasResults ? this.open() : this.close()
229227
this.container.dispatchEvent(new CustomEvent('load'))
230228
this.container.dispatchEvent(new CustomEvent('loadend'))
231229
})
@@ -246,6 +244,8 @@ export default class Autocomplete {
246244
this.results.hidden = false
247245
}
248246
}
247+
this.container.open = true
248+
this.interactingWithList = true
249249
}
250250

251251
close(): void {
@@ -258,5 +258,7 @@ export default class Autocomplete {
258258
this.results.hidden = true
259259
}
260260
}
261+
this.container.open = false
262+
this.interactingWithList = false
261263
}
262264
}

test/auto-complete-element.js

Lines changed: 39 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -18,19 +18,8 @@ describe('auto-complete element', function () {
1818
})
1919
})
2020

21-
describe('requesting server results', function () {
22-
beforeEach(function () {
23-
document.body.innerHTML = `
24-
<div id="mocha-fixture">
25-
<auto-complete src="/search" for="popup">
26-
<input type="text">
27-
<ul id="popup"></ul>
28-
<div id="popup-feedback"></div>
29-
</auto-complete>
30-
</div>
31-
`
32-
})
33-
21+
// eslint-disable-next-line func-style
22+
const serverResponseExamples = function () {
3423
it('requests html fragment', async function () {
3524
const container = document.querySelector('auto-complete')
3625
const input = container.querySelector('input')
@@ -147,25 +136,6 @@ describe('auto-complete element', function () {
147136
assert.isFalse(container.open)
148137
})
149138

150-
it('does not close on blur after mousedown', async function () {
151-
const container = document.querySelector('auto-complete')
152-
const input = container.querySelector('input')
153-
154-
triggerInput(input, 'hub')
155-
await once(container, 'loadend')
156-
157-
const link = container.querySelector('a[role=option]')
158-
159-
assert.equal('', container.value)
160-
link.dispatchEvent(new MouseEvent('mousedown', {bubbles: true}))
161-
input.dispatchEvent(new Event('blur'))
162-
assert(container.open)
163-
164-
await sleep(100)
165-
input.dispatchEvent(new Event('blur'))
166-
assert.isFalse(container.open)
167-
})
168-
169139
it('closes on Escape', async function () {
170140
const container = document.querySelector('auto-complete')
171141
const input = container.querySelector('input')
@@ -175,10 +145,10 @@ describe('auto-complete element', function () {
175145
await once(container, 'loadend')
176146

177147
assert.isTrue(container.open)
178-
assert.isFalse(popup.hidden)
148+
if (!popup.popover) assert.isFalse(popup.hidden)
179149
assert.isFalse(keydown(input, 'Escape'))
180150
assert.isFalse(container.open)
181-
assert.isTrue(popup.hidden)
151+
if (!popup.popover) assert.isTrue(popup.hidden)
182152
})
183153

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

192162
assert.isTrue(container.open)
193-
assert.isFalse(popup.hidden)
163+
if (!popup.popover) assert.isFalse(popup.hidden)
194164

195165
assert.isFalse(keydown(input, 'ArrowUp', true))
196166
assert.isFalse(container.open)
197-
assert.isTrue(popup.hidden)
167+
if (!popup.popover) assert.isTrue(popup.hidden)
198168

199169
assert.isFalse(keydown(input, 'ArrowDown', true))
200170
assert.isTrue(container.open)
201-
assert.isFalse(popup.hidden)
171+
if (!popup.popover) assert.isFalse(popup.hidden)
202172
})
203173

204174
it('allows providing a custom fetch method', async () => {
@@ -216,6 +186,38 @@ describe('auto-complete element', function () {
216186
assert.equal(2, popup.children.length)
217187
assert.equal(popup.querySelector('li').textContent, 'Mock Custom Fetch Result 1')
218188
})
189+
}
190+
191+
describe('requesting server results (non-popover)', function () {
192+
beforeEach(function () {
193+
document.body.innerHTML = `
194+
<div id="mocha-fixture">
195+
<auto-complete src="/search" for="popup">
196+
<input type="text">
197+
<ul id="popup"></ul>
198+
<div id="popup-feedback"></div>
199+
</auto-complete>
200+
</div>
201+
`
202+
})
203+
204+
serverResponseExamples()
205+
})
206+
207+
describe('requesting server results (popover)', function () {
208+
beforeEach(function () {
209+
document.body.innerHTML = `
210+
<div id="mocha-fixture">
211+
<auto-complete src="/search" for="popup">
212+
<input type="text">
213+
<ul popover id="popup"></ul>
214+
<div id="popup-feedback"></div>
215+
</auto-complete>
216+
</div>
217+
`
218+
})
219+
220+
serverResponseExamples()
219221
})
220222

221223
describe('clear button provided', () => {

0 commit comments

Comments
 (0)