Skip to content

feat(x-markdown): add componentsProps to pass extra props to custom components - #1993

Open
Div627 wants to merge 1 commit into
mainfrom
feat/x-markdown-components-props
Open

feat(x-markdown): add componentsProps to pass extra props to custom components#1993
Div627 wants to merge 1 commit into
mainfrom
feat/x-markdown-components-props

Conversation

@Div627

@Div627 Div627 commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

中文版模板 / Chinese template

🤔 This is a ...

  • 🆕 New feature

🔗 Related Issues

close #1989

💡 Background and Solution

Custom components registered via components could only receive extra business data (theme, callbacks, dynamic state, …) through inline wrapper functions:

// ❌ New component type on every render → React unmounts/remounts the whole
// subtree, losing internal state and hurting streaming performance
components={{ code: (props) => <CustomCode {...props} {...extraProps} /> }}

This PR adds a componentsProps option that passes extra props by tag name while keeping component references stable:

<XMarkdown
  components={{ 'custom-chart': CustomChart }}
  componentsProps={{ 'custom-chart': { theme, onSelect } }}
/>

Design notes:

  • The renderProps approach suggested in the issue (calling renderElement(props) directly instead of React.createElement) was intentionally not taken: it would strip custom components of their identity as real React components (hooks would attach to the parent, no reconciliation boundary). componentsProps is a purely additive API instead — fully backward compatible.
  • Extra props are merged over parsed HTML attributes (componentsProps wins on conflicts). This also matters because DOMPurify strips non-standard, non-data-* attributes (e.g. theme) from raw HTML anyway, so componentsProps is the reliable way to pass such data.
  • Internally computed fields still win: children, and block / streamStatus / parsed lang for code, protecting streaming semantics.
  • The generated reconciliation key is now always applied last so it can never be clobbered by attributes or extra props.
  • When componentsProps changes, components receive a normal props update without remounting (covered by a mount-count test).

Only applies to tags registered in components; entries for unregistered tags are ignored.

📝 Change Log

Language Changelog
🇺🇸 English XMarkdown adds a componentsProps option to pass extra props to custom components by tag name, keeping component references stable and avoiding remounts caused by inline functions.
🇨🇳 Chinese XMarkdown 新增 componentsProps 选项,支持按标签名向自定义组件传递额外 props,保持组件引用稳定,避免内联函数导致的重复挂载。

🤖 Generated with Claude Code

Summary by CodeRabbit

  • 新功能

    • 新增 componentsProps 配置,可按组件标签名向自定义组件传递额外属性。
    • 传入的属性可覆盖解析得到的同名 HTML 属性。
    • 更新属性时仅刷新组件内容,不会导致组件重复挂载。
  • 文档

    • 补充了 componentsProps 的使用方式、属性合并规则及最佳实践说明。

…omponents

Custom components registered via `components` could only receive extra
business data (theme, callbacks, etc.) through inline wrapper functions,
which create a new component type on every render and force React to
unmount/remount the whole subtree — losing internal state and hurting
performance in streaming scenarios.

`componentsProps` passes extra props by tag name while keeping component
references stable. Extra props are merged over parsed HTML attributes at
element creation; internally computed fields (children, and block /
streamStatus / lang for code) still win. The generated reconciliation key
is now always applied last so it can never be clobbered.

close #1989

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@dosubot dosubot Bot added enhancement New feature or request javascript Pull requests that update Javascript code labels Jul 24, 2026
@coderabbitai

coderabbitai Bot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

XMarkdown 新增 componentsProps API,按自定义组件名称传递额外 props,并在 Renderer 中完成合并。测试覆盖属性覆盖、组件隔离及更新时不重复挂载;中英文文档同步补充用法与 API 说明。

Changes

componentsProps 支持

