Skip to content

Conversation

@kuangyaqin
Copy link

@kuangyaqin kuangyaqin commented Dec 1, 2025

中文版模板 / Chinese template

🤔 This is a ...

  • 🆕 New feature
  • 🐞 Bug fix
  • 📝 Site / documentation improvement
  • 📽️ Demo improvement
  • 💄 Component style improvement
  • 🤖 TypeScript definition improvement
  • 📦 Bundle size optimization
  • ⚡️ Performance optimization
  • ⭐️ Feature enhancement
  • 🌐 Internationalization
  • 🛠 Refactoring
  • 🎨 Code style optimization
  • ✅ Test Case
  • 🔀 Branch merge
  • ⏩ Workflow
  • ⌨️ Accessibility improvement
  • ❓ Other (about what?)

🔗 Related Issues

  • Describe the source of related requirements, such as links to relevant issue discussions.
  • For example: close #xxxx, fix #xxxx

💡 Background and Solution

  • The specific problem to be addressed.
  • List the final API implementation and usage if needed.
  • If there are UI/interaction changes, consider providing screenshots or GIFs.

📝 Change Log

Language Changelog
🇺🇸 English
🇨🇳 Chinese

Summary by CodeRabbit

发布说明

  • 新特性
    • 标签类型的槽位现已支持可选的关闭按钮功能,用户可点击按钮移除标签,配置和编辑器内容将自动更新。

✏️ Tip: You can customize this high-level summary in your review settings.

@github-actions
Copy link
Contributor

github-actions bot commented Dec 1, 2025

Prepare preview

@dosubot dosubot bot added the enhancement New feature or request label Dec 1, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 1, 2025

📝 Walkthrough

Walkthrough

为SlotTextArea组件中的tag类型插槽增强了关闭功能支持。通过扩展SlotConfigTagType接口添加allowClose属性,在renderSlot中实现关闭按钮逻辑,并在demo中演示了该功能的使用方式。

Changes

内聚块 / 文件 变更摘要
Tag类型插槽关闭功能实现
packages/x/components/sender/SlotTextArea.tsx
在renderSlot中添加调试日志,为allowClose为真的tag类型插槽渲染关闭控制按钮,实现标签移除、DOM元素清理和onChange回调触发
接口定义扩展
packages/x/components/sender/interface.ts
在SlotConfigTagType接口中添加可选的allowClose属性;SenderProps声明重新格式化,无语义变更
Demo配置演示
packages/x/components/sender/demo/agent.tsx
在AgentInfo.deep_search.slotConfig添加一个tag插槽;在AgentInfo.ai_code.slotConfig添加一个支持allowClose的tag插槽

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

  • 关闭按钮实现逻辑 - 验证onChange事件触发、DOM移除和配置更新的正确性
  • allowClose属性使用 - 确保demo中的配置与接口定义一致
  • 调试日志 - 确认console.log的必要性或是否应在生产代码中保留

Poem

🐰 标签又添新翅膀,关闭按钮轻轻放,
点击一下化清烟,插槽更新心欢畅!
代码整洁又优雅,梦想闪闪在远方。

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed PR标题清晰准确地总结了主要变更:为Sender组件插槽模式的tag标签添加可关闭功能,与代码变更内容完全对应。
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @kuangyaqin, 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!

此拉取请求旨在增强 Sender 组件的插槽模式功能,特别是为 tag 类型插槽引入了可关闭选项。这一改进提升了用户在编辑内容时对标签的交互和管理能力,使得用户可以更灵活地控制和移除已插入的标签,从而优化了整体的用户体验。

Highlights

  • 标签插槽可关闭功能: 为 Sender 组件的插槽模式中的 tag 类型标签添加了可关闭功能。用户现在可以通过点击标签上的“×”图标来移除标签。
  • 接口更新: 在 SlotConfigTagType 接口中新增了 allowClose?: boolean 属性,用于控制标签是否可关闭。
  • 逻辑实现: 在 SlotTextArea.tsx 中实现了标签关闭的逻辑,包括从配置中移除、从 DOM 中移除以及更新编辑器状态。
  • 示例更新: 在 demo/agent.tsx 中更新了示例配置,展示了如何使用带有可关闭功能的 tag 类型插槽。
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 by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

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 pull request 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.

Copy link
Contributor

@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

