Skip to content

Conversation

NearImba
Copy link

@NearImba NearImba commented Sep 16, 2025

🤔 这个变动的性质是?

  • ⭐️ 功能增强

🔗 相关 Issue

fix 54884

💡 需求背景和解决方案

Select已选且filterSort启用的情况下,用搜索的方式重新选择,选项没有滚到最上面,不方便用户选择

解决方法
Select组件当提供filterSort参数时,搜索时默认定位到第一个元素
改动前:
用户需要手动滚到最上面去选取最相关的选项
before

改动后:
自动滚到最上供用户选择
after

📝 更新日志

Select组件当提供filterSort参数时,搜索时默认定位到第一个元素

语言 更新描述
🇺🇸 英文 when filterSort is provided in Select component,scroll to first option during searching
🇨🇳 中文 Select组件当提供filterSort参数时,搜索时默认定位到第一个元素

Summary by CodeRabbit

  • 新功能

    • 在启用自定义过滤排序且输入搜索词时,Select(单选)会自动滚动到首个匹配结果,搜索体验更顺滑。
    • 过滤排序策略在组件内贯穿生效,排序与搜索行为更一致。
  • 文档

    • 新增“海量数据 + 过滤排序 + 搜索值”示例,展示在大数据集下的使用方式。
    • 既有示例保持不变。

Copy link

vercel bot commented Sep 16, 2025

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

Project Deployment Preview Comments Updated (UTC)
select Ready Ready Preview Comment Sep 22, 2025 10:19am

Copy link
Contributor

coderabbitai bot commented Sep 16, 2025

Walkthrough

将 Select 的 filterSort 能力通过上下文传递到 OptionList;在单选且搜索时,若启用 filterSort,打开列表时将活动项固定为第一个选项。补充了 SelectContext 类型。新增示例:使用大规模国家数据集与自定义 sorterBySearchValue 的过滤排序演示。

Changes

Cohort / File(s) Summary
Docs 示例:大数据与自定义排序
docs/examples/filterSort.tsx
新增 countries 数据集与选项映射;新增 sorterBySearchValue 比较器;扩展示例,演示带 filterSort 的大数据搜索过滤排序;保留既有示例。
OptionList 行为调整
src/OptionList.tsx
从 SelectContext 读取 filterSort;在单选、下拉打开且存在搜索值时,若启用 filterSort,将活动项 index 设为 0,改变自动滚动定位逻辑;其他情形维持原有计算。
Select 属性传递与上下文
src/Select.tsx, src/SelectContext.ts
在 SelectProps/Context 中纳入 filterSort;将其写入 SelectContext 并加入 memo 依赖;在 SelectContextProps 中新增可选属性 filterSort?: SelectProps['filterSort']

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor U as User
  participant S as Select
  participant Ctx as SelectContext
  participant OL as OptionList
  participant L as VirtualList

  U->>S: 输入搜索值 / 打开下拉
  S->>Ctx: 提供 { value, searchValue, filterSort, ... }
  OL->>Ctx: 读取上下文
  alt 单选且下拉打开
    alt filterSort 已提供 且 searchValue 非空
      note over OL,L: 新逻辑:活动项 index = 0
      OL->>L: scrollTo(0)
    else 默认逻辑
      OL->>OL: 计算匹配项 index(前缀/等值)
      OL->>L: scrollTo(index)
    end
  end
  U->>S: 选择项
  S->>U: 更新值
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • zombieJ
  • afc163

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 标题“fix: when filterSort function is provided, scroll to first option during searching”准确描述了本次变更的核心行为:在提供 filterSort 时,搜索过程中自动滚动到首个选项,表述简洁且与变更集直接相关,能让审阅者快速理解主要修复点。
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Tip

👮 Agentic pre-merge checks are now available in preview!

Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.

  • Built-in checks – Quickly apply ready-made checks to enforce title conventions, require pull request descriptions that follow templates, validate linked issues for compliance, and more.
  • Custom agentic checks – Define your own rules using CodeRabbit’s advanced agentic capabilities to enforce organization-specific policies and workflows. For example, you can instruct CodeRabbit’s agent to verify that API documentation is updated whenever API schema files are modified in a PR. Note: Upto 5 custom checks are currently allowed during the preview period. Pricing for this feature will be announced in a few weeks.

