diff --git a/src/components/Markdown/Markdown.test.tsx b/src/components/Markdown/Markdown.test.tsx
index b5b84e3e..10d5e5bf 100644
--- a/src/components/Markdown/Markdown.test.tsx
+++ b/src/components/Markdown/Markdown.test.tsx
@@ -103,6 +103,19 @@ describe('Markdown', () => {
const { getByText } = render()
expect(getByText('This is a blockquote.')).toBeDefined()
})
+
+ it('renders a horizontal rule', () => {
+ const text = 'First paragraph\n---\nSecond paragraph'
+ const { container } = render()
+
+ const paragraphs = container.querySelectorAll('p')
+ expect(paragraphs.length).toBe(2)
+ expect(paragraphs[0]?.textContent).toBe('First paragraph')
+ expect(paragraphs[1]?.textContent).toBe('Second paragraph')
+
+ const hr = container.querySelector('hr')
+ expect(hr).toBeDefined()
+ })
})
describe('Markdown code blocks', () => {
diff --git a/src/components/Markdown/Markdown.tsx b/src/components/Markdown/Markdown.tsx
index 8e0b299d..81a27d91 100644
--- a/src/components/Markdown/Markdown.tsx
+++ b/src/components/Markdown/Markdown.tsx
@@ -17,6 +17,7 @@ type Token =
| { type: 'list', ordered: boolean, items: Token[][] }
| { type: 'blockquote', children: Token[] }
| { type: 'codeblock', language?: string, content: string }
+ | { type: 'hr' }
function parseMarkdown(text: string): Token[] {
const tokens: Token[] = []
@@ -50,6 +51,13 @@ function parseMarkdown(text: string): Token[] {
continue
}
+ // Horizontal rule
+ if (/^---+$/.test(line.trim())) {
+ tokens.push({ type: 'hr' })
+ i++
+ continue
+ }
+
// Heading
const headingMatch = /^(#{1,6})\s+(.*)/.exec(line)
if (headingMatch !== null) {
@@ -110,6 +118,7 @@ function parseMarkdown(text: string): Token[] {
if (ln.startsWith('>')) break // blockquote
if (/^(#{1,6})\s+/.test(ln)) break // heading
if (/^(\s*)([-*+–•‣◦○⚬]|\d+\.)\s+/.test(ln)) break // list item
+ if (/^---+$/.test(ln.trim())) break // horizontal rule
paraLines.push(ln)
i++
@@ -499,6 +508,8 @@ function renderTokens(tokens: Token[], keyPrefix = ''): ReactNode[] {
{ key },
createElement('code', null, token.content)
)
+ case 'hr':
+ return createElement('hr', { key })
default:
return null
}