修复对话 markdown 无序列表渲染
- ChatMarkdownMessage:无序列表改用真正的列表标记(list-disc + pl-4),不再手写 '- ' 文本前缀 - ChatMarkdownMessage:删除列表项里手写的短横线,换行后的第二行恢复悬挂缩进,同时恢复列表语义 - ChatMarkdownMessage:移除随之无用的 ListKindContext - ChatMarkdownMessage.test.tsx:用例改为断言 list-disc/pl-4 与「列表项文本不含手写短横线」 - 实测:真实面板注入同 class 标记后 list-style-type=disc、li 为 list-item、换行行与首行文字左边缘对齐
This commit is contained in:
@@ -66,7 +66,6 @@ export class MarkdownErrorBoundary extends Component<
|
||||
}
|
||||
|
||||
const ListDepthContext = createContext(0);
|
||||
const ListKindContext = createContext<'unordered' | 'ordered' | null>(null);
|
||||
type ListItemParagraphPosition = 'first' | 'continuation';
|
||||
|
||||
const ListItemContext = createContext<ListItemParagraphPosition | null>(null);
|
||||
@@ -75,15 +74,11 @@ function MarkdownUnorderedList({ children }: { children?: ReactNode }) {
|
||||
const depth = useContext(ListDepthContext);
|
||||
return (
|
||||
<ListDepthContext.Provider value={depth + 1}>
|
||||
<ListKindContext.Provider value="unordered">
|
||||
<ul
|
||||
className={`m-0 mt-2 list-none space-y-1 first:mt-0 ${
|
||||
depth > 0 ? 'pl-4' : 'pl-0'
|
||||
}`}
|
||||
>
|
||||
{children}
|
||||
</ul>
|
||||
</ListKindContext.Provider>
|
||||
{/* 用真正的列表标记(`list-disc`)而不是手写 `'- '` 文本:手写前缀既没有悬挂缩进
|
||||
(换行后的第二行会顶回最左边),也不算列表语义(读屏读成普通文本)。 */}
|
||||
<ul className="m-0 mt-2 list-disc space-y-1 pl-4 first:mt-0">
|
||||
{children}
|
||||
</ul>
|
||||
</ListDepthContext.Provider>
|
||||
);
|
||||
}
|
||||
@@ -98,14 +93,12 @@ function MarkdownOrderedList({
|
||||
const depth = useContext(ListDepthContext);
|
||||
return (
|
||||
<ListDepthContext.Provider value={depth + 1}>
|
||||
<ListKindContext.Provider value="ordered">
|
||||
<ol
|
||||
start={start}
|
||||
className="m-0 mt-2 list-decimal space-y-1 pl-5 first:mt-0"
|
||||
>
|
||||
{children}
|
||||
</ol>
|
||||
</ListKindContext.Provider>
|
||||
<ol
|
||||
start={start}
|
||||
className="m-0 mt-2 list-decimal space-y-1 pl-5 first:mt-0"
|
||||
>
|
||||
{children}
|
||||
</ol>
|
||||
</ListDepthContext.Provider>
|
||||
);
|
||||
}
|
||||
@@ -145,7 +138,6 @@ function StreamingMarkdownParagraph({ children }: { children?: ReactNode }) {
|
||||
}
|
||||
|
||||
function MarkdownListItem({ children }: { children?: ReactNode }) {
|
||||
const listKind = useContext(ListKindContext);
|
||||
let paragraphIndex = 0;
|
||||
const childrenWithParagraphContext = Children.map(
|
||||
children,
|
||||
@@ -168,7 +160,6 @@ function MarkdownListItem({ children }: { children?: ReactNode }) {
|
||||
);
|
||||
return (
|
||||
<li className="break-words whitespace-normal">
|
||||
{listKind === 'unordered' ? '- ' : null}
|
||||
{childrenWithParagraphContext}
|
||||
</li>
|
||||
);
|
||||
|
||||
@@ -31,7 +31,7 @@ describe('ChatMarkdownMessage', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('为嵌套无序列表保留逐层缩进', () => {
|
||||
it('无序列表用真正的列表标记并逐层缩进,不再手写短横线', () => {
|
||||
const { container } = render(
|
||||
<ChatMarkdownMessage
|
||||
role="assistant"
|
||||
@@ -43,9 +43,17 @@ describe('ChatMarkdownMessage', () => {
|
||||
|
||||
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');
|
||||
// 真正的列表标记:靠 `list-disc` 画项目符号、`pl-4` 让换行后的第二行保持悬挂缩进。
|
||||
for (const list of Array.from(lists)) {
|
||||
expect(list.className).toContain('list-disc');
|
||||
expect(list.className).toContain('pl-4');
|
||||
expect(list.className).not.toContain('list-none');
|
||||
}
|
||||
// 列表项文本里不能再出现手写的 `- ` 前缀(那会让换行行顶回最左边,也不符合列表语义)。
|
||||
for (const item of Array.from(container.querySelectorAll('ul > li'))) {
|
||||
expect(item.textContent ?? '').not.toMatch(/^\s*-\s/);
|
||||
}
|
||||
expect(container.querySelector('ul > li')?.textContent).toBe('无序号 A');
|
||||
});
|
||||
|
||||
it('为四到六级标题提供递进的字号与字重', () => {
|
||||
|
||||
Reference in New Issue
Block a user