Skip to content

refactor: 重构collapse为details实现 #362

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

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

IVLIU
Copy link

@IVLIU IVLIU commented Mar 17, 2025

关联antd ant-design/ant-design#48974

Summary by CodeRabbit

  • Chores

    • 优化项目配置,避免跟踪不必要的依赖锁定文件。
  • 重构

    • 引入平滑的状态切换,提升界面响应体验。
    • 改进折叠显示组件,采用原生控件增强交互语义和无障碍支持。
    • 更新相关接口类型以反映新的HTML元素结构。
  • 新特性

    • 新增开发依赖@rc-component/np以支持项目功能。

Copy link

vercel bot commented Mar 17, 2025

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

Name Status Preview Comments Updated (UTC)
collapse ✅ Ready (Inspect) Visit Preview 💬 Add feedback Mar 19, 2025 7:33am

Copy link

coderabbitai bot commented Mar 17, 2025

Walkthrough

此次修改包含以下变更:

  • .gitignore 文件中新增了一行 pnpm-lock.yaml,使得该文件被忽略。
  • src/Collapse.tsx 中,将 onItemClick 函数中的状态更新使用 React.startTransition 包装,以提升渲染性能。
  • src/Panel.tsx 中,将组件的 HTML 结构由 <div> 更改为 <details><summary>,并更新了转发引用的类型。
  • src/interface.ts 中,相应地将类型声明中的 HTMLDivElement 替换为 HTMLDetailsElement,同时将通用样式对象更新为 React.CSSProperties
  • package.json 中新增了开发依赖 @rc-component/np

Changes

文件 变更摘要
.gitignore 添加 pnpm-lock.yaml 行,以忽略该文件
src/Collapse.tsx onItemClick 中用 React.startTransition 包装状态更新逻辑
src/Panel.tsx
src/interface.ts
更改 HTML 元素和类型:由 HTMLDivElement 改为 HTMLDetailsElement
更新结构(使用 <details><summary>)及样式类型定义
package.json 新增开发依赖 "@rc-component/np": "^1.0.3"

Sequence Diagram(s)

sequenceDiagram
    participant U as 用户
    participant C as Collapse组件
    participant R as React.startTransition
    participant S as setActiveKey

    U->>C: 点击折叠项
    C->>R: 调用状态更新包装
    R->>S: 执行状态更新
    S-->>R: 更新完成
    R-->>C: 渲染更新完成
Loading

Possibly related PRs

Poem

嗨,我是小兔,跳跃在代码间,
.gitignore添新行,锁定了那秘密的关。
startTransition 邀舞动渲染节奏,
<details>展现优雅,语义清晰宛如诗。
代码花开无限可能,🐰✨欢庆每个更新时刻!

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/Panel.tsx