Please see the documentation for more information.

Example:

reviews:
  pre_merge_checks:
    custom_checks:
      - name: "Undocumented Breaking Changes"
        mode: "warning"
        instructions: |
          Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal).

Please share your feedback with us on this Discord post.


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

@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 @NearImba, 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!

此拉取请求旨在优化 Select 组件的用户交互体验。它解决了在启用自定义 filterSort 排序功能并进行搜索时,选项列表不会自动滚动到第一个匹配结果的问题。通过此项改进,用户在搜索时能够更直观地看到最相关的选项,从而提高操作效率和整体可用性。

Highlights

  • Select 组件搜索体验改进: 当 Select 组件配置了 filterSort 属性且用户正在进行搜索时,选项列表现在会自动滚动到第一个匹配项,显著提升了用户查找和选择的便捷性。
  • filterSort 属性传递机制完善: filterSort 属性现在通过 SelectContext 在组件树中正确传递,确保了 OptionList 组件能够访问并应用自定义的排序逻辑。
  • 新增示例与测试数据: 为了更好地演示此功能,文档中新增了一个包含大量国家数据的 Select 示例,并引入了 sorterBySearchValue 函数,以展示在大数据量下的搜索和排序效果。
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

@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 很好地解决了在 Select 组件中,当提供了 filterSort 属性时,搜索时列表不会自动滚动到最顶部的问题。你的解决方案通过在 OptionList 中检查 filterSortsearchValue 的存在来将活动选项设置为列表的第一个,这是直接且有效的。相关的属性也通过 SelectContext 正确地传递了。我只在示例代码中发现了一个小问题,并提供了一个建议。整体来说,这是一个高质量的改动!

Comment on lines +996 to +1002
const sorterBySearchValue = (oa, ob, info) =>
info.searchValue
? oa.label.toLowerCase().indexOf(info.searchValue) >
ob.label.toLowerCase().indexOf(info.searchValue)
? 1
: -1
: oa.label.localeCompare(ob.label);

Choose a reason for hiding this comment

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

medium

sorterBySearchValue 这个排序函数的实现存在一些问题,可能会导致排序结果不符合预期:

  1. info.searchValue 没有被转换为小写,如果用户输入大写字母进行搜索,indexOf 将无法正确匹配。
  2. 当一个选项不匹配(indexOf 返回 -1)而另一个选项匹配时,排序逻辑会出错,不匹配的项可能会排在匹配项的前面。

建议修改为更健壮的实现方式,处理不匹配的情况,并根据匹配位置进行排序。

const sorterBySearchValue = (oa, ob, info) => {
  if (!info.searchValue) {
    return oa.label.localeCompare(ob.label);
  }
  const lowerSearch = info.searchValue.toLowerCase();
  const indexA = oa.label.toLowerCase().indexOf(lowerSearch);
  const indexB = ob.label.toLowerCase().indexOf(lowerSearch);

  if (indexA === indexB) {
    return oa.label.localeCompare(ob.label);
  }
  if (indexA === -1) {
    return 1;
  }
  if (indexB === -1) {
    return -1;
  }
  return indexA - indexB;
};

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 (3)
src/OptionList.tsx (1)

185-185: Effect 依赖缺少 filterSort

该 Effect 使用了 filterSort,但未在依赖中声明。运行期切换 filterSort 时不会更新滚动行为。

-  }, [open, searchValue]);
+  }, [open, searchValue, filterSort]);
docs/examples/filterSort.tsx (2)

996-1003: 排序比较器不稳定且大小写处理不一致

  • 未对 searchValue 做小写化,大小写不一致。
  • 相等时返回 -1,违反比较器契约,可能导致不稳定排序。

建议改为:

-const sorterBySearchValue = (oa, ob, info) =>
-  info.searchValue
-    ? oa.label.toLowerCase().indexOf(info.searchValue) >
-      ob.label.toLowerCase().indexOf(info.searchValue)
-      ? 1
-      : -1
-    : oa.label.localeCompare(ob.label);
+const sorterBySearchValue = (oa, ob, info) => {
+  const s = String(info.searchValue || '').toLowerCase();
+  const a = String(oa.label).toLowerCase();
+  const b = String(ob.label).toLowerCase();
+  if (!s) return a.localeCompare(b);
+  const ia = a.indexOf(s);
+  const ib = b.indexOf(s);
+  if (ia === ib) return a.localeCompare(b);
+  if (ia === -1) return 1;
+  if (ib === -1) return -1;
+  return ia - ib;
+};

