diff --git a/components/bubble/Bubble.tsx b/components/bubble/Bubble.tsx index 3b07e3cc..18dd1f59 100644 --- a/components/bubble/Bubble.tsx +++ b/components/bubble/Bubble.tsx @@ -18,6 +18,11 @@ export interface BubbleContextProps { onUpdate?: VoidFunction; } +type RenderSlotNode = + | BubbleProps['footer'] + | BubbleProps['header'] + | BubbleProps['extra']; + export const BubbleContext = React.createContext({}); const Bubble: React.ForwardRefRenderFunction = (props, ref) => { @@ -40,6 +45,7 @@ const Bubble: React.ForwardRefRenderFunction = (props, r onTypingComplete, header, footer, + extra, _key, ...otherHtmlProps } = props; @@ -117,7 +123,7 @@ const Bubble: React.ForwardRefRenderFunction = (props, r () => (messageRender ? messageRender(typedContent as any) : typedContent), [typedContent, messageRender], ); - const renderSlot = (node: BubbleProps['footer'] | BubbleProps['header']) => + const renderSlot = (node: RenderSlotNode) => typeof node === 'function' ? node(typedContent, { key: _key }) : node; // ============================ Render ============================ @@ -148,6 +154,21 @@ const Bubble: React.ForwardRefRenderFunction = (props, r )} > {contentNode} + {(extra || extra === 0) && ( +
+ {renderSlot(extra)} +
+ )} ); diff --git a/components/bubble/__tests__/__snapshots__/demo-extend.test.ts.snap b/components/bubble/__tests__/__snapshots__/demo-extend.test.ts.snap index 1369428b..ca91376b 100644 --- a/components/bubble/__tests__/__snapshots__/demo-extend.test.ts.snap +++ b/components/bubble/__tests__/__snapshots__/demo-extend.test.ts.snap @@ -1432,6 +1432,83 @@ exports[`renders components/bubble/demo/debug-list.tsx extend context correctly exports[`renders components/bubble/demo/debug-list.tsx extend context correctly 2`] = `[]`; +exports[`renders components/bubble/demo/extra.tsx extend context correctly 1`] = ` +
+
+
+ Hello ice ! +
+ + + +
+
+
+
+
+ Hello Ant Design X ! +
+ + + +
+
+
+
+`; + +exports[`renders components/bubble/demo/extra.tsx extend context correctly 2`] = `[]`; + exports[`renders components/bubble/demo/header-and-footer.tsx extend context correctly 1`] = `
`; +exports[`renders components/bubble/demo/extra.tsx correctly 1`] = ` +
+
+
+ Hello ice ! +
+ + + +
+
+
+
+
+ Hello Ant Design X ! +
+ + + +
+
+
+
+`; + exports[`renders components/bubble/demo/header-and-footer.tsx correctly 1`] = `
{ expect(element?.textContent).toBe('Footer for: Test content'); }); + it('should render static extra', () => { + const { container } = render(); + const element = container.querySelector('.ant-bubble .ant-bubble-extra'); + expect(element).toBeTruthy(); + expect(element?.textContent).toBe('extra'); + }); + + it('should render extra with function and get content', () => { + const content = 'extra content'; + const extraFunction = (content: BubbleContentType) => ( +
{`Extra for: ${content}`}
+ ); + const { container } = render(); + const element = container.querySelector( + '.ant-bubble .ant-bubble-extra .test-extra', + ); + expect(element).toBeTruthy(); + expect(element?.textContent).toBe('Extra for: extra content'); + }); + it('Bubble support typing', () => { const { container } = render(); expect(container.querySelector('.ant-bubble')).toHaveClass('ant-bubble-typing'); diff --git a/components/bubble/demo/_semantic.tsx b/components/bubble/demo/_semantic.tsx index 7eeaf8d8..c3f4e8e4 100644 --- a/components/bubble/demo/_semantic.tsx +++ b/components/bubble/demo/_semantic.tsx @@ -1,4 +1,4 @@ -import { CopyOutlined, SyncOutlined, UserOutlined } from '@ant-design/icons'; +import { CopyOutlined, LoadingOutlined, SyncOutlined, UserOutlined } from '@ant-design/icons'; import { Bubble } from '@ant-design/x'; import { Avatar, Button, Space, theme } from 'antd'; import React from 'react'; @@ -11,12 +11,14 @@ const locales = { header: '头部的容器', content: '聊天内容的容器', footer: '底部的容器', + extra: '额外的容器', }, en: { avatar: 'Wrapper element of the avatar', header: 'Wrapper element of the header', content: 'Wrapper element of the content', footer: 'Wrapper element of the footer', + extra: 'Wrapper element of the extra', }, }; @@ -33,6 +35,7 @@ const App: React.FC = () => { { name: 'header', desc: locale.header }, { name: 'content', desc: locale.content }, { name: 'footer', desc: locale.footer }, + { name: 'extra', desc: locale.extra }, ]} > {