Skip to content

fix: apply rawOpen fix to multiple mode#1202

Merged
zombieJ merged 2 commits intomasterfrom
multiple-fix
Feb 5, 2026
Merged

fix: apply rawOpen fix to multiple mode#1202
zombieJ merged 2 commits intomasterfrom
multiple-fix

Conversation

@zombieJ
Copy link
Member

@zombieJ zombieJ commented Feb 5, 2026

Pass rawOpen through context and use it in MultipleContent to prevent search value from being cleared when emptyListContent blocks the dropdown from opening. Also adds test coverage for the multiple mode case.

fix ant-design/ant-design#56735

Summary by CodeRabbit

发行说明

  • Bug 修复

    • 改进了多选模式下搜索框的行为,当内容列表打开时不再意外清除搜索输入。
    • 进一步修正了在特殊打开条件(例如自定义空列表展示阻止关闭)下的搜索保留逻辑,避免输入被提前清空。
  • 测试

    • 优化并参数化了测试,确保单选和多选模式下的搜索输入和 onSearch 行为一致。

Pass rawOpen through context and use it in MultipleContent to
prevent search value from being cleared when emptyListContent
blocks the dropdown from opening. Also adds test coverage
for the multiple mode case.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@vercel
Copy link

vercel bot commented Feb 5, 2026

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

Project Deployment Actions Updated (UTC)
select Ready Ready Preview, Comment Feb 5, 2026 9:49am

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 5, 2026

Walkthrough

将 BaseSelectContext 中暴露 rawOpen 状态,并在 MultipleContent 中将清空搜索的判断从 triggerOpen 切换为 rawOpen;同时更新类型声明和相关测试以覆盖单/多选场景。

Changes

Cohort / File(s) Summary
Context 上下文
src/BaseSelect/index.tsx, src/hooks/useBaseProps.ts
向 BaseSelectContext 的提供值中添加 rawOpen(并将其加入 memo 依赖),同时在类型 BaseSelectContextProps 中新增 rawOpen: boolean
搜索清空逻辑
src/SelectInput/Content/MultipleContent.tsx
将自动清空搜索的条件从 triggerOpen 改为 rawOpen,并添加注释说明何时清空搜索以避免在某些 rawOpen 控制场景下误清空。
测试
tests/Select.test.tsx
将单个测试重构为参数化测试(single 与 multiple 模式),验证在 notFoundContent 为 null 且无匹配项时输入行为一致。

Sequence Diagram(s)

sequenceDiagram
    participant User as User
    participant MC as MultipleContent
    participant BSC as BaseSelectContext
    User->>MC: 输入字符(typing)
    MC->>BSC: 读取当前 open 状态(rawOpen)
    BSC-->>MC: 返回 rawOpen 值
    alt rawOpen == true
        MC->>MC: 保留搜索内容(不清空)
    else rawOpen == false
        MC->>MC: 清空搜索内容
    end
    MC-->>User: 更新输入框显示 / onSearch 回调
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • afc163

诗歌

🐰 搜索框轻轻敲,rawOpen为我保驾护航,
notFound不再偷懒,字符全都能留下,
单选多选皆欢喜,输入流畅又安心,
小兔跳跃庆修复,代码里藏着阳光。

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed PR标题'fix: apply rawOpen fix to multiple mode'准确地概括了主要变更内容,即将rawOpen修复应用到多选模式。
Linked Issues check ✅ Passed PR的所有代码变更都与解决issue #56735有关,即修复notFoundContent为null时搜索输入被清除的问题。
Out of Scope Changes check ✅ Passed 所有代码变更都在PR的定义范围内,包括传递rawOpen到上下文、在MultipleContent中使用它、以及添加测试覆盖。
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ 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 multiple-fix

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 @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 addresses a bug in the Select component where the search input's value was incorrectly cleared in 'multiple' mode when the dropdown was prevented from opening due to emptyListContent. The fix involves correctly propagating the rawOpen state through the component context and using it in the search value clearing logic, ensuring the search input behaves as expected. Additionally, comprehensive test coverage has been added for this specific scenario in multiple mode.

Highlights

  • Context Propagation: The rawOpen property is now passed through the BaseSelect component's context, making it accessible to child components like MultipleContent.
  • Search Value Clearing Logic Fix: The logic in MultipleContent that clears the search value has been updated to use rawOpen instead of triggerOpen. This prevents the search value from being prematurely cleared when the dropdown is blocked by emptyListContent in multiple selection mode.
  • Improved Test Coverage: New test cases have been added to Select.test.tsx specifically for the multiple mode, ensuring that typing functionality works correctly when notFoundContent is null and no options match, thus covering the bug fix.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • src/BaseSelect/index.tsx
    • Passed rawOpen prop to the BaseSelect component's context.
  • src/SelectInput/Content/MultipleContent.tsx
    • Updated the condition for clearing computedSearchValue from !triggerOpen to !rawOpen to prevent premature clearing when emptyListContent is present.
    • Added a comment explaining the change: 'Use rawOpen to avoid clearing search when emptyListContent blocks open'.
  • src/hooks/useBaseProps.ts
    • Added rawOpen: boolean; to the BaseSelectContextProps interface to support context propagation.
  • tests/Select.test.tsx
    • Refactored the 'should allow typing when notFoundContent is null and no options match' test into a describe block.
    • Added a new it block within the describe block to specifically test the multiple mode for the Select component, ensuring search input functionality is maintained under the specified conditions.
