Skip to content
Redpanda UI
Esc
↑↓navigate↵open⌘Jpreview
On this page

Message Scroller

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

Installation

npx shadcn@latest add @redpanda/message-scroller
pnpm dlx shadcn@latest add @redpanda/message-scroller
yarn dlx shadcn@latest add @redpanda/message-scroller
bunx shadcn@latest add @redpanda/message-scroller
nubx shadcn@latest add @redpanda/message-scroller
aube dlx shadcn@latest add @redpanda/message-scroller

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 →

Last updated on October 7, 2026

Was this page helpful?