Skip to content

fix(ui-kit-chat): user input detaches thread auto-follow so touch scrolling wins over streaming re-pin - #154

Merged
omridevk merged 2 commits into
mainfrom
fix/thread-scroll-user-detach
Jul 30, 2026
Merged

fix(ui-kit-chat): user input detaches thread auto-follow so touch scrolling wins over streaming re-pin#154
omridevk merged 2 commits into
mainfrom
fix/thread-scroll-user-detach

Conversation

@omridevk

Copy link
Copy Markdown
Contributor

On iOS WKWebView the thread pane was un-scrollable during streaming: the auto-follow re-pins to bottom on every mutation, and release depended on a scroll event observed away-from-bottom - a race WKWebView loses because its scroll events arrive late/coalesced while mutations apply instantly. Desktop never showed it because Blink delivers scroll synchronously. The only gesture listener (pointerdown) never gated the re-pin.

Fix: an explicit userDetached flag set by real scroll intent (touchmove, wheel, scroll keys) gates the re-pin; it clears when the user lands back at bottom or explicitly follows again (the Latest pill / run start). The snap-back suppressor no longer applies during an active touch, so rubber-band bounces cannot mask release. Once a finger moves, no stream batch can drag the view back - the race is deleted, not narrowed.

Tests: new real-Chromium vitest browser project for the hook (6 behavior tests: touch/wheel/key detach, at-bottom + pill re-attach, tap does not detach), proven non-vacuous (gate reverted: 5/6 fail). Existing storybook play coverage for the hook still 4/4. Adds two test-only devDeps at pins already used by sibling packages.

Verified by orchestrator: full diff review + hard-rule greps (flagged hits are pre-existing lines), package suite rerun 57/57 incl. the chromium project, fallow pass 0 introduced.

🤖 Generated with Claude Code

Copilot AI review requested due to automatic review settings July 30, 2026 18:51

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds gesture-aware thread auto-follow detachment to prevent streaming content from overriding user scrolling.

Changes:

  • Tracks touch, wheel, and keyboard scroll intent.
  • Adds six Chromium browser tests.
  • Adds browser-test dependencies and release changeset.

Reviewed changes

Copilot reviewed 5 out of 6 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
.changeset/thread-scroll-user-detach.md Documents the patch.
packages/ui-kit-chat/package.json Adds browser-test dependencies.
packages/ui-kit-chat/src/behaviors/use-thread-auto-scroll.ts Implements gesture detachment and reattachment.
packages/ui-kit-chat/test/thread-auto-scroll.browser.test.tsx Tests auto-follow behavior in Chromium.
packages/ui-kit-chat/vitest.config.ts Adds a Playwright browser project.
pnpm-lock.yaml Locks the new dependencies.
Files not reviewed (1)
  • pnpm-lock.yaml: Generated file
Comments suppressed due to low confidence (1)

packages/ui-kit-chat/src/behaviors/use-thread-auto-scroll.ts:129

  • Downward keys (ArrowDown, PageDown, and End) also detach while already at bottom. If a stream mutation arrives before keyup, the viewport becomes geometrically away from bottom, so the keyup recomputation cannot reattach and a key intended to stay at/latest breaks auto-follow. Only upward keys should detach from the bottom; downward keys should detach only when the viewport is already away from it.
    const handleKeyDown = (event: KeyboardEvent) => {
      if (SCROLL_KEYS.has(event.key)) detach()
    }

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread packages/ui-kit-chat/src/behaviors/use-thread-auto-scroll.ts
Copilot AI review requested due to automatic review settings July 30, 2026 20:54

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 6 changed files in this pull request and generated no new comments.

Files not reviewed (1)
  • pnpm-lock.yaml: Generated file
Comments suppressed due to low confidence (1)

packages/ui-kit-chat/src/behaviors/use-thread-auto-scroll.ts:168

  • Downward keys are treated as detach intent even when the viewport is already at the bottom. If a streaming mutation lands between keydown and keyup, userDetached blocks the re-pin; keyup then observes the newly increased distance from the bottom and cannot reattach, so ArrowDown/PageDown/End can permanently stop following despite never moving the reader away. Apply the same direction-aware handling as wheel input, and add a regression case that streams between a downward keydown/keyup at the bottom.
    const handleKeyDown = (event: KeyboardEvent) => {
      if (SCROLL_KEYS.has(event.key)) detach()
    }

@omridevk
omridevk merged commit cf6fc75 into main Jul 30, 2026
18 checks passed
@omridevk
omridevk deleted the fix/thread-scroll-user-detach branch July 30, 2026 22:17
@github-actions github-actions Bot mentioned this pull request Jul 31, 2026
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.

2 participants