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.json 的 files[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 | 型別 | 預設值 | 說明 |
|---|---|---|---|
messages | StreamMessage[] | — | 訊息陣列 |
streaming | boolean | false | 為 true 時最後一則助理訊息逐字打字揭示 |
onStop | () => void | — | 點擊「停止」的回呼,提供時串流中顯示停止按鈕 |
onRetry | () => void | — | 點擊「重試」的回呼,提供且非串流中時顯示重試按鈕 |
charsPerSecond | number | 45 | 打字揭示速度(字元/秒) |
markdown | boolean | true | 助理訊息是否以 Markdown 解析 |
autoScroll | boolean | true | 內容成長時自動捲到底(手動上捲時暫停) |
maxHeight | number | string | 320 | 捲動區最大高度 |
className | string | — | 追加到外框容器的 className |
StreamMessage
| 欄位 | 型別 | 說明 |
|---|---|---|
id | string | 唯一識別碼,作為 key 與逐字揭示邊界 |
role | "user" | "assistant" | 角色:使用者靠右、助理靠左 |
content | string | 內容,助理訊息預設以 Markdown 漸現 |
status | "streaming" | "done" | "stopped" | "error" | 狀態;error/stopped 顯示對應提示 |
細節
- 逐字揭示以
requestAnimationFrame依charsPerSecond推進,內容成長時自動追上目前長度 - 每個單字掛載時以淡入+上移+去模糊浮現,Markdown 區塊在語法閉合時成形
- 未閉合的程式碼區塊(串流中途)仍會即時渲染為
code,符合真實串流的視覺 - 串流中顯示閃爍游標;尚未有內容時顯示三點等待指示
- 「停止/重試」以
AnimatePresence交替進出,停止鈕帶脈動效果 - 貼齊底部時內容成長會自動捲動,使用者往上捲則暫停,回到底部恢復
- 所有
requestAnimationFrame與計時器於狀態切換與卸載時皆清理
可及性
- 捲動區帶
role="log"與aria-live="polite",串流內容會被輔助科技朗讀 - 串流中的訊息氣泡帶
aria-busy,完成後解除 - 連結帶
rel="noopener noreferrer",於新分頁開啟 - 使用者系統開啟「減少動態效果」時:略過逐字揭示直接顯示完整內容、移除游標與單字動畫、等待指示與停止脈動退化為靜態