Skip to content

Commit f561123

Browse files
committed
feat(richtext): add blockquote
1 parent 62ab574 commit f561123

File tree

4 files changed

+71
-4
lines changed

4 files changed

+71
-4
lines changed

packages/decap-cms-widget-richtext/src/RichtextControl/VisualEditor.js

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ import {
2222
import { createSoftBreakPlugin, createExitBreakPlugin } from '@udecode/plate-break';
2323
import { createListPlugin, ELEMENT_UL, ELEMENT_OL, ELEMENT_LI } from '@udecode/plate-list';
2424
import { createLinkPlugin, ELEMENT_LINK } from '@udecode/plate-link';
25+
import { createBlockquotePlugin, ELEMENT_BLOCKQUOTE } from '@udecode/plate-block-quote';
26+
import { createTrailingBlockPlugin } from '@udecode/plate-trailing-block';
2527
import { ClassNames } from '@emotion/react';
2628
import { fonts, lengths, zIndex } from 'decap-cms-ui-default';
2729

@@ -35,6 +37,7 @@ import HeadingElement from './components/Element/HeadingElement';
3537
import ListElement from './components/Element/ListElement';
3638
import { markdownToSlate, slateToMarkdown } from '../serializers';
3739
import LinkElement from './components/Element/LinkElement';
40+
import BlockquoteElement from './components/Element/BlockquoteElement';
3841

3942
function visualEditorStyles({ minimal }) {
4043
return `
@@ -69,9 +72,18 @@ export default function VisualEditor({ t, field, className, isDisabled, onChange
6972
createCodePlugin(),
7073
createListPlugin(),
7174
createLinkPlugin(),
75+
createBlockquotePlugin(),
7276
createSoftBreakPlugin({
7377
options: {
74-
rules: [{ hotkey: 'shift+enter' }],
78+
rules: [
79+
{ hotkey: 'shift+enter' },
80+
{
81+
hotkey: 'enter',
82+
query: {
83+
allow: [ELEMENT_BLOCKQUOTE],
84+
},
85+
},
86+
],
7587
},
7688
}),
7789
createExitBreakPlugin({
@@ -97,13 +109,17 @@ export default function VisualEditor({ t, field, className, isDisabled, onChange
97109
],
98110
},
99111
}),
112+
createTrailingBlockPlugin({
113+
options: { type: ELEMENT_PARAGRAPH },
114+
}),
100115
],
101116
{
102117
components: {
103118
[MARK_BOLD]: withProps(PlateLeaf, { as: 'b' }),
104119
[MARK_CODE]: CodeLeaf,
105120
[MARK_ITALIC]: withProps(PlateLeaf, { as: 'em' }),
106121
[ELEMENT_PARAGRAPH]: ParagraphElement,
122+
[ELEMENT_BLOCKQUOTE]: BlockquoteElement,
107123
[ELEMENT_LINK]: LinkElement,
108124
[ELEMENT_H1]: withProps(HeadingElement, { variant: 'h1' }),
109125
[ELEMENT_H2]: withProps(HeadingElement, { variant: 'h2' }),
@@ -136,9 +152,7 @@ export default function VisualEditor({ t, field, className, isDisabled, onChange
136152
onChange(mdValue);
137153
}
138154

139-
const initialValue = props.value
140-
? markdownToSlate(props.value, {})
141-
: emptyValue;
155+
const initialValue = props.value ? markdownToSlate(props.value, {}) : emptyValue;
142156

143157
return (
144158
<ClassNames>
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import React from 'react';
2+
import { PlateElement } from '@udecode/plate-common';
3+
import styled from '@emotion/styled';
4+
import { colors } from 'decap-cms-ui-default';
5+
6+
const bottomMargin = '16px';
7+
8+
const StyledBlockQuote = styled.blockquote`
9+
padding-left: 16px;
10+
border-left: 3px solid ${colors.background};
11+
margin-left: 0;
12+
margin-right: 0;
13+
margin-bottom: ${bottomMargin};
14+
`;
15+
16+
function BlockquoteElement({ children, ...props }) {
17+
return (
18+
<PlateElement asChild {...props}>
19+
<StyledBlockQuote>{children}</StyledBlockQuote>
20+
</PlateElement>
21+
);
22+
}
23+
24+
export default BlockquoteElement;
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import React from 'react';
2+
import { useEditorRef, focusEditor, toggleNodeType } from '@udecode/plate-common';
3+
import { unwrapList } from '@udecode/plate-list';
4+
import { ELEMENT_BLOCKQUOTE } from '@udecode/plate-block-quote';
5+
6+
import ToolbarButton from './ToolbarButton';
7+
8+
function BlockquoteToolbarButton(props) {
9+
const editor = useEditorRef();
10+
11+
function handleClick() {
12+
unwrapList(editor);
13+
toggleNodeType(editor, { activeType: ELEMENT_BLOCKQUOTE });
14+
focusEditor(editor);
15+
}
16+
const pressed = false;
17+
return <ToolbarButton isActive={pressed} onClick={handleClick} {...props} />;
18+
}
19+
20+
export default BlockquoteToolbarButton;

packages/decap-cms-widget-richtext/src/RichtextControl/components/Toolbar/Toolbar.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import MarkToolbarButton from './MarkToolbarButton';
99
import HeadingToolbarButton from './HeadingToolbarButton';
1010
import ListToolbarButton from './ListToolbarButton';
1111
import LinkToolbarButton from './LinkToolbarButton';
12+
import BlockquoteToolbarButton from './BlockquoteToolbarButton';
1213

1314
const ToolbarContainer = styled.div`
1415
position: relative;
@@ -67,6 +68,14 @@ function Toolbar(props) {
6768
t={t}
6869
/>
6970
<HeadingToolbarButton isVisible={isVisible} disabled={disabled} t={t} />
71+
{isVisible('blockquote') && (
72+
<BlockquoteToolbarButton
73+
type="quote"
74+
label={t('editor.editorWidgets.markdown.quote')}
75+
icon="quote"
76+
disabled={disabled}
77+
/>
78+
)}
7079
<ListToolbarButton
7180
type="ul"
7281
label={t('editor.editorWidgets.markdown.bulletedList')}

0 commit comments

Comments
 (0)