Skip to content

feat(Mermaid): add mermaid.initialize config and headerActions config#1631

Merged
Div627 merged 10 commits intomainfrom
feature_mermaid
Jan 9, 2026
Merged

feat(Mermaid): add mermaid.initialize config and headerActions config#1631
Div627 merged 10 commits intomainfrom
feature_mermaid

Conversation

@Div627
Copy link
Contributor

@Div627 Div627 commented Jan 8, 2026

中文版模板 / Chinese template

🤔 This is a ...

  • 🆕 New feature
  • 🐞 Bug fix
  • 📝 Site / documentation improvement
  • 📽️ Demo improvement
  • 💄 Component style improvement
  • 🤖 TypeScript definition improvement
  • 📦 Bundle size optimization
  • ⚡️ Performance optimization
  • ⭐️ Feature enhancement
  • 🌐 Internationalization
  • 🛠 Refactoring
  • 🎨 Code style optimization
  • ✅ Test Case
  • 🔀 Branch merge
  • ⏩ Workflow
  • ⌨️ Accessibility improvement
  • ❓ Other (about what?)

🔗 Related Issues

  • Describe the source of related requirements, such as links to relevant issue discussions.
  • For example: close #xxxx, fix #xxxx

💡 Background and Solution

  • The specific problem to be addressed.
  • List the final API implementation and usage if needed.
  • If there are UI/interaction changes, consider providing screenshots or GIFs.

📝 Change Log

Language Changelog
🇺🇸 English Add mermaid.initialize config and headerActions config
🇨🇳 Chinese 支持传入 mermaid 初始化配置和配置顶部的操作烂

Summary by CodeRabbit

Summary by CodeRabbit

  • 新功能

    • Mermaid 组件新增 config 与 actions 属性,支持缩放、下载、复制与自定义头部操作;新增 Header Actions 示例并导出默认演示。
  • 改进

    • 按渲染时合并配置初始化,头部动作按渲染类型动态构建,滚轮缩放可控,渲染与交互更稳健。
  • 文档

    • 中/英文文档新增 Header Actions 示例并扩展组件 API 与 FAQ 使用说明。
  • 测试

    • 大幅扩展测试覆盖,增加多种边界、性能与交互场景验证。

✏️ Tip: You can customize this high-level summary in your review settings.

@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Jan 8, 2026

Deploying ant-design-x with  Cloudflare Pages  Cloudflare Pages

Latest commit: b6170d4
Status: ✅  Deploy successful!
Preview URL: https://127005d5.ant-design-x.pages.dev
Branch Preview URL: https://feature-mermaid.ant-design-x.pages.dev

View logs

@github-actions
Copy link
Contributor

github-actions bot commented Jan 8, 2026

Preview failed

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 8, 2026

📝 Walkthrough

Walkthrough

为 Mermaid 组件添加 configactions 公共 props,改为按渲染合并并在渲染时初始化 mermaid,动态构建头部动作并同步更新测试、示例与文档。(不超 50 字)

Changes

内聚组 / 文件(s) 变更摘要
Mermaid 组件核心
packages/x/components/mermaid/Mermaid.tsx
新增 props:config?: MermaidConfigactions?: { enableZoom?: boolean; enableDownload?: boolean; enableCopy?: boolean; customActions?: ItemType[] };移除组件级别早期全局 mermaid.initialize,改为在专用 effect 中基于 `(config
测试与覆盖
packages/x/components/mermaid/__tests__/index.test.tsx
引入 MermaidConfig 类型并定义 MockMermaid 接口,测试中把 require('mermaid') 映射为具名 mock(mockInitialize / mockRender 等);调整断言以验证 mermaid 初始化、render 调用、配置合并、渲染类型切换、头部动作与交互(剪贴板、下载、缩放)行为;增加大量边界与交互场景测试。
演示示例
packages/x/components/mermaid/demo/custom-header.tsx, packages/x/components/mermaid/demo/header-actions.tsx
custom-header.tsx:替换为样式化英文头部并调整外层内边距与示例文本;header-actions.tsx:新增交互示例(默认导出 App 组件),提供复选开关控制 enableZoom/enableDownload/enableCopy/customActions 并演示自定义动作回调与消息提示。
文档(中/英)
packages/x/components/mermaid/index.en-US.md, packages/x/components/mermaid/index.zh-CN.md
文档新增 Header Actions 示例并扩展 API:将 classNames 类型改为 `Partial<Record<'root'

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant MermaidComponent
  participant MermaidLib as mermaid
  participant ActionsUI
  participant Browser

  User->>MermaidComponent: 提供 content 与 props (config, actions)
  MermaidComponent->>MermaidComponent: 合并 config,决定 renderType 与 header 动作
  MermaidComponent->>MermaidLib: mermaid.initialize(mergedConfig)
  MermaidComponent->>MermaidLib: mermaid.parse / mermaid.render(content)
  MermaidLib-->>MermaidComponent: 返回渲染结果 (SVG/HTML) 或错误
  MermaidComponent->>ActionsUI: 提供基于 renderType 与 actions 的 allItems 并渲染头部
  User->>ActionsUI: 触发动作(缩放/下载/复制/自定义)
  ActionsUI->>Browser: 执行下载/复制/缩放等浏览器交互
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

诗篇

我是小兔在图里跳,🐰
每次渲染带新配巧妙,
头部按钮随你开与闭,
缩放下载复制都能要,
自定义动作一并庆跑 ✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 标题准确总结了主要变更:为 Mermaid 组件添加 mermaid.initialize 配置和 headerActions 配置支持。
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 feature_mermaid

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.

@dosubot dosubot bot added the enhancement New feature or request label Jan 8, 2026
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @Div627, 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 significantly enhances the Mermaid component by introducing new configuration capabilities. It allows developers to customize the Mermaid diagram's initialization settings through a dedicated config prop and provides fine-grained control over the header actions (like zoom, download, and copy) via a new headerActions prop. These additions make the Mermaid component more flexible and adaptable to various application requirements, enabling dynamic styling and interactive element management.

Highlights

  • Mermaid Configuration (config prop): Introduced a new config prop to the Mermaid component, allowing users to pass custom MermaidConfig options for dynamic initialization of Mermaid diagrams.
  • Header Actions Customization (headerActions prop): Added a headerActions prop to control the visibility of default header buttons (zoom, download, copy) and to include custom actions in the Mermaid component's header.
  • Dynamic Initialization: The mermaid.initialize call has been refactored and now dynamically applies configuration settings, including those provided via the new config prop, before rendering the diagram.
  • Enhanced Test Coverage: New test cases have been added to thoroughly validate the functionality of both the config and headerActions props, ensuring robust and predictable behavior.

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

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.

@Div627 Div627 linked an issue Jan 8, 2026 that may be closed by this pull request
@codecov
Copy link

codecov bot commented Jan 8, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 97.17%. Comparing base (0bb44d8) to head (b6170d4).
⚠️ Report is 11 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #1631   +/-   ##
=======================================
  Coverage   97.16%   97.17%           
=======================================
  Files         140      140           
  Lines        4273     4288   +15     
  Branches     1187     1209   +22     
