diff --git a/src/Text.tsx b/src/Text.tsx index fec4c6a..95e653d 100644 --- a/src/Text.tsx +++ b/src/Text.tsx @@ -16,6 +16,20 @@ type Modifier = Exclude; type TextInlineProps = Omit; +const replaceLineBreaks = (text: string) => { + const split = text.split(/\r?\n|\r/g); + return ( + <> + {split.map((part, idx) => ( + + {idx > 0 &&
} + {part} +
+ ))} + + ); +}; + const Text = ({ text, ...modifiers }: TextInlineProps) => { // Get matching React component from the context const { modifiers: modifierComponents, missingModifierTypes } = useComponentsContext(); @@ -48,7 +62,7 @@ const Text = ({ text, ...modifiers }: TextInlineProps) => { return {children}; }, // By default, return the text without any wrapper to avoid useless nesting - <>{text} + replaceLineBreaks(text) ); }; diff --git a/tests/BlocksRenderer.test.tsx b/tests/BlocksRenderer.test.tsx index 73b01e4..b90f7bf 100644 --- a/tests/BlocksRenderer.test.tsx +++ b/tests/BlocksRenderer.test.tsx @@ -1,3 +1,5 @@ +/* eslint-disable testing-library/no-node-access */ + import * as React from 'react'; import { render, screen } from '@testing-library/react'; @@ -61,7 +63,6 @@ describe('BlocksRenderer', () => { expect(boldTag[1]).toHaveTextContent(/and bold underlines/i); // Should still fallback to default components - // eslint-disable-next-line testing-library/no-node-access const underlineTag = document.querySelector('u'); expect(underlineTag).toHaveTextContent(/and bold underlines/i); }); @@ -83,7 +84,6 @@ describe('BlocksRenderer', () => { /> ); - // eslint-disable-next-line testing-library/no-node-access const paragraph = screen.getByText('A paragraph').closest('p'); expect(paragraph).toHaveTextContent('A paragraph with bold'); }); @@ -109,12 +109,28 @@ describe('BlocksRenderer', () => { /> ); - // eslint-disable-next-line testing-library/no-node-access const brElement = screen.getByText('First paragraph').nextElementSibling; expect(brElement).toBeInTheDocument(); expect(brElement?.tagName).toBe('BR'); }); + it('renders paragraphs with line breaks', () => { + render( + + ); + + const paragraph = screen.getByText(/First line/).closest('p'); + const paragraphParts = paragraph?.innerHTML?.split('
'); + expect(paragraphParts).toEqual(['First line', 'Second line']); + }); + it('renders quotes', () => { render( { const quote = screen.getByText('A quote'); expect(quote).toBeInTheDocument(); - // eslint-disable-next-line testing-library/no-node-access expect(quote.closest('blockquote')).toBeInTheDocument(); }); @@ -142,9 +157,7 @@ describe('BlocksRenderer', () => { const code = screen.getByText('my code'); expect(code).toBeInTheDocument(); - // eslint-disable-next-line testing-library/no-node-access expect(code.closest('code')).toBeInTheDocument(); - // eslint-disable-next-line testing-library/no-node-access expect(code.closest('pre')).toBeInTheDocument(); }); @@ -322,13 +335,11 @@ describe('BlocksRenderer', () => { const text = screen.getByText('My text'); expect(text).toBeInTheDocument(); - /* eslint-disable testing-library/no-node-access */ expect(text.closest('strong')).toBeInTheDocument(); expect(text.closest('em')).toBeInTheDocument(); expect(text.closest('u')).toBeInTheDocument(); expect(text.closest('del')).toBeInTheDocument(); expect(text.closest('code')).toBeInTheDocument(); - /* eslint-enable testing-library/no-node-access */ }); it('ignores disabled or unknown modifiers', () => { @@ -357,7 +368,6 @@ describe('BlocksRenderer', () => { const text = screen.getByText('My text'); expect(text).toBeInTheDocument(); - // eslint-disable-next-line testing-library/no-node-access expect(text.closest('strong')).not.toBeInTheDocument(); console.warn = originalWarn;