Layer / File(s) Summary
API 定义与渲染器接入
packages/x-markdown/src/XMarkdown/interface.ts, packages/x-markdown/src/XMarkdown/index.tsx, packages/x-markdown/src/XMarkdown/core/Renderer.ts
新增 componentsProps 类型,将其传入 Renderer,并加入渲染器 memo 依赖。
组件 Props 合并与验证
packages/x-markdown/src/XMarkdown/core/Renderer.ts, packages/x-markdown/src/XMarkdown/__tests__/index.test.tsx
按组件名称合并额外 props;测试覆盖属性覆盖、组件隔离及更新时不重复挂载。
API 与使用文档
packages/x/docs/x-markdown/components.*.md, packages/x/docs/x-markdown/examples.*.md
补充传递额外 props、合并规则、组件引用稳定性及 API 表说明。

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant XMarkdown
  participant Renderer
  participant CustomComponent
  XMarkdown->>Renderer: 传入 componentsProps
  Renderer->>Renderer: 按组件名称合并组件属性
  Renderer->>CustomComponent: 传递最终 props
  XMarkdown->>Renderer: 更新 componentsProps
  Renderer->>CustomComponent: 更新 props
Loading

Suggested labels: documentation

Suggested reviewers: kimteayon

Poem

兔子捧来 props 香,
稳定组件不慌张。
属性合并有新章,
更新只换新衣裳。
测试跳起胡萝卜舞,
文档也闪亮亮!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 标题准确概括了为自定义组件新增 componentsProps 透传额外 props 的主要变更。
Linked Issues check ✅ Passed 实现与 #1989 的目标一致:通过稳定组件引用传递额外 props,并避免内联包装导致的重复挂载。
Out of Scope Changes check ✅ Passed 测试与文档更新都直接服务于 componentsProps 功能,没有明显无关的范围外改动。
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/x-markdown-components-props

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.

@gemini-code-assist

Copy link
Copy Markdown
Contributor

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

@codecov

codecov Bot commented Jul 24, 2026

Copy link
Copy Markdown

Bundle Report

Changes will increase total bundle size by 8 bytes (0.0%) ⬆️. This is within the configured threshold ✅

Detailed changes
Bundle name Size Change
antdx-array-push 2.11MB 8 bytes (0.0%) ⬆️

Affected Assets, Files, and Routes:

view changes for bundle: antdx-array-push

Assets Changed:

Asset Name Size Change Total Size Change (%)
antdx.min.js 8 bytes 2.11MB 0.0%

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/x-markdown/src/XMarkdown/core/Renderer.ts`:
- Around line 206-207: 调整 Renderer 中构造组件 props 的合并顺序:先合并解析出的属性与
componentsProps,再写入内部生成的 domNode 和 streamStatus,确保额外 props 无法覆盖内部字段。处理 className
时让 componentsProps.className 覆盖 HTML 解析出的 class,而不是进行拼接。补充覆盖
domNode、streamStatus 及 className 冲突场景的测试。

In `@packages/x/docs/x-markdown/components.zh-CN.md`:
- Line 56: Update the props-priority wording at
packages/x/docs/x-markdown/components.zh-CN.md:56-56 to state that
componentsProps only overrides parsed HTML attributes, while internally computed
children, key, and code-component fields block, lang, and streamStatus retain
priority. Apply the equivalent clarification at
packages/x/docs/x-markdown/components.en-US.md:56-56, keeping both language
versions consistent.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 9f04e5be-3bec-4450-96aa-26cd8f573d03

📥 Commits

Reviewing files that changed from the base of the PR and between 13afbf4 and 678aa34.

📒 Files selected for processing (8)
  • packages/x-markdown/src/XMarkdown/__tests__/index.test.tsx
  • packages/x-markdown/src/XMarkdown/core/Renderer.ts
  • packages/x-markdown/src/XMarkdown/index.tsx
  • packages/x-markdown/src/XMarkdown/interface.ts
  • packages/x/docs/x-markdown/components.en-US.md
  • packages/x/docs/x-markdown/components.zh-CN.md
  • packages/x/docs/x-markdown/examples.en-US.md
  • packages/x/docs/x-markdown/examples.zh-CN.md

Comment on lines +206 to +207
...this.options.componentsProps?.[name],
key,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

修正 componentsProps 的优先级顺序。

当前实现允许额外 props 覆盖内部生成的 domNodestreamStatus;同时,componentsProps.className 会与 HTML 的 class 拼接而非覆盖。应先合并解析属性与额外 props,再写入内部字段,并让额外 class 属性覆盖解析出的 class。补充这些冲突场景的测试。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/x-markdown/src/XMarkdown/core/Renderer.ts` around lines 206 - 207,
调整 Renderer 中构造组件 props 的合并顺序:先合并解析出的属性与 componentsProps,再写入内部生成的 domNode 和
streamStatus,确保额外 props 无法覆盖内部字段。处理 className 时让 componentsProps.className 覆盖
HTML 解析出的 class,而不是进行拼接。补充覆盖 domNode、streamStatus 及 className 冲突场景的测试。

