Skip to content

Conversation

@zombieJ
Copy link
Member

@zombieJ zombieJ commented Dec 1, 2025

fix ant-design/ant-design#56002

Summary by CodeRabbit

发布说明

  • 问题修复
    • 修复了动态改变 Select 下拉框后缀图标时导致下拉框意外关闭的问题。现在在修改后缀内容时,下拉框状态能够正确保持。

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

@vercel
Copy link

vercel bot commented Dec 1, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
select Ready Ready Preview Comment Dec 1, 2025 7:36am

@gemini-code-assist
Copy link

Summary of Changes

Hello @zombieJ, 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 resolves a bug in the Select component that caused its dropdown to close unexpectedly when a mouseDown event occurred on certain elements, particularly those that are dynamically rendered or hidden. The solution implements a targeted event marking system to prevent the global close logic from being triggered by these specific interactions, thereby improving the component's stability and user experience.

Highlights

  • Fix for unintended dropdown closure: Addresses an issue where mouseDown events on dynamically rendered or hidden elements within the Select component incorrectly triggered the dropdown to close.
  • Event marking mechanism: Introduces a new flag _ignore_global_close on the native event object to explicitly signal the useSelectTriggerControl hook to disregard specific mouseDown events for global close logic.
  • New test case: Adds a comprehensive test to ensure that dynamic icon changes within the Select component do not lead to unexpected dropdown closures.
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.

@codecov
Copy link

codecov bot commented Dec 1, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.41%. Comparing base (23fa3da) to head (72a709e).
⚠️ Report is 1 commits behind head on master.

Additional details and impacted files
@@           Coverage Diff           @@
##           master    #1178   +/-   ##
=======================================
  Coverage   99.41%   99.41%           
=======================================
  Files          31       31           
  Lines        1200     1202    +2     
  Branches      428      427    -1     
=======================================
+ Hits         1193     1195    +2     
  Misses          7        7           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 1, 2025

概览

此PR修复了Select组件在点击箭头图标时下拉菜单立即关闭的问题。通过在SelectInput中为事件标记_ignore_global_close标志,并在全局鼠标按下处理器中检查该标志,防止动态渲染的图标元素触发意外的关闭行为。

变更详情

文件/内容 变更摘要
Bug修复及测试
src/SelectInput/index.tsx
src/hooks/useSelectTriggerControl.ts
tests/Select.test.tsx
在SelectInput的onInternalMouseDown中设置事件的_ignore_global_close标志以标记不应触发全局关闭的事件。在useSelectTriggerControl的全局鼠标按下处理器中添加守卫条件,仅在弹出菜单打开且事件未被标记时才执行关闭逻辑。新增测试用例验证动态后缀图标变更不会导致下拉菜单意外关闭。

代码审查工作量估计

🎯 2 (简单) | ⏱️ ~12 分钟

  • 变更范围小且集中,涉及3个文件
  • 核心逻辑为添加事件标志和条件检查,属于同构变更模式
  • 建议重点关注:
    • useSelectTriggerControl.ts中新增守卫条件的准确性和完整性
    • 测试用例中mousedown事件的模拟方式是否能充分覆盖真实场景

可能相关的PR

  • fix: not prevent when child #1174:同样修改了SelectInput的onInternalMouseDown行为(一个改进对子元素点击的preventDefault处理,另一个设置_ignore_global_close标志并更新全局鼠标按下守卫),两者相互关联。

诗歌

🐰 箭头点击莫再逃,
旗帜标记显奥妙,
全局守卫把关好,
下拉菜单稳稳待,
搜索体验焕然新!

Pre-merge checks and finishing touches

✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 标题准确反映了变更的主要目的:防止隐藏元素上的鼠标按下事件触发选择器关闭。
Linked Issues check ✅ Passed 代码变更完全满足#56002的要求:通过添加_ignore_global_close标志防止点击动态图标时关闭下拉菜单。
Out of Scope Changes check ✅ Passed 所有变更都直接关联到修复问题#56002,没有发现超出范围的更改。
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
  • Commit unit tests in branch fix-mouse-down

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.

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: 0

🧹 Nitpick comments (1)
src/SelectInput/index.tsx (1)

175-179: 考虑更精确地限定标记范围

