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 902618b6..ec8d7f7f 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 30ac7986..12c470d5 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 c8652015..fb31fd07 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 987c2ddc..9e3de444 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 c9d033c7..4696dca6 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();