Conversation

A scrollable container for a thread of messages.

Anatomy

Wraps a scroll area and adds stick-to-bottom behavior so streamed content keeps the latest message in view. The container needs a constrained height for scrolling to be meaningful, so wrap it in any sized parent.

TSX

API

Reference for each part of the component, including its available props and behavior.

Conversation

The root. Holds the stick-to-bottom context and renders the vertical scrollbar internally so the chrome stays consistent. When new content arrives, the viewport scrolls to the bottom only if the user was already there. Once the user scrolls up, auto-scroll pauses and the scroll button reveals itself. The current state is exposed as data-at-bottom on the root, on ConversationContent, and on the button. Use it to fade gradients, dim siblings, or swap icons without owning the scroll math.

Prop

ConversationContent

The scrollable viewport. Owns the column layout for messages and the resize observer that keeps the latest content in view. Pass children as you would inside a flex column. Override the spacing via className per instance.

Prop

ConversationScrollButton

Headless trigger that jumps back to the latest message and resumes auto-scroll. Optional. Wires the click handler and forwards data-at-bottom so the caller can fade or hide the button based on scroll state. Pass render to provide the styled button and children for the icon. There is no default styling, position, or icon, so the caller owns the placement and look.

Prop

useConversation

Hook for wiring a fully custom button (or any other reactive surface) to the same scroll state. Returns { isAtBottom, scrollToBottom }. Must be called inside <Conversation>. scrollToBottom accepts an optional ScrollBehavior ("smooth" by default).

TSX