Bubble
Importimport { Bubble } from "@ant-design/x"; |
Sourcecomponents/bubble |
Importimport { Bubble } from "@ant-design/x"; |
Sourcecomponents/bubble |
Often used in chat scenarios.
Common Props Reference: Common Props
Attribute | Description | Type | Default | Version |
---|---|---|---|---|
placement | Bubble position | start | end | start | - |
loading | Loading state | boolean | - | - |
loadingRender | Custom loading content renderer | () => React.ReactNode | - | - |
content | Bubble content | ContentType | - | - |
contentRender | Custom content renderer | (content: ContentType, info: InfoType ) => React.ReactNode | - | - |
editable | Editable | boolean | EditableBubbleOption | false | - |
typing | Typing animation effect | boolean | BubbleAnimationOption | ((content: ContentType, info: InfoType) => boolean | BubbleAnimationOption) | false | - |
streaming | Streaming mode | boolean | false | - |
variant | Bubble style variant | filled | outlined | shadow | borderless | filled | - |
shape | Bubble shape | default | round | corner | default | - |
footerPlacement | Footer slot position | outer-start | outer-end | inner-start | inner-end | outer-start | - |
components | Slot configuration | { header?: BubbleSlot; footer?: BubbleSlot; avatar?: BubbleSlot; extra?: BubbleSlot; } | - | - |
onTyping | Typing animation callback | (rendererContent: string, currentContent: string) => void | - | - |
onTypingComplete | Typing animation complete callback | (content: string) => void | - | - |
onEditing | Callback when content changes in editing mode | (content: string) => void | - | - |
streaming
notifies Bubble whether the current content
is streaming input. In streaming mode, regardless of whether Bubble input animation is enabled, Bubble will not trigger the onTypingComplete
callback until streaming
becomes false
, even if the current content
is fully output. Only when streaming
becomes false
and the content is fully output will Bubble trigger onTypingComplete
. This avoids multiple triggers due to unstable streaming and ensures only one trigger per streaming process.
In this example, you can try to force the streaming flag off:
onTypingComplete
may occur because streaming speed cannot keep up with animation speed.onTypingComplete
.Bubble.List auto-scroll is a simple reverse sorting scheme. In a fixed-height Bubble.List, if the message content is insufficient to fill the height, the content is bottom-aligned. It is recommended not to set a fixed height for Bubble.List, but to set a fixed height for its parent container and use flex layout (display: flex
and flex-direction: column
). This way, Bubble.List adapts its height and aligns content to the top when content is sparse, as shown in the Bubble List demo.
<div style={{ height: 600, display: 'flex', flexDirection: 'column' }}><Bubble.List items={items} autoScroll /></div>
If you do not want to use flex layout, you can set max-height
for Bubble.List. When content is sparse, the height adapts and aligns to the top.
<Bubble.List items={items} autoScroll rootStyle={{ maxHeight: 600 }} />
Attribute | Description | Type | Default | Version |
---|---|---|---|---|
items | Bubble data list, key and role required. When used with X SDK useXChat , you can pass status to help Bubble manage configuration | (BubbleProps & { key: string | number, role: string , status: MessageStatus})[] | - | - |
autoScroll | Auto-scroll | boolean | true | - |
role | Role default configuration | RoleType | - | - |
Default type
type ContentType = React.ReactNode | AnyObject | string | number;
Custom type usage
type CustomContentType {...}<Bubble<CustomContentType> {...props} />
type BubbleSlot<ContentType> =| React.ReactNode| ((content: ContentType, info: InfoType) => React.ReactNode);
type MessageStatus = 'local' | 'loading' | 'updating' | 'success' | 'error' | 'abort';
type InfoType = {status: MessageStatus;};
interface EditableBubbleOption {/*** @description Whether editable*/editing?: boolean;/*** @description OK button*/okText?: React.ReactNode;/*** @description Cancel button*/cancelText?: React.ReactNode;}
interface BubbleAnimationOption {/*** @description Animation effect type, typewriter, fade-in* @default 'fade-in'*/effect: 'typing' | 'fade-in';/*** @description Content step unit, array format for random interval* @default 6*/step?: number | [number, number];/*** @description Animation trigger interval* @default 100*/interval?: number;/*** @description Whether to keep the common prefix when restarting animation* @default true*/keepPrefix?: boolean;/*** @description Suffix UI for typewriter effect* @default undefined*/suffix?: React.ReactNode;}
type RoleProps = Pick<BubbleProps,| 'typing'| 'variant'| 'shape'| 'placement'| 'rootClassName'| 'classNames'| 'className'| 'rootStyle'| 'styles'| 'style'| 'loading'| 'loadingRender'| 'contentRender'| 'footerPlacement'| 'components'> & { key: string | number; role: string };export type FuncRoleProps = (data: BubbleData) => RoleProps;export type RoleType = Partial<Record<'ai' | 'system' | 'user', RoleProps | FuncRoleProps>> &Record<string, RoleProps | FuncRoleProps>;