当前实现对 SelectInput 的所有 mouseDown 事件设置了 _ignore_global_close 标记,但根据关联 issue (#56002),问题仅出现在点击后缀图标(箭头)时。将此标记应用于所有点击可能会掩盖其他应该触发关闭的场景。

建议仅在点击后缀/图标区域时设置此标记:

 const onInternalMouseDown: SelectInputProps['onMouseDown'] = useEvent((event) => {
   if (!disabled) {
-    // https://github.com/ant-design/ant-design/issues/56002
-    // Tell `useSelectTriggerControl` to ignore this event
-    // When icon is dynamic render, the parentNode will miss
-    // so we need to mark the event directly
-    (event.nativeEvent as any)._ignore_global_close = true;

     const inputDOM = getDOM(inputRef.current);
     if (inputDOM && event.target !== inputDOM && !inputDOM.contains(event.target as Node)) {
+      // https://github.com/ant-design/ant-design/issues/56002
+      // Tell `useSelectTriggerControl` to ignore this event
+      // When icon is dynamic render, the parentNode will miss
+      // so we need to mark the event directly
+      (event.nativeEvent as any)._ignore_global_close = true;
       event.preventDefault();
     }

这样可以将标记限制在非输入区域的点击(如后缀图标),更符合修复的原始意图。

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 23fa3da and 72a709e.

📒 Files selected for processing (3)
  • src/SelectInput/index.tsx (1 hunks)
  • src/hooks/useSelectTriggerControl.ts (1 hunks)
  • tests/Select.test.tsx (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
tests/Select.test.tsx (1)
tests/utils/common.ts (1)
  • expectOpen (4-20)
🔇 Additional comments (2)
src/hooks/useSelectTriggerControl.ts (1)

22-25: 实现看起来正确

全局关闭的防护逻辑正确地检查了 _ignore_global_close 标记。这与 SelectInput 中的设置相匹配,可以防止在点击动态渲染元素时意外关闭。

可选的类型安全改进建议:
如果将来需要重构,可以考虑定义一个类型扩展来避免 as any

interface ExtendedMouseEvent extends MouseEvent {
  _ignore_global_close?: boolean;
}

不过对于当前实现,使用 as any 是可以接受的快速解决方案。

tests/Select.test.tsx (1)

392-430: 测试覆盖了核心场景

此测试有效验证了动态后缀图标变化时下拉框不会关闭的场景,直接针对 issue #56002 中描述的问题。实现正确使用了相同的 mouseDownEvent 来模拟事件从元素冒泡到 window。

可选的额外测试场景:
如果要进一步加强覆盖,可以考虑添加以下场景的测试:

  1. 验证在非动态后缀(后缀不变化)的情况下点击也不会关闭
  2. 验证点击其他区域(如选项列表外部)仍然会正常关闭

不过对于当前的修复,这个测试已经足够。

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 effectively addresses the reported issue where a mouseDown event on a dynamically rendered suffix icon incorrectly closed the select dropdown. The solution involves marking the native event object to signal the global close handler to ignore it. While this approach resolves the immediate problem, directly modifying native event objects with any type casting can introduce fragility and reduce type safety. Consider alternative React-specific mechanisms for communicating this intent, such as using a context or a ref, for a more robust and maintainable solution in the future.

// Tell `useSelectTriggerControl` to ignore this event
// When icon is dynamic render, the parentNode will miss
// so we need to mark the event directly
(event.nativeEvent as any)._ignore_global_close = true;

Choose a reason for hiding this comment

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

medium

Directly modifying the native event object and casting it to any can lead to type safety issues and potential conflicts with other libraries that might also manipulate event objects. While this approach fixes the immediate bug, it relies on undocumented behavior and can be fragile. Consider using a more idiomatic React pattern, such as a context provider or a ref, to pass this _ignore_global_close flag to the useSelectTriggerControl hook.

if (
open &&
// Marked by SelectInput mouseDown event
!(event as any)._ignore_global_close &&

Choose a reason for hiding this comment

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

medium

Accessing a custom property _ignore_global_close on the event object with (event as any) reduces type safety and couples this hook tightly to the implementation details of SelectInput. If the structure of the native event or the SelectInput component changes, this could break unexpectedly. A more robust solution would involve a clear, type-safe communication channel between the components, such as a shared state or a dedicated prop.

@zombieJ zombieJ merged commit 1790cf0 into master Dec 1, 2025
12 checks passed
@zombieJ zombieJ deleted the fix-mouse-down branch December 1, 2025 07:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Select with showSearch: dropdown closes immediately when clicking arrow icon in v6.0.0

2 participants