Skip to content

Conversation

leshalv
Copy link
Contributor

@leshalv leshalv commented Sep 12, 2025

Fix ProFormUploadButton TS2786: ProFormUploadButton cannot be used as a JSX component.

Summary by CodeRabbit

  • 重构
    • 优化上传按钮组件内部实现,移除多余包装并简化引用传递链路,提升可维护性与一致性;对外接口与交互保持不变。
  • 性能
    • 减少一层组件包装,略微降低装载与渲染开销,运行更为轻量。

Copy link

coderabbitai bot commented Sep 12, 2025

Important

Review skipped

Review was skipped due to path filters

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml

CodeRabbit blocks several paths by default. You can override this behavior by explicitly including those paths in the path filters. For example, including **/dist/** will override the default block on the dist directory, by removing the pattern from both the lists.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

📝 Walkthrough

Walkthrough

src/form/components/UploadButton/index.tsx 中,将传递给 warpField 的内部组件由外部包裹的 React.forwardRef(BaseProFormUploadButton) 改为直接使用已在内部通过 React.forwardRef 包裹的 BaseProFormUploadButton。其他选项、值提取与渲染逻辑未变,公开 API 签名不变。

Changes

Cohort / File(s) Change Summary
上传按钮封装调整
src/form/components/UploadButton/index.tsx
将内部组件声明改为在组件内使用 React.forwardRef(即 BaseProFormUploadButton 为已包裹的 forwardRef 组件),并直接将该组件传入 warpField;保留原有 options、value 提取、渲染(包括 handlePreview/getBase64、showUploadButton、isPictureCard、Upload props、Button 与 Image preview)与对外类型/签名不变。

Sequence Diagram(s)

sequenceDiagram
    autonumber
    participant Caller as 使用方
    participant Warp as warpField
    participant Comp as BaseProFormUploadButton
    Note left of Comp #DFF2E1: Comp 包含内部 React.forwardRef
    Caller->>Warp: 请求包裹组件(组件参数)
    Warp->>Comp: 渲染传入组件
    Comp-->>Warp: 返回渲染结果 (含 ref 转发内部处理)
    Warp-->>Caller: 返回包裹后的表单字段组件
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Pre-merge checks (3 passed)

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed 标题 "fix(form): ProFormUploadButton warning" 简洁且遵循 conventional commit 风格,直接表明这是对 form 模块中 ProFormUploadButton 警告的修复。PR 摘要与目标显示该变更通过调整内部 forwardRef 实现来解决 TypeScript 的 TS2786 问题,因此标题与主要改动一致且相关。标题无多余噪音,能让审阅者快速理解此次提交的目的。
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.

Poem

我是小兔敲键盘,耳朵像天线般
轻拂一层 forwardRef,路径更直更轻安
warpField 点点头,上传按钮仍如常
字节跳跃无声处,胡萝卜也香甜 🥕
(\_/) 代码稳,(•̀ᴗ•́)و 勇往前

Pre-merge checks (3 passed)

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed 标题 "fix(form): ProFormUploadButton warning" 简洁且遵循 conventional commit 风格,直接表明这是对 form 模块中 ProFormUploadButton 警告的修复。PR 摘要与目标显示该变更通过调整内部 forwardRef 实现来解决 TypeScript 的 TS2786 问题,因此标题与主要改动一致且相关。标题无多余噪音,能让审阅者快速理解此次提交的目的。
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@dosubot dosubot bot added the size:XS This PR changes 0-9 lines, ignoring generated files. label Sep 12, 2025
Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary of Changes

Hello @leshalv, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request addresses and resolves a TypeScript compilation error (TS2786) related to the ProFormUploadButton component. The fix involves a minor but crucial adjustment in how the component is wrapped, ensuring it correctly integrates with the warpField higher-order component without causing type conflicts. This change improves the stability and type-safety of the form components.

Highlights

  • TypeScript Error Fix: Resolved a TS2786 TypeScript error that prevented ProFormUploadButton from being correctly used as a JSX component.
  • Component Definition Refinement: Simplified the definition of ProFormUploadButton by removing a redundant React.forwardRef call, as the BaseProFormUploadButton already handles ref forwarding.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in issue comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@leshalv
Copy link
Contributor Author

leshalv commented Sep 12, 2025

#9159

@dosubot dosubot bot added the form label Sep 12, 2025
Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request aims to fix a TypeScript warning TS2786 for ProFormUploadButton. The change involves removing React.forwardRef when wrapping the base component. However, my review found that this change likely introduces a new issue, as the warpField higher-order component expects a full React component, not a render function. The root cause of the original warning appears to be an incorrect type assertion on a line not included in this diff. I've left a specific comment with a suggestion to revert the current change.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/form/components/UploadButton/index.tsx (1)

170-176: 将导出断言改为 ForwardRefExoticComponent(避免 TS2786)

已验证:warpField 的签名接受 React.ForwardRefExoticComponent

(src/form/components/FormItem/warpField.tsx:59–62);src/form/components/UploadButton/index.tsx 当前用 as typeof BaseProFormUploadButton 断言可能触发 TS2786,按下方改为断言为 ForwardRefExoticComponent 或 ComponentType。

-const ProFormUploadButton = warpField<ProFormUploadButtonProps>?.(
-  BaseProFormUploadButton,
-  {
-    getValueFromEvent: (value: { fileList: UploadProps['fileList'] }) =>
-      value.fileList,
-  },
-) as typeof BaseProFormUploadButton;
+type ProFormUploadButtonComponent = React.ForwardRefExoticComponent<
+  ProFormUploadButtonProps & React.RefAttributes<any>
+>;
+const ProFormUploadButton = warpField<ProFormUploadButtonProps>(
+  BaseProFormUploadButton,
+  {
+    getValueFromEvent: (value: { fileList: UploadProps['fileList'] }) =>
+      value.fileList,
+  },
+) as ProFormUploadButtonComponent;
🧹 Nitpick comments (3)
src/form/components/UploadButton/index.tsx (3)

122-130: listType 传递不一致:Upload 忽略了 fieldProps.listType

isPictureCard 用了 (listType ?? fieldProps?.listType),但传给 <Upload> 的是 listType || 'picture',导致当只设置了 fieldProps.listType="picture-card" 时,UI 判断与实际渲染不一致。

建议统一计算并复用:

-const isPictureCard = (listType ?? fieldProps?.listType) === 'picture-card';
+const resolvedListType = listType ?? fieldProps?.listType ?? 'picture';
+const isPictureCard = resolvedListType === 'picture-card';
...
-  listType={listType || 'picture'}
+  listType={resolvedListType}

140-143: 可访问性:picture-card 模式的触发元素缺少按钮语义与键盘可达性

<span> 作为上传触发元素时没有语义/可聚焦/键盘触发支持,不利于 A11y。建议补充语义与键盘交互。

-<span>
+<span
+  role="button"
+  tabIndex={0}
+  aria-label={typeof title === 'string' ? title : '上传'}
+  onKeyDown={(e) => {
+    if (e.key === 'Enter' || e.key === ' ') {
+      e.preventDefault();
+      (e.currentTarget as HTMLElement).click();
+    }
+  }}
+>
  {icon} {title}
</span>

154-156: 样式:避免内联样式,使用类名隐藏容器

为符合项目样式约定,避免内联样式。若可行,使用类名(如 Tailwind 的 hidden 或 antd 的 wrapperClassName)替代。

-  wrapperStyle={{ display: 'none' }}
+  wrapperClassName="hidden"

如当前 antd 版本不支持 wrapperClassName,可退回内联或使用 rootClassName,但建议统一到类名方案。

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f949426 and 8c40317.

📒 Files selected for processing (1)
  • src/form/components/UploadButton/index.tsx (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{tsx,jsx}

📄 CodeRabbit inference engine (.cursor/rules/react.mdc)

**/*.{tsx,jsx}: Use early returns whenever possible to make the code more readable.
Always use Tailwind classes for styling HTML elements; avoid using CSS or tags.
Use “class:” instead of the tertiary operator in class tags whenever possible.
Use descriptive variable and function/const names. Also, event functions should be named with a “handle” prefix, like “handleClick” for onClick and “handleKeyDown” for onKeyDown.
Implement accessibility features on elements. For example, a tag should have a tabindex=“0”, aria-label, on:click, and on:keydown, and similar attributes.
Use consts instead of functions, for example, “const toggle = () =>”. Also, define a type if possible.

