Skip to content

feat: support classnames and styles #1128

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Mar 13, 2025
Merged

Conversation

thinkasany
Copy link
Contributor

@thinkasany thinkasany commented Feb 25, 2025

Summary by CodeRabbit

  • 新功能
    • 为选择组件新增可选属性,支持通过语义化配置自定义类名和内联样式,实现前缀和后缀样式的灵活定制。
    • TransBtn 组件新增可选样式属性,支持用户传递自定义样式。
    • Selector 组件新增前缀类名和前缀样式属性,增强其自定义选项。
    • OptionList 组件增强了对上下文样式的支持,允许更灵活的样式应用。
    • Input 组件集成了上下文支持,增强了动态样式的应用能力。
  • 测试
    • 新增测试用例,确保自定义类名和样式在组件中正确渲染并满足预期效果。

Copy link

vercel bot commented Feb 25, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
select ✅ Ready (Inspect) Visit Preview 💬 Add feedback Mar 13, 2025 6:29am

Copy link
Contributor

coderabbitai bot commented Feb 25, 2025

Walkthrough

此次变更在多个组件中新增和调整了自定义样式和类名的属性。通过在 BaseSelectSelectSelector 以及 TransBtn 组件中引入或更新 classNamesstylesprefixClassNameprefixStylestyle 属性,开发者可以更细粒度地定制各个部分的外观。同时,在测试文件中添加了新用例,以验证自定义属性的正确应用。

Changes

文件 变更摘要
src/BaseSelect/index.tsx
src/Select.tsx
为组件接口新增 classNamesstyles 属性,类型定义为 Partial<Record<SemanticName, string>>Partial<Record<SemanticName, React.CSSProperties>>,允许通过语义标识定制组件不同部分的类名和样式。
src/Selector/index.tsx
src/TransBtn.tsx
更新接口,Selector 添加 prefixClassNameprefixStyle 属性;TransBtn 增加可选的 style 属性,通过这些属性实现前缀和按钮的定制化。
tests/Select.test.tsx 添加新测试用例,验证 Select 组件对自定义类名和样式的支持,确保前缀和后缀能够正确应用传入的定制化属性。
src/SelectContext.ts
src/Selector/Input.tsx
更新 SelectContextProps 接口,新增 classNamesstyles 属性,以支持上下文中样式和类名的定制化;Input 组件整合上下文属性以增强功能。

Possibly related PRs

Suggested reviewers

  • zombieJ

Poem

我是一只爱跳跃的小兔,
代码中添上新彩虹,
样式与类名齐舞动,
每一行都闪着春风,
在软软的草地上欢快跳,
迎接变更带来的新梦。

Warning

There were issues while running some tools. Please review the errors and either fix the tool’s configuration or disable the tool if it’s a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

src/BaseSelect/index.tsx

