The scrolling part of a chat with an AI assistant: it follows the newest message while it streams, inside a panel that keeps its height.
$ pnpm dlx shadcn@latest add https://dashral.com/r/conversation.jsonInstallation
$ pnpm dlx shadcn@latest add https://dashral.com/r/conversation.jsonAdds the component, the components it builds on, its npm packages and the theme tokens it uses. Using Dashral often? Add the registry to components.json once:
{
"registries": {
"@dashral": "https://dashral.com/r/{name}.json"
}
}Then add components by name:
$ pnpm dlx shadcn@latest add @dashral/conversationUsage
import { Message } from "@/components/dashral/message"
import { Conversation } from "@/components/dashral/conversation"
<Conversation className="h-96">
<Message from="user">What were sales yesterday?</Message>
<Message from="assistant">$12,480 across 96 orders.</Message>
</Conversation>Examples
API reference
Conversation
Also takes every prop of <div>(opens in a new tab).
| Prop | Type | Default |
|---|---|---|
children | ReactNodeThe messages, oldest first: Message, or your own. | — |
empty | { icon?, title?, description?, actions? } | ReactNodeWhat fills the middle while there are no messages: EmptyState's props, or your own content. | — |
stickToBottom | booleanFollow the newest message until the reader scrolls up; a message from you brings the bottom back. | true |
fade | numberHow far the top and bottom edges fade while there's more to scroll that way, in px. | 32 |
scrollbar | booleanShow the scrollbar as well as the fade. | false |
aria-label | stringNames the log. | "Conversation" |
classNames | { viewport?, content?, jump? }Classes for the scroll area, the list inside it and Jump to latest. | — |
className | stringExtra classes, merged with cn() so yours win. | — |
Keyboard
| Keys | Action |
|---|---|
| Tab | Focus the conversation, to scroll it |
| ↑ ↓orPage UporPage Down | Scroll |
| EnterorSpace | On Jump to latest: back to the newest message |
Accessibility
- The messages are a log (role="log"), so screen readers announce new ones politely; a streaming Message holds its words back until it's whole.
- The scroll area takes focus when nothing inside does, so it scrolls with the keyboard; the hidden scrollbar doesn't stop wheel, trackpad, touch or keys.
- Jump to latest is a named button, there only while you're away from the bottom.
Motion
- Jump to latest scrolls smoothly, and jumps with reduced motion; following a stream never animates. The button fades and scales in over --duration-fast.