Skip to content
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

feat: tab support classnames and styles #784

Merged
merged 5 commits into from
Feb 20, 2025

Conversation

thinkasany
Copy link
Contributor

@thinkasany thinkasany commented Feb 19, 2025

Summary by CodeRabbit

  • 新增功能
    • 组件现可通过自定义样式和类名灵活调整外观,包括下拉弹窗、标签项和指示器等部分,增强了视觉定制能力。
  • 测试
    • 新增和调整了测试用例,验证自定义样式和类名的正确应用,确保整体功能稳定可靠。

Copy link

vercel bot commented Feb 19, 2025

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

Name Status Preview Comments Updated (UTC)
tabs ✅ Ready (Inspect) Visit Preview 💬 Add feedback Feb 20, 2025 6:39am

Copy link

coderabbitai bot commented Feb 19, 2025

Walkthrough

本次变更主要为多个组件添加了自定义样式和类名的支持。

  • OperationNodeTabNodeTabNavList 中新增可选属性以定制弹出层、标签项等的样式和类名。
  • Tabs 组件中引入了 SemanticName 类型,并相应更新了属性接口。
  • 增加和改进了测试用例,验证这些新属性的功能与渲染效果。

Changes

文件 变更摘要
src/TabNavList/{OperationNode, TabNode, index}.tsx 在各组件的 props 接口中新增了可选属性(如 popupStyle, className, classNames, styles),以支持对弹出层、标签项及对应指示器的自定义样式和类名。
src/Tabs.tsx 新增 SemanticName 类型,并在 TabsProps 中添加 classNamesstyles 属性,同时调整了与 popup 相关的逻辑及文档说明。
tests/{index, overflow}.test.tsx 添加和调整了测试用例,验证组件对自定义类名和样式的支持及正确的属性传递和渲染行为。

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/TabNavList/index.tsx

