消息组件
消息展示相关组件:ConversationList、Conversation、Subtitle。
ConversationList
对话历史列表组件,自动订阅对话变化。
基本用法
import {PilotKit, ConversationList} from '@bdky/aaas-pilot-kit-react-widget';
function App() {
return (
<PilotKit {...props}>
<ConversationList />
</PilotKit>
);
}
响应式适配
📱 详见 响应式适配指南
| 特性 | PC 端 | 移动端 |
|---|---|---|
| 对话显示 | 显示全部历史 | 仅显示最新一条 |
| 关闭按钮 | 显示 | 隐藏 |
| 滚动跟随按钮 | 显示 | 隐藏 |
| 位置 | 绝对定位左侧 | 相对定位 |
Props
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
variant | 'auto' | 'mobile' | 'desktop' | 'auto' | 显示模式 |
className | string | - | 自定义类名 |
style | CSSProperties | - | 自定义样式 |
autoScroll | boolean | true | 是否自动滚动到底部 |
closable | boolean | true | 是否显示关闭按钮 |
closeIcon | ReactNode | - | 自定义关闭图标 |
onClose | () => void | - | 关闭回调 |
children | (props: IConversationRenderProps) => ReactNode | - | 自定义渲染 |
自定义渲染
<ConversationList>
{({conversations, latestConversation}) => (
<div className="my-conversation-list">
{conversations.map(conv => (
<div key={conv.id} className="my-conversation-item">
{conv.type === 'client' ? '用户' : 'AI'}
</div>
))}
</div>
)}
</ConversationList>
样式定制
| 类名 | 说明 |
|---|---|
.apk-conversation-list | 根容器 |
.apk-conversation-list--mobile | 移动端样式 |
.apk-conversation-list--desktop | 桌面端样式 |
.apk-conversation-list__inner | 内层滚动容器 |
.apk-conversation-list__follow-button | 滚动跟随按钮 |
.apk-conversation-list__icons-wrapper | 关闭按钮容器 |
Conversation
单条消息组件,展示消息内容。
基本用法
通常配合 ConversationList 使用,也可单独使用:
import {Conversation} from '@bdky/aaas-pilot-kit-react-widget';
function CustomList({conversations}) {
return (
<div>
{conversations.map(conv => (
<Conversation
key={conv.id}
conversation={conv}
isLatest={conv === conversations[conversations.length - 1]}
/>
))}
</div>
);
}
响应式适配
| 特性 | PC 端 | 移动端 |
|---|---|---|
| 圆角 | 20px | 不同方向不同圆角 |
| 边距 | 左右 30px | 左右 39px |
| 背景 | 半透明 | 更深的半透明 |
Props
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
conversation | AnyConversation | 必填 | 对话对象 |
isLatest | boolean | false | 是否是最新一条 |
variant | 'auto' | 'mobile' | 'desktop' | 'auto' | 显示模式 |
className | string | - | 自定义类名 |
style | CSSProperties | - | 自定义样式 |
onComplete | (payload) => void | - | 对话完成回调 |
children | (props: IConversationContentProps) => ReactNode | - | 自定义渲染 |
自定义渲染
<Conversation conversation={conv}>
{({contents, fullText, type, isCompleted}) => (
<div className={`my-message my-message--${type}`}>
<p>{fullText}</p>
{!isCompleted && <span className="typing">...</span>}
</div>
)}
</Conversation>
样式定制
| 类名 | 说明 |
|---|---|
.apk-conversation | 根容器 |
.apk-conversation--client | 用户消息 |
.apk-conversation--ai | AI 消息 |
.apk-conversation--mobile | 移动端样式 |
.apk-conversation--desktop | 桌面端样式 |
.apk-conversation__content-item | 内容项 |
.apk-conversation__content-text | 文字内容 |
.apk-conversation__content-image | 图片内容 |
.apk-conversation__content-video | 视频内容 |
Subtitle
实时字幕组件,显示最新一条对话的内容。
基本用法
import {PilotKit, Subtitle} from '@bdky/aaas-pilot-kit-react-widget';
function App() {
return (
<PilotKit {...props}>
<Subtitle showSpeaker />
</PilotKit>
);
}
可展开字幕
const [expanded, setExpanded] = useState(false);
<Subtitle
expandable
expanded={expanded}
onExpand={() => setExpanded(true)}
/>
Props
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
className | string | - | 自定义类名 |
style | CSSProperties | - | 自定义样式 |
showSpeaker | boolean | true | 是否显示说话人 |
aiSpeakerName | string | 'AI' | AI 说话人名称 |
userSpeakerName | string | '我' | 用户说话人名称 |
expandable | boolean | false | 是否可展开 |
expanded | boolean | false | 是否已展开 |
onExpand | () => void | - | 展开回调 |
children | (props: ISubtitleRenderProps) => ReactNode | - | 自定义渲染 |
自定义渲染
<Subtitle>
{({speakerName, fullText, conversation, isExpanded, toggleExpand}) => (
<div className="my-subtitle">
<span className="speaker">{speakerName}</span>
<p className="text">{fullText}</p>
<button onClick={toggleExpand}>
{isExpanded ? '收起' : '展开'}
</button>
</div>
)}
</Subtitle>
样式定制
| 类名 | 说明 |
|---|---|
.apk-subtitle | 根容器 |
.apk-subtitle__wrapper | 内容包装器 |
.apk-subtitle__expand-btn | 展开按钮 |
.apk-subtitle__text | 文本区域 |
.apk-subtitle__scroll-view | 滚动视图 |
相关
- React SDK useConversation - 底层 Hook
- React SDK useConversationList - 底层 Hook