Skip to content

Commit 0e93b7a

Browse files
committed
Clear selection and return keydown event during composition
keydown and composition events get triggered in different orders across browsers so we can't rely on the 'mid composition' state and would need to clear selection to prevent triggering activation unintentionally
1 parent 6128691 commit 0e93b7a

File tree

1 file changed

+19
-0
lines changed

1 file changed

+19
-0
lines changed

combobox-nav.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,18 @@
11
/* @flow strict */
22

3+
const compositionMap = new WeakMap()
4+
35
export function install(input: HTMLTextAreaElement | HTMLInputElement, list: HTMLElement): void {
6+
input.addEventListener('compositionstart', trackComposition)
7+
input.addEventListener('compositionend', trackComposition)
48
input.addEventListener('keydown', keyboardBindings)
59
list.addEventListener('click', commitWithElement)
610
}
711

812
export function uninstall(input: HTMLTextAreaElement | HTMLInputElement, list: HTMLElement): void {
913
input.removeAttribute('aria-activedescendant')
14+
input.removeEventListener('compositionstart', trackComposition)
15+
input.removeEventListener('compositionend', trackComposition)
1016
input.removeEventListener('keydown', keyboardBindings)
1117
list.removeEventListener('click', commitWithElement)
1218
}
@@ -17,6 +23,7 @@ function keyboardBindings(event: KeyboardEvent) {
1723
if (event.shiftKey || event.metaKey || event.altKey) return
1824
const input = event.currentTarget
1925
if (!(input instanceof HTMLTextAreaElement || input instanceof HTMLInputElement)) return
26+
if (compositionMap.get(input)) return
2027
const list = document.getElementById(input.getAttribute('aria-owns') || '')
2128
if (!list) return
2229

@@ -96,3 +103,15 @@ export function navigate(
96103
}
97104
}
98105
}
106+
107+
function trackComposition(event: Event) {
108+
const input = event.currentTarget
109+
if (!(input instanceof HTMLTextAreaElement || input instanceof HTMLInputElement)) return
110+
compositionMap.set(input, event.type === 'compositionstart')
111+
112+
const list = document.getElementById(input.getAttribute('aria-owns') || '')
113+
if (!list) return
114+
const target = list.querySelector('[aria-selected="true"]')
115+
if (!target) return
116+
target.setAttribute('aria-selected', 'false')
117+
}

0 commit comments

Comments
 (0)