Message Components
Message display related components: ConversationList, Conversation, Subtitle.
ConversationList
Conversation history list component, automatically subscribes to conversation changes.
Basic Usage
import {PilotKit, ConversationList} from '@bdky/aaas-pilot-kit-react-widget';
import '@bdky/aaas-pilot-kit-react-widget/styles.css';
function App() {
return (
<PilotKit {...props}>
<ConversationList />
</PilotKit>
);
}
Responsive Adaptation
| Feature | PC | Mobile |
|---|---|---|
| Conversation Display | Show all history | Show only the latest one |
| Close Button | Visible | Hidden |
| Scroll Follow Button | Visible | Hidden |
| Position | Absolute positioning on the left | Relative positioning |
Props
| Property | Type | Default | Description |
|---|---|---|---|
variant | 'auto' | 'mobile' | 'desktop' | 'auto' | Display mode |
className | string | - | Custom class name |
style | CSSProperties | - | Custom style |
autoScroll | boolean | true | Whether to auto-scroll to bottom |
closable | boolean | true | Whether to show close button |
closeIcon | ReactNode | - | Custom close icon |
onClose | () => void | - | Close callback |
children | (props: IConversationRenderProps) => ReactNode | - | Custom render |
Custom Rendering
<ConversationList>
{({conversations, latestConversation}) => (
<div className="my-conversation-list">
{conversations.map(conv => (
<div key={conv.id} className="my-conversation-item">
{conv.type === 'client' ? 'User' : 'AI'}
</div>
))}
</div>
)}
</ConversationList>
Style Customization
| Class Name | Description |
|---|---|
.apk-conversation-list | Root container |
.apk-conversation-list--mobile | Mobile style |
.apk-conversation-list--desktop | Desktop style |
.apk-conversation-list__inner | Inner scroll container |
.apk-conversation-list__follow-button | Scroll follow button |
.apk-conversation-list__icons-wrapper | Close button container |
Conversation
Single message component, displays message content.
Basic Usage
Usually used with ConversationList, but can also be used independently:
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>
);
}
Responsive Adaptation
| Feature | PC | Mobile |
|---|---|---|
| Border Radius | 20px | Different border radius for different directions |
| Margin | Left/right 30px | Left/right 39px |
| Background | Semi-transparent | Darker semi-transparent |
Props
| Property | Type | Default | Description |
|---|---|---|---|
conversation | AnyConversation | Required | Conversation object |
isLatest | boolean | false | Whether it's the latest one |
variant | 'auto' | 'mobile' | 'desktop' | 'auto' | Display mode |
className | string | - | Custom class name |
style | CSSProperties | - | Custom style |
onComplete | (payload) => void | - | Conversation completion callback |
children | (props: IConversationContentProps) => ReactNode | - | Custom render |
Custom Rendering
<Conversation conversation={conv}>
{({contents, fullText, type, isCompleted}) => (
<div className={`my-message my-message--${type}`}>
<p>{fullText}</p>
{!isCompleted && <span className="typing">...</span>}
</div>
)}
</Conversation>
Style Customization
| Class Name | Description |
|---|---|
.apk-conversation | Root container |
.apk-conversation--client | User message |
.apk-conversation--ai | AI message |
.apk-conversation--mobile | Mobile style |
.apk-conversation--desktop | Desktop style |
.apk-conversation__content-item | Content item |
.apk-conversation__content-text | Text content |
.apk-conversation__content-image | Image content |
.apk-conversation__content-video | Video content |
Subtitle
Real-time subtitle component, displays the content of the latest conversation.
Basic Usage
import {PilotKit, Subtitle} from '@bdky/aaas-pilot-kit-react-widget';
import '@bdky/aaas-pilot-kit-react-widget/styles.css';
function App() {
return (
<PilotKit {...props}>
<Subtitle showSpeaker />
</PilotKit>
);
}
Expandable Subtitle
const [expanded, setExpanded] = useState(false);
<Subtitle
expandable
expanded={expanded}
onExpand={() => setExpanded(true)}
/>
Props
| Property | Type | Default | Description |
|---|---|---|---|
className | string | - | Custom class name |
style | CSSProperties | - | Custom style |
showSpeaker | boolean | true | Whether to show speaker |
aiSpeakerName | string | 'AI' | AI speaker name |
userSpeakerName | string | 'Me' | User speaker name |
expandable | boolean | false | Whether expandable |
expanded | boolean | false | Whether expanded |
onExpand | () => void | - | Expand callback |
children | (props: ISubtitleRenderProps) => ReactNode | - | Custom render |
Custom Rendering
<Subtitle>
{({speakerName, fullText, conversation, isExpanded, toggleExpand}) => (
<div className="my-subtitle">
<span className="speaker">{speakerName}</span>
<p className="text">{fullText}</p>
<button onClick={toggleExpand}>
{isExpanded ? 'Collapse' : 'Expand'}
</button>
</div>
)}
</Subtitle>
Style Customization
| Class Name | Description |
|---|---|
.apk-subtitle | Root container |
.apk-subtitle__wrapper | Content wrapper |
.apk-subtitle__expand-btn | Expand button |
.apk-subtitle__text | Text area |
.apk-subtitle__scroll-view | Scroll view |
Related
- React SDK useConversation - Underlying Hook
- React SDK useConversationList - Underlying Hook