Skip to content

shadcn.io is an independent project built on shadcn/ui

Chat Messages Scroll Area for React

A fixed-height list of chat messages. Each row has an avatar, a name, a timestamp and a message.

A fixed-height panel lists chat messages. Each row has an avatar, a name, a time such as 10:30 AM and a message. The list scrolls vertically.

Use a fixed-height panel for a transcript that should not grow the page. A Message Scroller sticks to the latest message. On React, Base UI does not send the messages.

Preview

Preview width

Installation

Sign in to get your install command
Free with an account. It carries your token, so the CLI installs everything in one go.
Use email insteadNo credit card

Anatomy

Scroll Area anatomy: root, viewport, content, scrollbar, thumb

Usage

<div className="w-full max-w-md">
  <ScrollArea className="h-[400px] rounded-md border bg-background">
    <div className="flex flex-col gap-4 p-4">
      {messages.map((msg) => (
        <div className="flex gap-3" key={msg.id}>
          <Avatar>
            <AvatarImage alt={msg.user} src={msg.avatar} />
            <AvatarFallback>{msg.initials}</AvatarFallback>
          </Avatar>
          <div className="flex flex-1 flex-col gap-1">
            <div className="flex items-baseline gap-2">
              <span className="font-semibold text-sm">{msg.user}</span>
              <span className="text-muted-foreground text-xs">
                {msg.time}
              </span>
            </div>
            <p className="text-sm">{msg.message}</p>
          </div>
        </div>
      ))}
    </div>
  </ScrollArea>
</div>

FAQ

What height is the message list?

ScrollArea is h-[400px], with rounded-md border bg-background. Eight messages scroll inside that box. The wrapper around the area is w-full max-w-md.

How is one message laid out?

A row with flex gap-3. Avatar is first. The name, time, and text stack in flex-1 with gap-1. The name and time share a row with flex items-baseline gap-2.

What does the avatar show?

AvatarImage uses alt set to the sender's name and src set to their image. AvatarFallback is the initials, such as HB or SC. Avatar leaves size at the default.

How are the name and time styled?

The name is a span with font-semibold text-sm. The time is a span with text-xs text-muted-foreground, a clock time such as 10:30 AM. The message is a p with text-sm.

Where is the padding between messages?

The inner wrapper is flex flex-col gap-4 p-4. The gap is between messages, and the padding scrolls with them. This file renders a static list. It does not move the scroll position when it renders.

How many messages are in the file?

Eight, each with an id, a user, a time, and a message. The row key is msg.id. The list is the only child of ScrollArea.

API Reference

Scroll Area

No extra props in this demo. The rest is on the Scroll Area page.

Avatar

Sets alt={msg.user} and src={msg.avatar}. The rest is on the Avatar page.