跳至主要内容

自訂 Header

用 renderHeader 取代預設的聊天機器人 header。透過 useAsgardContext 讀取 SDK 內部狀態,並用 onMessageSent / onReset 生命週期 callback 做資料同步。

訊息計數器

在聊天機器人中發送任何訊息,就能看到自訂 header 上的計數器增加。點 header 上的 Reset 即可歸零。

目前數量
0
聊天機器人載入中…

程式範例​

import { Chatbot, useAsgardContext } from "@asgard-js/react";

function MyHeader({ count }: { count: number }) {
const { avatar, resetChannel } = useAsgardContext();
return (
<header>
{avatar && <img src={avatar} alt="" />}
<span>已發送訊息數:{count}</span>
<button onClick={() => resetChannel?.()}>重置</button>
</header>
);
}

function Demo() {
const [count, setCount] = useState(0);
return (
<Chatbot
onMessageSent={() => setCount((c) => c + 1)}
onReset={() => setCount(0)}
renderHeader={() => <MyHeader count={count} />}
{...rest}
/>
);
}

renderHeader 拿得到組好的 actions​

renderHeader 收一個參數,而不是空的:

interface ChatHeaderRendererArgs {
botName: string | null;
title: string | null;
actions: ChatHeaderAction[]; // 已經組好的右側動作鈕,含內建的
renderDefault: () => ReactNode;
}

actions 是已經組裝完成的那一串,包含內建的 File Explorer 切換鈕在內。接管整條 bar 不代表 要重刻那些按鈕——照著 actions 畫就好:

<Chatbot
renderHeader={({ title, actions, renderDefault }) => (
<header>
<strong>{title}</strong>
{actions.map((action) => (
<button
key={action.id}
onClick={action.onClick}
disabled={action.disabled || action.busy}
aria-pressed={action.active}
title={action.label}
>
{action.render ? action.render() : action.icon}
</button>
))}
</header>
)}
{...rest}
/>

回傳 null 則整條 bar 隱藏。只想換標題文字區塊的話用 renderTitle,見 對話標題。

用 headerActions 加自己的按鈕​

不需要接管整條 bar 也可以加動作鈕——headerActions 接在內建的後面:

欄位型別說明
idstring穩定識別(React key、測試掛勾、覆寫目標)
iconReactNode圖示;busy 時被 spinner 取代
labelstring無障礙標籤與 hover tooltip(必填,純圖示按鈕不可省)
onClick() => void點擊
activeboolean「按下」狀態(如 File Explorer 開著)→ 高亮 + aria-pressed
busyboolean忙碌(如重置中)→ spinner + 停用
disabledboolean停用
render() => ReactNode完全自訂的格子(用量徽章、版本下拉選單之類)。給了就跳過標準按鈕渲染,但仍佔著它在序列中的位置

useAsgardContext 常用欄位​

在 renderHeader 內部可以透過此 hook 取得 SDK 內部狀態:

欄位型別說明
avatarstringBot 頭像 URL
titlestring聊天室標題
isConnectingboolean是否正在連線
isResettingboolean是否正在重置
resetChannel() => void重置 channel
closeChannel() => void關閉 channel
messagesMap<string, ConversationMessage>所有訊息