Activity
  • No specific review comments or discussions have been recorded yet for this pull request.
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 Feb 5, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.43%. Comparing base (6f33131) to head (8fcb5c7).
⚠️ Report is 1 commits behind head on master.

Additional details and impacted files
@@           Coverage Diff           @@
##           master    #1202   +/-   ##
=======================================
  Coverage   99.43%   99.43%           
=======================================
  Files          31       31           
  Lines        1230     1230           
  Branches      419      419           
=======================================
  Hits         1223     1223           
  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.

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

This pull request correctly fixes an issue where the search value was being cleared in multiple mode when notFoundContent is null and no options match. The changes are well-targeted, passing rawOpen through the context and using it to decide whether to clear the search input. The added test case for multiple mode effectively covers this fix. I have one suggestion to refactor the new tests to reduce code duplication and improve maintainability.

Comment on lines 2000 to 2056
describe('should allow typing when notFoundContent is null and no options match', () => {
it('single', () => {
const onSearch = jest.fn();
const { container } = render(
<Select showSearch notFoundContent={null} onSearch={onSearch}>
<Option value="jack">Jack</Option>
<Option value="lucy">Lucy</Option>
</Select>,
);

const input = container.querySelector('input');
const input = container.querySelector('input');

// Type 'j' - should match 'Jack'
fireEvent.change(input, { target: { value: 'j' } });
expect(onSearch).toHaveBeenLastCalledWith('j');
expect(input.value).toBe('j');
expect(container.querySelectorAll('.rc-select-item-option')).toHaveLength(1);

// Type 'j' - should match 'Jack'
fireEvent.change(input, { target: { value: 'j' } });
expect(onSearch).toHaveBeenLastCalledWith('j');
expect(input.value).toBe('j');
expect(container.querySelectorAll('.rc-select-item-option')).toHaveLength(1);

// Type 'x' - no match, but input should still work
fireEvent.change(input, { target: { value: 'x' } });
expect(onSearch).toHaveBeenLastCalledWith('x');
expect(input.value).toBe('x');

// Type more characters - should continue working
fireEvent.change(input, { target: { value: 'xyz' } });
expect(onSearch).toHaveBeenLastCalledWith('xyz');
expect(input.value).toBe('xyz');
// Type 'x' - no match, but input should still work
fireEvent.change(input, { target: { value: 'x' } });
expect(onSearch).toHaveBeenLastCalledWith('x');
expect(input.value).toBe('x');

// Type more characters - should continue working
fireEvent.change(input, { target: { value: 'xyz' } });
expect(onSearch).toHaveBeenLastCalledWith('xyz');
expect(input.value).toBe('xyz');
});

it('multiple', () => {
const onSearch = jest.fn();
const { container } = render(
<Select mode="multiple" showSearch notFoundContent={null} onSearch={onSearch}>
<Option value="jack">Jack</Option>
<Option value="lucy">Lucy</Option>
</Select>,
);

const input = container.querySelector('input');

// Type 'j' - should match 'Jack'
fireEvent.change(input, { target: { value: 'j' } });
expect(onSearch).toHaveBeenLastCalledWith('j');
expect(input.value).toBe('j');
expect(container.querySelectorAll('.rc-select-item-option')).toHaveLength(1);

// Type 'x' - no match, but input should still work
fireEvent.change(input, { target: { value: 'x' } });
expect(onSearch).toHaveBeenLastCalledWith('x');
expect(input.value).toBe('x');

// Type more characters - should continue working
fireEvent.change(input, { target: { value: 'xyz' } });
expect(onSearch).toHaveBeenLastCalledWith('xyz');
expect(input.value).toBe('xyz');
});
});
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The tests for 'single' and 'multiple' modes are nearly identical. To improve maintainability and reduce code duplication, you could refactor them using it.each to run the same test logic for both modes.

  describe('should allow typing when notFoundContent is null and no options match', () => {
    it.each(['single', 'multiple'] as const)('%s', (mode) => {
      const onSearch = jest.fn();
      const { container } = render(
        <Select
          mode={mode === 'single' ? undefined : mode}
          showSearch
          notFoundContent={null}
          onSearch={onSearch}
        >
          <Option value="jack">Jack</Option>
          <Option value="lucy">Lucy</Option>
        </Select>,
      );

      const input = container.querySelector('input');

      // Type 'j' - should match 'Jack'
      fireEvent.change(input, { target: { value: 'j' } });
      expect(onSearch).toHaveBeenLastCalledWith('j');
      expect(input.value).toBe('j');
      expect(container.querySelectorAll('.rc-select-item-option')).toHaveLength(1);

      // Type 'x' - no match, but input should still work
      fireEvent.change(input, { target: { value: 'x' } });
      expect(onSearch).toHaveBeenLastCalledWith('x');
      expect(input.value).toBe('x');

      // Type more characters - should continue working
      fireEvent.change(input, { target: { value: 'xyz' } });
      expect(onSearch).toHaveBeenLastCalledWith('xyz');
      expect(input.value).toBe('xyz');
    });
  });

Combine single and multiple mode tests into a parametrized
test using it.each for better maintainability.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@zombieJ zombieJ merged commit 6d84c2f into master Feb 5, 2026
11 of 12 checks passed
@zombieJ zombieJ deleted the multiple-fix branch February 5, 2026 09:51
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.

Unable to enter search query into searchable select when notFoundContent is set to null

1 participant