fix(composer): add IME composition guard to textarea paste handler - #216
Merged
Conversation
PR #202 added an IME guard to the composer textarea's keydown handler so Enter during CJK composition wouldn't fire submit mid-character. The paste handler (components.tsx:5726) had the same exposure but was left out. Symptom: a user mid-CJK composition who pastes a clipboard file (e.g. screenshot captured via system shortcut) hits the file-import path, which calls `event.preventDefault()` — that aborts the in-flight IME composition and eats the partially-typed character. Rare but real. The same kind of bug pattern as the keydown one. Fix: prepend `if (event.nativeEvent.isComposing) return;` at the top of `onTextareaPaste`, matching the exact pattern at line 5640 in the keydown handler. 2 lines + 6-line WHY comment. When IME is active, the paste should fall through to the textarea's native paste so the IME can handle (or ignore) it as the user expects. The file-import path only matters once composition has ended. Found via PR-FE-BUG-HUNT scan; 2 sibling Explore agents also ran on Daily Review and cron PlanReminderPanel — both reported findings that I manually verified as false positives (Daily Review agent contradicted itself mid-output; cron `reminder.schedule` null-safety claim is impossible because TypeScript types it as required non-null). Reporting transparently so kenji/WAWQAQ can discount those. ## Diff 1 file, 8 insertions(+), 0 deletions(-). No overlap with any open PR. ## Verification Disk still ~100%, couldn't run `pnpm install && pnpm test`. Matches existing pattern verbatim, so behavior outside the IME edge case is unchanged.
jackwener
added a commit
that referenced
this pull request
Jun 24, 2026
…216) (#221) WAWQAQ reported `pnpm dev` build broken with: src/components.tsx:5732:27 - error TS2339: Property 'isComposing' does not exist on type 'ClipboardEvent'. if (event.nativeEvent.isComposing) return; ~~~~~~~~~~~ PR #216 (paste-handler IME guard) copied the `event.nativeEvent.isComposing` pattern verbatim from the keydown handler at line 5640. That works on the keydown handler because the DOM types declare `isComposing: boolean` on `KeyboardEvent` and `InputEvent`. ClipboardEvent does NOT declare it — even though most browsers happen to expose it on the underlying event. Hot-fix: narrow the runtime check with `'isComposing' in native` + a typed-cast to `{ isComposing?: boolean }`. Compiles cleanly AND preserves the runtime IME guard when the browser does expose it. Behavior unchanged for the normal path: - IME active + paste → bail (same as before) - No IME + paste of file → import (same as before) - No IME + text paste → fall through (same as before) In browsers that don't expose `isComposing` on ClipboardEvent at all, the guard becomes a no-op — same as PR #216 before this hotfix, just without breaking the build.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
PR-FE-BUG-HUNT-10 — extending PR #202's IME pattern from keydown to paste.
Bug
`onTextareaPaste` at `packages/ui/src/components.tsx:5726` was missing an IME composition guard. The sibling `onTextareaKeyDown` at line 5640 already had `if (event.nativeEvent.isComposing || event.key === 'Process') return;` (added in PR #202 for the Enter-during-CJK case), but the paste path was left out.
Symptom
A user mid-CJK composition who pastes a clipboard file (e.g. macOS screenshot captured via `Cmd+Ctrl+Shift+4` lands in clipboard) hits the file-import branch, which calls `event.preventDefault()` — that aborts the in-flight IME composition and eats the partially-typed character. Rare but real, same pattern as the keydown bug PR #202 fixed.
Fix
Prepend `if (event.nativeEvent.isComposing) return;` at the top of `onTextareaPaste`, matching the keydown pattern at line 5640. When IME is active, paste should fall through to the native textarea so the IME can handle (or ignore) it as the user expects. The file-import path only matters after composition ends.
Hunt context
Found via parallel Explore-agent scan on 3 layers (Daily Review, cron, composer). The other two findings were false positives on manual verify:
Reporting transparently so kenji / WAWQAQ can discount them.
Diff
`1 file changed, 8 insertions(+), 0 deletions(-)` — single function, single guard, matches existing sibling pattern verbatim.
Verification
Disk still ~100%, couldn't run `pnpm install && pnpm test`. Pattern-matches PR #202's verified keydown guard, so behavior outside the IME edge case is unchanged.