Redpanda UIRedpanda UI
Components

Message Scroller

Anchors conversation turns, follows streamed replies, restores threads, preserves prepended history, and jumps to messages.

Made by shadcn
Loading component...

Installation

Usage

MessageScroller owns conversation scroll behavior without owning messages, AI state, transport, persistence, or model state.

import {
  MessageScroller,
  MessageScrollerButton,
  MessageScrollerContent,
  MessageScrollerItem,
  MessageScrollerProvider,
  MessageScrollerViewport,
} from "@/components/redpanda-ui/components/message-scroller"
<MessageScrollerProvider autoScroll defaultScrollPosition="end">
  <MessageScroller>
    <MessageScrollerViewport>
      <MessageScrollerContent>
        {messages.map((message) => (
          <MessageScrollerItem
            key={message.id}
            messageId={message.id}
            scrollAnchor={message.startsTurn}
          >
            <Message>{/* message content */}</Message>
          </MessageScrollerItem>
        ))}
      </MessageScrollerContent>
    </MessageScrollerViewport>
    <MessageScrollerButton />
  </MessageScroller>
</MessageScrollerProvider>

Anatomy

MessageScrollerProvider
└── MessageScroller
    ├── MessageScrollerViewport
    │   └── MessageScrollerContent
    │       └── MessageScrollerItem…
    └── MessageScrollerButton

Behavior

  • Anchors a new turn near the start of the viewport while preserving prior context.
  • Follows streamed content only while the reader remains at the live edge.
  • Stops following after scroll, touch, keyboard, or selection intent.
  • Preserves position when earlier history is prepended.
  • Supports start, end, and last-anchor restoration.
  • Exposes commands and visibility state through useMessageScroller, useMessageScrollerScrollable, and useMessageScrollerVisibility.

Give every MessageScrollerItem a stable messageId when using jump or visibility APIs. Mark only the first item in a turn with scrollAnchor.

Scroll fade

The registry theme includes the full scroll-fade utility family for block, inline, and individual edges, including configurable fade sizes and reduced browser fallbacks. MessageScrollerViewport uses a bottom-edge fade by default.

Accessibility

The viewport defaults to a focusable region named “Messages”. Content defaults to a live log with aria-relevant="additions". Override labels when multiple conversations appear on one page.

Credits

Recent changes

  • patchv1.2.0Pin shipped dependency floors to the version we develop against. Registry items now declare ranges like `^5.1.9` (the actual installed version) instead of collapsing to `^5.0.0`, so consumers start on the known-tested baseline while caret semantics still allow any compatible release within the same major.#133
  • minorv1.1.0Theme docs refresh, readability pass on semantic foregrounds, and consumer-facing Base UI regression fixes.#121
  • minorv1.0.0Post-Base-UI polish. Public API unchanged.#116
  • majorv1.0.0Migrate every Radix-based primitive to `@base-ui/react@^1.4.0` (Base UI).#114
  • minorv0.3.0Add theme-provider component to the registry with documentation and tests. Includes playground type improvements (export RegistryItem, remove as-const boilerplate) and docs site dark mode border color fix.#109
See full history →
Built by malinskibeniamin. The source code is available on GitHub.

On this page