Skip to content

fix(web): prevent number-key shortcuts from hijacking input in focused editor#1810

Open
D3OXY wants to merge 2 commits intopingdotgg:mainfrom
D3OXY:fix/number-keys-in-focused-input
Open

fix(web): prevent number-key shortcuts from hijacking input in focused editor#1810
D3OXY wants to merge 2 commits intopingdotgg:mainfrom
D3OXY:fix/number-keys-in-focused-input

Conversation

@D3OXY
Copy link
Copy Markdown
Contributor

@D3OXY D3OXY commented Apr 7, 2026

Summary

Fixes #1794

When the AI presents a question with numbered options, a global keydown handler on document lets users press 19 to quick-select an option. The handler guards against firing inside editable elements by checking event.target:

if (target instanceof HTMLInputElement || target instanceof HTMLTextAreaElement) return;
if (target instanceof HTMLElement && target.isContentEditable) return;

The main composer is a Lexical editor (ComposerPromptEditor), which renders a <div contenteditable="true"> containing nested child elements — including ComposerMentionNode decorations that explicitly set contentEditable = "false". When the keydown event.target resolves to one of these nested children, target.isContentEditable returns false (because isContentEditable respects the nearest contenteditable attribute in the ancestor chain, including intervening contenteditable="false" nodes). The guard fails and the number key triggers option selection instead of typing into the editor.

Fix

Replace target.isContentEditable with target.closest('[contenteditable]:not([contenteditable="false"])'). This walks up the DOM tree looking for any ancestor with a contenteditable attribute that isn't explicitly "false", covering all valid editable states ("true", "", "plaintext-only") while still correctly skipping past Lexical's contenteditable="false" mention decoration nodes to find the editor root.

- if (target instanceof HTMLElement && target.isContentEditable) {
+ if (
+   target instanceof HTMLElement &&
+   target.closest('[contenteditable]:not([contenteditable="false"])')
+ ) {

Test plan

  • Open a session and trigger an AI question with numbered options
  • Click into the composer editor and type number keys (1, 2, 3) — they appear as text in the editor, not select options
  • Click outside the editor and press number keys — they select options as before
  • Verify option buttons are still clickable

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 7, 2026

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 657c5201-0b93-4b2b-974f-7e1349d35104

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions bot added size:XS 0-9 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list. labels Apr 7, 2026
@macroscopeapp
Copy link
Copy Markdown
Contributor

macroscopeapp bot commented Apr 7, 2026

Approvability

Verdict: Approved

This is a straightforward bug fix that improves keyboard shortcut handling by checking ancestor contenteditable elements, not just the target. The unresolved review comment references incorrect code—the actual selector correctly handles all contenteditable states.

You can customize Macroscope's approvability policy. Learn more.

Addresses review feedback — the previous selector only matched
contenteditable="true" exactly, missing "" and "plaintext-only".
Use :not([contenteditable="false"]) to catch all valid editable states
while still walking past Lexical's contenteditable="false" mention nodes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XS 0-9 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Using numbers in questions prompt while input is focused selects option

1 participant