Oops! Something went wrong! :(

ESLint: 8.57.1

Error: Cannot read config file: /.eslintrc.js
Error: Cannot find module '@umijs/fabric/dist/eslint'
Require stack:

  • /.eslintrc.js
  • /node_modules/.pnpm/@eslint+eslintrc@2.1.4/node_modules/@eslint/eslintrc/dist/eslintrc.cjs
  • /node_modules/.pnpm/eslint@8.57.1/node_modules/eslint/lib/cli-engine/cli-engine.js
  • /node_modules/.pnpm/eslint@8.57.1/node_modules/eslint/lib/eslint/eslint.js
  • /node_modules/.pnpm/eslint@8.57.1/node_modules/eslint/lib/eslint/index.js
  • /node_modules/.pnpm/eslint@8.57.1/node_modules/eslint/lib/cli.js
  • /node_modules/.pnpm/eslint@8.57.1/node_modules/eslint/bin/eslint.js
    at Module._resolveFilename (node:internal/modules/cjs/loader:1248:15)
    at Module._load (node:internal/modules/cjs/loader:1074:27)
    at TracingChannel.traceSync (node:diagnostics_channel:315:14)
    at wrapModuleLoad (node:internal/modules/cjs/loader:217:24)
    at Module.require (node:internal/modules/cjs/loader:1339:12)
    at require (node:internal/modules/helpers:135:16)
    at Object. (/.eslintrc.js:1:14)
    at Module._compile (node:internal/modules/cjs/loader:1546:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1691:10)
    at Module.load (node:internal/modules/cjs/loader:1317:32)
src/Select.tsx

Oops! Something went wrong! :(

ESLint: 8.57.1

Error: Cannot read config file: /.eslintrc.js
Error: Cannot find module '@umijs/fabric/dist/eslint'
Require stack:

  • /.eslintrc.js
  • /node_modules/.pnpm/@eslint+eslintrc@2.1.4/node_modules/@eslint/eslintrc/dist/eslintrc.cjs
  • /node_modules/.pnpm/eslint@8.57.1/node_modules/eslint/lib/cli-engine/cli-engine.js
  • /node_modules/.pnpm/eslint@8.57.1/node_modules/eslint/lib/eslint/eslint.js
  • /node_modules/.pnpm/eslint@8.57.1/node_modules/eslint/lib/eslint/index.js
  • /node_modules/.pnpm/eslint@8.57.1/node_modules/eslint/lib/cli.js
  • /node_modules/.pnpm/eslint@8.57.1/node_modules/eslint/bin/eslint.js
    at Module._resolveFilename (node:internal/modules/cjs/loader:1248:15)
    at Module._load (node:internal/modules/cjs/loader:1074:27)
    at TracingChannel.traceSync (node:diagnostics_channel:315:14)
    at wrapModuleLoad (node:internal/modules/cjs/loader:217:24)
    at Module.require (node:internal/modules/cjs/loader:1339:12)
    at require (node:internal/modules/helpers:135:16)
    at Object. (/.eslintrc.js:1:14)
    at Module._compile (node:internal/modules/cjs/loader:1546:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1691:10)
    at Module.load (node:internal/modules/cjs/loader:1317:32)

Tip

⚡🧪 Multi-step agentic review comment chat (experimental)
  • We're introducing multi-step agentic chat in review comments. This experimental feature enhances review discussions with the CodeRabbit agentic chat by enabling advanced interactions, including the ability to create pull requests directly from comments.
    - To enable this feature, set early_access to true under in the settings.

📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6c7ff1a and 53322ad.

📒 Files selected for processing (2)
  • src/BaseSelect/index.tsx (5 hunks)
  • src/Select.tsx (5 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/Select.tsx
🔇 Additional comments (6)
src/BaseSelect/index.tsx (6)

33-33: 类型定义看起来不错!

为基础选择组件的语义部分定义明确的类型很好,这样可以在TypeScript中提供更好的类型安全和自动完成功能。


135-136: 很好的实现自定义样式和类名的功能

添加classNamesstyles属性允许组件用户为选择器的不同部分(前缀、后缀和输入框)提供自定义样式,这与PR的目标完全一致。这种实现方式既灵活又类型安全。


411-416: 从上下文中提取样式属性的实现很好

SelectContext中提取classNamesstyles属性,并将classNames重命名为selectClassNames以避免命名冲突,这是一个好的做法。记得确保SelectContext在其定义中包含了这些新属性。


731-732: 适当地应用后缀类名

使用可选链运算符?.来安全地访问selectClassNames.suffix是个好做法,这样即使selectClassNamesundefined也不会导致错误。


734-734: 为TransBtn组件添加自定义样式支持

TransBtn组件添加style属性支持是实现样式自定义功能的关键部分,确保用户可以调整下拉箭头的样式。


824-825:

✅ Verification successful

为Selector组件添加前缀样式支持

selectClassNames?.prefixstyles?.prefix传递给Selector组件的prefixClassNameprefixStyle属性是一个很好的做法。请确保Selector组件已更新,能够接收并正确处理这些新的props。

请运行以下脚本,验证Selector组件是否已更新以接收这些新的props:


🏁 Script executed:

#!/bin/bash
# 检查Selector组件的prop定义是否包含prefixClassName和prefixStyle
rg -A 5 -B 5 'interface\s+SelectorProps' src/Selector/

Length of output: 1865


确认:Selector组件已正确支持前缀样式属性

经过验证,src/Selector/index.tsx 中的 SelectorProps 接口已经包含了 prefixClassNameprefixStyle 属性,确认该组件已更新以正确接收这些新props。

✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

codecov bot commented Feb 25, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 98.26%. Comparing base (e8096c0) to head (53322ad).
Report is 1 commits behind head on master.

Additional details and impacted files
@@           Coverage Diff           @@
##           master    #1128   +/-   ##
=======================================
  Coverage   98.26%   98.26%           
=======================================
  Files          39       39           
  Lines        1499     1501    +2     
  Branches      424      426    +2     
=======================================
+ Hits         1473     1475    +2     
  Misses         26       26           

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

src/Select.tsx Outdated
@@ -107,6 +107,7 @@ export type SelectHandler<ValueType, OptionType extends BaseOptionType = Default

type ArrayElementType<T> = T extends (infer E)[] ? E : T;

export type SemanticName = 'prefix' | 'suffix';
Copy link
Member

Choose a reason for hiding this comment

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

感觉有点少,结构上应该是和 Mentions 差不多:

  • root
  • prefix
  • suffix
  • input
  • popup
  • list
  • item
  • tag (多选时的展示内容,这个名字不一定好)

Copy link
Member

Choose a reason for hiding this comment

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

ps: 这个搞了 TreeSelect 和 Cascade 除了 option list 应该都是共用的

Copy link
Contributor Author

Choose a reason for hiding this comment

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

tag 或许可以用 selection, 我先用 tag 好了,等后面在讨论一下,对应修改。先写具体逻辑。
image

Copy link
Contributor Author

Choose a reason for hiding this comment

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

其实有 tagRender 或许可以不提供这个,不然还得去改 rc-overflow
image
目前做到这样子好像够用了。
image

@thinkasany
Copy link
Contributor Author

备注:
root 就是 classname 和 style
popup 也可以在 antd 侧磨平,其他的需要加一下
image
image

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 (2)
src/Select.tsx (2)

110-162: 考虑扩展 SemanticName 类型定义

根据之前的讨论,组件结构中还应该包含 'root'、'popup' 和 'tag'(多选时的展示内容)这些部分。建议考虑将这些语义名称也添加到 SemanticName 类型中,使样式自定义更加完整。

可以这样扩展类型定义:

-export type SemanticName = 'prefix' | 'suffix' | 'item' | 'list' | 'input';
+export type SemanticName = 'root' | 'prefix' | 'suffix' | 'item' | 'list' | 'input' | 'popup' | 'tag';

161-162: 添加 JSDoc 注释以提高代码可读性

建议为新增的属性添加 JSDoc 注释,清晰说明其用途和使用方法,这将有助于其他开发者理解如何使用这些新功能。

+/**
+ * 为选择器的不同部分提供自定义类名
+ */
 classNames?: Partial<Record<SemanticName, string>>;
+/**
+ * 为选择器的不同部分提供自定义样式
+ */
 styles?: Partial<Record<SemanticName, React.CSSProperties>>;
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 986a688 and 45599f6.

📒 Files selected for processing (1)
  • src/Select.tsx (4 hunks)
🔇 Additional comments (5)
src/Select.tsx (5)

110-110: 新增 SemanticName 类型定义,用于支持自定义样式

这个导出类型很好地定义了可以自定义样式的组件部分,包括 'prefix'、'suffix'、'item'、'list' 和 'input'。这为用户提供了明确的接口来理解哪些部分可以被自定义。


161-162: 为 SelectProps 接口增加了自定义样式和类名的能力

添加了两个新属性,使组件具有更细粒度的样式自定义能力:

  • classNames: 允许为不同的语义部分设置自定义类名
  • styles: 允许为不同的语义部分设置自定义样式

这些属性的类型定义正确,使用 Partial<Record<SemanticName, ...>> 结构确保了类型安全。


210-212: 从 props 中解构新增的样式属性

正确地将 classNames 重命名为 selectClassNames,避免了可能的命名冲突。


633-635: 将自定义样式属性添加到 SelectContext

通过将 classNamesstyles 添加到 context 中,子组件可以访问这些样式配置,实现了样式的向下传递。


637-639: 更新 useMemo 依赖数组,确保样式变更时重新计算

正确地将 selectClassNamesstyles 添加到依赖数组中,确保这些属性变更时会触发 context 的重新计算。

src/Select.tsx Outdated
@@ -107,6 +107,7 @@ export type SelectHandler<ValueType, OptionType extends BaseOptionType = Default

type ArrayElementType<T> = T extends (infer E)[] ? E : T;

export type SemanticName = 'prefix' | 'suffix' | 'item' | 'list' | 'input';
Copy link
Member

Choose a reason for hiding this comment

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

item 改成 listItem 如何?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

@@ -131,6 +132,8 @@ export type BaseSelectPropsWithoutPrivate = Omit<BaseSelectProps, keyof BaseSele
export interface BaseSelectProps extends BaseSelectPrivateProps, React.AriaAttributes {
className?: string;
style?: React.CSSProperties;
classNames?: Partial<Record<SemanticName, string>>;
Copy link
Member

Choose a reason for hiding this comment

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

BaseSelect 里不应该反向引用 Select 的定义,因为 TreeSelect 和 Cascader 里是没有这个的。BaseSelect 应该只有 'prefix' | 'suffix' | 'input',然后 Select 里拓展出来

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.

None yet

2 participants