react-tag-input-component
react-tag-input-component copied to clipboard
fix: Prevent Keydown event being triggered twice for CJK languages
Problem
In Chrome-based browsers, entering Non-Latin-based language such as Chinese, Japanese and Korean (CJK) triggers Keydown event 2 times. Hence, the LAST letter is added to the tag list as well.

(chrome)

(safari)
Causes
The root cause of the problem has to do with Chrome, IME and Keydown Event. Typing CJK languages need the help of IME. When IME is used, Chrome triggers Keydown event twice.
While each letter in an English word is simply an alphabet character, each letter in CJK is composed of 2 or more characters. Keydown event has a boolean property 'isComposing’ to track if the user is composing a letter.
When a user types in some CJK word, isComposing property returns true - since the last letter is still considered being 'in the composition process’. When pressing the 'separator' key, Chrome’s bug triggers Keydown event twice, firstly for the whole word and secondly for the last letter which still remains in the input box because it was considered being composed when the first Keydown event was triggered. This results in both the word and the last letter to be added the tag list.
For the record, for any alphabet character, ‘isComposing’ property always returns ‘false’ value. Hence, the fix won't affect other languages.
Solution
Since alphabet characters always return falsy isComposing property, we only need to track if 'isComposing' is true. By doing so, the first Keydown event is ignored and ends composition process, and the second Keydown event correctly submits the whole word.
const handleOnKeyUp = e => {
...
if (text && (separators || defaultSeparators).includes(e.key)) {
e.preventDefault();
**if (e.nativeEvent.isComposing || e.nativeEvent.keyCode === 229) return;**
...
}
...
}
Reference
https://groups.google.com/g/mozilla.dev.platform/c/oZEz5JH9ZK8
https://github.com/vuejs/vue/issues/10277#issuecomment-873337252