Skip to content

Commit f34d463

Browse files
Fix unintended double triggering of key bindings during IME composition (#339)
* Fix unintended double triggering of key bindings during IME composition * fix conditional --------- Co-authored-by: Paco <[email protected]>
1 parent 2814a00 commit f34d463

File tree

1 file changed

+50
-48
lines changed

1 file changed

+50
-48
lines changed

cmdk/src/index.tsx

Lines changed: 50 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -579,58 +579,60 @@ const Command = React.forwardRef<HTMLDivElement, CommandProps>((props, forwarded
579579
onKeyDown={(e) => {
580580
etc.onKeyDown?.(e)
581581

582-
if (!e.defaultPrevented) {
583-
switch (e.key) {
584-
case 'n':
585-
case 'j': {
586-
// vim keybind down
587-
if (vimBindings && e.ctrlKey) {
588-
next(e)
589-
}
590-
break
591-
}
592-
case 'ArrowDown': {
582+
// Check if IME composition is finished before triggering key binds
583+
// This prevents unwanted triggering while user is still inputting text with IME
584+
// e.keyCode === 229 is for the CJK IME with Legacy Browser [https://w3c.github.io/uievents/#determine-keydown-keyup-keyCode]
585+
// isComposing is for the CJK IME with Modern Browser [https://developer.mozilla.org/en-US/docs/Web/API/CompositionEvent/isComposing]
586+
const isComposing = e.nativeEvent.isComposing || e.keyCode === 229
587+
588+
if (e.defaultPrevented || isComposing) {
589+
return
590+
}
591+
592+
switch (e.key) {
593+
case 'n':
594+
case 'j': {
595+
// vim keybind down
596+
if (vimBindings && e.ctrlKey) {
593597
next(e)
594-
break
595598
}
596-
case 'p':
597-
case 'k': {
598-
// vim keybind up
599-
if (vimBindings && e.ctrlKey) {
600-
prev(e)
601-
}
602-
break
603-
}
604-
case 'ArrowUp': {
599+
break
600+
}
601+
case 'ArrowDown': {
602+
next(e)
603+
break
604+
}
605+
case 'p':
606+
case 'k': {
607+
// vim keybind up
608+
if (vimBindings && e.ctrlKey) {
605609
prev(e)
606-
break
607610
}
608-
case 'Home': {
609-
// First item
610-
e.preventDefault()
611-
updateSelectedToIndex(0)
612-
break
613-
}
614-
case 'End': {
615-
// Last item
616-
e.preventDefault()
617-
last()
618-
break
619-
}
620-
case 'Enter': {
621-
// Check if IME composition is finished before triggering onSelect
622-
// This prevents unwanted triggering while user is still inputting text with IME
623-
// e.keyCode === 229 is for the Japanese IME and Safari.
624-
// isComposing does not work with Japanese IME and Safari combination.
625-
if (!e.nativeEvent.isComposing && e.keyCode !== 229) {
626-
// Trigger item onSelect
627-
e.preventDefault()
628-
const item = getSelectedItem()
629-
if (item) {
630-
const event = new Event(SELECT_EVENT)
631-
item.dispatchEvent(event)
632-
}
633-
}
611+
break
612+
}
613+
case 'ArrowUp': {
614+
prev(e)
615+
break
616+
}
617+
case 'Home': {
618+
// First item
619+
e.preventDefault()
620+
updateSelectedToIndex(0)
621+
break
622+
}
623+
case 'End': {
624+
// Last item
625+
e.preventDefault()
626+
last()
627+
break
628+
}
629+
case 'Enter': {
630+
// Trigger item onSelect
631+
e.preventDefault()
632+
const item = getSelectedItem()
633+
if (item) {
634+
const event = new Event(SELECT_EVENT)
635+
item.dispatchEvent(event)
634636
}
635637
}
636638
}

0 commit comments

Comments
 (0)