Skip to content

Conversation

@chensid
Copy link
Contributor

@chensid chensid commented Nov 29, 2025

🤔 这个 PR 的性质是?

  • 日常 bug 修复
  • 新特性提交
  • 文档改进
  • 演示代码改进
  • 组件样式/交互改进
  • CI/CD 改进
  • 重构
  • 代码风格优化
  • 测试用例
  • 分支合并
  • 其他

🔗 相关 Issue

#6176

💡 需求背景和解决方案

TChatContent 组件的 markdown 渲染配置(如 customRenderer)无法通过 props 传递生效,因为 Marked 实例在组件内部硬编码创建,不接受外部配置。

解决方案:

  • 新增 markedOptions prop,支持透传 MarkedExtension 配置
  • 使用工厂函数创建 Marked 实例,在默认渲染器基础上应用用户配置
  • 监听 markedOptions 变化,动态重建实例

用法:

<t-chat-content 
  role="assistant" 
  :content="doc" 
  :marked-options="{
    renderer: {
      code(code, lang, escaped) {
        return `<pre>${code}</pre>`;
      }
    }
  }"
/>

📝 更新日志

  • 本条 PR 不需要纳入 Changelog

tdesign-vue-next

@tdesign-vue-next/chat

  • fix(ChatContent): 修复 markedOptions 自定义 markdown 渲染配置不生效的问题 #6176

@tdesign-vue-next/auto-import-resolver

☑️ 请求合并前的自查清单

⚠️ 请自检并全部勾选全部选项⚠️

  • 文档已补充或无须补充
  • 代码演示已提供或无须提供
  • TypeScript 定义已补充或无须补充
  • Changelog 已提供或无须提供

