Is there documentation that explains how to preserve paragraph breaks when content is pasted into draft.js? Other formating looks reasonable but all the paragraph blocks are collapsed into a single paragraph block when pasting.
-
try https://github.com/sstur/draft-js-import-html, which help you import html. – Jiang YD Aug 22 '16 at 03:25
-
No, draft-js-import-html is no help in this case. (I use draft-js-import-html already to convert HTML to editorState for loading content -- works fine). But that's no help when _pasting_ content from another app: _all the paragraph separators get stripped out._ – SteveB Aug 23 '16 at 13:42
-
pasting html string or plain text? – Jiang YD Aug 24 '16 at 03:28
-
_Not_ plain text, but text copied to the clip board from any other application that uses rich text. Pasting such text into TInyMCE, Quil, CKEditor, etc. all preserve both inline formatting and paragraphs. Pasting into draft.js removes the line breaks, so that the entire pasted text is a single paragraph. – SteveB Aug 25 '16 at 13:31
-
draft only process plain text or html. – Jiang YD Aug 26 '16 at 05:34
-
"draft only process plain text or html" -- Actually this is _incorrect_. Draft.js itself processes neither. It has it's own internal format (read the docs), but one may convert other formats (plain text, HTML, RTF, or whatever) to the internal format. The problem here is there is no obvious method to intercept a paste and do the translation before the pasted text is inserted. – SteveB Aug 27 '16 at 14:07
-
yes I mean 'process pasting plain text or html' actually. – Jiang YD Aug 29 '16 at 01:28
-
I believe it was a design decision. If you copy a big block of text from another editor, it's probably going to insert a newline after each line of text in the paragraph. So instead, they parse them out. https://github.com/facebook/draft-js/issues/231 – kjprice Dec 07 '16 at 19:40
-
@SteveB Did you ever figure out how to preserve paragraphs? I'm trying to do that in react-rte - https://github.com/sstur/react-rte – Sam Feb 06 '17 at 23:48
2 Answers
You can handle this using a prop for Editor.
handlePastedText = (text: string, html?: string, editorState: EditorState) => {
const selection = editorState.getSelection();
const pastedBlocks = ContentState.createFromText(text).blockMap;
const newState = Modifier.replaceWithFragment(
editorState.getCurrentContent(),
editorState.getSelection(),
pastedBlocks,
);
const newEditorState = EditorState.push(editorState, newState, "insert-fragment");
this.handleChange(newEditorState);
return "handled";
};
And then pass this as props in Editor. This will solve your problem.
Unfortunately, there is no public documentation of processing of pasted content. But since draft-js is open-sourced, reading the sources comes to the rescue.
Draft-js 0.9.1 and below
Just specify p
as aliased element for unstyled
block using blockRenderMap:
import { Map } from 'immutable';
import Editor from 'draft-js';
const customRenderMap = Map({
unstyled: {
element: 'div',
// will be used in convertFromHTMLtoContentBlocks
aliasedElements: ['p'],
},
});
<Editor
editorState={this.state.editorState}
blockRenderMap={customRenderMap}
/>
Explanation:
When you paste content to draft-js, editOnPaste function gets invoked. Inside it draft determines that content you pasted is html (yes, when you copy-paste any text from text processors like MS Word, Google Docs or Apple Pages, it's actually html), and calls convertFromHTMLToContentBlocks().
convertFromHTMLToContentBlocks()
in its turn uses blockRenderMap to determine how to split html to blocks.
Draft-js 0.10.0
div
is aliased with p
by default in draft-js@0.10.0

- 6,030
- 2
- 31
- 41