Oops! Something went wrong! :(

ESLint: 8.57.1

ESLint couldn't find the config "prettier" to extend from. Please check that the name of the config is correct.

The config "prettier" was referenced from the config file in "/.eslintrc.js".

If you still have problems, please stop by https://eslint.org/chat/help to chat with the team.

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

@IVLIU IVLIU changed the title feat: 重构collapse为details实现 refactor: 重构collapse为details实现 Mar 17, 2025
@afc163
Copy link
Member

afc163 commented Mar 19, 2025

ci 挂了

Copy link

codecov bot commented Mar 19, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 99.13%. Comparing base (74a99fe) to head (ce3ba4c).

Additional details and impacted files
@@            Coverage Diff             @@
##           master     #362      +/-   ##
==========================================
+ Coverage   99.12%   99.13%   +0.01%     
==========================================
  Files           5        5              
  Lines         114      116       +2     
  Branches       43       43              
==========================================
+ Hits          113      115       +2     
  Misses          1        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.

@IVLIU
Copy link
Author

IVLIU commented Mar 19, 2025

ci 挂了

fixed 少个包

@afc163
Copy link
Member

afc163 commented Mar 19, 2025

收起动画丢了。

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

🧹 Nitpick comments (1)
src/Panel.tsx (1)

45-48: 考虑重新评估 ARIA 角色的必要性

使用 detailssummary 元素后,这些元素已经具有原生的语义和辅助功能。可以考虑是否仍然需要设置 role="tab"role="button" 和其他 ARIA 属性,因为这些可能与元素的原生语义冲突。

HTML5 的 detailssummary 元素原生支持可访问性,无需额外的 ARIA 角色。

Is it necessary to add ARIA roles to details and summary elements?
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between df7f09e and ce3ba4c.

📒 Files selected for processing (1)
  • src/Panel.tsx (5 hunks)
🧰 Additional context used
🧬 Code Definitions (1)
src/Panel.tsx (2)
src/interface.ts (1) (1)
  • CollapsePanelProps (45-67)
src/index.tsx (1) (1)
  • CollapsePanelProps (3-3)
🔇 Additional comments (3)
src/Panel.tsx (3)

8-8: 使用更符合语义的 HTML 元素

forwardRef 类型从 HTMLDivElement 更改为 HTMLDetailsElement 是一个很好的改进,这符合 HTML 语义化的最佳实践,details 元素本身就是为折叠内容设计的。


83-83: 类型定义更新合理

headerProps 的类型从 HTMLDivElement 更改为更通用的 HTMLElement 是合理的,因为现在头部使用的是 summary 元素。


36-39:

❓ Verification inconclusive

请确认事件传播行为是否符合预期

添加 e.stopPropagation() 阻止了事件冒泡,这在某些情况下是必要的,但请确认这不会破坏依赖事件冒泡的父组件功能。


🏁 Script executed:

#!/bin/bash
# 查找可能依赖事件冒泡的代码
rg -A 5 "onItemClick" --type ts --type tsx

Length of output: 70


事件冒泡行为验证建议

文件:src/Panel.tsx (行 36-39)
代码示例:

  onClick: (e: React.MouseEvent) => {
    onItemClick?.(panelKey);
    e.stopPropagation();
  },

说明:

  • 此处调用 e.stopPropagation() 用于阻止事件冒泡,请确认这一行为不会对依赖事件冒泡机制的父组件造成影响。
  • 建议检查项目中其他对 onItemClick 的引用,以确保没有依赖事件继续冒泡的逻辑。

请运行上面的脚本,并手动确认是否有其他地方依赖事件冒泡逻辑,以便确保代码行为符合预期。


🏁 Script executed:

#!/bin/bash
# 重新搜索所有文件中 onItemClick 的使用情况,不限制文件类型
rg -A 5 "onItemClick" || echo "未发现 onItemClick 使用记录"

Length of output: 8169


请确认是否有依赖事件冒泡的父组件逻辑

通过搜索代码可知,代码在 src/Panel.tsx 第 36-39 行设置了如下点击处理逻辑:

onClick: (e: React.MouseEvent) => {
  onItemClick?.(panelKey);
  e.stopPropagation();
},
  • 脚本搜索显示,onItemClick 在多个文件(如 src/interface.ts, src/hooks/useItems.tsxsrc/Panel.tsx)中作为回调使用。测试用例也验证了在点击时 onItemClick 正确触发,并且在禁用或特定场景下,行为符合预期。
  • 从现有代码和测试来看,没有明显依赖点击事件冒泡的父组件逻辑。但由于 e.stopPropagation() 的作用会完全阻断事件冒泡,请您确认在业务场景下父组件或其他外部逻辑是否需要捕获同一事件进行额外处理。

请根据具体业务逻辑,确认后续是否需要调整,以免破坏依赖事件冒泡的父组件的功能。

Comment on lines +91 to +92
<details {...resetProps} ref={ref} className={collapsePanelClassNames} open={isActive}>
<summary {...headerProps}>
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

HTML 结构重构可能影响动画效果

div 替换为 detailssummary 是符合语义化的改进,但根据 PR 描述中的评论,这一变更导致折叠动画效果丢失。虽然代码仍然使用 CSSMotion 组件,但 details 元素的原生行为可能与自定义动画产生冲突。

需要确认:

  1. 动画效果是否已恢复
  2. details 元素的原生展开/折叠行为是否与 CSSMotion 兼容

建议添加必要的样式或逻辑以确保动画效果正常工作。可以考虑:

  1. 使用 CSS 禁用 details 的默认动画
  2. 调整 CSSMotion 配置以适应新的 HTML 结构
/* 可能需要添加的样式 */
details {
  transition: none; /* 禁用默认动画 */
}

Also applies to: 102-102, 128-128

@IVLIU
Copy link
Author

IVLIU commented Mar 19, 2025

收起动画丢了。

我在想有没有必要开个discussion讨论下这个问题
改造前开闭实现其实是利用content的height值变化来实现的,本质上是没有open状态的
改造后基于details的实现其实是有open状态的,即content的可见性是有open决定的,而不是content的height

因此改造后的渲染流程如下

open = true时,content展现,然后高度过渡
open = false时,content隐藏,此时动画不可见

所以我觉得需要讨论下这部分的实现,我先说下我的想法

  1. 渐进式增强,对于高版本浏览器,移除CSSMotion,使用::details-content实现展开关闭动画,对于不支持的,使用CSSMotion实现展开动画
  2. 内部再维护一个动画状态,拦截details的点击事件,优先改变动画状态,待动画执行完毕再改变open状态

个人上是更倾向方式1,这样的话,在高版本浏览器中,组件将变得足够简单,性能也将更上一层楼,仅做状态同步即可

@afc163
Copy link
Member

afc163 commented Mar 19, 2025

1 可以的,我也倾向渐进式。

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