=======================================
+ Hits         4152     4167   +15     
  Misses        119      119           
  Partials        2        2           

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

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 introduces valuable new features for configuring the Mermaid component, specifically for mermaid.initialize and header actions. The implementation is solid, and the addition of comprehensive tests is a great effort. I have a few suggestions to enhance performance and improve the test suite's correctness and clarity. My feedback focuses on optimizing the Mermaid initialization logic and refining some of the test cases.

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

🤖 Fix all issues with AI agents
In @packages/x/components/mermaid/Mermaid.tsx:
- Line 106: The regex used to trim trailing backticks/whitespace in the
assignment to cleanContent (children.replace(/[`\s]+$/g, '')) can cause
performance issues; remove the unnecessary global flag and use a
single-end-anchor replace instead (i.e., replace with a regex without the 'g'
flag) so change the call on children.replace used to create cleanContent to use
/[`\s]+$/ (no g) to avoid backtracking overhead.
🧹 Nitpick comments (1)
packages/x/components/mermaid/Mermaid.tsx (1)

98-104: 考虑仅在 config 变化时重新初始化。

当前实现在每次渲染时都调用 mermaid.initialize()(虽然有节流)。如果 config 没有改变,这可能会造成不必要的性能开销。

♻️ 优化建议:使用 useMemo 缓存配置
+ const mermaidConfig = useMemo(() => ({
+   startOnLoad: false,
+   securityLevel: 'strict',
+   theme: 'default',
+   fontFamily: 'monospace',
+   ...(config || {}),
+ }), [config]);

  const renderDiagram = throttle(async () => {
    if (!children || !containerRef.current || renderType === RenderType.Code) return;

    try {
-     mermaid.initialize({
-       startOnLoad: false,
-       securityLevel: 'strict',
-       theme: 'default',
-       fontFamily: 'monospace',
-       ...(config || {}),
-     });
+     mermaid.initialize(mermaidConfig);

      const cleanContent = children.replace(/[`\s]+$/g, '');
      const { svg } = await mermaid.render(id, cleanContent);
      containerRef.current.innerHTML = svg;
    } catch (error) {
      warning(false, 'Mermaid', `Render failed: ${error}`);
    }
  }, 100);

这样可以确保只有在 config 真正改变时才重新创建配置对象,减少不必要的初始化。

📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 86b380e and a35a195.

📒 Files selected for processing (2)
  • packages/x/components/mermaid/Mermaid.tsx
  • packages/x/components/mermaid/__tests__/index.test.tsx
🧰 Additional context used
🪛 GitHub Check: CodeQL
packages/x/components/mermaid/Mermaid.tsx

[failure] 106-106: Polynomial regular expression used on uncontrolled data
This regular expression that depends on library input may run slow on strings with many repetitions of '\t'.

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: build preview
  • GitHub Check: size
  • GitHub Check: test
  • GitHub Check: Cloudflare Pages
🔇 Additional comments (10)
packages/x/components/mermaid/Mermaid.tsx (5)

5-5: LGTM!

导入 MermaidConfig 类型并添加 config 属性定义正确,可选属性保证了向后兼容性。

Also applies to: 26-26


27-32: LGTM!

headerActions 属性设计合理,通过可选标志位控制内置操作的显示,customActions 支持自定义操作扩展。


56-57: LGTM!

属性解构正确,headerActions = {} 的默认值保证了向后兼容性和类型安全。


237-290: LGTM!

动态操作按钮构建逻辑清晰,默认值保证了向后兼容性。根据 renderTypeheaderActions 配置正确地条件渲染缩放、下载和复制功能,customActions 的合并也处理得当。


312-312: LGTM!

将合并后的操作列表传递给 Actions 组件的实现正确。

packages/x/components/mermaid/__tests__/index.test.tsx (5)

2-2: LGTM!

添加 MermaidConfig 类型导入和 MockMermaid 接口定义提升了测试代码的类型安全性,mock 方法的类型标注正确。

Also applies to: 57-62


67-70: LGTM!

将 mermaid mock 转换为 MockMermaid 类型并提取 mock 方法的实现正确,确保了整个测试文件的类型安全。


939-979: LGTM!

配置测试覆盖全面,验证了自定义配置与默认配置的合并逻辑,包括完整配置覆盖和部分配置覆盖两种场景。测试断言使用 expect.objectContaining 保证了灵活性。


981-1018: LGTM!

headerActions 配置测试覆盖完整,验证了 showZoomshowDownloadshowCopy 三个标志位的功能,以及自定义操作的渲染。测试正确使用 queryByLabelText 验证元素不存在的情况。


808-1187: LGTM!

新增的测试用例覆盖全面,包括:

  • 边界条件测试(大型图表、特殊字符、空白处理、快速切换)
  • 性能测试(节流、内存清理、并发渲染)
  • 可访问性测试(ARIA 属性、键盘导航)
  • 集成测试(上下文配置合并)

测试质量高,显著提升了组件的健壮性和可靠性。

@github-actions
Copy link
Contributor

github-actions bot commented Jan 8, 2026

size-limit report 📦

Path Size
packages/x/dist/antdx.min.js 441.46 KB (+76 B 🔺)
packages/x-sdk/dist/x-sdk.min.js 7.58 KB
packages/x-markdown/dist/x-markdown.min.js 28.77 KB
packages/x-markdown/dist/plugins/latex.min.js 61.95 KB

@codecov
Copy link

codecov bot commented Jan 8, 2026

Bundle Report

Changes will decrease total bundle size by 1.26MB (-40.34%) ⬇️. This is within the configured threshold ✅

Detailed changes
Bundle name Size Change
x-markdown-array-push 106.64kB -1.26MB (-92.21%) ⬇️
antdx-array-push 1.76MB 165 bytes (0.01%) ⬆️

Affected Assets, Files, and Routes:

view changes for bundle: x-markdown-array-push

Assets Changed:

Asset Name Size Change Total Size Change (%)
x-markdown.min.js (New) 103.89kB 103.89kB 100.0% 🚀
x-markdown.min.css (New) 2.75kB 2.75kB 100.0% 🚀
latex.min.js (Deleted) -268.81kB 0 bytes -100.0% 🗑️
static/KaTeX_AMS-Regular.*.ttf (Deleted) -63.63kB 0 bytes -100.0% 🗑️
static/KaTeX_Main-Regular.*.ttf (Deleted) -53.58kB 0 bytes -100.0% 🗑️
static/KaTeX_Main-Bold.*.ttf (Deleted) -51.34kB 0 bytes -100.0% 🗑️
static/KaTeX_Main-Italic.*.ttf (Deleted) -33.58kB 0 bytes -100.0% 🗑️
static/KaTeX_AMS-Regular.*.woff (Deleted) -33.52kB 0 bytes -100.0% 🗑️
static/KaTeX_Main-BoldItalic.*.ttf (Deleted) -32.97kB 0 bytes -100.0% 🗑️
static/KaTeX_Math-Italic.*.ttf (Deleted) -31.31kB 0 bytes -100.0% 🗑️
static/KaTeX_Math-BoldItalic.*.ttf (Deleted) -31.2kB 0 bytes -100.0% 🗑️
static/KaTeX_Main-Regular.*.woff (Deleted) -30.77kB 0 bytes -100.0% 🗑️
static/KaTeX_Main-Bold.*.woff (Deleted) -29.91kB 0 bytes -100.0% 🗑️
static/KaTeX_AMS-Regular.*.woff2 (Deleted) -28.08kB 0 bytes -100.0% 🗑️
static/KaTeX_Typewriter-Regular.*.ttf (Deleted) -27.56kB 0 bytes -100.0% 🗑️
static/KaTeX_Main-Regular.*.woff2 (Deleted) -26.27kB 0 bytes -100.0% 🗑️
static/KaTeX_Main-Bold.*.woff2 (Deleted) -25.32kB 0 bytes -100.0% 🗑️
static/KaTeX_SansSerif-Bold.*.ttf (Deleted) -24.5kB 0 bytes -100.0% 🗑️
latex.min.css (Deleted) -24.32kB 0 bytes -100.0% 🗑️
static/KaTeX_SansSerif-Italic.*.ttf (Deleted) -22.36kB 0 bytes -100.0% 🗑️
static/KaTeX_Main-Italic.*.woff (Deleted) -19.68kB 0 bytes -100.0% 🗑️
static/KaTeX_Fraktur-Bold.*.ttf (Deleted) -19.58kB 0 bytes -100.0% 🗑️
static/KaTeX_Fraktur-Regular.*.ttf (Deleted) -19.57kB 0 bytes -100.0% 🗑️
static/KaTeX_SansSerif-Regular.*.ttf (Deleted) -19.44kB 0 bytes -100.0% 🗑️
static/KaTeX_Main-BoldItalic.*.woff (Deleted) -19.41kB 0 bytes -100.0% 🗑️
static/KaTeX_Math-Italic.*.woff (Deleted) -18.75kB 0 bytes -100.0% 🗑️
static/KaTeX_Math-BoldItalic.*.woff (Deleted) -18.67kB 0 bytes -100.0% 🗑️
static/KaTeX_Main-Italic.*.woff2 (Deleted) -16.99kB 0 bytes -100.0% 🗑️
static/KaTeX_Main-BoldItalic.*.woff2 (Deleted) -16.78kB 0 bytes -100.0% 🗑️
static/KaTeX_Script-Regular.*.ttf (Deleted) -16.65kB 0 bytes -100.0% 🗑️
static/KaTeX_Math-Italic.*.woff2 (Deleted) -16.44kB 0 bytes -100.0% 🗑️
static/KaTeX_Math-BoldItalic.*.woff2 (Deleted) -16.4kB 0 bytes -100.0% 🗑️
static/KaTeX_Typewriter-Regular.*.woff (Deleted) -16.03kB 0 bytes -100.0% 🗑️
static/KaTeX_SansSerif-Bold.*.woff (Deleted) -14.41kB 0 bytes -100.0% 🗑️
static/KaTeX_SansSerif-Italic.*.woff (Deleted) -14.11kB 0 bytes -100.0% 🗑️
static/KaTeX_Typewriter-Regular.*.woff2 (Deleted) -13.57kB 0 bytes -100.0% 🗑️
static/KaTeX_Fraktur-Bold.*.woff (Deleted) -13.3kB 0 bytes -100.0% 🗑️
static/KaTeX_Fraktur-Regular.*.woff (Deleted) -13.21kB 0 bytes -100.0% 🗑️
static/KaTeX_Caligraphic-Bold.*.ttf (Deleted) -12.37kB 0 bytes -100.0% 🗑️
static/KaTeX_Caligraphic-Regular.*.ttf (Deleted) -12.34kB 0 bytes -100.0% 🗑️
static/KaTeX_SansSerif-Regular.*.woff (Deleted) -12.32kB 0 bytes -100.0% 🗑️
static/KaTeX_Size1-Regular.*.ttf (Deleted) -12.23kB 0 bytes -100.0% 🗑️
static/KaTeX_SansSerif-Bold.*.woff2 (Deleted) -12.22kB 0 bytes -100.0% 🗑️
static/KaTeX_SansSerif-Italic.*.woff2 (Deleted) -12.03kB 0 bytes -100.0% 🗑️
static/KaTeX_Size2-Regular.*.ttf (Deleted) -11.51kB 0 bytes -100.0% 🗑️
static/KaTeX_Fraktur-Bold.*.woff2 (Deleted) -11.35kB 0 bytes -100.0% 🗑️
static/KaTeX_Fraktur-Regular.*.woff2 (Deleted) -11.32kB 0 bytes -100.0% 🗑️
static/KaTeX_Script-Regular.*.woff (Deleted) -10.59kB 0 bytes -100.0% 🗑️
static/KaTeX_Size4-Regular.*.ttf (Deleted) -10.36kB 0 bytes -100.0% 🗑️
static/KaTeX_SansSerif-Regular.*.woff2 (Deleted) -10.34kB 0 bytes -100.0% 🗑️
static/KaTeX_Script-Regular.*.woff2 (Deleted) -9.64kB 0 bytes -100.0% 🗑️
static/KaTeX_Caligraphic-Bold.*.woff (Deleted) -7.72kB 0 bytes -100.0% 🗑️
static/KaTeX_Caligraphic-Regular.*.woff (Deleted) -7.66kB 0 bytes -100.0% 🗑️
static/KaTeX_Size3-Regular.*.ttf (Deleted) -7.59kB 0 bytes -100.0% 🗑️
static/KaTeX_Caligraphic-Bold.*.woff2 (Deleted) -6.91kB 0 bytes -100.0% 🗑️
static/KaTeX_Caligraphic-Regular.*.woff2 (Deleted) -6.91kB 0 bytes -100.0% 🗑️
static/KaTeX_Size1-Regular.*.woff (Deleted) -6.5kB 0 bytes -100.0% 🗑️
static/KaTeX_Size2-Regular.*.woff (Deleted) -6.19kB 0 bytes -100.0% 🗑️
static/KaTeX_Size4-Regular.*.woff (Deleted) -5.98kB 0 bytes -100.0% 🗑️
static/KaTeX_Size1-Regular.*.woff2 (Deleted) -5.47kB 0 bytes -100.0% 🗑️
static/KaTeX_Size2-Regular.*.woff2 (Deleted) -5.21kB 0 bytes -100.0% 🗑️
static/KaTeX_Size4-Regular.*.woff2 (Deleted) -4.93kB 0 bytes -100.0% 🗑️
static/KaTeX_Size3-Regular.*.woff (Deleted) -4.42kB 0 bytes -100.0% 🗑️
static/KaTeX_Size3-Regular.*.woff2 (Deleted) -3.62kB 0 bytes -100.0% 🗑️
view changes for bundle: antdx-array-push

Assets Changed:

Asset Name Size Change Total Size Change (%)
antdx.min.js 165 bytes 1.76MB 0.01%

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/x/components/mermaid/Mermaid.tsx (1)

140-140: 缺少 config 依赖项导致配置变更不生效。

useEffect 的依赖数组中缺少 config,这意味着当用户动态更改 config prop 时,不会触发重新渲染。这会导致配置更新被忽略,直到 childrenrenderType 发生变化。

💡 添加缺失的依赖项
  useEffect(() => {
    if (renderType === RenderType.Code && containerRef.current) {
      // 清理图表内容,避免在代码视图下出现渲染错误
      containerRef.current.innerHTML = '';
    } else {
      renderDiagram();
    }
-  }, [children, renderType]);
+  }, [children, renderType, config]);

注意:由于 renderDiagram 是在组件函数体内定义的,它会在每次渲染时重新创建。为了避免不必要的效果触发,建议使用 useCallback 包装 renderDiagram

🤖 Fix all issues with AI agents
In @packages/x/components/mermaid/demo/header-actions.tsx:
- Around line 21-28: The Share menu item (key: 'share', icon: ShareAltOutlined)
currently calls onItemClick which only invokes message.success('Chart link
copied to clipboard') without performing any clipboard action; either change the
toast to a generic message like "Share button clicked" or implement actual
clipboard logic inside the onItemClick handler to copy the intended chart
URL/text and then call message.success with a matching confirmation; update the
onItemClick for the 'share' item and ensure any referenced value (chart link or
serialized chart) is available when invoking navigator.clipboard.writeText(...)
or the alternative copy fallback before showing message.success.

In @packages/x/components/mermaid/Mermaid.tsx:
- Line 125: Replace the vulnerable regex usage in the Mermaid component where
cleanContent is created via children.replace(/[`\s]+$/, '') with a safe
non-regex approach: use children.trimEnd() (or children.replaceAll/backed by a
fixed algorithm if preserving trailing backticks is required) to remove trailing
whitespace without risking ReDoS; update the assignment to set cleanContent from
children.trimEnd() and ensure any logic depending on the previous regex behavior
still holds.
🧹 Nitpick comments (3)
packages/x/components/mermaid/__tests__/index.test.tsx (1)

846-874: 存在重复的测试用例。

Lines 846-859 和 861-874 的两个测试用例(should handle null config propshould handle undefined config prop)在实现上完全相同,都测试 config={undefined} 的情况。建议合并这两个测试用例,或者如果需要分别测试 null 和 undefined,请确保测试用例确实测试了不同的输入。

♻️ 建议的重构
-    it('should handle null config prop', async () => {
-      render(<Mermaid config={undefined}>{mermaidContent}</Mermaid>);
-
-      await waitFor(() => {
-        expect(mockInitialize).toHaveBeenCalledWith(
-          expect.objectContaining({
-            startOnLoad: false,
-            securityLevel: 'strict',
-            theme: 'default',
-            fontFamily: 'monospace',
-          }),
-        );
-      });
-    });
-
-    it('should handle undefined config prop', async () => {
+    it('should handle null and undefined config prop', async () => {
       render(<Mermaid config={undefined}>{mermaidContent}</Mermaid>);

       await waitFor(() => {
         expect(mockInitialize).toHaveBeenCalledWith(
           expect.objectContaining({
             startOnLoad: false,
             securityLevel: 'strict',
             theme: 'default',
             fontFamily: 'monospace',
           }),
         );
       });
     });
packages/x/components/mermaid/Mermaid.tsx (2)

44-54: 浅比较可能无法检测嵌套配置变化。

第 53 行使用浅比较(!==)来检测配置变化,这对于 MermaidConfig 中的嵌套对象或数组类型属性可能无法检测到深层变化。例如,如果用户只修改了嵌套对象的某个属性,变化将不会被检测到。

对于大多数场景,这种实现已经足够且性能良好,但建议在文档中说明此限制,或者如果用户报告配置未生效的问题,可以考虑使用深度比较。


107-107: 建议添加节流函数的清理逻辑。

renderDiagram 使用 throttle 包装,但没有在组件卸载时调用清理。虽然在实践中影响较小,但添加清理逻辑是最佳实践,可以防止潜在的内存泄漏。

♻️ 建议的清理实现

使用 useCallbackuseEffect 来管理节流函数的生命周期:

-  const renderDiagram = throttle(async () => {
+  const renderDiagramFn = useCallback(async () => {
     if (!children || !containerRef.current || renderType === RenderType.Code) return;
 
     try {
       if (isConfigChanged(lastConfigRef.current, config)) {
         mermaid.initialize({
           startOnLoad: false,
           securityLevel: 'strict',
           theme: 'default',
           fontFamily: 'monospace',
           ...(config || {}),
         });
         lastConfigRef.current = config;
       }
 
       const isValid = await mermaid.parse(children, { suppressErrors: true });
       if (!isValid) throw new Error('Invalid Mermaid syntax');
 
       const cleanContent = children.trimEnd().replace(/`+$/, '');
       const { svg } = await mermaid.render(id, cleanContent);
       containerRef.current.innerHTML = svg;
     } catch (error) {
       warning(false, 'Mermaid', `Render failed: ${error}`);
     }
-  }, 100);
+  }, [children, renderType, config]);
+
+  const renderDiagram = useMemo(() => throttle(renderDiagramFn, 100), [renderDiagramFn]);
+
+  useEffect(() => {
+    return () => {
+      renderDiagram.cancel();
+    };
+  }, [renderDiagram]);
📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a35a195 and b472fad.

📒 Files selected for processing (6)
  • packages/x/components/mermaid/Mermaid.tsx
  • packages/x/components/mermaid/__tests__/index.test.tsx
  • packages/x/components/mermaid/demo/custom-header.tsx
  • packages/x/components/mermaid/demo/header-actions.tsx
  • packages/x/components/mermaid/index.en-US.md
  • packages/x/components/mermaid/index.zh-CN.md
🧰 Additional context used
🪛 GitHub Check: CodeQL
packages/x/components/mermaid/Mermaid.tsx

[failure] 125-125: Polynomial regular expression used on uncontrolled data
This regular expression that depends on library input may run slow on strings with many repetitions of '\t'.

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: size
  • GitHub Check: build preview
  • GitHub Check: test
  • GitHub Check: test
  • GitHub Check: Cloudflare Pages
🔇 Additional comments (12)
packages/x/components/mermaid/demo/custom-header.tsx (1)

1-38: 示例代码清晰,展示了自定义 header 的用法。

代码结构合理,样式设置恰当,能够清楚地演示如何使用自定义 header 功能。Export 和 Reset 按钮作为示例占位符是合理的。

packages/x/components/mermaid/index.zh-CN.md (1)

24-42: 文档更新完整,准确反映了新增的 API。

新增的 demo 引用和 API 属性说明清晰,类型定义准确,默认值也已明确标注。文档与代码实现保持一致。

packages/x/components/mermaid/demo/header-actions.tsx (1)

38-71: 示例实现清晰,有效展示了 headerActions 的配置能力。

交互式的配置界面能够很好地演示各个 headerActions 选项的效果,代码结构清晰,易于理解。

packages/x/components/mermaid/__tests__/index.test.tsx (4)

58-71: 类型定义改进提升了测试代码的类型安全性。

引入 MockMermaid 接口并进行显式类型转换,使测试代码更加清晰和类型安全。这是一个良好的实践。


940-980: 配置测试覆盖全面,验证了配置合并逻辑。

测试用例正确验证了自定义配置与默认配置的合并行为,以及部分配置覆盖的场景。


982-1030: headerActions 测试覆盖充分,验证了各项配置选项。

测试用例完整地验证了 showZoomshowDownloadshowCopy 以及 customActions 的功能,确保配置能够正确控制 UI 元素的显示与隐藏。


809-1200: 新增测试覆盖全面,包含边界条件、性能和集成场景。

测试套件涵盖了大量边界情况、特殊字符处理、性能场景以及与上下文的集成,为新增的 configheaderActions 功能提供了充分的测试保障。

packages/x/components/mermaid/index.en-US.md (1)

23-41: 英文文档更新准确,与中文文档保持一致。

新增的 demo 引用和 API 属性说明清晰完整,类型定义和默认值标注准确,与代码实现和中文文档保持一致。

packages/x/components/mermaid/Mermaid.tsx (4)

5-5: LGTM!类型定义清晰且结构合理。

新增的 configheaderActions props 提供了灵活的配置能力,所有字段都是可选的,保证了向后兼容性。

Also applies to: 26-32


111-120: 初始化逻辑合理,但需修复依赖项问题。

条件初始化逻辑实现正确,只在配置变化时重新初始化 mermaid,避免了不必要的性能开销。合并配置的方式也很合理,允许用户覆盖默认配置。

但请注意,第 140 行的 useEffect 缺少 config 依赖项,这会导致配置变更不触发重新渲染(详见该行的单独评论)。


142-167: LGTM!缩放功能的条件启用实现正确。

正确地根据 headerActions.showZoom 配置来控制缩放功能的启用,并且依赖项也正确包含了 headerActions。实现清晰且符合预期。


259-312: LGTM!动态操作构建逻辑实现优雅且功能完整。

renderHeader 的重构非常出色:

  • 根据 renderTypeheaderActions 配置动态构建操作项
  • 合理的默认值(缩放、下载、复制默认启用)
  • 支持通过 customActions 扩展自定义操作
  • 代码结构清晰,易于维护

这种实现方式为用户提供了很大的灵活性。

Also applies to: 334-334

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

🤖 Fix all issues with AI agents
In @packages/x/components/mermaid/Mermaid.tsx:
- Line 126: The current replacement using the regex /[`\s]+$/ in Mermaid.tsx
(assigning to cleanContent from children) is flagged for potential ReDoS; change
it to a safer approach by first removing trailing whitespace and then removing
trailing backticks (e.g., two separate replaces on children: one using a simple
/\s+$/ to strip trailing whitespace and another using /`+$/ to strip trailing
backticks) so you avoid the combined backtracking pattern; update the assignment
to cleanContent accordingly and keep references to the original children value.
- Around line 44-54: isConfigChanged currently performs only a shallow
comparison and will miss changes inside nested objects of MermaidConfig (e.g.,
config.flowchart.htmlLabels); replace the shallow logic in isConfigChanged with
a deep equality check (for example use lodash.isEqual) to compare prev and next,
or alternatively recursively compare nested keys of MermaidConfig, ensuring to
import and call the deep-equal utility where isConfigChanged is defined so
nested property changes are detected.
📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b472fad and 34f9e12.

📒 Files selected for processing (1)
  • packages/x/components/mermaid/Mermaid.tsx
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: afc163
Repo: ant-design/x PR: 0
File: :0-0
Timestamp: 2025-04-11T14:47:09.527Z
Learning: 当评审 ant-design/x 仓库中的 PR 时,需要用中文回复中文评论。该项目的文档支持中英双语。
Learnt from: afc163
Repo: ant-design/x PR: 0
File: :0-0
Timestamp: 2025-04-11T14:47:09.527Z
Learning: 当评审 ant-design/x 仓库中的 PR 时,需要用中文回复中文评论。该项目的文档支持中英双语。
🪛 GitHub Check: CodeQL
packages/x/components/mermaid/Mermaid.tsx

[failure] 126-126: Polynomial regular expression used on uncontrolled data
This regular expression that depends on library input may run slow on strings with many repetitions of '\t'.

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: build preview
  • GitHub Check: size
  • GitHub Check: test
  • GitHub Check: test
  • GitHub Check: Cloudflare Pages
🔇 Additional comments (5)
packages/x/components/mermaid/Mermaid.tsx (5)

26-32: 新功能 API 设计合理

configheaderActions 的 API 设计清晰,类型定义完整。默认值处理(如 showZoomshowDownloadshowCopy 默认为 true)在后续代码中实现得当。


111-121: 按需初始化逻辑正确

将 mermaid 初始化从全局改为按需执行是合理的设计。默认配置(startOnLoad: falsesecurityLevel: 'strict' 等)安全且合理,配置合并逻辑正确。


260-313: 动态操作栏构建逻辑清晰

根据 renderTypeheaderActions 配置动态构建操作项的逻辑实现得很好:

  • 默认值合理(均为 true
  • 图表模式显示缩放和下载,代码模式显示复制
  • customActions 正确地追加到内置操作之后

147-148: 缩放控制门控正确

通过 showZoom 标志来控制是否添加滚轮事件监听器的实现是正确的,避免了不必要的事件处理。


168-168: 确保 headerActions 对象引用的稳定性

headerActions 添加到依赖数组是正确的,但在当前的 demo 实现中(header-actions.tsx 第 31-36 行),headerActions 对象在每次父组件渲染时都会被重新创建,这会导致该 effect 不必要地频繁重新执行。

建议在父组件中使用 useMemo 来稳定 headerActions 的引用,避免频繁触发 wheel handler 的事件监听器重新绑定。例如:

const headerActions = useMemo(() => ({
  showZoom,
  showDownload,
  showCopy,
  ...(showCustom && { customActions }),
}), [showZoom, showDownload, showCopy, showCustom, customActions]);

或者,组件内部可以考虑对 headerActions 进行浅比较,而不是依赖整个对象的引用相等性。

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

🤖 Fix all issues with AI agents
In @packages/x/components/mermaid/Mermaid.tsx:
- Around line 98-104: The code currently calls mermaid.initialize inside
renderDiagram (causing repeated global re-inits on children/renderType/config
changes); move the single global mermaid.initialize call out of renderDiagram
and invoke it once at application/component startup (e.g., in the Mermaid
component mount logic or app init) to set defaults; keep per-diagram
customizations by using Mermaid init directive comments (%%{init: {...}}%%) or
pass config overrides to mermaid.render instead of re-calling
mermaid.initialize; update references to renderDiagram, config, children, and
renderType accordingly so they only render/parse diagrams without
re-initializing mermaid.
📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 34f9e12 and 8e856a0.

📒 Files selected for processing (1)
  • packages/x/components/mermaid/Mermaid.tsx
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: afc163
Repo: ant-design/x PR: 0
File: :0-0
Timestamp: 2025-04-11T14:47:09.527Z
Learning: 当评审 ant-design/x 仓库中的 PR 时,需要用中文回复中文评论。该项目的文档支持中英双语。
Learnt from: afc163
Repo: ant-design/x PR: 0
File: :0-0
Timestamp: 2025-04-11T14:47:09.527Z
Learning: 当评审 ant-design/x 仓库中的 PR 时,需要用中文回复中文评论。该项目的文档支持中英双语。
🪛 GitHub Check: CodeQL
packages/x/components/mermaid/Mermaid.tsx

[failure] 109-109: Polynomial regular expression used on uncontrolled data
This regular expression that depends on library input may run slow on strings with many repetitions of '\t'.

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: build preview
  • GitHub Check: size
  • GitHub Check: test
  • GitHub Check: test
  • GitHub Check: Cloudflare Pages
🔇 Additional comments (6)
packages/x/components/mermaid/Mermaid.tsx (6)

5-5: 类型导入正确

正确导入了 MermaidConfig 类型用于类型注解,符合 TypeScript 最佳实践。


26-32: 新增 props 定义合理

configheaderActions 的类型定义清晰,所有字段均为可选,保证了向后兼容性。


56-57: props 提取正确

headerActions 提供空对象默认值是合理的,避免了后续解构时的空值问题。


124-124: 依赖项更新正确

正确将 config 添加到 useEffect 依赖数组,确保配置变更时重新渲染图表。


130-132: 缩放控制逻辑正确

正确根据 showZoom 标志控制滚轮缩放功能的启用,并将 headerActions 添加到依赖项中确保配置变更时正确重新初始化事件监听器。

Also applies to: 151-151


243-296: 动态 action 构建实现正确

正确根据 renderTypeheaderActions 配置动态构建操作按钮列表:

  • 图片模式:根据标志显示缩放和下载操作
  • 代码模式:根据标志显示复制操作
  • 正确追加自定义操作,提供良好的扩展性

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
packages/x/components/mermaid/Mermaid.tsx (2)

94-114: 修复 throttle 函数重复创建问题

每次组件重新渲染时,throttle 都会创建一个新的节流函数,这导致:

  1. 节流效果失效
  2. 内存泄漏(旧的节流函数未清理)
  3. 性能下降
🔧 建议使用 useCallback 包裹节流函数
+  const renderDiagram = React.useCallback(
+    throttle(async () => {
       if (!children || !containerRef.current || renderType === RenderType.Code) return;

       try {
         mermaid.initialize({
           startOnLoad: false,
           securityLevel: 'strict',
           theme: 'default',
           fontFamily: 'monospace',
           ...(config || {}),
         });

         const isValid = await mermaid.parse(children, { suppressErrors: true });
         if (!isValid) throw new Error('Invalid Mermaid syntax');

         const { svg } = await mermaid.render(id, children);
         containerRef.current.innerHTML = svg;
       } catch (error) {
         warning(false, 'Mermaid', `Render failed: ${error}`);
       }
-    }, 100);
+    }, 100),
+    [children, renderType, config, id]
+  );

注意:这种方式下,throttle 本身仍会在依赖变化时重新创建。更优方案是使用 useMemo 包裹 throttle 或使用 useRef 保存节流函数。


125-150: headerActions 对象依赖存在同样的重渲染风险

config 类似,headerActions 作为对象依赖项可能导致 wheel 事件监听器频繁注销和重新绑定。

♻️ 优化建议:仅依赖实际使用的值
+  const { showZoom = true } = headerActions;
+
   useEffect(() => {
     const container = containerRef.current;
     if (!container || renderType !== RenderType.Image) return;

-    const { showZoom = true } = headerActions;
     if (!showZoom) return;

     let lastTime = 0;
     const wheelHandler = (e: WheelEvent) => {
       // ... wheel handler logic
     };

     container.addEventListener('wheel', wheelHandler, { passive: false });

     return () => {
       container.removeEventListener('wheel', wheelHandler);
     };
-  }, [renderType, headerActions]);
+  }, [renderType, showZoom]);

这样只有 showZoom 的实际值变化时才会重新绑定事件。

🧹 Nitpick comments (2)
packages/x/components/mermaid/Mermaid.tsx (2)

238-320: 建议提取 header actions 构建逻辑以提升可维护性

renderHeader 函数较长(约 80 行),其中 actions 构建逻辑(lines 242-295)可以提取为独立的辅助函数或自定义 hook,提高代码可读性和可测试性。

💡 可选重构示例
// 提取到组件外部或单独文件
const buildHeaderActions = (
  renderType: RenderType,
  headerActions: MermaidProps['headerActions'],
  contextLocale: any,
  handlers: {
    handleZoomIn: () => void;
    handleZoomOut: () => void;
    handleReset: () => void;
    handleDownload: () => void;
  },
  children: string
): ItemType[] => {
  const {
    showZoom = true,
    showDownload = true,
    showCopy = true,
    customActions = [],
  } = headerActions || {};

  const items: ItemType[] = [];

  if (renderType === RenderType.Image) {
    if (showZoom) {
      items.push(/* zoom actions */);
    }
    if (showDownload) {
      items.push(/* download action */);
    }
  } else {
    if (showCopy) {
      items.push(/* copy action */);
    }
  }

  return [...items, ...customActions];
};

// 在 renderHeader 中使用
const allItems = buildHeaderActions(
  renderType,
  headerActions,
  contextLocale,
  { handleZoomIn, handleZoomOut, handleReset, handleDownload },
  children
);

123-123: config 属性添加使用指导,避免不必要的 effect 重新运行

虽然 config 是可选的,但如果在父组件中传递新的对象引用(即使值相同),useEffect 会频繁执行。虽然组件本身通过 React.memo() 保护,但 effect 的重复运行仍可能导致不必要的图表初始化。

建议在 API 文档中明确说明:如果需要传递 config 属性,应使用 useMemo 等方式保持引用稳定,或确保 config 对象在组件层级中是常量。

📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8e856a0 and c45fc64.

📒 Files selected for processing (1)
  • packages/x/components/mermaid/Mermaid.tsx
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: afc163
Repo: ant-design/x PR: 0
File: :0-0
Timestamp: 2025-04-11T14:47:09.527Z
Learning: 当评审 ant-design/x 仓库中的 PR 时,需要用中文回复中文评论。该项目的文档支持中英双语。
Learnt from: afc163
Repo: ant-design/x PR: 0
File: :0-0
Timestamp: 2025-04-11T14:47:09.527Z
Learning: 当评审 ant-design/x 仓库中的 PR 时,需要用中文回复中文评论。该项目的文档支持中英双语。
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: build preview
  • GitHub Check: test
  • GitHub Check: size
  • GitHub Check: test
🔇 Additional comments (1)
packages/x/components/mermaid/Mermaid.tsx (1)

5-5: API 设计清晰,类型定义完善

使用 mermaid 官方的 MermaidConfig 类型,headerActions 的接口设计合理,既支持开关控制内置操作,也支持自定义扩展。

Also applies to: 26-32

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

🤖 Fix all issues with AI agents
In @packages/x/components/mermaid/Mermaid.tsx:
- Around line 93-102: The issue is that updating config re-initializes mermaid
via the useEffect around mermaid.initialize but does not re-render existing
diagrams because renderDiagram's dependency array omits config; update the
component so that renderDiagram depends on config (add config to its dependency
array) or explicitly call renderDiagram when config changes so diagrams are
re-rendered with the new mermaid settings; reference the renderDiagram callback
and the useEffect that calls mermaid.initialize to implement this change.
🧹 Nitpick comments (3)
packages/x/components/mermaid/Mermaid.tsx (3)

27-32: 建议验证 customActions 的 key 是否与内置操作冲突。

当前 headerActions.customActions 没有验证其 key 是否与内置操作(zoomInzoomOutzoomResetdownloadcopy)冲突。如果用户传入相同的 key,可能导致意外的行为或重复的操作项。

建议在构建 allItems 时添加 key 冲突检测或在文档中明确说明保留的 key。

♻️ 可选的冲突检测方案
+  const RESERVED_KEYS = ['zoomIn', 'zoomOut', 'zoomReset', 'download', 'copy'];
+  
   const allItems = [...items, ...customActions];
+  
+  if (process.env.NODE_ENV !== 'production') {
+    const customKeys = customActions.map(item => item.key);
+    const conflicts = customKeys.filter(key => RESERVED_KEYS.includes(key));
+    if (conflicts.length > 0) {
+      warning(false, 'Mermaid', `customActions contains reserved keys: ${conflicts.join(', ')}`);
+    }
+  }

128-153: 考虑添加关于 headerActions 稳定性的文档说明。

当前实现将 headerActions 添加到 effect 依赖数组(第153行),这是正确的。但如果父组件每次渲染都创建新的 headerActions 对象,会导致滚轮事件监听器频繁重新注册。

建议在 API 文档中提醒用户:

  • 使用 useMemo 包裹 headerActions 对象
  • 或将其提升为稳定的常量(如果配置不变)

这不是代码缺陷,但可以改善性能体验。


245-298: 动作构建逻辑清晰且功能完整。

头部动作的动态构建实现得很好:

  • 根据 renderTypeheaderActions 标志位灵活控制显示项
  • 默认值保持向后兼容
  • 支持 customActions 扩展

代码逻辑正确,易于维护。

如果未来需要更细粒度的控制(例如单独控制 zoomIn/zoomOut/zoomReset),可以考虑扩展 headerActions 接口:

headerActions?: {
  zoom?: boolean | { in?: boolean; out?: boolean; reset?: boolean };
  download?: boolean;
  copy?: boolean;
  customActions?: ItemType[];
}

但当前设计对于大多数使用场景已经足够。

📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c45fc64 and c92e8c7.

📒 Files selected for processing (1)
  • packages/x/components/mermaid/Mermaid.tsx
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: test
  • GitHub Check: size
  • GitHub Check: test
  • GitHub Check: build preview
  • GitHub Check: Cloudflare Pages
🔇 Additional comments (1)
packages/x/components/mermaid/Mermaid.tsx (1)

112-112: 确认直接使用 children 而非预处理文本的变更意图。

代码现在直接将 children 传递给 mermaid.render,而 AI 摘要提到之前使用经过清理的 newText。虽然第109行已通过 mermaid.parse 验证语法,但请确认:

  1. 是否需要预处理文本(如去除首尾空白、规范化换行符)?
  2. 原始 newText 的清理逻辑是否有必要?
  3. 是否已测试包含特殊空白字符或格式的边缘情况?

如果此变更是有意为之,建议在提交信息或代码注释中说明原因。

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/x/components/mermaid/Mermaid.tsx (1)

132-153: 对象依赖导致事件监听器频繁重建。

Line 153 将 headerActions 对象作为依赖项,如果父组件未对其进行 memoization,会导致 wheel 事件监听器频繁移除和重新添加,影响性能。

建议改为仅依赖所使用的具体值。

♻️ 建议的修复方案
+  const { showZoom = true } = headerActions;
+
   useEffect(() => {
     const container = containerRef.current;
     if (!container || renderType !== RenderType.Image) return;
 
-    const { showZoom = true } = headerActions;
     if (!showZoom) return;
 
     let lastTime = 0;
     const wheelHandler = (e: WheelEvent) => {
       e.preventDefault();
       e.stopPropagation();
 
       const now = Date.now();
       if (now - lastTime < 16) return;
       lastTime = now;
 
       const delta = e.deltaY > 0 ? -0.1 : 0.1;
       setScale((prev) => Math.max(0.5, Math.min(3, prev + delta)));
     };
 
     container.addEventListener('wheel', wheelHandler, { passive: false });
 
     return () => {
       container.removeEventListener('wheel', wheelHandler);
     };
-  }, [renderType, headerActions]);
+  }, [renderType, showZoom]);
🤖 Fix all issues with AI agents
In @packages/x/components/mermaid/Mermaid.tsx:
- Line 126: The effect dependency array in the Mermaid component currently
includes the config object (useEffect(..., [children, renderType, config])),
which can cause unnecessary re-renders if parent passes a new object identity
each render; either update the docs/props docs to instruct consumers to memoize
config with React.useMemo (showing the example with useMemo) or change the
component to do a deep-equality check before re-rendering the chart: store the
previous config in a ref inside Mermaid and compare using a stable deep-equal
(e.g., isEqual) or JSON.stringify, and only trigger the render logic when the
deep comparison shows a real change (keep children and renderType handling
intact).
📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c92e8c7 and 6029151.

📒 Files selected for processing (1)
  • packages/x/components/mermaid/Mermaid.tsx
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: build preview
  • GitHub Check: size
  • GitHub Check: test
  • GitHub Check: test
🔇 Additional comments (5)
packages/x/components/mermaid/Mermaid.tsx (5)

5-5: LGTM!类型导入正确。

MermaidConfig 类型导入符合预期,用于新增的 config 属性类型标注。


26-32: LGTM!新增 props 设计合理。

configheaderActions 的类型定义清晰,可选字段保持了向后兼容性,customActions 提供了良好的扩展性。


245-298: LGTM!动态操作构建逻辑正确。

Header actions 的动态构建逻辑清晰:

  • 默认值(showZoom/showDownload/showCopy 均为 true)保持向后兼容
  • 根据 renderType 正确区分 Image 和 Code 视图的操作项
  • customActions 追加在最后,允许用户扩展

56-57: LGTM!Props 提取正确。

configheaderActions 的提取方式合理,headerActions 默认为空对象便于后续解构使用。


93-102: mermaid.initialize() 是幂等的,重复调用是安全的。

Mermaid 11.12.1 设计用于支持重复调用 mermaid.initialize(),它只会合并全局配置而不会产生副作用。在 useEffect 中依据 config 变化重新初始化是正确的模式,允许用户在运行时动态修改 Mermaid 配置。

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 (5)
packages/x/components/mermaid/index.zh-CN.md (3)

38-40: MermaidConfig 和 ItemType 类型定义需要更详细的说明

config 属性使用 MermaidConfig 类型,headerActions 中的 customActions 使用 ItemType 类型,但文档中未给出这些类型的定义或链接。建议补充以下信息:

  • MermaidConfig 的主要配置项(如 themefontFamily 等)
  • ItemType 的结构定义

这样用户能更快理解如何使用这些配置项,而不用查找实现代码。


52-74: FAQ 章节内容清晰,但建议补充更多场景

现有FAQ很好地解决了 config 对象引用稳定性问题。建议进一步补充:

  • 何时使用 headerActions 自定义操作(customActions 的实际用例)
  • classNamesstyles 的作用域说明('root'、'header'、'graph'、'code' 各代表什么)
  • onRenderTypeChange 的常见应用场景

这些补充能帮助用户更好地理解新特性的应用场景。


56-56: FAQ 中的代码示例可添加类型注解

FAQ 代码示例中的 config 变量未标注类型。建议改为:

const config = React.useMemo(
  () => ({
    theme: isDark ? 'dark' : 'base',
    fontFamily: 'monospace',
  } as MermaidConfig),
  [isDark],
);

或在常量示例中显式标注,便于用户了解正确的类型。

packages/x/components/mermaid/index.en-US.md (2)

37-39: 英文文档中的类型说明需要补充超链接

与中文版本一致,MermaidConfigItemType 需要提供类型定义或外部链接。建议:

  • 添加指向实现代码或类型定义文件的链接
  • 或在 Semantic DOM 部分之前新增 "Types" 或 "Type Definitions" 章节

这可以提高文档的可用性。


55-55: FAQ 开场句式可优化

当前表述:

"When passing the config prop, ensure it is a reference-stable object. Avoid passing object literals directly in JSX (e.g., config={{ theme: 'base' }}), as this will cause Mermaid to re-initialize on every parent re-render. ✅ Recommended approaches:"

建议拆分为两句以提高可读性:

"When passing the config prop, ensure it is a reference-stable object. Avoid passing object literals directly in JSX (e.g., config={{ theme: 'base' }}), as this will cause Mermaid to re-initialize on every parent re-render.

✅ Recommended approaches:"

📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6029151 and e8cc1ee.

📒 Files selected for processing (2)
  • packages/x/components/mermaid/index.en-US.md
  • packages/x/components/mermaid/index.zh-CN.md
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: build preview
  • GitHub Check: test
  • GitHub Check: size
  • GitHub Check: test
  • GitHub Check: Cloudflare Pages

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 (6)
packages/x/components/mermaid/__tests__/index.test.tsx (4)

846-874: 重复测试用例。

should handle null config propshould handle undefined config prop 两个测试用例实际上完全相同,都传入 config={undefined}。如果需要测试 null 场景,第一个测试应该传入 config={null}

♻️ 建议修复
     it('should handle null config prop', async () => {
-      render(<Mermaid config={undefined}>{mermaidContent}</Mermaid>);
+      render(<Mermaid config={null as any}>{mermaidContent}</Mermaid>);

       await waitFor(() => {
         expect(mockInitialize).toHaveBeenCalledWith(

927-938: 键盘导航测试断言不充分。

该测试触发 keyDown 事件后,只验证了 'Code' 按钮存在,但该按钮在事件触发前就已存在。测试应该验证键盘事件是否真正触发了模式切换(例如检查 syntax-highlighter 是否出现)。

♻️ 建议改进
     it('should handle keyboard navigation', () => {
       render(<Mermaid>{mermaidContent}</Mermaid>);

       const codeButton = screen.getByText('Code');

       // 测试键盘事件
-      fireEvent.keyDown(codeButton, { key: 'Enter' });
+      fireEvent.keyDown(codeButton, { key: 'Enter' });
+      fireEvent.keyUp(codeButton, { key: 'Enter' });
+      // 或使用 click 模拟键盘激活
+      fireEvent.click(codeButton);

-      // 验证代码视图被激活
-      expect(screen.getByText('Code')).toBeInTheDocument();
+      // 验证代码视图被激活
+      expect(screen.getByTestId('syntax-highlighter')).toBeInTheDocument();
     });

893-905: 节流测试断言不够精确。

注释说明由于节流,render 调用次数应少于内容变化次数,但断言只验证了 mockRender 至少被调用一次。应该断言调用次数来验证节流机制是否生效。

♻️ 建议改进
       await waitFor(() => {
-        // 由于节流,render调用次数应该少于内容变化次数
-        expect(mockRender).toHaveBeenCalled();
+        // 由于节流,render调用次数应该少于内容变化次数(3次)
+        const callCount = mockRender.mock.calls.length;
+        expect(callCount).toBeGreaterThanOrEqual(1);
+        expect(callCount).toBeLessThan(4); // 验证节流生效
       });

1053-1061: resize 事件测试缺乏行为验证。

测试触发了 resize 事件但只验证了组件仍然存在,没有验证任何与 resize 相关的行为变化。如果组件不响应 resize 事件,这个测试可以考虑移除或补充有意义的断言。

packages/x/components/mermaid/index.zh-CN.md (1)

38-39: API 文档完整,建议补充类型链接。

MermaidConfigItemType 类型可以考虑添加链接指向对应的类型定义,方便用户查阅。MermaidConfig 来自 mermaid 库,ItemType 来自 antd 的 Dropdown 组件。

packages/x/components/mermaid/index.en-US.md (1)

53-56: 建议改进 FAQ 格式一致性。

中文文档中 "✅ 推荐做法:" 独立成行,但英文版本将 "✅ Recommended approaches:" 合并在段落末尾。建议保持格式一致以提升可读性。

♻️ 建议修改
-When passing the `config` prop, ensure it is a reference-stable object. Avoid passing object literals directly in JSX (e.g., `config={{ theme: 'base' }}`), as this will cause Mermaid to re-initialize on every parent re-render. ✅ Recommended approaches:
+When passing the `config` prop, ensure it is a reference-stable object. Avoid passing object literals directly in JSX (e.g., `config={{ theme: 'base' }}`), as this will cause Mermaid to re-initialize on every parent re-render.
+
+✅ Recommended approaches:
📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e8cc1ee and 500e5aa.

📒 Files selected for processing (5)
  • packages/x/components/mermaid/Mermaid.tsx
  • packages/x/components/mermaid/__tests__/index.test.tsx
  • packages/x/components/mermaid/demo/header-actions.tsx
  • packages/x/components/mermaid/index.en-US.md
  • packages/x/components/mermaid/index.zh-CN.md
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/x/components/mermaid/Mermaid.tsx
  • packages/x/components/mermaid/demo/header-actions.tsx
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: build preview
  • GitHub Check: size
  • GitHub Check: test
  • GitHub Check: test
  • GitHub Check: Cloudflare Pages
🔇 Additional comments (9)
packages/x/components/mermaid/__tests__/index.test.tsx (5)

58-63: 类型定义清晰明确!

MockMermaid 接口定义与 mock 结构匹配,提升了测试的类型安全性。


68-71: Mock 引用设置合理。

使用类型转换并提取独立的 mock 引用变量,便于测试中重复使用和断言验证。


982-1030: Actions 配置测试覆盖全面。

测试用例完整覆盖了 enableZoomenableDownloadenableCopy 开关以及 customActions 自定义操作的渲染场景。


940-980: 配置合并测试逻辑清晰。

测试正确验证了自定义配置与默认配置的合并行为,包括完整配置覆盖和部分配置覆盖两种场景。


1162-1199: 集成测试覆盖上下文配置场景。

测试通过模拟内部 hooks 验证了上下文配置和组件 props 的合并行为,确保组件正确继承和覆盖上下文配置。

packages/x/components/mermaid/index.zh-CN.md (2)

24-24: 新增示例入口正确。

header-actions.tsx 示例文件引用与 PR 新增功能一致。


51-74: FAQ 内容实用,示例清晰。

FAQ 部分很好地解释了如何避免 config 对象引用不稳定导致的重复渲染问题,提供的 useMemo 和常量提取两种方案都很实用。

packages/x/components/mermaid/index.en-US.md (2)

23-23: 示例入口与中文文档一致。


33-41: API 表格更新完整。

新增的 classNameclassNamesstylesconfigactionsonRenderTypeChangeprefixClsstyle 属性文档齐全,类型定义准确。

@dosubot dosubot bot added the lgtm This PR has been approved by a maintainer label Jan 9, 2026
@Div627 Div627 merged commit 978c6c9 into main Jan 9, 2026
16 checks passed
@Div627 Div627 deleted the feature_mermaid branch January 9, 2026 03:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request lgtm This PR has been approved by a maintainer

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature] Mermaid 组件支持设置禁用鼠标滚轮滚动缩放图

3 participants