From 13f80f0d95f734e41f25b698ed79d87fb0bc2741 Mon Sep 17 00:00:00 2001 From: greymoth Date: Mon, 29 Jun 2026 15:08:11 +0900 Subject: [PATCH] fix: ignore IME composition Enter in chat-thread and attachment rename inputs (#22270) ## What's this PR doing? Two inline rename inputs run their action on `Enter` without ignoring the `Enter` that confirms an IME composition: - `AiChatThreadListItem` (renaming an AI chat thread). It also calls `preventDefault()`, so the composition-commit `Enter` is swallowed and the half-typed title gets saved. - `AttachmentRow` (renaming an attachment). The same `Enter` saves the unfinished name. When you type with an IME (Japanese, Chinese, Korean), the first `Enter` after typing confirms the candidate text rather than submitting, so these handlers fire with text the user hasn't finished entering. ## Why The codebase already guards this where keyboard handling goes through `useHotkeysOnFocusedElement` (`if (keyboardEvent.isComposing || keyboardEvent.keyCode === 229) return`), and the inline inputs that don't use that hook add the same check themselves: see `SettingsAccountsBlocklistInput`, `SettingsDevelopersApiKeysNew`, and the sign-up workspace forms. These two rename inputs were just missing it. ## How Add the same `isComposing || keyCode === 229` guard before the `Enter` branch. For input without an IME, `isComposing` is `false` and `keyCode` is `13`, so the rename-on-Enter behavior stays the same. This only skips the action on the composition-commit key. I checked the change against the repo's Prettier config locally. I couldn't add a unit test because jsdom doesn't dispatch real composition events (`isComposing` stays `false`), so it can't reproduce the keystroke. Happy to add an e2e test if that's preferred. Review in cubic --- .../src/modules/activities/files/components/AttachmentRow.tsx | 3 +++ .../src/modules/ai/components/AiChatThreadListItem.tsx | 3 +++ 2 files changed, 6 insertions(+) diff --git a/packages/twenty-front/src/modules/activities/files/components/AttachmentRow.tsx b/packages/twenty-front/src/modules/activities/files/components/AttachmentRow.tsx index 21c87e416b..3d6b1bb0e0 100644 --- a/packages/twenty-front/src/modules/activities/files/components/AttachmentRow.tsx +++ b/packages/twenty-front/src/modules/activities/files/components/AttachmentRow.tsx @@ -141,6 +141,9 @@ export const AttachmentRow = ({ }; const handleOnKeyDown = (e: React.KeyboardEvent) => { + if (e.nativeEvent.isComposing || e.keyCode === 229) { + return; + } if (e.key === 'Enter') { saveAttachmentName(); } diff --git a/packages/twenty-front/src/modules/ai/components/AiChatThreadListItem.tsx b/packages/twenty-front/src/modules/ai/components/AiChatThreadListItem.tsx index c8bb174ea8..8f52274d15 100644 --- a/packages/twenty-front/src/modules/ai/components/AiChatThreadListItem.tsx +++ b/packages/twenty-front/src/modules/ai/components/AiChatThreadListItem.tsx @@ -129,6 +129,9 @@ export const AiChatThreadListItem = ({ thread }: AiChatThreadListItemProps) => { onFocus={(event) => event.target.select()} onBlur={() => commitRename(draftTitle)} onKeyDown={(event) => { + if (event.nativeEvent.isComposing || event.keyCode === 229) { + return; + } if (event.key === Key.Enter) { event.preventDefault(); void commitRename(draftTitle);