[Blocks editor] Handle multi line quotes (#18200)

* Handle enter on quotes

* Add test case

* Remove italic style

* Remove log
This commit is contained in:
Rémi de Juvigny 2023-10-03 15:16:34 +02:00 committed by GitHub
parent 493eb0a58d
commit 3f54767ebc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 91 additions and 2 deletions

View File

@ -556,4 +556,69 @@ describe('useBlocksStore', () => {
},
]);
});
it('handles enter key on a quote', () => {
const { result } = renderHook(useBlocksStore);
baseEditor.children = [
{
type: 'quote',
children: [
{
type: 'text',
text: 'Some quote',
},
],
},
];
// Simulate enter key press at the end of the quote
Transforms.select(baseEditor, {
anchor: Editor.end(baseEditor, []),
focus: Editor.end(baseEditor, []),
});
result.current.quote.handleEnterKey(baseEditor);
// Should enter a line break within the quote
expect(baseEditor.children).toEqual([
{
type: 'quote',
children: [
{
type: 'text',
text: 'Some quote\n',
},
],
},
]);
// Simulate enter key press at the end of the quote again
Transforms.select(baseEditor, {
anchor: Editor.end(baseEditor, []),
focus: Editor.end(baseEditor, []),
});
result.current.quote.handleEnterKey(baseEditor);
// Should delete the line break and create a paragraph after the quote
expect(baseEditor.children).toEqual([
{
type: 'quote',
children: [
{
type: 'text',
text: 'Some quote',
},
],
},
{
type: 'paragraph',
children: [
{
type: 'text',
text: '',
},
],
},
]);
});
});

View File

@ -89,10 +89,9 @@ const CodeBlock = styled.pre.attrs({ role: 'code' })`
`;
const Blockquote = styled.blockquote.attrs({ role: 'blockquote' })`
margin: ${({ theme }) => `${theme.spaces[6]} 0`};
margin: ${({ theme }) => `${theme.spaces[4]} 0`};
font-weight: ${({ theme }) => theme.fontWeights.regular};
border-left: ${({ theme }) => `${theme.spaces[1]} solid ${theme.colors.neutral150}`};
font-style: italic;
padding: ${({ theme }) => theme.spaces[2]} ${({ theme }) => theme.spaces[5]};
`;
@ -399,6 +398,31 @@ export function useBlocksStore() {
},
matchNode: (node) => node.type === 'quote',
isInBlocksSelector: true,
handleEnterKey(editor) {
/**
* To determine if we should break out of the quote node, check 2 things:
* 1. If the cursor is at the end of the quote node
* 2. If the last line of the quote node is empty
*/
const [quoteNode, quoteNodePath] = Editor.above(editor, {
match: (n) => n.type === 'quote',
});
const isNodeEnd = Editor.isEnd(editor, editor.selection.anchor, quoteNodePath);
const isEmptyLine = quoteNode.children.at(-1).text.endsWith('\n');
if (isNodeEnd && isEmptyLine) {
// Remove the last line break
Transforms.delete(editor, { distance: 1, unit: 'character', reverse: true });
// Break out of the quote node new paragraph
Transforms.insertNodes(editor, {
type: 'paragraph',
children: [{ type: 'text', text: '' }],
});
} else {
// Otherwise insert a new line within the quote node
Transforms.insertText(editor, '\n');
}
},
},
'list-ordered': {
renderElement: (props) => <List {...props} />,