修复聊天嵌套列表缩进
为 Markdown 无序列表按嵌套层级增加内边距 补充多层无序列表渲染回归测试
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import type { ErrorInfo, ReactNode } from 'react';
|
||||
import { Component } from 'react';
|
||||
import { Component, createContext, useContext } from 'react';
|
||||
import ReactMarkdown, { type Components } from 'react-markdown';
|
||||
import remarkGfm from 'remark-gfm';
|
||||
|
||||
@@ -44,6 +44,34 @@ class MarkdownErrorBoundary extends Component<
|
||||
}
|
||||
}
|
||||
|
||||
const ListDepthContext = createContext(0);
|
||||
|
||||
function MarkdownUnorderedList({ children }: { children?: ReactNode }) {
|
||||
const depth = useContext(ListDepthContext);
|
||||
return (
|
||||
<ListDepthContext.Provider value={depth + 1}>
|
||||
<ul
|
||||
className={`m-0 mt-2 list-none space-y-1 first:mt-0 ${
|
||||
depth > 0 ? 'pl-4' : 'pl-0'
|
||||
}`}
|
||||
>
|
||||
{children}
|
||||
</ul>
|
||||
</ListDepthContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
function MarkdownOrderedList({ children }: { children?: ReactNode }) {
|
||||
const depth = useContext(ListDepthContext);
|
||||
return (
|
||||
<ListDepthContext.Provider value={depth + 1}>
|
||||
<ol className="m-0 mt-2 list-decimal space-y-1 pl-5 first:mt-0">
|
||||
{children}
|
||||
</ol>
|
||||
</ListDepthContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
const markdownComponents: Components = {
|
||||
// TODO: 产品确认安全外链策略后,再将链接文本恢复为可点击元素。
|
||||
a: ({ children }) => children,
|
||||
@@ -60,14 +88,8 @@ const markdownComponents: Components = {
|
||||
p: ({ children }) => (
|
||||
<p className="m-0 mt-2 break-words first:mt-0">{children}</p>
|
||||
),
|
||||
ul: ({ children }) => (
|
||||
<ul className="m-0 mt-2 list-none space-y-1 pl-0 first:mt-0">{children}</ul>
|
||||
),
|
||||
ol: ({ children }) => (
|
||||
<ol className="m-0 mt-2 list-decimal space-y-1 pl-5 first:mt-0">
|
||||
{children}
|
||||
</ol>
|
||||
),
|
||||
ul: MarkdownUnorderedList,
|
||||
ol: MarkdownOrderedList,
|
||||
li: ({ children }) => <li className="break-words">- {children}</li>,
|
||||
blockquote: ({ children }) => (
|
||||
<blockquote className="m-0 mt-2 border-l-2 border-(--platform-surface-border) pl-3 text-(--platform-text-soft) first:mt-0">
|
||||
|
||||
@@ -21,6 +21,23 @@ describe('ChatMarkdownMessage', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('为嵌套无序列表保留逐层缩进', () => {
|
||||
const { container } = render(
|
||||
<ChatMarkdownMessage
|
||||
role="assistant"
|
||||
text={
|
||||
'- 无序号 A\n- 无序号 B\n - 缩进一层的子项\n - 缩进两层的子项\n - 回到一层子项\n- 无序号 C'
|
||||
}
|
||||
/>,
|
||||
);
|
||||
|
||||
const lists = container.querySelectorAll('ul');
|
||||
expect(lists).toHaveLength(3);
|
||||
expect(lists[0]?.className).toContain('pl-0');
|
||||
expect(lists[1]?.className).toContain('pl-4');
|
||||
expect(lists[2]?.className).toContain('pl-4');
|
||||
});
|
||||
|
||||
it('不会把 react-markdown 的 node 元数据泄漏到代码节点', () => {
|
||||
const { container } = render(
|
||||
<ChatMarkdownMessage
|
||||
|
||||
Reference in New Issue
Block a user