你好,感谢你的贡献!这个PR为Sender组件中的tag类型插槽增加了可关闭的功能。代码实现很直接,但在onClick事件处理器中存在一些实践上的问题。

主要的反馈点如下:

  1. SlotTextArea.tsx中,关闭标签的onClick事件处理器直接操作了DOM并修改了ref。这是一种脆弱的实现方式,可能会导致UI状态不一致。建议采用更符合React模式的方法,通过父组件的状态更新来驱动DOM变化。
  2. 代码中残留了一个用于调试的console.log语句,建议在合并前移除。

详细的建议请见具体的代码审查评论。总的来说,功能是好的,但实现方式可以更健壮、更易于维护。

Comment on lines +205 to +217
onClick={(e) => {
e.stopPropagation();
// 从配置中移除
slotConfigRef.current = slotConfigRef.current.filter(
(item) => item.key !== node.key,
);
// 从DOM中移除
const slotDom = getSlotDom(node.key as string);
slotDom?.parentNode?.removeChild(slotDom);
// 更新状态
const newValue = getEditorValue();
onChange?.(newValue.value, undefined, newValue.config);
}}
Copy link
Contributor

Choose a reason for hiding this comment

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

high

这个 onClick 处理器直接修改了DOM (removeChild) 和一个React ref (slotConfigRef.current)。这种做法比较脆弱,并且违反了React的单向数据流原则,可能导致难以预料的bug。

  1. 直接DOM操作: slotDom?.parentNode?.removeChild(slotDom) 会导致React的虚拟DOM和真实DOM之间出现不一致。如果父组件没有正确地通过onChange回调更新slotConfig prop来触发重渲染,UI就会处于一个损坏的状态。
  2. Ref突变: 对slotConfigRef.current的直接修改是多余的,因为getEditorValue()会从DOM中重新生成配置,并且这个ref会在slotConfig prop变化时被重置。这使得代码的意图变得不清晰。

建议重构此逻辑,避免在事件处理器中直接操作DOM和ref。一个更安全的方式是,在临时修改DOM以计算新值后,立即恢复DOM,然后通过onChange将新的配置和值传递给父组件,由父组件来驱动UI的更新。