Oops! Something went wrong! :(

ESLint: 8.57.1

ESLint couldn't find the plugin "eslint-plugin-react".

(The package "eslint-plugin-react" was not found when loaded as a Node module from the directory "".)

It's likely that the plugin isn't installed correctly. Try reinstalling by running the following:

npm install eslint-plugin-react@latest --save-dev

The plugin "eslint-plugin-react" was referenced from the config file in ".eslintrc.js » /node_modules/.pnpm/@umijs+fabric@4.0.1_jest@29.7.0_@types+node@22.13.4__postcss@8.5.3/node_modules/@umijs/fabric/dist/eslint.js".

If you still can't figure out the problem, please stop by https://eslint.org/chat/help to chat with the team.


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 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. (Beta)
  • @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

@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/TabNavList/index.tsx (1)

425-428: 应用自定义类名和样式到标签项

为标签项添加自定义类名和样式支持,同时保持原有的样式逻辑。建议添加注释说明样式的优先级和合并策略。

 className={tabsClassNames?.item}
 /* first node should not have margin left */
-style={i === 0 ? styles?.item : { ...tabNodeStyle, ...styles?.item }}
+// 自定义样式优先级高于默认样式
+style={i === 0 ? styles?.item : { ...tabNodeStyle, ...styles?.item }}
tests/index.test.tsx (1)

692-716: 完善类名和样式的测试用例

测试用例完整验证了自定义类名和样式的功能,建议补充以下场景的测试:

  1. 动态更新样式和类名
  2. 样式优先级
  3. 空值处理

建议添加如下测试场景:

// 测试动态更新
it('should update styles and classNames dynamically', () => {
  const { container, rerender } = render(
    <Tabs
      items={[{ key: 'test', label: 'test' }]}
      styles={{ item: { color: 'blue' } }}
      classNames={{ item: 'custom-item' }}
    />
  );
  
  // 验证初始样式
  const item = container.querySelector('.rc-tabs-tab');
  expect(item).toHaveStyle({ color: 'blue' });
  expect(item).toHaveClass('custom-item');
  
  // 更新样式
  rerender(
    <Tabs
      items={[{ key: 'test', label: 'test' }]}
      styles={{ item: { color: 'red' } }}
      classNames={{ item: 'new-item' }}
    />
  );
  
  // 验证更新后的样式
  expect(item).toHaveStyle({ color: 'red' });
  expect(item).toHaveClass('new-item');
});

// 测试空值处理
it('should handle empty styles and classNames', () => {
  const { container } = render(
    <Tabs
      items={[{ key: 'test', label: 'test' }]}
      styles={{}}
      classNames={{}}
    />
  );
  
  const item = container.querySelector('.rc-tabs-tab');
  expect(item).toBeInTheDocument();
});
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between ffde754 and c9e8ba1.

📒 Files selected for processing (6)
  • src/TabNavList/OperationNode.tsx (4 hunks)
  • src/TabNavList/TabNode.tsx (3 hunks)
  • src/TabNavList/index.tsx (5 hunks)
  • src/Tabs.tsx (3 hunks)
  • tests/index.test.tsx (1 hunks)
  • tests/overflow.test.tsx (3 hunks)
🔇 Additional comments (13)
src/TabNavList/TabNode.tsx (2)

27-27: 新增 className 属性以支持自定义样式

TabNodeProps 接口添加了可选的 className 属性,增强了组件的样式定制能力。


86-91: 正确集成了 className 属性

使用 classNames 工具函数合并了默认类名和自定义类名,保持了良好的样式继承性。

src/Tabs.tsx (3)

37-37: 引入语义化样式类型定义

新增 SemanticName 类型,用于定义标签页组件中不同部分的语义化样式标识。


44-45: 增强样式定制能力

新增两个属性以支持更细粒度的样式定制:

  • classNames: 用于定制不同部分的类名
  • styles: 用于定制不同部分的内联样式

188-190: 优化弹出层样式处理逻辑

合理地整合了弹出层的类名和样式属性,使用 classNames 工具函数确保样式正确合并。

src/TabNavList/OperationNode.tsx (2)

29-29: 支持弹出层样式定制

OperationNodeProps 接口添加了 styles 属性,支持自定义弹出层样式。


187-199: 优化下拉菜单样式处理

改进了下拉菜单的样式应用逻辑:

  • 使用 classNames 合并类名
  • 通过 overlayStyle 应用自定义样式
tests/overflow.test.tsx (2)

509-515: 完善样式相关测试用例

扩展了弹出层样式测试,验证:

  • 自定义类名 custom-popup
  • 语义化类名 classnames-popup
  • 内联样式 { color: 'red' }

526-528: 验证样式应用正确性

全面测试了样式应用结果:

  • 验证自定义类名存在
  • 验证语义化类名存在
  • 验证内联样式正确应用
src/TabNavList/index.tsx (4)

33-33: 导入 SemanticName 类型以支持语义化样式

从 Tabs 组件导入 SemanticName 类型,用于类名和样式的语义化定制。


59-60: 新增类名和样式的类型定义

使用 Partial 类型来定义可选的语义化类名和样式属性,提供了良好的类型安全性和灵活性。


115-116: 解构新增的样式属性

在组件参数中解构 classNames 和 styles 属性,并使用更具语义化的命名 tabsClassNames。


616-620: 完善指示器的样式定制

为指示器添加自定义类名和样式支持,保持动画效果的同时支持样式定制。

@@ -26,6 +26,7 @@ export interface OperationNodeProps {
tabMoving?: boolean;
getPopupContainer?: (node: HTMLElement) => HTMLElement;
popupClassName?: string;
styles?: { popup?: React.CSSProperties };
Copy link
Member

Choose a reason for hiding this comment

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

只要一个 popup 就够了吗? Tab 应该还有 item 的

Copy link

codecov bot commented Feb 20, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 98.96%. Comparing base (ffde754) to head (7c99121).
Report is 1 commits behind head on master.

Additional details and impacted files
@@           Coverage Diff           @@
##           master     #784   +/-   ##
=======================================
  Coverage   98.96%   98.96%           
=======================================
  Files          18       18           
  Lines         772      772           
  Branches      224      227    +3     
=======================================
  Hits          764      764           
  Misses          8        8           

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

Copy link

@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

🔭 Outside diff range comments (1)
src/TabNavList/index.tsx (1)

1-644: 💡 Verification agent

❓ Verification inconclusive

验证新增属性的类型安全性

建议添加类型测试以确保 classNamesstyles 属性只接受有效的语义名称。


🏁 Script executed:

#!/bin/bash
# 搜索是否存在相关的类型测试
rg -t typescript "describe.*TabNavList.*types?" tests/

Length of output: 91


请重新验证类型测试覆盖情况
当前使用的 rg -t typescript 命令因文件类型 “typescript” 未被识别而没有产生预期输出。建议改为搜索所有 TypeScript 测试文件以确认是否存在针对 TabNavList 组件的类型测试。请运行下面的新脚本以验证是否存在相关测试代码:


🏁 Script executed:

#!/bin/bash
# 使用 -g "*.ts" 参数在 tests 目录中搜索包含 TabNavList 类型测试描述的测试代码
rg "describe.*TabNavList.*types?" -g "*.ts" tests/

Length of output: 52


请补充类型测试以确保 classNamesstyles 属性的类型安全性
目前在 tests 目录下未搜索到针对 TabNavList 组件中 classNamesstyles 属性的类型测试代码。为确保这两个属性只接受有效的语义名称,建议添加如下类型测试:

  • 为组件传入无效的语义名称时应触发 TypeScript 错误
  • 确认传入正确的语义名称时,不会报错

这将有助于在未来避免因属性值不符合预期而引起的问题。

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

425-427: 建议优化样式合并逻辑

当前实现在处理第一个标签页的样式时使用了条件运算符,可以通过优化合并逻辑使代码更简洁。

建议修改为:

-style={i === 0 ? styles?.item : { ...tabNodeStyle, ...styles?.item }}
+style={{ ...(i === 0 ? {} : tabNodeStyle), ...styles?.item }}
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between ad56db4 and 5cdd44b.

📒 Files selected for processing (1)
  • src/TabNavList/index.tsx (5 hunks)
🔇 Additional comments (2)
src/TabNavList/index.tsx (2)

33-33: 新增的类型和接口定义清晰且符合预期

接口设计合理,使用 Partial<Record> 允许用户只定义需要的样式和类名。

Also applies to: 59-60


616-619: 指示器样式实现正确且优雅

样式和类名的应用方式正确,同时保持了原有的动画功能。

Copy link

@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/TabNavList/index.tsx (2)

115-116: 解构属性命名需要优化

classNames 重命名为 tabsClassNames 是个好的实践,但 styles 也应该遵循同样的命名模式以保持一致性。

建议修改为:

- styles,
+ tabsStyles,

425-427: 样式合并逻辑需要优化

当前的样式合并逻辑对第一个节点做了特殊处理,但实现方式不够优雅。

建议修改为:

- style={i === 0 ? styles?.item : { ...tabNodeStyle, ...styles?.item }}
+ style={{ ...(i !== 0 ? tabNodeStyle : {}), ...styles?.item }}
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 5cdd44b and 7c99121.

📒 Files selected for processing (1)
  • src/TabNavList/index.tsx (6 hunks)
🔇 Additional comments (3)
src/TabNavList/index.tsx (3)

33-33: 新增的类型和接口属性定义清晰且合理

接口扩展通过 SemanticName 类型为不同的组件部分提供了样式自定义能力,设计合理。

Also applies to: 59-60


616-620: 指示器样式实现合理

指示器的类名和样式合并逻辑实现得当,保持了良好的扩展性。


633-633: 弹出层样式传递正确

OperationNode 组件的 popupStyle 属性传递正确。

@zombieJ zombieJ merged commit ca9a372 into react-component:master Feb 20, 2025
9 checks passed
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.

2 participants