Draft.js React 16.6
Draft.js rich text example
by Thibaud Colas
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/immutable/3.8.1/immutable.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.1/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.1/umd/react-dom.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/draft-js/0.10.5/Draft.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/draft-js/0.10.5/Draft.css">
<!--
Source https://github.com/facebook/draft-js/tree/master/examples/draft-0-10-0/rich
-->
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Draft • Rich Text</title>
<style>
#target { width: 600px; }
</style>
</head>
<body>
<div id="target"></div>
<script>
window.startContent = {
"entityMap": {},
"blocks": [{
"key": "1fv8t",
"text": "Unstyled",
"type": "unstyled",
"depth": 0,
"inlineStyleRanges": [],
"entityRanges": [],
"data": {}
},
{
"key": "f0898",
"text": "List item",
"type": "unordered-list-item",
"depth": 0,
"inlineStyleRanges": [],
"entityRanges": [],
"data": {}
},
{
"key": "9qh91",
"text": "Code block",
"type": "code-block",
"depth": 0,
"inlineStyleRanges": [],
"entityRanges": [],
"data": {}
}
]
};
</script>
</body>
</html>
CSS
.RichEditor-root {
background: #fff;
border: 1px solid #ddd;
font-family: 'Georgia', serif;
font-size: 14px;
padding: 15px;
}
.RichEditor-editor {
border-top: 1px solid #ddd;
cursor: text;
font-size: 16px;
margin-top: 10px;
}
.RichEditor-editor .public-DraftEditorPlaceholder-root,
.RichEditor-editor .public-DraftEditor-content {
margin: 0 -15px -15px;
padding: 15px;
}
.RichEditor-editor .public-DraftEditor-content {
min-height: 100px;
}
.RichEditor-hidePlaceholder .public-DraftEditorPlaceholder-root {
display: none;
}
.RichEditor-editor .RichEditor-blockquote {
border-left: 5px solid #eee;
color: #666;
font-family: 'Hoefler Text', 'Georgia', serif;
font-style: italic;
margin: 16px 0;
padding: 10px 20px;
}
.RichEditor-editor .public-DraftStyleDefault-pre {
background-color: rgba(0, 0, 0, 0.05);
font-family: 'Inconsolata', 'Menlo', 'Consolas', monospace;
font-size: 16px;
padding: 20px;
}
.RichEditor-controls {
font-family: 'Helvetica', sans-serif;
font-size: 14px;
margin-bottom: 5px;
user-select: none;
}
.RichEditor-styleButton {
color: #999;
cursor: pointer;
margin-right: 16px;
padding: 2px 0;
display: inline-block;
}
.RichEditor-activeButton {
color: #5890ff;
}
Babel + JSX
'use strict';
const {Editor, EditorState, RichUtils, convertFromRaw} = Draft;
class RichEditorExample extends React.Component {
constructor(props) {
super(props);
this.state = {editorState: EditorState.createWithContent(convertFromRaw(window.startContent))};
this.focus = () => this.refs.editor.focus();
this.onChange = (editorState) => this.setState({editorState});
this.handleKeyCommand = (command) => this._handleKeyCommand(command);
this.onTab = (e) => this._onTab(e);
this.toggleBlockType = (type) => this._toggleBlockType(type);
this.toggleInlineStyle = (style) => this._toggleInlineStyle(style);
}
_handleKeyCommand(command) {
const {editorState} = this.state;
const newState = RichUtils.handleKeyCommand(editorState, command);
if (newState) {
this.onChange(newState);
return true;
}
return false;
}
_onTab(e) {
const maxDepth = 4;
this.onChange(RichUtils.onTab(e, this.state.editorState, maxDepth));
}
_toggleBlockType(blockType) {
this.onChange(
RichUtils.toggleBlockType(
this.state.editorState,
blockType
)
);
}
_toggleInlineStyle(inlineStyle) {
this.onChange(
RichUtils.toggleInlineStyle(
this.state.editorState,
inlineStyle
)
);
}
render() {
const {editorState} = this.state;
// If the user changes block type before entering any text, we can
// either style the placeholder or hide it. Let's just hide it now.
let className = 'RichEditor-editor';
var contentState = editorState.getCurrentContent();
if (!contentState.hasText()) {
if (contentState.getBlockMap().first().getType() !==...