Copilot AI and others added 6 commits November 29, 2025 10:35
… rendering (Tencent#6176)

Co-authored-by: chensid <41440132+chensid@users.noreply.github.com>
Co-authored-by: chensid <41440132+chensid@users.noreply.github.com>
fix(Chat): add markedOptions prop to TChatContent for custom markdown rendering (Tencent#6176)
fix(Chat): add markedOptions prop to TChatContent for custom markdown rendering
@tdesign-bot
Copy link
Collaborator

TDesign Component Site Preview Open

Component Preview
tdesign-vue-next 完成
@tdesign-vue-next/chat 完成

Copilot finished reviewing on behalf of chensid November 29, 2025 11:23
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes a bug where custom markdown rendering options couldn't be passed to the TChatContent component. The solution adds a new markedOptions prop that accepts configuration for the Marked markdown parser, enabling users to customize rendering behavior such as code block formatting.

Key Changes:

  • Added markedOptions prop to TChatContent component for custom markdown rendering configuration
  • Refactored Marked instance creation into a factory function that merges default options with user-provided options
  • Implemented reactivity using ref and watch to handle dynamic markedOptions changes

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 6 comments.

File Description
packages/pro-components/chat/type.ts Added markedOptions prop definition to TdChatContentProps interface
packages/pro-components/chat/chat-content-props.ts Added markedOptions prop declaration with Object type
packages/pro-components/chat/chat-content.tsx Refactored Marked instance creation into factory function, added reactivity with watch, and imported MarkedExtension type

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

*/
content?: string;
/**
* 透传给 Marked 的参数,用于自定义 markdown 渲染
Copy link

Copilot AI Nov 29, 2025

Choose a reason for hiding this comment

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

[nitpick] The documentation comment is in Chinese but should also consider adding an English translation or example for broader accessibility. Additionally, the JSDoc could include more details about what options are supported. Consider:

/**
 * 透传给 Marked 的参数,用于自定义 markdown 渲染
 * Options passed to Marked instance for custom markdown rendering
 * @see https://marked.js.org/using_advanced#extensions
 */
Suggested change
* 透传给 Marked 的参数,用于自定义 markdown 渲染
* 透传给 Marked 的参数,用于自定义 markdown 渲染
* Options passed to the Marked instance for custom markdown rendering.
* See: https://marked.js.org/using_advanced#extensions

Copilot uses AI. Check for mistakes.
Comment on lines +95 to 106
// Use ref to store marked instance and watch for changes
const markedRef = ref(createMarkedInstance(props.markedOptions));

// Watch for changes in markedOptions and recreate the instance
watch(
() => props.markedOptions,
(newOptions) => {
markedRef.value = createMarkedInstance(newOptions);
},
{ deep: true },
);

Copy link

Copilot AI Nov 29, 2025

Choose a reason for hiding this comment

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

Consider using a computed property instead of ref + watch for better reactivity and simpler code. The current approach creates a new Marked instance on every change, which could be expensive. A computed property would provide the same functionality more idiomatically:

const markedRef = computed(() => createMarkedInstance(props.markedOptions));

Then update line 111 to:

return markedRef.value.parse(markdown);

This eliminates the need for the watch block (lines 98-105) and ensures the Marked instance is only recreated when markedOptions actually changes, without needing { deep: true }.

Suggested change
// Use ref to store marked instance and watch for changes
const markedRef = ref(createMarkedInstance(props.markedOptions));
// Watch for changes in markedOptions and recreate the instance
watch(
() => props.markedOptions,
(newOptions) => {
markedRef.value = createMarkedInstance(newOptions);
},
{ deep: true },
);
// Use computed to create marked instance based on markedOptions
const markedRef = computed(() => createMarkedInstance(props.markedOptions));

Copilot uses AI. Check for mistakes.
},
}),
{
// Create marked instance with default options
Copy link

Copilot AI Nov 29, 2025

Choose a reason for hiding this comment

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

[nitpick] The comment "Create marked instance with default options" is slightly misleading since the function also accepts and applies user-provided markedOptions. Consider updating it to be more accurate:

// Create marked instance with default renderer and optional user overrides
Suggested change
// Create marked instance with default options
// Create marked instance with default renderer and optional user overrides

Copilot uses AI. Check for mistakes.
/**
* 透传给 Marked 的参数,用于自定义 markdown 渲染
*/
markedOptions?: Record<string, any>;
Copy link

Copilot AI Nov 29, 2025

Choose a reason for hiding this comment

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

The type Record<string, any> is too loose and bypasses TypeScript's type checking. Since the code imports MarkedExtension from 'marked' in chat-content.tsx, consider using MarkedExtension as the type instead:

markedOptions?: MarkedExtension;

This would provide better type safety and IDE autocomplete for users of the component. You'll need to add import { MarkedExtension } from 'marked'; to this file.

Copilot uses AI. Check for mistakes.
Comment on lines +17 to +18
markedOptions: {
type: Object as PropType<TdChatContentProps['markedOptions']>,
Copy link

Copilot AI Nov 29, 2025

Choose a reason for hiding this comment

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

The prop type should use MarkedExtension instead of Record<string, any> for better type safety:

markedOptions: {
  type: Object as PropType<MarkedExtension>,
},

This requires importing MarkedExtension from 'marked'. This change would work together with updating the type definition in type.ts.

Copilot uses AI. Check for mistakes.
}),
{
// Create marked instance with default options
const createMarkedInstance = (markedOptions?: Record<string, any>) => {
Copy link

Copilot AI Nov 29, 2025

Choose a reason for hiding this comment

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

The parameter type annotation markedOptions?: Record<string, any> is inconsistent with the actual usage. Since the function casts it to MarkedExtension on line 89, the parameter should be typed as MarkedExtension for clarity:

const createMarkedInstance = (markedOptions?: MarkedExtension) => {

This removes the need for the type cast on line 89 and provides better type safety.

Copilot uses AI. Check for mistakes.
@pkg-pr-new
Copy link

pkg-pr-new bot commented Nov 29, 2025

tdesign-vue-next-demo

npm i https://pkg.pr.new/Tencent/tdesign-vue-next/@tdesign-vue-next/auto-import-resolver@6214
npm i https://pkg.pr.new/Tencent/tdesign-vue-next@6214
npm i https://pkg.pr.new/Tencent/tdesign-vue-next/@tdesign-vue-next/chat@6214

commit: ab5d573

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