From 86bd48d39031b7e06a2912a6f6f8f79e48f05f40 Mon Sep 17 00:00:00 2001 From: Michael Ramos Date: Sun, 1 Mar 2026 22:38:02 -0800 Subject: [PATCH] fix: guard Enter key handlers with isComposing for CJK IME support CJK users press Enter to confirm IME character selection, which was triggering form submission instead. Add !e.nativeEvent.isComposing guard to all Enter-to-submit handlers in the plan editor UI. Fixes #191 Co-Authored-By: Claude Opus 4.6 --- packages/ui/components/AnnotationPanel.tsx | 2 +- packages/ui/components/AnnotationToolbar.tsx | 2 +- packages/ui/components/AttachmentsButton.tsx | 2 +- packages/ui/components/ImageAnnotator/index.tsx | 2 +- packages/ui/components/Viewer.tsx | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/ui/components/AnnotationPanel.tsx b/packages/ui/components/AnnotationPanel.tsx index 902618b..ec8d7f7 100644 --- a/packages/ui/components/AnnotationPanel.tsx +++ b/packages/ui/components/AnnotationPanel.tsx @@ -174,7 +174,7 @@ const AnnotationCard: React.FC<{ }; const handleKeyDown = (e: React.KeyboardEvent) => { - if (e.key === 'Enter' && (e.metaKey || e.ctrlKey)) { + if (e.key === 'Enter' && (e.metaKey || e.ctrlKey) && !e.nativeEvent.isComposing) { e.preventDefault(); handleSaveEdit(); } else if (e.key === 'Escape') { diff --git a/packages/ui/components/AnnotationToolbar.tsx b/packages/ui/components/AnnotationToolbar.tsx index 30ac798..12c470d 100644 --- a/packages/ui/components/AnnotationToolbar.tsx +++ b/packages/ui/components/AnnotationToolbar.tsx @@ -257,7 +257,7 @@ export const AnnotationToolbar: React.FC = ({ onChange={(e) => setInputValue(e.target.value)} onKeyDown={(e) => { if (e.key === "Escape") setStep("menu"); - if (e.key === "Enter" && !e.shiftKey) { + if (e.key === "Enter" && !e.shiftKey && !e.nativeEvent.isComposing) { e.preventDefault(); if (inputValue.trim() || images.length > 0) { onAnnotate(activeType!, inputValue || undefined, images.length > 0 ? images : undefined); diff --git a/packages/ui/components/AttachmentsButton.tsx b/packages/ui/components/AttachmentsButton.tsx index c865201..fb31fd0 100644 --- a/packages/ui/components/AttachmentsButton.tsx +++ b/packages/ui/components/AttachmentsButton.tsx @@ -310,7 +310,7 @@ export const AttachmentsButton: React.FC = ({ type="text" value={manualPath} onChange={(e) => setManualPath(e.target.value)} - onKeyDown={(e) => e.key === 'Enter' && handleManualAdd()} + onKeyDown={(e) => e.key === 'Enter' && !e.nativeEvent.isComposing && handleManualAdd()} placeholder="Paste path or URL..." className="flex-1 px-2 py-1.5 text-xs bg-background border border-border rounded-md focus:outline-none focus:ring-1 focus:ring-primary" /> diff --git a/packages/ui/components/ImageAnnotator/index.tsx b/packages/ui/components/ImageAnnotator/index.tsx index 987c2dd..9e3de44 100644 --- a/packages/ui/components/ImageAnnotator/index.tsx +++ b/packages/ui/components/ImageAnnotator/index.tsx @@ -241,7 +241,7 @@ export const ImageAnnotator: React.FC = ({ value={name} onChange={(e) => setName(e.target.value)} onKeyDown={(e) => { - if (e.key === 'Enter') { + if (e.key === 'Enter' && !e.nativeEvent.isComposing) { e.preventDefault(); handleAccept(); } diff --git a/packages/ui/components/Viewer.tsx b/packages/ui/components/Viewer.tsx index c9d033c..4696dca 100644 --- a/packages/ui/components/Viewer.tsx +++ b/packages/ui/components/Viewer.tsx @@ -737,7 +737,7 @@ export const Viewer = forwardRef(({ setGlobalCommentValue(''); } // Enter to submit, Shift+Enter for newline - if (e.key === 'Enter' && !e.shiftKey) { + if (e.key === 'Enter' && !e.shiftKey && !e.nativeEvent.isComposing) { e.preventDefault(); if (globalCommentValue.trim()) { handleAddGlobalComment();