Files:

  • src/form/components/UploadButton/index.tsx

@dosubot dosubot bot added size:L This PR changes 100-499 lines, ignoring generated files. and removed size:XS This PR changes 0-9 lines, ignoring generated files. labels Sep 12, 2025
Copy link

@coderabbitai coderabbitai bot left a 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

♻️ Duplicate comments (2)
src/form/components/UploadButton/index.tsx (2)

172-178: 移除多余可选链并修正断言目标类型,避免把结果错误收窄为 Base 的类型

这里的 warpField?. 没必要;同时把结果断言为 typeof BaseProFormUploadButton(尤其在 Base 被错误标注为 React.FC 时)容易再次引发 TS2786。建议断言到更准确的 ForwardRefExoticComponent 形态,或在确保类型正确后直接去掉断言。

-const ProFormUploadButton = warpField<ProFormUploadButtonProps>?.(
+const ProFormUploadButton = warpField<ProFormUploadButtonProps>(
   BaseProFormUploadButton,
   {
     getValueFromEvent: (value: { fileList: UploadProps['fileList'] }) =>
       value.fileList,
   },
-) as typeof BaseProFormUploadButton;
+) as React.ForwardRefExoticComponent<
+  ProFormUploadButtonProps & React.RefAttributes<HTMLElement>
+>;

