fix(web): triple-click selects the clicked composer line - #7879
fix(web): triple-click selects the clicked composer line#7879Moustafa93 wants to merge 1 commit into
Conversation
Lexical's triple-click normalization assumes one paragraph per line, but the composer keeps the whole prompt in a single paragraph with line breaks, so triple-clicking any line above the last selected the entire prompt. Snapshot the browser's native line selection before Lexical's click handler runs and restore it afterwards, without swallowing the event. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
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. Comment |
ApprovabilityVerdict: Skipped Macroscope did not run approvability analysis for this PR. Macroscope could not determine whether this PR modifies its approvability configuration, so the PR was not approved automatically. A PR that may change the rules that govern approval is never approved automatically. |
In one line
Currently, triple-clicking a line in the prompt input selects the whole input rather than the line, due to a Lexical quirk. This PR fixes this to allow triple-clicks to select the clicked line only.
Problem
A UI/UX bug - Triple-clicking any line above the last in a multi-line composer draft selected the entire prompt instead of the clicked line, with no way to select only that line by clicking. The exception is the last line, where for this line and this line only, triple-clicking selects only the line, as expected.
This goes against typical conventions of "double-click selects word" and "triple-click selects line", and was a point of frustration for me personally.
Demonstration
Before
Before.mov
After
After.mov
Cause
Lexical's triple-click normalization assumes one paragraph per line, but the composer keeps the whole prompt in a single paragraph separated by line breaks. So Lexical's "select the clicked paragraph" behavior inadvertently became "select the whole input." The bottom line only worked because the native selection never crossed into a following node there.
Fix
We capture a snapshot of the browser's native correct line selection in a click listener before Lexical takes over, and restore the snapshot afterwards.
In this way we keep the correct behavior without swallowing any events, so React handlers, click-outside dismissal, and Lexical's CLICK_COMMAND all still work.
There was a potential smaller fix of stopping propagation of
detail === 3clicks so Lexical's normalization doesn't run for triple-clicks. But this would have swallowed events and potentially caused latent bugs.Web only; desktop inherits the fix through the shared web app, and mobile uses a native input and is unaffected.
Fix implemented with Fable 5 via Claude Code (in t3code of course ;) )
Note
Low Risk
UI-only selection fix in the composer. Document click listeners are gated to triple-clicks inside the editor and do not change data or auth.
Overview
Makes triple-click in the prompt composer select the clicked line instead of the whole draft.
Lexical treats a triple-click as “select the paragraph,” but the composer stores the prompt as one paragraph with line breaks. The new
ComposerTripleClickLinePluginsnapshots the browser’s native line selection on capture and restores it after Lexical’s click handling, without swallowing the event.Reviewed by Cursor Bugbot for commit e7b9a9b. Bugbot is set up for automated code reviews on this repo. Configure here.
Note
Fix triple-click to select clicked line in
ComposerPromptEditorAdds
ComposerTripleClickLinePluginto the Lexical editor in ComposerPromptEditor.tsx. On triple-click, it snapshots the DOM selection on the capture phase and restores it on the bubble phase, syncing the Lexical selection via$setSelection($createRangeSelectionFromDom(...)). This prevents the browser from overriding the line selection with a different range.Macroscope summarized e7b9a9b.