diff --git a/examples/blocks/Blockquote.js b/examples/blocks/Blockquote.js new file mode 100644 index 00000000..865bf328 --- /dev/null +++ b/examples/blocks/Blockquote.js @@ -0,0 +1,41 @@ +// @flow +import React from "react"; +import { EditorBlock } from "draft-js"; + +// import { updateDataOfBlock } from "../../model/"; + +type Props = {| + block: ContentBlock, + blockProps: BlockProps, +|}; + +class Blockquote extends React.Component { + constructor(props) { + super(props); + this.updateData = this.updateData.bind(this); + } + + updateData() { + const { block, blockProps } = this.props; + const { setEditorState, getEditorState } = blockProps; + const data = block.getData(); + const checked = data.has("checked") && data.get("checked") === true; + const newData = data.set("checked", !checked); + setEditorState(updateDataOfBlock(getEditorState(), block, newData)); + } + + render() { + const { block } = this.props; + const data = block.getData(); + return ( +
+ + + + +
+ ); + } +} + +export default Blockquote; diff --git a/examples/constants/ui.js b/examples/constants/ui.js index fc90bfae..5b2dbbe0 100644 --- a/examples/constants/ui.js +++ b/examples/constants/ui.js @@ -12,6 +12,7 @@ import Document, { DOCUMENT_ICON } from "../entities/Document"; import EmbedBlock from "../blocks/EmbedBlock"; import ImageBlock from "../blocks/ImageBlock"; +import Blockquote from "../blocks/Blockquote"; import FontIcon from "../components/FontIcon"; @@ -115,3 +116,22 @@ export const REDACTED_STYLE = { description: "Redacted", style: { backgroundColor: "currentcolor" }, }; + +export const SECTION_BREAK_BLOCK = { + type: "section-break", + description: "Section break", + icon: + "M256 384V0h768v384h-64V64H320v320h-64zm768 192v448H256V576h64v384h640V576h64zM512 448h128v64H512v-64zm-192 0h128v64H320v-64zm384 0h128v64H704v-64zm192 0h128v64H896v-64zM0 288l192 192L0 672V288z", + block: { + component: () => Section break, + editable: false, + }, +}; + +export const BLOCKQUOTE_BLOCK = { + type: BLOCK_TYPE.BLOCKQUOTE, + block: { + component: Blockquote, + editable: true, + }, +}; diff --git a/examples/docs.story.js b/examples/docs.story.js index 0a06c4d2..f70c9061 100644 --- a/examples/docs.story.js +++ b/examples/docs.story.js @@ -13,6 +13,8 @@ import { ENTITY_CONTROL, REDACTED_STYLE, BR_ICON, + SECTION_BREAK_BLOCK, + BLOCKQUOTE_BLOCK, } from "./constants/ui"; import EditorWrapper from "./components/EditorWrapper"; @@ -96,6 +98,31 @@ storiesOf("Docs", module) ]} /> )) + .add("Custom block rendering", () => ( + + )) .add("Entities", () => ( span { + background-color: $WHITE; + padding: $spacing * 1; + } +} + .docs-ui-theming .Draftail-Toolbar { border: 0; background: transparent; diff --git a/lib/components/DraftailEditor.js b/lib/components/DraftailEditor.js index fbd0d055..2f000b69 100644 --- a/lib/components/DraftailEditor.js +++ b/lib/components/DraftailEditor.js @@ -651,11 +651,33 @@ class DraftailEditor extends Component { /* :: blockRenderer: (block: ContentBlock) => {}; */ blockRenderer(block: ContentBlock) { - const { entityTypes } = this.props; + const { blockTypes, entityTypes } = this.props; const { editorState } = this.state; - const contentState = editorState.getCurrentContent(); - if (block.getType() !== BLOCK_TYPE.ATOMIC) { + const type = block.getType(); + const blockType = blockTypes.find((b) => b.type === type); + + // The block should use the configured custom rendering. + if (blockType && blockType.block) { + return { + component: blockType.block.component, + editable: blockType.block.editable, + props: { + // The editorState is available for arbitrary content manipulation. + editorState, + // Whole blockType configuration, as provided to the editor. + blockType, + // Make the whole editor read-only, except for the block. + lockEditor: this.lockEditor, + // Make the editor editable again. + unlockEditor: this.unlockEditor, + // Update the editorState with arbitrary changes. + onChange: this.onChange, + }, + }; + } + + if (type !== BLOCK_TYPE.ATOMIC) { return null; } @@ -667,6 +689,7 @@ class DraftailEditor extends Component { }; } + const contentState = editorState.getCurrentContent(); const entity = contentState.getEntity(entityKey); const isHorizontalRule = entity.type === ENTITY_TYPE.HORIZONTAL_RULE;