/>;
```

`componentsProps` 以标签名为 key,对应的 props 会与解析出的 HTML 属性合并后传给组件(同名时 `componentsProps` 优先)。`componentsProps` 变化时组件只会正常更新 props,不会被重新挂载。

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

同步修正文档中的 props 优先级说明。

Renderer 中 componentsProps 仅覆盖解析出的 HTML 属性;childrenkey 以及代码组件的 blocklangstreamStatus 会在之后由内部逻辑重新计算。当前两份文档都表述为所有冲突均由 componentsProps 覆盖,需改为明确列出内部字段仍保持优先级。

  • packages/x/docs/x-markdown/components.zh-CN.md#L56-L56: 将“同名时 componentsProps 优先”限定为解析出的 HTML 属性。
  • packages/x/docs/x-markdown/components.en-US.md#L56-L56: 同步英文表述,说明内部计算字段不会被覆盖。
📍 Affects 2 files
  • packages/x/docs/x-markdown/components.zh-CN.md#L56-L56 (this comment)
  • packages/x/docs/x-markdown/components.en-US.md#L56-L56
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/x/docs/x-markdown/components.zh-CN.md` at line 56, Update the
props-priority wording at packages/x/docs/x-markdown/components.zh-CN.md:56-56
to state that componentsProps only overrides parsed HTML attributes, while
internally computed children, key, and code-component fields block, lang, and
streamStatus retain priority. Apply the equivalent clarification at
packages/x/docs/x-markdown/components.en-US.md:56-56, keeping both language
versions consistent.

@github-actions

Copy link
Copy Markdown
Contributor

⚠️ Performance benchmark report not found.


This comment is automatically generated by the x-markdown performance CI.

@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying ant-design-x with  Cloudflare Pages  Cloudflare Pages

Latest commit: 678aa34
Status: ✅  Deploy successful!
Preview URL: https://68da7151.ant-design-x.pages.dev
Branch Preview URL: https://feat-x-markdown-components-p.ant-design-x.pages.dev

View logs

@codecov

codecov Bot commented Jul 24, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 97.06%. Comparing base (13afbf4) to head (678aa34).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #1993   +/-   ##
=======================================
  Coverage   97.06%   97.06%           
=======================================
  Files         159      159           
  Lines        5766     5766           
  Branches     1712     1713    +1     
=======================================
  Hits         5597     5597           
  Misses        167      167           
  Partials        2        2           

☔ View full report in Codecov by Harness.
📢 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.

@github-actions

Copy link
Copy Markdown
Contributor

size-limit report 📦

Path Size
packages/x/dist/antdx.min.js 510.79 KB
packages/x-sdk/dist/x-sdk.min.js 55.54 KB
packages/x-markdown/dist/x-markdown.min.js 34.42 KB (+24 B 🔺)
packages/x-markdown/dist/plugins/latex.min.js 61.91 KB

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request javascript Pull requests that update Javascript code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

markdown选项components增加props传参功能

1 participant