AI 應用元件

腳本式對話展示

依腳本自動播放的對話展示 React 元件:使用者氣泡 spring 彈入、三點打字指示、助理逐字串流回覆與程式碼區塊,可循環。

把一段寫好的對話腳本變成會自己播放的聊天畫面,適合放在產品首頁、功能介紹或客服流程說明。使用者訊息從右下以 spring 彈入並帶輕微 overshoot;助理回覆前先出現三點打字指示,接著氣泡從左彈入、文字逐字串流,附帶的程式碼區塊則逐行出現並帶行號與複製按鈕。進入視口才開始播放,有新內容時自動捲到底;開啟 loop 會在播完後淡出清空、從頭再來。可選 frame="phone" 包進簡化的 CSS 手機殼。

把這個效果裝進你的專案

在專案資料夾執行指令,CLI 會加入原始碼與依賴套件,再依下方使用範例引用元件。

npx webberui@latest add scripted-chat-thread

還沒有專案,或安裝遇到問題?看快速開始 →

Playground

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

22
400
編輯中的呼叫預設屬性
<ScriptedChatThread/>

完整範例包含預覽的排版與資料。先安裝元件,再把範例檔貼入你的專案。

安裝

npx webberui@latest add https://webberui.com/r/scripted-chat-thread.json

或在 components.json 設定 registries 後,改用 @webberui/scripted-chat-thread 安裝。

使用

import { ScriptedChatThread } from "@/components/ui/scripted-chat-thread";

<ScriptedChatThread
  frame="phone"
  loop
  messages={[
    { role: "user", content: "我的訂單三天了還沒出貨" },
    { role: "assistant", content: "抱歉讓你久等了!方便提供訂單編號嗎?" },
    { role: "user", content: "#BK20261025" },
    {
      role: "assistant",
      typingMs: 1200,
      content: "已完成揀貨,預計明天出貨。查詢範例:",
      code: {
        lang: "ts",
        text: 'const res = await fetch("https://api.example.com/v1/orders/BK20261025");',
      },
    },
  ]}
  onComplete={() => console.log("播放完成")}
/>

需要手動控制播放時,傳入 ref 取得 restart():

const threadRef = React.useRef<ScriptedChatThreadHandle>(null);

<ScriptedChatThread ref={threadRef} autoplay={false} messages={script} />
<button onClick={() => threadRef.current?.restart()}>重新播放</button>

Props

Prop型別預設值說明
messagesScriptedChatMessage[]—依序播放的對話腳本
autoplaybooleantrue是否自動播放;true 時進入視口才開始,false 時顯示播放鈕或等 ref.restart()
loopbooleanfalse播完後停 2500ms、淡出清空並從頭重播
charMsnumber22助理文字每字的毫秒數;未提供時讀取 CSS 變數 --wb-sct-char-ms,再退回 22
gapMsnumber600訊息與訊息之間的間隔毫秒數
springConfigScriptedChatSpring{ stiffness: 400, damping: 28 }氣泡進場的 spring 參數
frame"none" | "phone""none"外框:none 為一般卡片,phone 包在簡化的 CSS 手機殼內
heightnumber | string440對話捲動區的高度(數字為 px)
avatarReact.ReactNode圓形字母「助」助理頭像;預設為強調色圓形字母
ariaLabelstring"對話示範"容器的無障礙名稱
onComplete() => void—整段腳本播放完成時回呼(loop 時每輪觸發一次)
refReact.Ref<ScriptedChatThreadHandle>—命令式 API,提供 restart()
classNamestring—透傳到最外層容器

ScriptedChatMessage

欄位型別預設值說明
idstring索引訊息識別碼,用作 React key
role"user" | "assistant"—發話者:user 靠右、assistant 靠左並帶頭像
contentstring—文字內容;assistant 會逐字串流
codeScriptedChatCode—程式碼區塊;接在文字之後逐行串流
typingMsnumber900assistant 回覆前顯示打字指示的毫秒數

ScriptedChatCode

欄位型別預設值說明
langstring—語言標籤,顯示於區塊左上角
textstring—程式碼原文,以換行分行

ScriptedChatSpring

欄位型別預設值說明
stiffnessnumber400彈性係數,越大越快越彈
dampingnumber28阻尼,越小 overshoot 越明顯

ScriptedChatThreadHandle

欄位型別預設值說明
restart() => void—清空並從第一則訊息重新播放

細節

  • 播放節奏:使用者氣泡彈入後停 400ms;助理先顯示打字指示 typingMs,再逐字串流(每字 charMs),程式碼以逐行串流(每行 charMs × 8);每則訊息之間間隔 gapMs。
  • 自動捲底:只有使用者原本就在底部(距底小於 24px)時才會跟著捲;往上捲會暫停跟隨並顯示「回到最新」小按鈕,按下即回到底部繼續跟隨。
  • messages 以內容比對,寫成 inline 陣列也不會因父層重新渲染而重播。
  • CSS 變數:--wb-sct-char-ms 設定預設逐字速度(charMs prop 優先),--wb-sct-accent 設定頭像與游標的強調色。
  • 可以把本元件放進 chat-scroller 內組合使用,但兩者互不依賴;本元件自己就有捲底與「回到最新」行為。

可及性

  • 捲動容器為 role="log"、aria-live="polite",以 ariaLabel(預設「對話示範」)命名
  • 串流中的部分文字對輔助科技隱藏;訊息完成後才把完整文字(含發話者)放進可讀節點,避免螢幕閱讀器逐字朗讀
  • 打字指示帶 sr-only「正在輸入」;程式碼的複製按鈕與「回到最新」、「播放對話」皆為 type="button",有可見的 focus 外框
  • 使用者系統開啟「減少動態效果」時,不彈入、不串流、不顯示打字指示,所有訊息以 150ms 淡入直接全部出現,onComplete 立即觸發