Search documentation

Find a component or a docs page

Message Scroller

A chat scroll container that anchors turns, follows streamed responses, preserves position when older messages load, and jumps to the latest message.

Chat window

A full chat window: an Empty state until the first message, then a scrolling transcript that follows the live edge. Type and press send — the reply lands a beat later and the view stays pinned to the bottom. Scroll up mid-thread and the jump-to-latest button appears. (The send/reply loop is a docs-only demo harness; in a real app an ActionCable or streaming source would produce the rows.)

Interactive chat

Usage

MessageScroller fills its parent, so place it inside a height-constrained container. With auto_scroll: true it follows the live edge while you are pinned to the bottom and releases the moment you scroll up (auto-scroll is off by default, as in shadcn). Scroll up in the panel below — a jump-to-latest button appears.

Streaming chat

Anchoring turns

Mark the row that starts a new turn with scroll_anchor. When it is appended, the viewport moves it near the top and keeps a peek of the previous item above it, so the new turn does not feel detached.

Anchored user turn

Loading older messages

Insert older rows at the top of MessageScrollerContent and the reader's row stays where it was: the browser's scroll anchoring keeps it in place. Pass preserve_scroll_on_prepend: false to MessageScrollerViewport to turn that off.

Scroll commands

The provider owns the scroll state, so controls placed anywhere inside it can drive the viewport. These buttons call the controller's scrollToStart and scrollToEnd actions directly.

Jump to start or end

Installation

Components

ComponentBuilt usingSource
MessageScrollerPhlex
MessageScrollerButtonPhlex
MessageScrollerContentPhlex
MessageScrollerDocsPhlex
MessageScrollerItemPhlex
MessageScrollerProviderPhlex
MessageScrollerViewportPhlex
MessageScrollerControllerStimulus JS