fix(front): ignore IME composition Enter in input hotkeys (#20958)
## What Pressing Enter to confirm an IME (CJK) composition no longer submits the input. The Enter / Escape / Tab handlers now ignore key events fired while a composition is in progress (`isComposing`, or the legacy `keyCode === 229`). Fixes #20954 ## Why `isComposing` was not checked anywhere in `twenty-front`, so the Enter that confirms a Japanese / Chinese / Korean conversion was also consumed as a submit / escape / tab hotkey — making it very hard to type CJK text into any input that submits on Enter. ## Changes - `useHotkeysOnFocusedElement` — central guard; covers every input wired through `useRegisterInputEvents` (~13 components) and all hotkeys routed through this hook. - Direct `onKeyDown` Enter handlers: `CreateWorkspace`, `SettingsDevelopersApiKeysNew`, `SettingsAccountsBlocklistInput`. ## Notes - No effect on non-IME (Latin) typing — `isComposing` is only true during an active composition. It also improves accented / dead-key input on Latin layouts. - `react-hotkeys-hook@4` does not handle IME composition on its own, so the guard is explicit. ## Testing Manually verified with a Japanese IME on Chrome (macOS) against the v2.8.3 self-hosted image: romaji + Enter now only confirms the conversion; a second Enter on committed text submits as expected. The GIF in #20954 shows the original buggy behavior. Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
+3
@@ -74,6 +74,9 @@ export const SettingsAccountsBlocklistInput = ({
|
||||
});
|
||||
|
||||
const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
|
||||
if (e.nativeEvent.isComposing || e.keyCode === 229) {
|
||||
return;
|
||||
}
|
||||
if (e.key === Key.Enter) {
|
||||
submit();
|
||||
}
|
||||
|
||||
+4
@@ -48,6 +48,10 @@ export const useHotkeysOnFocusedElement = ({
|
||||
return useHotkeys(
|
||||
keys,
|
||||
(keyboardEvent, hotkeysEvent) => {
|
||||
if (keyboardEvent.isComposing || keyboardEvent.keyCode === 229) {
|
||||
return;
|
||||
}
|
||||
|
||||
callScopedHotkeyCallback({
|
||||
keyboardEvent,
|
||||
hotkeysEvent,
|
||||
|
||||
@@ -141,6 +141,9 @@ export const CreateWorkspace = () => {
|
||||
);
|
||||
|
||||
const handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {
|
||||
if (event.nativeEvent.isComposing || event.keyCode === 229) {
|
||||
return;
|
||||
}
|
||||
if (event.key === Key.Enter) {
|
||||
event.preventDefault();
|
||||
handleSubmit(onSubmit)();
|
||||
|
||||
+3
@@ -159,6 +159,9 @@ export const SettingsDevelopersApiKeysNew = () => {
|
||||
placeholder={t`E.g. backoffice integration`}
|
||||
value={formValues.name}
|
||||
onKeyDown={(e) => {
|
||||
if (e.nativeEvent.isComposing || e.keyCode === 229) {
|
||||
return;
|
||||
}
|
||||
if (e.key === Key.Enter) {
|
||||
handleSave();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user