14-993: 文档示例大体量常量建议外置,减小打包体积

countries 移到独立 JSON 并按需导入,降低示例页初始体积。

可按此思路修改(示例):

-const countries = [ /* ...大数组... */ ].map((item) => {
-  return {
-    value: item.id,
-    label: item.en,
-  };
-});
+// 顶部新增:import countriesRaw from './countries.json';
+const countries = countriesRaw.map((item) => ({
+  value: item.id,
+  label: item.en,
+}));

在文件顶部补充:

import countriesRaw from './countries.json';
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between eac8428 and 2c50a81.

📒 Files selected for processing (4)
  • docs/examples/filterSort.tsx (2 hunks)
  • src/OptionList.tsx (2 hunks)
  • src/Select.tsx (2 hunks)
  • src/SelectContext.ts (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
src/SelectContext.ts (1)
src/Select.tsx (1)
  • SelectProps (122-182)
🔇 Additional comments (6)
src/SelectContext.ts (1)

40-41: 类型透传到 Context,设计合理

filterSort 加入 SelectContextProps 与后续使用保持一致,无运行时影响。

src/OptionList.tsx (2)

65-66: 从 Context 解构 filterSort 合理

为后续滚动策略提供条件输入,变更本身安全。


162-169: 我要运行脚本检查代码以验证建议(查找 getEnabledActiveIndex、memoFlattenOptions、filterSort 等)。下面运行的脚本会打印相关文件片段。

#!/bin/bash
set -euo pipefail
echo "PWD: $(pwd)"
echo "查找 OptionList.tsx 文件..."
rg -n --hidden --no-ignore-vcs "OptionList.tsx" || true

echo "查找 getEnabledActiveIndex 的定义或使用..."
rg -n --hidden --no-ignore-vcs "getEnabledActiveIndex" -S || true

echo "查找 memoFlattenOptions / filterSort / searchValue..."
rg -n --hidden --no-ignore-vcs "memoFlattenOptions" -S || true
rg -n --hidden --no-ignore-vcs "filterSort" -S || true
rg -n --hidden --no-ignore-vcs "searchValue" -S || true

# 打印找到的 OptionList.tsx 的相关行(若存在)
for f in $(rg --hidden --no-ignore-vcs --files | rg "OptionList.tsx" || true); do
  echo "=== 文件: $f ==="
  sed -n '1,320p' "$f" || true
  echo "--- lines 140-200 ---"
  sed -n '140,200p' "$f" || true
done

# 如果未找到上面文件,再尝试在 src/ 中直接打印(兼容不同仓库结构)
if [ -f "src/OptionList.tsx" ]; then
  echo "=== src/OptionList.tsx ==="
  sed -n '1,320p' src/OptionList.tsx
  echo "--- lines 140-200 ---"
  sed -n '140,200p' src/OptionList.tsx
fi
src/Select.tsx (2)

676-676: 将 filterSort 放入 Context 值 — 同步到消费者组件

与上游搜索配置对齐,便于 OptionList 调整行为。


697-697: Memo 依赖包含 filterSort — 正确

保证 filterSort 变化时 Context 及时重建。

docs/examples/filterSort.tsx (1)

1021-1028: 新增大数据示例有助于复现/验证行为

示例配置与 PR 目标一致,利于手动验证自动滚动。

Copy link

codecov bot commented Sep 17, 2025

Codecov Report

❌ Patch coverage is 75.00000% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 98.05%. Comparing base (eac8428) to head (2c50a81).

Files with missing lines Patch % Lines
src/OptionList.tsx 75.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1163      +/-   ##
==========================================
- Coverage   98.11%   98.05%   -0.07%     
==========================================
  Files          39       39              
  Lines        1489     1491       +2     
  Branches      452      455       +3     
==========================================
+ Hits         1461     1462       +1     
- Misses         28       29       +1     

☔ 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.

@NearImba
Copy link
Author

I run npm test -- --coverage locally, those changes seem to be covered already.
how to fixed codecov error ?
image

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组件在有选中项的情况下,onSearch输入的时候下拉选项框的滚动条没有置顶
2 participants