Skip to content

Commit a33b39a

Browse files
authored
✨ feat: 新增加每个单元的自定义渲染按钮配置透出 (#318)
* ✨ feat: add chat item actions render * ✨ feat: ci pass
1 parent 56880dd commit a33b39a

File tree

9 files changed

+98
-15
lines changed

9 files changed

+98
-15
lines changed

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@
100100
"commitlint-config-gitmoji": "^2.3.1",
101101
"conventional-changelog-gitmoji-config": "^1.5.2",
102102
"cross-env": "^7.0.3",
103-
"dumi": "2.2.16",
103+
"dumi": "^2.2.16",
104104
"dumi-theme-antd-style": "latest",
105105
"eslint": "^8.57.0",
106106
"father": "4.3.1",

src/ActionIconGroup/index.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@ export interface ActionIconGroupItems {
1616
}
1717

1818
export interface ActionEvent {
19-
item: ActionIconGroupItems;
19+
item?: ActionIconGroupItems;
2020
key: string;
21-
keyPath: string[];
21+
keyPath?: string[];
2222
}
2323

2424
export interface ActionIconGroupProps extends Omit<DivProps, 'content'> {

src/ChatItem/index.tsx

+3-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ const ChatItem = memo<ChatItemProps>((props) => {
1919
avatarAddon,
2020
onAvatarClick,
2121
actions,
22+
actionsClick,
2223
className,
2324
primary,
2425
loading,
@@ -121,7 +122,8 @@ const ChatItem = memo<ChatItemProps>((props) => {
121122
className={`${cx(styles.actions, `${prefixClass}-list-item-actions`)}`}
122123
/>
123124
);
124-
return chatItemRenderConfig?.actionsRender?.(props, dom) || dom;
125+
126+
return chatItemRenderConfig?.actionsRender?.(props, dom, actionsClick) || dom;
125127
}, [actions]);
126128

127129
const titleDom = useMemo(() => {

src/ChatItem/type.ts

+13-1
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,27 @@
11
import { ReactNode } from 'react';
22

3+
import { ActionEvent } from '@/ActionIconGroup';
34
import { ActionsProps } from '@/ChatList/ActionsBar';
45
import { EditableMessageProps } from '@/EditableMessage';
56
import { ChatMessageError, DivProps, MetaData } from '@/types';
67
import { MarkdownProps } from '@ant-design/pro-editor';
78

89
export type WithFalse<T> = T | false;
910

11+
export type actionsClickProps = {
12+
onStartEdit: () => void;
13+
onFinishEdit: () => void;
14+
onClick: (actionKey: ActionEvent) => void;
15+
};
1016
export interface ChatItemProps<T = Record<string, any>> {
1117
/**
1218
* @description Actions to be displayed in the chat item
1319
*/
1420
actions?: ReactNode;
21+
/**
22+
* @description Actions click props,only use in render
23+
*/
24+
actionsClick?: actionsClickProps;
1525
/**
1626
* @description Metadata for the avatar
1727
*/
@@ -88,7 +98,9 @@ export interface ChatItemProps<T = Record<string, any>> {
8898
chatItemRenderConfig?: {
8999
titleRender?: WithFalse<(props: ChatItemProps, defaultDom: ReactNode) => ReactNode>;
90100
contentRender?: WithFalse<(props: ChatItemProps, defaultDom: ReactNode) => ReactNode>;
91-
actionsRender?: WithFalse<(props: ChatItemProps, defaultDom: ReactNode) => ReactNode>;
101+
actionsRender?: WithFalse<
102+
(props: ChatItemProps, defaultDom: ReactNode, actionsClick: actionsClickProps) => ReactNode
103+
>;
92104
avatarRender?: WithFalse<(props: ChatItemProps, defaultDom: ReactNode) => ReactNode>;
93105
render?: WithFalse<
94106
(

src/ChatList/ChatListItem.tsx

+18-10
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ const ChatListItem = (props: ChatListItemProps) => {
192192
/**
193193
* 渲染操作按钮的函数。
194194
* @param data 聊天消息的数据。
195-
* @returns 渲染操作按钮的组件
195+
* @returns 渲染操作按钮的配置项
196196
*/
197197
const Actions = useRefFunction(({ data }: { data: ChatMessage }) => {
198198
if (!renderActions || !item?.role) return;
@@ -216,14 +216,21 @@ const ChatListItem = (props: ChatListItemProps) => {
216216
onActionsClick?.(action, data);
217217
};
218218

219-
return (
220-
<RenderFunction
221-
{...data}
222-
onActionClick={(actionKey) => handleActionClick?.(actionKey, data)}
223-
text={text}
224-
actionsProps={chatItemRenderConfig?.actionsProps?.[item.role]}
225-
/>
226-
);
219+
return {
220+
click: {
221+
onStartEdit: () => setEditing(true),
222+
onFinishEdit: () => setEditing(false),
223+
onClick: (actionKey) => handleActionClick?.(actionKey, data),
224+
},
225+
components: (
226+
<RenderFunction
227+
{...data}
228+
onActionClick={(actionKey) => handleActionClick?.(actionKey, data)}
229+
text={text}
230+
actionsProps={chatItemRenderConfig?.actionsProps?.[item.role]}
231+
/>
232+
),
233+
};
227234
});
228235

229236
/**
@@ -243,7 +250,8 @@ const ChatListItem = (props: ChatListItemProps) => {
243250
<ChatItem
244251
className={chatItemClassName}
245252
data-id={item.id}
246-
actions={<Actions data={item} />}
253+
actions={Actions({ data: item }).components}
254+
actionsClick={Actions({ data: item }).click}
247255
avatar={(item as any).meta}
248256
avatarAddon={groupNav}
249257
editing={editing}

src/ChatList/index.tsx

+2
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,8 @@ const ChatList = memo<ChatListProps>(
9595
type,
9696
};
9797

98+
console.log('renderItems', renderItems);
99+
98100
const historyLength = data.length;
99101
const enableHistoryDivider =
100102
enableHistoryCount &&
+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/**
2+
* compact: true
3+
*/
4+
import { ProChat } from '@ant-design/pro-chat';
5+
import { useTheme } from 'antd-style';
6+
7+
import { Button } from 'antd';
8+
import { MockResponse } from '../mocks/streamResponse';
9+
10+
export default () => {
11+
const theme = useTheme();
12+
13+
return (
14+
<div style={{ background: theme.colorBgLayout }}>
15+
<ProChat
16+
chatItemRenderConfig={{
17+
actionsRender: (props, dom, actionsProps) => {
18+
if (props?.editing) {
19+
return null;
20+
}
21+
return (
22+
<Button
23+
type="default"
24+
onClick={() => {
25+
actionsProps?.onStartEdit();
26+
}}
27+
>
28+
Start Editing
29+
</Button>
30+
);
31+
},
32+
}}
33+
request={async (messages) => {
34+
const mockedData: string = `这是一段模拟的流式字符串数据。本次会话传入了${messages.length}条消息`;
35+
36+
const mockResponse = new MockResponse(mockedData);
37+
38+
return mockResponse.getResponse();
39+
}}
40+
/>
41+
</div>
42+
);
43+
};

src/ProChat/index.en-US.md

+8
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,14 @@ ProChat uses `meta` to represent the avatars, names, and other information of bo
7878

7979
<code src="./demos/actions.tsx"></code>
8080

81+
## Customize Item Actions
82+
83+
You can use the actionsRender parameter under ChatItemConfig to complete the Actions configuration for each Item
84+
85+
> We do not recommend that you modify it. If you do not want it, you can directly delete this function and write it yourself using render.
86+
87+
<code src="./demos/actions-chat-item.tsx"></code>
88+
8189
## Customize the [Back to Bottom] button
8290

8391
You can customize the [Back to Bottom] button to varying degrees through the backToBottomConfiguration parameter

src/ProChat/index.md

+8
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,14 @@ ProChat 使用 `meta` 来表意会话双方的头像、名称等信息。设定
8888

8989
<code src="./demos/actions.tsx"></code>
9090

91+
## 自定义 Item 的 Actions
92+
93+
你可以使用 ChatItemConfig 下的 actionsRender 参数来完成每一个 Item 的 Actions 配置
94+
95+
> 我们并不建议你去修改,如果不想要可以直接删除这块功能自己用 render 来写
96+
97+
<code src="./demos/actions-chat-item.tsx"></code>
98+
9199
## 自定义「回到底部」按钮
92100

93101
你可以通过 backToBottomConfig 参数对「回到底部」按钮进行不同程度的自定义

0 commit comments

Comments
 (0)