Chat Thread
A conversa inteira ao redor do composer. Sua pergunta fica fixa no topo enquanto a resposta chega em streaming, checkpoints na lateral saltam entre mensagens, e toda resposta pode ser copiada, editada, repetida, avaliada e alternada entre versões. As respostas renderizam Markdown com blocos de código, tabelas e citações, e o raciocínio, as chamadas de ferramenta e o Prompt Input se encaixam diretamente.
O Chat Thread é a conversa ao redor do composer: suas mensagens, as respostas do modelo e o que você pode fazer com elas. Ele começa com o seu estado vazio e o composer centralizado e depois encaixa o composer na parte de baixo quando há mensagens, sem remontá-lo, então o foco e o texto do rascunho permanecem no lugar.
A mensagem que você acabou de enviar sobe para o topo enquanto a resposta chega em streaming logo abaixo, e a visão acompanha o novo texto até você rolar para longe. Uma trilha de checkpoints à direita permite saltar entre as suas mensagens, com uma prévia no hover. O histórico mais antigo é carregado pelo topo sem a visão se mexer.
Passe o mouse sobre uma mensagem para copiar, editar ou tentar de novo. Edições e novas tentativas viram versões entre as quais você pode alternar, e nada se perde. Respostas com falha oferecem Try again, respostas interrompidas dizem isso, e o polegar para cima ou para baixo é um clique. Dentro de cada resposta, Reasoning, ToolCalls e Markdown dos outros blocos se encaixam diretamente.
Adicione o registro Pro ao components.json
components.json Adicione seu token
Crie um token na sua página de conta e coloque-o em
.env.localcomoHEXTAUI_PRO_TOKEN.Adicione o bloco
pnpm dlx shadcn@latest add @hextaui-pro/chat-thread
Com o AI SDK
Mapeie as mensagens do useChat para a thread. As partes de reasoning vão para Reasoning, as partes de ferramenta para ToolCalls e o texto para Markdown. Fixe a última mensagem do usuário, use regenerate para Try again e reenvie uma edição a partir daquele ponto.
Anatomia
As partes que você compõe, de fora para dentro.
| Parte | Descrição |
|---|---|
ChatThread | A moldura: scroller, checkpoints, estado vazio e o espaço do composer. |
ChatUserMessage | Sua mensagem: anexos, balão, horário, versões, copiar e editar. |
ChatAssistantMessage | Uma resposta. Coloque Reasoning, ToolCalls e Markdown dentro dela; ela adiciona as ações e os estados de erro e de interrompido. |
ChatDivider | Uma linha rotulada entre grupos de mensagens. |
ChatAttachments, ChatAction, ChatCopy, ChatBranchSwitch, ChatEditor | As peças que as mensagens usam, exportadas para layouts personalizados. |
| Prop | Tipo | Padrão |
|---|---|---|
childrenMensagens e divisores, em ordem. | ReactNode | – |
composerGeralmente o Prompt Input. Centralizado quando vazio, encaixado na parte de baixo nos demais casos. | ReactNode | – |
emptyExibido acima do composer quando não há mensagens. | ReactNode | – |
busyMarca a conversa como ocupada para tecnologias assistivas enquanto uma resposta chega em streaming. | boolean | false |
hasOlderMostra "Load earlier messages" no topo. | boolean | false |
loadingOlderMostra um spinner nesse botão. A posição de rolagem é restaurada quando vira false. | boolean | false |
onLoadOlderAdicione aqui as mensagens mais antigas, no início. | () => void | – |
| Prop | Tipo | Padrão |
|---|---|---|
idId estável. Mantenha-o igual entre as versões para que a visão não pule. | string | – |
textA mensagem. Também usada na prévia do checkpoint. | string | – |
pinRola esta mensagem até o topo quando ela aparece. Defina-a na mensagem recém-enviada. | boolean | false |
files{ id, name, size?, type?, url? }. Imagens com url aparecem como miniaturas. | ChatFile[] | – |
timeExibido no hover, no locale de quem lê. | Date | – |
branch{ index, count, onChange } para as setas de versão. | ChatBranch | – |
onEditMostra Edit. Chamado com o novo texto quando ele mudou. | (text: string) => void | – |
attachmentsConteúdo personalizado acima do balão. | ReactNode | – |
| Prop | Tipo | Padrão |
|---|---|---|
idId estável. | string | – |
childrenReasoning, ToolCalls, Markdown ou qualquer outra coisa. | ReactNode | – |
textTexto simples para o Copy. | string | – |
streamingOculta as ações até a resposta terminar. | boolean | false |
lastMantém as ações visíveis em vez de mostrá-las no hover. | boolean | false |
metaLado direito da linha de ações, como o modelo e o esforço. | ReactNode | – |
branchSetas de versão para as novas tentativas. | ChatBranch | – |
feedbackA avaliação atual. | "up" | "down" | null | null |
onFeedbackMostra os polegares. Chamado com null quando uma avaliação é desfeita. | (feedback) => void | – |
onRetryMostra Try again. | () => void | – |
errorMostra a mensagem com Try again no lugar das ações. | string | null | – |
stoppedMarca uma resposta que foi interrompida antes do fim. | boolean | false |
| Prop | Tipo | Padrão |
|---|---|---|
childrenO rótulo, como Hoje ou "Mudou para o Nova 3 Max". | ReactNode | – |
| Tecla | Ação |
|---|---|
| Tab | Percorre as ações das mensagens. Elas aparecem no foco, não apenas no hover. |
| Enter | Envia uma mensagem editada. |
| ShiftEnter | Adiciona uma linha durante a edição. |
| Esc | Cancela uma edição. |
| ↑↓PgUpPgDn | Rola a conversa quando ela tem o foco. |
- A conversa é uma região rotulada que contém um log, então as novas mensagens são anunciadas assim que chegam e a região é marcada como ocupada enquanto uma resposta chega em streaming.
- Toda ação com ícone tem um rótulo e um tooltip. Os polegares usam aria-pressed, Copy e o feedback confirmam por uma região live polite, e os erros usam role=alert.
- Os checkpoints são um marco de navegação de botões chamados "Mensagem 2: …", e o atual tem aria-current.
- As setas de versão são um grupo chamado "Versão 1 de 2".
- O editor se foca sozinho com o cursor no fim e volta à mensagem em Cancel. O Enter espera enquanto um método de entrada está compondo texto.
- Os anéis de foco nunca são cortados pelo scroller, e as ações permanecem visíveis em telas de toque.
Construído com
Os componentes gratuitos do HextaUI de que Chat Thread é feito. Cada um é instalado separadamente.
Código
2 arquivos, adicionados a components/blocks/chat-thread.