import React from 'react'; import {Editor, EditorState, RichUtils} from 'draft-js'; class MarkdownEditor extends React.Component { constructor(props) { super(props); if(this.props.initialState != null) { this.state = {editorState: EditorState.createWithContent(this.props.initialState)} } else { this.state = {editorState: EditorState.createEmpty()}; } this.onChange = editorState => {this.setState({editorState}); this.props.onChange(editorState, this.props.name)}; this.handleKeyCommand = this.handleKeyCommand.bind(this); this.toggleBlockType = this._toggleBlockType.bind(this); this.toggleInlineStyle = this._toggleInlineStyle.bind(this); } handleKeyCommand(command, editorState) { const newState = RichUtils.handleKeyCommand(editorState, command); if (newState) { this.onChange(newState); return true; } return false; } _toggleBlockType(blockType) { this.onChange( RichUtils.toggleBlockType( this.state.editorState, blockType ) ); } _toggleInlineStyle(inlineStyle) { this.onChange( RichUtils.toggleInlineStyle( this.state.editorState, inlineStyle ) ); } render() { return ( <div className="editor-markdown p-2 p-2"> <BlockStyleControls editorState={this.state.editorState} onToggle={this.toggleBlockType} /> <InlineStyleControls editorState={this.state.editorState} onToggle={this.toggleInlineStyle} /> <hr /> <Editor placeholder={this.props.splaceholder} editorState={this.state.editorState} spellCheck={true} handleKeyCommand={this.handleKeyCommand} onChange={this.onChange} /> </div> ); } } const BLOCK_TYPES = [ {label: 'Blockquote', style: 'blockquote'}, {label: 'UL', style: 'unordered-list-item'}, {label: 'OL', style: 'ordered-list-item'}, {label: 'Code Block', style: 'code-block'}, ]; const BlockStyleControls = (props) => { const {editorState} = props; const selection = editorState.getSelection(); const blockType = editorState .getCurrentContent() .getBlockForKey(selection.getStartKey()) .getType(); return ( <div className="editor-controls"> {BLOCK_TYPES.map((type) => <StyleButton key={type.label} active={type.style === blockType} label={type.label} onToggle={props.onToggle} style={type.style} /> )} </div> ); }; var INLINE_STYLES = [ {label: 'Bold', style: 'BOLD'}, {label: 'Italic', style: 'ITALIC'}, {label: 'Monospace', style: 'CODE'}, ]; const InlineStyleControls = (props) => { const currentStyle = props.editorState.getCurrentInlineStyle(); return ( <div className="editor-controls"> {INLINE_STYLES.map((type) => <StyleButton key={type.label} active={currentStyle.has(type.style)} label={type.label} onToggle={props.onToggle} style={type.style} /> )} </div> ); }; class StyleButton extends React.Component { constructor() { super(); this.onToggle = (e) => { e.preventDefault(); this.props.onToggle(this.props.style); }; } render() { let className = 'editor-styleButton'; if (this.props.active) { className += ' editor-activeButton'; } return ( <span className={className} onMouseDown={this.onToggle}> {this.props.label} </span> ); } } export default MarkdownEditor