new·The score now tells you which way it movedA brain's exam only ever grows: its own material writes questions, and so does every question a real caller asked and did not get answered. The score is a percentage over that growing set, so a brain that learned more could post a smaller number — and this week three did. One of them answered two MORE questions than the week before and showed eighteen points less. Printed as a single percentage, that reads as decline to a reader and as punishment to anyone who contributes material.all news →
mozg.beta
Sign in

shadcn/ui · Components · all subjects

message-scroller/overview

7 notes, read out of this brain and free to use. Each one was extracted from a source and is re-checked against its exam.

MessageScroller is from @shadcn/react package

The behavior in MessageScroller comes from the @shadcn/react package. To use it directly with custom markup and styles, see Message Scroller under @shadcn/react. The API reference for props, data attributes, and hooks is documented on the @shadcn/react Message Scroller page and is identical for the styled component and unstyled parts.

shadcn/ui base component

MessageScroller is documented as a base component in shadcn/ui, part of the base component library.

MessageScroller component overview

MessageScroller is a chat transcript scroller built for streaming chat experiences. MessageScrollerProvider owns the scroll state and transcript-row behavior including opening position, streamed output, new-turn anchoring, prepended history, visibility, and scroll controls. MessageScroller is the styled frame that renders inside the provider. It is scoped to the scroll viewport and does not own messages, AI state, transport, persistence, branching, or model state.

MessageScroller performance characteristics

MessageScroller is benchmarked against large transcripts with markdown and composed message rows. The performance goal is to keep the scroll hot path outside of React state: no React rerenders for transcript rows, no forced layout on every scroll, and as little off-screen paint work as the browser can avoid. Scroll position, anchoring, and follow-output are tracked imperatively and mirrored onto the root and viewport through data-* attributes, so scrolling and streaming do not rerender transcript rows. The styled MessageScrollerItem ships with content-visibility: auto and contain-intrinsic-size. Rows stay in the DOM for selection, copy, find-in-page, SSR, and assistive tech, but the browser can skip rendering work for rows far outside the viewport.

MessageScroller virtualization approach

Virtualization is intentionally left outside the MessageScroller primitive. MessageScroller renders real DOM rows and stays fast well into thousands of turns, so most transcripts never need virtualization. When a transcript is large enough to need virtualization, use MessageScrollerViewport as the scroll element and let a virtualizer like @tanstack/react-virtual own the rows.

MessageScroller unstyled version

The behavior in MessageScroller comes from the @shadcn/react package. To use it directly with your own markup and styles, see Message Scroller under @shadcn/react documentation. The props, data attributes, and hooks are identical for the styled component and the unstyled parts.

Chat streaming scroll behavior principles

A great streaming chat should follow these principles: (1) Move only when the reader asked to move—if someone is reading, do not pull them somewhere else. (2) Follow only while they are following—if at the live edge, keep the stream in view. If scrolled away, leave them there. (3) Every interaction is a signal—scrolling, selecting text, using keyboard, opening links, or searching should all stop interface movement. (4) Start a new turn near the top of viewport giving it space to be read from the beginning. (5) Then stream in the answer so it grows into the screen, not immediately push everything away. (6) Keep part of the previous conversation in context—prompt and reply stay visually connected with enough of previous turn visible. (7) Let new content arrive offscreen so conversation keeps streaming without changing what reader looks at. (8) Show what is happening out of view with indicators when response is streaming or new messages arrived. (9) Make it easy to return to latest reply with a 'Jump to latest' action. (10) Let people jump anywhere in conversation with message links, search, unread markers, direct navigation. (11) Reopen where reader left off—saved conversation should open at last meaningful turn, often the last user message, not absolute bottom. (12) Keep reader place when layout changes—images load, markdown expands, code blocks render, older messages appear above without making reader lose place. (13) Handle interruptions without stealing position—stopping, retrying, regenerating, branching, errors should not unexpectedly move conversation. (14) Stay responsive in long threads with streaming text, markdown, code, images, long history. (15) Be accessible without the noise—keep transcript navigable, preserve keyboard focus, announce important events at comfortable pace. Never move the reader against their intent.

Give your agent this brain