diff --git a/src/ProChat/components/InputArea/index.tsx b/src/ProChat/components/InputArea/index.tsx index abad93f..e899f41 100644 --- a/src/ProChat/components/InputArea/index.tsx +++ b/src/ProChat/components/InputArea/index.tsx @@ -1,12 +1,13 @@ import { SendOutlined } from '@ant-design/icons'; -import { Button, ConfigProvider } from 'antd'; +import { Button, ButtonProps, ConfigProvider } from 'antd'; import { createStyles, cx } from 'antd-style'; -import { ReactNode, useContext, useRef, useState } from 'react'; +import { ReactNode, useContext, useMemo, useRef, useState } from 'react'; import { Flexbox } from 'react-layout-kit'; import { useStore } from '../../store'; import { gLocaleObject } from '@/locale'; +import { TextAreaProps } from 'antd/es/input'; import ActionBar from './ActionBar'; import { AutoCompleteTextArea } from './AutoCompleteTextArea'; import StopLoadingIcon from './StopLoading'; @@ -59,7 +60,9 @@ export type ChatInputAreaProps = { inputRender?: ( defaultDom: ReactNode, onMessageSend: (message: string) => void | Promise, + defaultProps: TextAreaProps, ) => ReactNode; + sendButtonRender?: (defaultDom: ReactNode, defaultProps: ButtonProps) => ReactNode; inputAreaRender?: ( defaultDom: ReactNode, onMessageSend: (message: string) => void | Promise, @@ -68,7 +71,7 @@ export type ChatInputAreaProps = { }; export const ChatInputArea = (props: ChatInputAreaProps) => { - const { className, onSend, inputAreaRender, inputRender } = props || {}; + const { className, onSend, inputAreaRender, inputRender, sendButtonRender } = props || {}; const [ sendMessage, isLoading, @@ -106,40 +109,90 @@ export const ChatInputArea = (props: ChatInputAreaProps) => { const prefixClass = getPrefixCls('pro-chat-input-area'); - const defaultInput = ( - { - setMessage(e.target.value); - }} - autoSize={{ maxRows: 8 }} - onCompositionStart={() => { - isChineseInput.current = true; - }} - onCompositionEnd={() => { - isChineseInput.current = false; - }} - onPressEnter={(e) => { - if (!isLoading && !e.shiftKey && !isChineseInput.current) { - e.preventDefault(); - send(); - } - }} - /> - ); + /** + * 默认的自动完成文本区域属性 + * + * @property {string} placeholder - 输入框的占位符 + * @property {Object} inputAreaProps - 输入框的其他属性 + * @property {string} inputAreaProps.className - 输入框的类名 + * @property {string} prefixClass - 输入框的前缀类名 + * @property {string} value - 输入框的值 + * @property {function} onChange - 输入框值改变时的回调函数 + * @property {Object} autoSize - 输入框的自动调整大小配置 + * @property {number} autoSize.maxRows - 输入框的最大行数 + * @property {function} onCompositionStart - 输入法开始输入时的回调函数 + * @property {function} onCompositionEnd - 输入法结束输入时的回调函数 + * @property {function} onPressEnter - 按下回车键时的回调函数 + */ + + const defaultAutoCompleteTextAreaProps = { + placeholder: placeholder || gLocaleObject(locale).placeholder, + ...inputAreaProps, + className: cx(styles.input, inputAreaProps?.className, `${prefixClass}-component`), + value: message, + onChange: (e) => { + setMessage(e.target.value); + }, + autoSize: { maxRows: 8 }, + onCompositionStart: () => { + isChineseInput.current = true; + }, + onCompositionEnd: () => { + isChineseInput.current = false; + }, + onPressEnter: (e) => { + if (!isLoading && !e.shiftKey && !isChineseInput.current) { + e.preventDefault(); + send(); + } + }, + }; + + const defaultInput = ; /** * 支持下自定义输入框 */ const inputDom = inputRender - ? inputRender?.(defaultInput, (message) => { - sendMessage(message); - }) + ? inputRender?.( + defaultInput, + (message) => { + sendMessage(message); + }, + defaultAutoCompleteTextAreaProps, + ) : defaultInput; + /** + * 根据 isLoading 状态返回默认的按钮道具。 + * 如果 isLoading 为 true,则按钮将具有文本类型,即 stopGenerateMessage 点击处理程序, + * 和 StopLoadingIcon 作为图标。 + * 如果 isLoading 为 false,则按钮将具有文本类型、发送点击处理程序、 + * 和 SendOutlined 图标作为图标。 + * @returns The default button props. + */ + const defaultButtonProps = useMemo(() => { + return isLoading + ? ({ + type: 'text', + className: styles.btn, + onClick: () => stopGenerateMessage(), + icon: , + } as const) + : ({ + type: 'text', + className: styles.btn, + onClick: () => send(), + icon: , + } as const); + }, [isLoading]); + + const defaultButtonDom =