83-101: 修正组件类型:React.FC 与 forwardRef 返回类型不兼容,导致 TS2786 隐患

React.forwardRef 返回的是 React.ForwardRefExoticComponent,不应赋值给 React.FC。请直接用带泛型的 forwardRef 定义基础组件,并补充 displayName,避免后续在 JSX 场景下再次触发 “cannot be used as a JSX component”。

-const BaseProFormUploadButton: React.FC<ProFormUploadButtonProps> =
-  React.forwardRef(
+const BaseProFormUploadButton = React.forwardRef<HTMLElement, ProFormUploadButtonProps>(
     (
       {
         fieldProps,
         action,
         accept,
         listType,
         title = '单击上传',
         max,
         icon = <UploadOutlined />,
         buttonProps,
         disabled,
         proFieldProps,
         imageProps,
         ...restProps
       },
       ref,
     ) => {
       ...
-    },
-  );
+    },
+);
+BaseProFormUploadButton.displayName = 'BaseProFormUploadButton';
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8c40317 and 11209c5.

📒 Files selected for processing (1)
  • src/form/components/UploadButton/index.tsx (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{tsx,jsx}

📄 CodeRabbit inference engine (.cursor/rules/react.mdc)

**/*.{tsx,jsx}: Use early returns whenever possible to make the code more readable.
Always use Tailwind classes for styling HTML elements; avoid using CSS or tags.
Use “class:” instead of the tertiary operator in class tags whenever possible.
Use descriptive variable and function/const names. Also, event functions should be named with a “handle” prefix, like “handleClick” for onClick and “handleKeyDown” for onKeyDown.
Implement accessibility features on elements. For example, a tag should have a tabindex=“0”, aria-label, on:click, and on:keydown, and similar attributes.
Use consts instead of functions, for example, “const toggle = () =>”. Also, define a type if possible.

Files:

  • src/form/components/UploadButton/index.tsx
🧬 Code graph analysis (1)
src/form/components/UploadButton/index.tsx (1)
src/form/components/FormItem/warpField.tsx (1)
  • warpField (59-376)
🔇 Additional comments (1)
src/form/components/UploadButton/index.tsx (1)

134-137: 确认 onChange 转发策略,避免忽略顶层 props.onChange

当前仅转发 fieldProps.onChange,顶层 props.onChange(已在类型中暴露)被忽略。请确认这与库内其他上传组件保持一致;如需兼容两处回调,可同时调用。

             onChange={(info) => {
               fieldProps?.onChange?.(info);
+              // 如需兼容顶层:
+              // (restProps as any)?.onChange?.(info);
             }}

Comment on lines +118 to +123
// 如果配置了 max ,并且 超过了文件列表的大小,就不展示按钮
const showUploadButton =
(max === undefined || !value || value?.length < max) && mode !== 'read';
const isPictureCard =
(listType ?? fieldProps?.listType) === 'picture-card';
return (
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

统一 listType 计算与传递的优先级,避免显示与实际不一致

isPictureCard 用的是 listType ?? fieldProps?.listType,但传入 <Upload> 时后续 {...fieldProps} 会覆盖前面的 listType。在同时传入两处时可能出现 UI 判断与实际渲染不一致。建议先计算一个最终值,统一用于判断与传参。

-      const isPictureCard =
-        (listType ?? fieldProps?.listType) === 'picture-card';
+      const resolvedListType =
+        (listType ?? fieldProps?.listType) ?? 'picture';
+      const isPictureCard = resolvedListType === 'picture-card';
       return (
         <>
           <Upload
             action={action}
             accept={accept}
             ref={ref}
-            listType={listType || 'picture'}
+            listType={resolvedListType}
             fileList={value}
             onPreview={handlePreview}
             {...fieldProps}

Also applies to: 124-152

🤖 Prompt for AI Agents
In src/form/components/UploadButton/index.tsx around lines 118-152, the
component computes isPictureCard using (listType ?? fieldProps?.listType) but
then spreads {...fieldProps} into <Upload> which can override listType and cause
mismatch between the UI check and actual render; compute a single finalListType
(e.g. const finalListType = fieldProps?.listType ?? listType ?? default) and use
that for isPictureCard and explicitly pass listType={finalListType} into the
<Upload> props (ensure the explicit prop comes after any spread so it wins), or
remove listType from the spread to avoid conflicts, applying the same fix to the
related code in lines 124-152.

@chenshuai2144
Copy link
Contributor

ci 挂了

@leshalv
Copy link
Contributor Author

leshalv commented Sep 15, 2025

ci 挂了

看起来像是npm没装上

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
form size:L This PR changes 100-499 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants