Uranus® Design System
AI

MessageList

Container rolável que mantém o usuário no fim da conversa enquanto novos tokens chegam.

MessageList envolve as mensagens com um ScrollArea e cuida do auto-scroll inteligente: enquanto o usuário estiver no fim, novas mensagens são reveladas automaticamente; assim que ele rola pra cima, mostramos um pílula "↓ Novas mensagens" sem forçar scroll.

Este exemplo precisa de mais altura para rolar e interagir como em um app real. Abra em tela cheia.

'use client';

import { Message, MessageList } from '@uranus-workspace/ai';

const items = [
  { id: '1', role: 'user' as const, text: 'Resuma os princípios do design system.' },
  {
    id: '2',
    role: 'assistant' as const,
    text: 'Tokens de uma direção, composição-first nos blocks, e tudo passa por axe a11y.',
    name: 'Uranus',
  },
  { id: '3', role: 'user' as const, text: 'E animações?' },
  {
    id: '4',
    role: 'assistant' as const,
    text: 'Reusam as variantes de Motion em `lib/animations.ts` e respeitam `prefers-reduced-motion`.',
    name: 'Uranus',
  },
];

export default function MessageListDefault() {
  return (
    <div className="mx-auto flex h-full min-h-[320px] w-full max-w-2xl flex-col rounded-lg border bg-background">
      <MessageList scrollKey={items.length}>
        {items.map((item) => (
          <Message key={item.id} role={item.role} name={item.name}>
            <Message.Content>{item.text}</Message.Content>
          </Message>
        ))}
      </MessageList>
    </div>
  );
}

Uso

import { Message, MessageList } from '@uranus-workspace/ai';

<MessageList scrollKey={`${messages.length}-${status}`}>
  {messages.map((message) => (
    <Message key={message.id} role={message.role} name={message.authorName}>
      <Message.Content>{message.text}</Message.Content>
    </Message>
  ))}
</MessageList>

API

  • scrollKey — qualquer valor que muda quando há novas mensagens (use messages.length). É a única dependência do auto-scroll para evitar loops.
  • renderMessage — opcional, recebe a mensagem e devolve o nó renderizado. Útil para injetar ToolCallCard, ReasoningPanel ou markdown sem reimplementar o layout.

Hooks relacionados

  • useAutoScroll — exposto separadamente, caso você queira aplicar a mesma heurística em outro container (logs, terminal).