-
-
Notifications
You must be signed in to change notification settings - Fork 191
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Feat]支持 Sender 组件 content 自定义渲染,以支持类似的 speech 交互变体需求或者支持其他的content自定义渲染需求 #354
base: main
Are you sure you want to change the base?
Conversation
📝 Walkthrough📝 WalkthroughWalkthrough本次更改引入了新的功能和文档更新,包括为 Changes
Possibly related issues
Possibly related PRs
Suggested reviewers
📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Outside diff range and nitpick comments (4)
components/sender/demo/CustomContent.tsx (3)
6-12
: 建议完善接口属性的类型定义
CustomContentProps
接口缺少必要的属性注释,建议添加 TypeScript 文档注释来说明每个属性的用途。建议按照以下方式添加注释:
interface CustomContentProps { + /** 内部值 */ innerValue?: string; + /** 值变更回调 */ onValueChange?: (newValue: string) => void; + /** 提交回调 */ onSubmit?: () => void; + /** 加载状态 */ loading?: boolean; + /** 禁用状态 */ disabled?: boolean; }
33-40
: 建议优化动画性能当前实现中的动画可能会导致性能问题:
- 使用
transform
触发合成层优化- 考虑添加
will-change
属性建议修改样式实现:
const WaveBar = styled.div<{ delay: number }>` background-color: white; width: 6px; height: 24px; border-radius: 4px; + will-change: transform; animation: ${waveAnimation} 1s ease-in-out infinite; animation-delay: ${({ delay }) => delay}s; `;
145-149
: 建议添加组件测试当前实现缺少单元测试,建议添加测试用例覆盖以下场景:
- 录音状态切换
- 回调函数调用
- 错误处理
- 键盘操作
- 加载和禁用状态
需要我帮您生成测试用例代码吗?
components/sender/index.tsx (1)
266-268
: 建议:优化默认组件实现空的 div 作为默认组件实现可能不够优雅,建议考虑以下改进:
-const CustomContent = getComponent(components, ['content'], () => <div />); +const CustomContent = getComponent(components, ['content'], null);
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
components/sender/demo/CustomContent.md
(1 hunks)components/sender/demo/CustomContent.tsx
(1 hunks)components/sender/index.en-US.md
(1 hunks)components/sender/index.tsx
(3 hunks)components/sender/index.zh-CN.md
(1 hunks)package.json
(2 hunks)
✅ Files skipped from review due to trivial changes (1)
- components/sender/demo/CustomContent.md
🔇 Additional comments (6)
components/sender/index.zh-CN.md (1)
25-25
: 文档更新正确且完整!
新增的自定义内容示例与组件功能相符,文档结构清晰。
components/sender/index.en-US.md (1)
24-24
: 中英文文档保持一致!
英文文档的更新与中文文档同步,保持了文档的一致性。
package.json (2)
154-154
: 类型定义添加正确
@types/styled-components 作为开发依赖添加是正确的做法。
96-97
: 建议:验证 styled-components 的兼容性和性能影响
新增的 styled-components 依赖可能会对包大小和运行时性能产生影响。
✅ Verification successful
Let me analyze the usage and configuration before providing the final response.
styled-components 的使用和大小限制已得到验证
根据分析结果:
- 项目已设置了包大小限制(350 KiB),这个限制是合理的
- styled-components 仅在少数文件中使用,主要用于自定义内容渲染
- 没有发现重复导入的问题
建议可以安全地继续使用 styled-components,因为:
- 使用范围受控,不会造成全局性影响
- 项目有明确的包大小限制保护
- 文档中已包含相关使用说明
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# 检查包大小影响
npm run size-limit
# 检查是否有重复的 styled-components 安装
rg -A 3 "styled-components" package-lock.json
Length of output: 201
Script:
#!/bin/bash
# Check if styled-components is used in the codebase
rg -l "styled-components"
# Check for potential duplicate styled-components imports
ast-grep --pattern 'import $_ from "styled-components"'
# Check package size related configurations
fd "size" --type f --extension json
cat package.json | grep -A 5 -B 5 "size"
Length of output: 2922
components/sender/index.tsx (2)
24-25
: 接口设计合理
新增的 content 自定义组件接口设计清晰,并且提供了良好的 TypeScript 类型支持。
301-309
: 验证:确保事件处理的兼容性
需要验证自定义内容组件是否会影响现有的事件处理逻辑。
✅ Verification successful
事件处理逻辑已经过验证,无需担心兼容性问题
通过代码分析,我们可以确认:
InputTextArea
组件是从components
属性中获取的,默认使用Input.TextArea
- 事件处理逻辑保持一致:
onChange
事件正确处理文本输入onPressEnter
事件与onInternalKeyPress
正确绑定- 所有事件处理函数都经过适当的类型检查
自定义内容组件不会影响现有的事件处理逻辑,因为它是作为可选的替代渲染内容提供的。
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# 检查组件中的事件处理使用情况
ast-grep --pattern 'onChange={$_}'
Length of output: 36
Script:
#!/bin/bash
# 搜索事件处理相关的代码
rg "onChange|onPressEnter|onKeyPress" -A 3 -B 3
# 查找 InputTextArea 组件的使用
rg "InputTextArea" -A 5 -B 5
# 检查事件处理函数的定义
ast-grep --pattern 'function $_(e) {
$$$
}'
Length of output: 28376
const Demo: React.FC = () => { | ||
const { message } = App.useApp(); | ||
const [recording, setRecording] = useState(false); | ||
const [value, setValue] = useState<string>(''); | ||
|
||
return ( | ||
<Sender | ||
value={value} | ||
components={{ | ||
content: ({ onValueChange, onSubmit }: CustomContentProps) => ( | ||
<CustomSpeechBox | ||
recording={recording} | ||
onClick={() => { | ||
if (recording) { | ||
message.success('录音结束'); | ||
onValueChange?.(''); | ||
onSubmit?.(); | ||
} else { | ||
message.info('开始录音'); | ||
onValueChange?.('录音内容...'); | ||
} | ||
setRecording(!recording); | ||
}} | ||
> | ||
<SpeechContent> | ||
{recording ? ( | ||
<div style={{ textAlign: 'center' }}> | ||
<AudioWave> | ||
<WaveBar delay={0} /> | ||
<WaveBar delay={0.2} /> | ||
<WaveBar delay={0.4} /> | ||
<WaveBar delay={0.6} /> | ||
<WaveBar delay={0.8} /> | ||
</AudioWave> | ||
<RecordingText>正在听...</RecordingText> | ||
</div> | ||
) : ( | ||
<> | ||
<Dots>· · · ·</Dots> | ||
<SpeechContentText>可以开始说话了</SpeechContentText> | ||
</> | ||
)} | ||
</SpeechContent> | ||
</CustomSpeechBox> | ||
), | ||
}} | ||
actions={() => null} | ||
onChange={setValue} | ||
onSubmit={() => { | ||
message.success('语音消息已发送!'); | ||
}} | ||
/> | ||
); | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
需要增强错误处理和可访问性
主要问题:
- 缺少错误处理机制
- 缺少键盘操作支持
- 缺少适当的 ARIA 属性
- 缺少加载和禁用状态的处理
建议进行以下改进:
const Demo: React.FC = () => {
const { message } = App.useApp();
const [recording, setRecording] = useState(false);
const [value, setValue] = useState<string>('');
+ const [error, setError] = useState<string | null>(null);
return (
<Sender
value={value}
components={{
content: ({ onValueChange, onSubmit, loading, disabled }: CustomContentProps) => (
<CustomSpeechBox
recording={recording}
+ role="button"
+ tabIndex={0}
+ aria-label={recording ? "正在录音" : "点击开始录音"}
+ aria-disabled={disabled}
+ disabled={disabled}
+ onKeyDown={(e) => {
+ if (e.key === 'Enter' || e.key === ' ') {
+ e.preventDefault();
+ if (!disabled && !loading) {
+ // 触发点击事件
+ e.currentTarget.click();
+ }
+ }
+ }}
onClick={() => {
+ if (disabled || loading) return;
+
if (recording) {
message.success('录音结束');
onValueChange?.('');
onSubmit?.();
} else {
message.info('开始录音');
onValueChange?.('录音内容...');
}
setRecording(!recording);
}}
>
<SpeechContent>
{loading ? (
+ <LoadingIndicator />
+ ) : disabled ? (
+ <DisabledState />
+ ) : recording ? (
// ... 现有的录音状态UI
) : (
// ... 现有的非录音状态UI
)}
</SpeechContent>
</CustomSpeechBox>
),
}}
actions={() => null}
onChange={setValue}
onSubmit={() => {
message.success('语音消息已发送!');
}}
/>
);
};
Committable suggestion skipped: line range outside the PR's diff.
{/* 自定义 content 渲染 */} | ||
{CustomContent ? ( | ||
<CustomContent /> | ||
) : ( | ||
<InputTextArea | ||
{...inputProps} | ||
disabled={disabled} | ||
value={innerValue} | ||
onChange={(e) => triggerValueChange((e.target as HTMLTextAreaElement).value)} | ||
onPressEnter={onInternalKeyPress} | ||
variant="borderless" | ||
readOnly={readOnly} | ||
/> | ||
)} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
建议:改进条件渲染逻辑
当前的条件渲染逻辑可以更加简洁,同时建议添加错误边界处理。
- {/* 自定义 content 渲染 */}
- {CustomContent ? (
- <CustomContent />
- ) : (
- <InputTextArea
- {...inputProps}
- disabled={disabled}
- value={innerValue}
- onChange={(e) => triggerValueChange((e.target as HTMLTextAreaElement).value)}
- onPressEnter={onInternalKeyPress}
- variant="borderless"
- readOnly={readOnly}
- />
- )}
+ {/* 自定义 content 渲染 */}
+ <React.Suspense fallback={null}>
+ {CustomContent ? (
+ <ErrorBoundary>
+ <CustomContent />
+ </ErrorBoundary>
+ ) : (
+ <InputTextArea
+ {...inputProps}
+ disabled={disabled}
+ value={innerValue}
+ onChange={(e) => triggerValueChange((e.target as HTMLTextAreaElement).value)}
+ onPressEnter={onInternalKeyPress}
+ variant="borderless"
+ readOnly={readOnly}
+ />
+ )}
+ </React.Suspense>
Committable suggestion skipped: line range outside the PR's diff.
New and removed dependencies detected. Learn more about Socket for GitHub ↗︎
🚮 Removed packages: npm/[email protected], npm/[email protected] |
支持 Sender 组件 content 自定义渲染,以支持类似的 speech 交互变体需求或者支持其他的content自定义渲染需求
Link To : #290
Summary by CodeRabbit
新功能
文档
依赖更新
styled-components
和开发依赖@types/styled-components
。