WebberUI

AI Message Stream

串流訊息列表:逐字打字淡入、Markdown 漸現,內建停止/重試動畫與自動捲動。

載入預覽⋯

Playground

即時調整 props、程式碼片段同步更新——直接試出你要的樣子再複製。

45
320
<AiMessageStream />

安裝

npx shadcn@latest add https://webberui.com/r/ai-message-stream.json

或在 components.json 設定 registries 後,改用 @webberui/ai-message-stream 安裝。

安裝依賴後,從 registry JSON(/r/ai-message-stream.jsonfiles[0].content)複製 ai-message-stream.tsx 原始碼到你的 components/ui/ 目錄:

npm install motion lucide-react clsx tailwind-merge

使用

import {
  AIMessageStream,
  type StreamMessage,
} from "@/components/ui/ai-message-stream";

const messages: StreamMessage[] = [
  { id: "u1", role: "user", content: "介紹一下串流回覆", status: "done" },
  { id: "a1", role: "assistant", content: "這是**串流**的回覆…", status: "streaming" },
];

<AIMessageStream
  messages={messages}
  streaming={isStreaming}
  onStop={() => controller.abort()}
  onRetry={regenerate}
/>

streaming 綁到模型串流狀態即可:為 true 時最後一則助理訊息會依 charsPerSecond 逐字浮現,並在標題列露出「停止產生」按鈕;轉回 false 後改顯示「重新產生」。助理訊息內容以輕量 Markdown 漸現——粗體、斜體、行內碼、清單、標題與連結會在語法完成的當下成形。

真實串流時,只要持續把新收到的 token 併入該則訊息的 content,揭示動畫會自動追上目前長度;content 一次給滿(如上方範例)則會完整打字輸出。

Props

AIMessageStream

Prop型別預設值說明
messagesStreamMessage[]訊息陣列
streamingbooleanfalsetrue 時最後一則助理訊息逐字打字揭示
onStop() => void點擊「停止」的回呼,提供時串流中顯示停止按鈕
onRetry() => void點擊「重試」的回呼,提供且非串流中時顯示重試按鈕
charsPerSecondnumber45打字揭示速度(字元/秒)
markdownbooleantrue助理訊息是否以 Markdown 解析
autoScrollbooleantrue內容成長時自動捲到底(手動上捲時暫停)
maxHeightnumber | string320捲動區最大高度
classNamestring追加到外框容器的 className

StreamMessage

欄位型別說明
idstring唯一識別碼,作為 key 與逐字揭示邊界
role"user" | "assistant"角色:使用者靠右、助理靠左
contentstring內容,助理訊息預設以 Markdown 漸現
status"streaming" | "done" | "stopped" | "error"狀態;errorstopped 顯示對應提示

細節

  • 逐字揭示以 requestAnimationFramecharsPerSecond 推進,內容成長時自動追上目前長度
  • 每個單字掛載時以淡入+上移+去模糊浮現,Markdown 區塊在語法閉合時成形
  • 未閉合的程式碼區塊(串流中途)仍會即時渲染為 code,符合真實串流的視覺
  • 串流中顯示閃爍游標;尚未有內容時顯示三點等待指示
  • 「停止/重試」以 AnimatePresence 交替進出,停止鈕帶脈動效果
  • 貼齊底部時內容成長會自動捲動,使用者往上捲則暫停,回到底部恢復
  • 所有 requestAnimationFrame 與計時器於狀態切換與卸載時皆清理

可及性

  • 捲動區帶 role="log"aria-live="polite",串流內容會被輔助科技朗讀
  • 串流中的訊息氣泡帶 aria-busy,完成後解除
  • 連結帶 rel="noopener noreferrer",於新分頁開啟
  • 使用者系統開啟「減少動態效果」時:略過逐字揭示直接顯示完整內容、移除游標與單字動畫、等待指示與停止脈動退化為靜態

On this page