Skip to content

feat(conversation): add Conversation and its scroll anchoring - #2

Closed
pratikbuilds wants to merge 1 commit into
conversation/01-contractfrom
conversation/05-conversation
Closed

pratikbuilds wants to merge 1 commit into
conversation/01-contractfrom
conversation/05-conversation

Conversation

@pratikbuilds

Copy link
Copy Markdown
Owner

Conversation owns the scroll container so every chat surface scrolls the same way. Scroll policy is a prop: settle lands a sent message at the top and never moves while text streams; stick follows the end while the reader is there. Layout shifts never scroll, and only the reader's own input breaks a follow.

The anchor algorithm and settle geometry are pure functions, and an anchor correction also applies mid-glide so a glide lands where it meant to. useConversation() shares an item registry, scrollToItem, scrollToEnd, captureAnchor/restoreAnchor, the scroll container and a per-frame scroll snapshot that tells the reader's scrolls from the engine's. The context value keeps its identity across scrolls.

Stacked on #1: review only this commit. Part of corbitsdev#94.

Notes for review

  • settle is built from the spec text (the reference design only sticks to the bottom); not yet compared side by side with other assistant chat UIs.
  • ConversationItem keys by itemId (an id prop would shadow the HTML id).
  • Scrolling lives in an imperative controller outside React; the context value is that object, so its identity never changes; atBottom updates at most once per frame.
  • Loading history: captureAnchor() before prepend, restoreAnchor() in a layout effect after commit; trimming above needs no calls.
  • Both policies start by following the end; settle stops following at the first send or the first scroll away.

Verification

  • This commit passes bun run typecheck and bun run lint on its own (the stack is checked commit by commit).
  • At the top of the stack: bun run check, bun run build, bun run dep-guard, bun run contrast-test and bun run test:e2e (Playwright specs and the Storybook axe sweep in light and dark) pass.

Closes corbitsdev#99

Conversation owns the scroll container so every chat surface scrolls
the same way. Scroll policy is a prop: settle lands a sent message at
the top and never moves while text streams; stick follows the end while
the reader is there. Layout shifts never scroll, and only the reader's
own input breaks a follow.

The anchor algorithm and settle geometry are pure functions, and an
anchor correction also applies mid-glide so a glide lands where it
meant to. useConversation() shares an item registry, scrollToItem,
scrollToEnd, captureAnchor/restoreAnchor, the scroll container and a
per-frame scroll snapshot that tells the reader's scrolls from the
engine's. The context value keeps its identity across scrolls.
@pratikbuilds

Copy link
Copy Markdown
Owner Author

Moved upstream: corbitsdev#114

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.

1 participant