From ac2dcf55ae0164239b2b223bf3a5cdff8c0f204f Mon Sep 17 00:00:00 2001 From: LofiSu Date: Fri, 13 Dec 2024 22:57:21 +0800 Subject: [PATCH] =?UTF-8?q?[Feat]=E6=94=AF=E6=8C=81=20Sender=20=E7=BB=84?= =?UTF-8?q?=E4=BB=B6=20content=20=E8=87=AA=E5=AE=9A=E4=B9=89=E6=B8=B2?= =?UTF-8?q?=E6=9F=93=EF=BC=8C=E4=BB=A5=E6=94=AF=E6=8C=81=E7=B1=BB=E4=BC=BC?= =?UTF-8?q?=E7=9A=84=20speech=20=E4=BA=A4=E4=BA=92=E5=8F=98=E4=BD=93?= =?UTF-8?q?=E9=9C=80=E6=B1=82=E6=88=96=E8=80=85=E6=94=AF=E6=8C=81=E5=85=B6?= =?UTF-8?q?=E4=BB=96=E7=9A=84content=E8=87=AA=E5=AE=9A=E4=B9=89=E6=B8=B2?= =?UTF-8?q?=E6=9F=93=E9=9C=80=E6=B1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/sender/demo/CustomContent.md | 7 ++ components/sender/demo/CustomContent.tsx | 149 +++++++++++++++++++++++ components/sender/index.en-US.md | 1 + components/sender/index.tsx | 39 +++--- components/sender/index.zh-CN.md | 1 + package.json | 4 +- 6 files changed, 180 insertions(+), 21 deletions(-) create mode 100644 components/sender/demo/CustomContent.md create mode 100644 components/sender/demo/CustomContent.tsx diff --git a/components/sender/demo/CustomContent.md b/components/sender/demo/CustomContent.md new file mode 100644 index 00000000..45c1006b --- /dev/null +++ b/components/sender/demo/CustomContent.md @@ -0,0 +1,7 @@ +## zh-CN + +通过 `content` 自定义内容组件,从而实现自定义内容渲染。 + +## en-US + +Customize the content component to achieve custom content rendering. diff --git a/components/sender/demo/CustomContent.tsx b/components/sender/demo/CustomContent.tsx new file mode 100644 index 00000000..2a6e6901 --- /dev/null +++ b/components/sender/demo/CustomContent.tsx @@ -0,0 +1,149 @@ +import { Sender } from '@ant-design/x'; +import { App } from 'antd'; +import React, { useState } from 'react'; +import styled, { keyframes } from 'styled-components'; + +interface CustomContentProps { + innerValue?: string; + onValueChange?: (newValue: string) => void; + onSubmit?: () => void; + loading?: boolean; + disabled?: boolean; +} + +const waveAnimation = keyframes` + 0% { + transform: scaleY(0.5); + } + 50% { + transform: scaleY(1.2); + } + 100% { + transform: scaleY(0.5); + } +`; + +const AudioWave = styled.div` + display: flex; + align-items: center; + justify-content: center; + gap: 4px; +`; + +const WaveBar = styled.div<{ delay: number }>` + background-color: white; + width: 6px; + height: 24px; + border-radius: 4px; + animation: ${waveAnimation} 1s ease-in-out infinite; + animation-delay: ${({ delay }) => delay}s; +`; + +const RecordingText = styled.div` + font-size: 14px; + color: white; + margin-top: 8px; + text-align: center; +`; + +const CustomSpeechBox = styled.div<{ recording: boolean }>` + display: flex; + align-items: center; + justify-content: center; + padding: 12px; + width: 100%; + height: 50px; + background: linear-gradient(180deg, #f7f7f7, #e5e5e5); + border-radius: 12px; + box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); + cursor: pointer; + + ${({ recording }) => + recording && + ` + background: linear-gradient(180deg, #d3e5ff, #b3d4ff); + `} +`; + +const SpeechContent = styled.div` + display: flex; + justify-content: center; + align-items: center; + flex-direction: column; +`; + +const Dots = styled.div` + font-size: 18px; + color: black; + font-weight: bold; + text-align: center; +`; + +const SpeechContentText = styled.p` + margin: 4px 0 0; + font-size: 14px; + color: black; + font-weight: 500; + text-align: center; +`; + +const Demo: React.FC = () => { + const { message } = App.useApp(); + const [recording, setRecording] = useState(false); + const [value, setValue] = useState(''); + + return ( + ( + { + if (recording) { + message.success('录音结束'); + onValueChange?.(''); + onSubmit?.(); + } else { + message.info('开始录音'); + onValueChange?.('录音内容...'); + } + setRecording(!recording); + }} + > + + {recording ? ( +
+ + + + + + + + 正在听... +
+ ) : ( + <> + · · · · + 可以开始说话了 + + )} +
+
+ ), + }} + actions={() => null} + onChange={setValue} + onSubmit={() => { + message.success('语音消息已发送!'); + }} + /> + ); +}; + +export default () => ( + + + +); diff --git a/components/sender/index.en-US.md b/components/sender/index.en-US.md index 2492ff98..14b0065d 100644 --- a/components/sender/index.en-US.md +++ b/components/sender/index.en-US.md @@ -21,6 +21,7 @@ coverDark: https://mdn.alipayobjects.com/huamei_iwk9zp/afts/img/A*cOfrS4fVkOMAAA Speech input Custom speech input Custom actions +Custom content Header panel Reference Adjust style diff --git a/components/sender/index.tsx b/components/sender/index.tsx index 61345e7a..e08084f3 100644 --- a/components/sender/index.tsx +++ b/components/sender/index.tsx @@ -21,6 +21,8 @@ type TextareaProps = GetProps; export interface SenderComponents { input?: CustomizeComponent; + /**Sender Content CustomizeComponent*/ + content?: CustomizeComponent; } export type ActionsRender = ( @@ -261,6 +263,9 @@ function Sender(props: SenderProps, ref: React.Ref) { } else if (actions) { actionNode = actions; } + // ============================ CustomContent ============================ + // 获取自定义的CustomContent组件(默认使用一个空的
占位) + const CustomContent = getComponent(components, ['content'], () =>
); // ============================ Render ============================ return wrapCSSVar( @@ -289,26 +294,20 @@ function Sender(props: SenderProps, ref: React.Ref) {
)} - {/* Input */} - { - triggerValueChange((e.target as HTMLTextAreaElement).value); - triggerSpeech(true); - }} - onPressEnter={onInternalKeyPress} - onCompositionStart={onInternalCompositionStart} - onCompositionEnd={onInternalCompositionEnd} - onKeyDown={onKeyDown} - onPaste={onInternalPaste} - variant="borderless" - readOnly={readOnly} - /> + {/* 自定义 content 渲染 */} + {CustomContent ? ( + + ) : ( + triggerValueChange((e.target as HTMLTextAreaElement).value)} + onPressEnter={onInternalKeyPress} + variant="borderless" + readOnly={readOnly} + /> + )} {/* Action List */}
语音输入 自定义语音输入 自定义按钮 +自定义内容 展开面板 引用 调整样式 diff --git a/package.json b/package.json index 54a693bb..22960140 100644 --- a/package.json +++ b/package.json @@ -93,7 +93,8 @@ "@babel/runtime": "^7.25.6", "classnames": "^2.5.1", "rc-motion": "^2.9.2", - "rc-util": "^5.43.0" + "rc-util": "^5.43.0", + "styled-components": "^6.1.13" }, "devDependencies": { "@ant-design/tools": "^18.0.2", @@ -150,6 +151,7 @@ "@types/react-resizable": "^3.0.8", "@types/semver": "^7.5.8", "@types/spinnies": "^0.5.3", + "@types/styled-components": "^5.1.34", "@types/tar": "^6.1.13", "@types/throttle-debounce": "^5.0.2", "@types/warning": "^3.0.3",