Skip to content

fix(desktop): scope drag-selection to the conversation pane - #4272

Open
iroiro147 wants to merge 1 commit into
block:mainfrom
iroiro147:fix/4077-conversation-selection-scope
Open

fix(desktop): scope drag-selection to the conversation pane#4272
iroiro147 wants to merge 1 commit into
block:mainfrom
iroiro147:fix/4077-conversation-selection-scope

Conversation

@iroiro147

@iroiro147 iroiro147 commented Aug 2, 2026

Copy link
Copy Markdown

Summary

Fixes #4077.

In split view, a native drag-selection starting in the channel could escape into the thread (and vice versa), sweeping hover action bars, quick reactions, reaction pills, emoji pickers, and popovers into the copied range.

Changes

  • Channel, thread, and right-auxiliary panes carry a data-selection-pane marker so the scope can resolve which pane a drag began in.
  • Interactive chrome that must never participate in a selection (hover action bar, reaction pill rows, emoji picker, drop-zone overlay) is marked data-selection-exclude + select-none.
  • A new useConversationSelectionScope hook on the shared conversation root listens for selectionchange; once a drag is anchored to a pane, the moving end is clamped back to the pane boundary if it escapes — keeping message text copyable while containing the scope.
  • Selections inside composers, inputs, textareas, contenteditables, and top-level dialogs/popovers are left alone, so typing, IME composition, and overlay interactions keep native behavior.
  • The clamp decisions are a pure module (lib/selection/conversationSelectionScope.ts) with a structural-DOM test suite (no jsdom needed).

Test plan

  • pnpm exec tsc --noEmit — clean
  • node --import ./test-loader.mjs --experimental-strip-types --test "src/**/*.test.mjs" — 3930/3930 pass
  • New conversationSelectionScope.test.mjs — 24/24 pass

In split view a drag-selection starting in the channel could escape into
the thread (and vice versa), sweeping hover action bars, quick reactions,
reaction pills, emoji pickers, and popovers into the copied range. The
channel and thread panes now carry a data-selection-pane marker, the
interactive chrome that must never be selected carries
data-selection-exclude + select-none, and a useConversationSelectionScope
hook on the shared conversation root listens for selectionchange and
clamps the focus end back to the anchor pane boundary when a drag tries
to escape it. Selections inside composers, inputs, contenteditables, and
top-level dialogs/popovers are left untouched so typing, IME composition,
and overlay interactions keep native behavior. Clamp decisions are pure
functions in lib/selection/conversationSelectionScope.ts, covered by a
structural-dom test suite so no jsdom is needed.

Fixes block#4077

Signed-off-by: Sarthak Singh <sarthak.singh@juspay.in>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] Scope message selection to the active conversation

1 participant