const renderSlot = (node: SlotConfigType, slotSpan: HTMLSpanElement) => {
if (!node.key) return null;
const value = getSlotValues()[node.key];
console.log(node, 'nodeqqqqq');
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

这里有一个 console.log 语句,可能是用于调试的。在合并到主分支之前,建议将其移除,以保持代码库的整洁。

Copy link
Contributor

@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: 1

🧹 Nitpick comments (2)
packages/x/components/sender/SlotTextArea.tsx (1)

199-223: tag 的 allowClose 关闭逻辑整体正确,但建议同步清理相关状态

当前关闭逻辑能正确:

  • slotConfigRef.current 里移除配置;
  • 从 DOM 中移除对应的 slotSpan
  • 调用 onChange 通知外部。

但同时还保留了与该 tag 相关的内部状态(如 slotDomMapslotPlaceholders,以及通过 getSlotValues() 维护的值),可能导致:

  • 残留的 portal 继续存在于 slotPlaceholders 中,白占内存;
  • 内部状态与实际 DOM 不完全一致。

建议在关闭时一并清理这些映射,类似:

        case 'tag':
           return (
             <div className={`${prefixCls}-slot-tag`}>
               {node.props?.label || ''}
               {node.allowClose && (
                 <span
                   className={`${prefixCls}-slot-tag-close`}
                   onClick={(e) => {
                     e.stopPropagation();
-                    // 从配置中移除
-                    slotConfigRef.current = slotConfigRef.current.filter(
-                      (item) => item.key !== node.key,
-                    );
-                    // 从DOM中移除
-                    const slotDom = getSlotDom(node.key as string);
-                    slotDom?.parentNode?.removeChild(slotDom);
-                    // 更新状态
+                    const slotKey = node.key as string;
+                    // 从配置中移除
+                    slotConfigRef.current = slotConfigRef.current.filter(
+                      (item) => item.key !== slotKey,
+                    );
+                    // 从 DOM 中移除并清理映射
+                    const slotDom = getSlotDom(slotKey);
+                    slotDom?.parentNode?.removeChild(slotDom);
+                    slotDomMap.current.delete(slotKey);
+                    setSlotPlaceholders((prev) => {
+                      const newMap = new Map(prev);
+                      newMap.delete(slotKey);
+                      return newMap;
+                    });
+                    // 同步清理该 slot 的值
+                    setSlotValues((prev) => {
+                      const next = { ...prev };
+                      delete next[slotKey];
+                      return next;
+                    });
+                    // 更新状态
                     const newValue = getEditorValue();
                     onChange?.(newValue.value, undefined, newValue.config);
                   }}
                 >
                   ×
                 </span>
               )}
             </div>
           );

另外,若后续有精力,可以考虑将关闭图标改为具有 role="button" 或使用真正的按钮组件,并支持键盘触发,以提升可访问性。

packages/x/components/sender/demo/agent.tsx (1)

63-71: ai_code 场景的可关闭 tag 示例清晰,可考虑同步强化 Files 动态 tag 的行为一致性

这一项 { type: 'tag', key: 'tag_type', allowClose: true, ... } 很好地演示了新加的 allowClose 能力,示例本身没有问题。

为了让示例行为更加统一,也可以考虑让下方 fileItemClick 中动态插入的文件 tag 同样支持关闭,例如:

  const fileItemClick: MenuProps['onClick'] = (item) => {
    const { icon, label } = FileInfo[item.key];
    senderRef.current?.insert?.([
      {
        type: 'tag',
        key: `${item.key}_${Date.now()}`,
+       allowClose: true,
        props: {
          label: (
            <Flex gap="small">
              {icon}
              {label}
            </Flex>
          ),
          value: item.key,
        },
      },
    ]);
  };

这样 demo 中所有 tag 插槽的交互能力会更加一致,也更直观展示 allowClose 的用途。

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 48d5344 and f9990c7.

📒 Files selected for processing (3)
  • packages/x/components/sender/SlotTextArea.tsx (2 hunks)
  • packages/x/components/sender/demo/agent.tsx (2 hunks)
  • packages/x/components/sender/interface.ts (2 hunks)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: afc163
Repo: ant-design/x PR: 0
File: :0-0
Timestamp: 2025-04-11T14:47:09.527Z
Learning: 当评审 ant-design/x 仓库中的 PR 时,需要用中文回复中文评论。该项目的文档支持中英双语。
Learnt from: afc163
Repo: ant-design/x PR: 0
File: :0-0
Timestamp: 2025-04-11T14:47:09.527Z
Learning: 当评审 ant-design/x 仓库中的 PR 时,需要用中文回复中文评论。该项目的文档支持中英双语。
🔇 Additional comments (3)
packages/x/components/sender/interface.ts (2)

63-71: 为 tag 插槽增加 allowClose 字段的类型设计是合理的

allowClose?: boolean 放在 SlotConfigTagType 上,与后续在 SlotTextArea 中通过 node.allowClose 控制是否展示关闭按钮的实现保持一致,向下兼容已有配置,类型上没有明显问题。


101-104: SenderProps 的 Pick 拆行只影响格式,不影响行为

这里对 SenderPropsextends Pick<TextareaProps, ...> 仅做了排版调整,没有增加或删除字段,类型行为保持不变,可以接受。

packages/x/components/sender/demo/agent.tsx (1)

39-46: deep_search 场景新增只读 tag 配置是合理的

这里新增的 { type: 'tag', key: 'tag_type', props: { value: 'tag1', label: 'tag 1' } }SlotConfigTagType 定义完全匹配,未开启 allowClose,可以很好地作为纯展示型 tag 示例。

const renderSlot = (node: SlotConfigType, slotSpan: HTMLSpanElement) => {
if (!node.key) return null;
const value = getSlotValues()[node.key];
console.log(node, 'nodeqqqqq');
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

请移除调试用的 console.log

console.log(node, 'nodeqqqqq'); 属于调试残留,保留在组件库中会污染使用方控制台输出,建议删除或改为受控的调试开关。

🤖 Prompt for AI Agents
In packages/x/components/sender/SlotTextArea.tsx around line 143, there is a
leftover debugging statement `console.log(node, 'nodeqqqqq');` that should be
removed from the production component; delete this line (or replace it with a
controlled debug/logging mechanism—e.g., use the library's logger or a
conditional debug flag driven by env or props) so the component no longer
pollutes consumers' consoles.

@kimteayon
Copy link
Collaborator

特性功能需要提交到feature

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants