UNPKG

last-draft

Version:

Last Draft... A Draft.js Editor

166 lines (142 loc) 5.08 kB
import React, { Component } from 'react' import { render } from 'react-dom' // eslint-disable-line no-unused-vars import Editor, { composeDecorators } from 'draft-js-plugins-editor' import { EditorState, RichUtils, getDefaultKeyBinding, KeyBindingUtil } from 'draft-js' import { fromJS } from 'immutable'; /* Emoji plugin */ import createEmojiPlugin from 'draft-js-emoji-plugin' import 'draft-js-emoji-plugin/lib/plugin.css' const emojiPlugin = createEmojiPlugin() const { EmojiSuggestions } = emojiPlugin /* Hashtag plugin */ import createHashtagPlugin from 'draft-js-hashtag-plugin' import 'draft-js-hashtag-plugin/lib/plugin.css' const hashtagPlugin = createHashtagPlugin() /* Image with Alignment, dnd, focus, resize plugin */ import createImagePlugin from 'draft-js-image-plugin' import createAlignmentPlugin from 'draft-js-alignment-plugin' import createFocusPlugin from 'draft-js-focus-plugin' import createResizeablePlugin from 'draft-js-resizeable-plugin' import createDndPlugin from 'draft-js-drag-n-drop-plugin' import 'draft-js-alignment-plugin/lib/plugin.css' import 'draft-js-focus-plugin/lib/plugin.css' const focusPlugin = createFocusPlugin() const resizeablePlugin = createResizeablePlugin() const dndPlugin = createDndPlugin() const alignmentPlugin = createAlignmentPlugin() const { AlignmentTool } = alignmentPlugin const decorator = composeDecorators( resizeablePlugin.decorator, alignmentPlugin.decorator, focusPlugin.decorator, dndPlugin.decorator ) const imagePlugin = createImagePlugin({ decorator }) /* Linkify */ import createLinkifyPlugin from 'draft-js-linkify-plugin' import 'draft-js-linkify-plugin/lib/plugin.css' const linkifyPlugin = createLinkifyPlugin() /* Mentions */ import createMentionPlugin, { defaultSuggestionsFilter } from 'draft-js-mention-plugin' const mentionPlugin = createMentionPlugin(); const { MentionSuggestions } = mentionPlugin; import 'draft-js-mention-plugin/lib/plugin.css' /* ld plugins */ /* Toolbar */ import createToolbarPlugin from 'last-draft-js-toolbar-plugin' import 'last-draft-js-toolbar-plugin/lib/plugin.css' const toolbarPlugin = createToolbarPlugin() const { Toolbar } = toolbarPlugin /* Side Toolbar */ import createSidebarPlugin from 'last-draft-js-sidebar-plugin' import 'last-draft-js-sidebar-plugin/lib/plugin.css' const sidebarPlugin = createSidebarPlugin() const { Sidebar } = sidebarPlugin /* Embed plugin */ import createEmbedPlugin from 'draft-js-embed-plugin' import 'draft-js-embed-plugin/lib/plugin.css' const embedPlugin = createEmbedPlugin() /* Link plugin */ import createLinkPlugin from 'draft-js-link-plugin' import 'draft-js-link-plugin/lib/plugin.css' const linkPlugin = createLinkPlugin() /* Color */ import {colorStyleMap} from 'draft-js-color-picker-plugin' /* init the plugins */ const plugins = [ dndPlugin, focusPlugin, alignmentPlugin, resizeablePlugin, imagePlugin, emojiPlugin, hashtagPlugin, linkifyPlugin, mentionPlugin, toolbarPlugin, sidebarPlugin, embedPlugin, linkPlugin ] export default class extends Component { constructor(props) { super(props) this.state = { suggestions: props.mentions || fromJS([]) } this.keyBindings = this.props.keyBindings || [] } onChange = (editorState) => { this.props.onChange(editorState) } focus = () => { this.editor.focus() } onSearchChange = ({ value }) => { if (this.props.mentionSearchAsync !== undefined) { /* async */ this.props.mentionSearchAsync(value) .then((data) => { this.setState({suggestions: fromJS(data.suggestions)}) }) } else { /* static list of users */ this.setState({ suggestions: defaultSuggestionsFilter(value, this.props.mentions), }) } } handleKeyCommand (command) { if (this.keyBindings.length) { const kb = this.keyBindings.find(k => k.name === command) if (kb) { kb.action() return true } } const newState = RichUtils.handleKeyCommand(this.props.editorState, command) if (newState) { this.props.onChange(newState) return true } return false } handleReturn (event) { if (!event.shiftKey) { return false } const newState = RichUtils.insertSoftNewline(this.props.editorState) this.props.onChange(newState) return true } render () { return ( <div> <div className='editor'> <Editor editorState={this.props.editorState} onChange={this.onChange} plugins={plugins} customStyleMap={colorStyleMap} handleKeyCommand={::this.handleKeyCommand} handleReturn={::this.handleReturn} ref={(element) => { this.editor = element }} /> <AlignmentTool /> <Toolbar /> <Sidebar /> <EmojiSuggestions /> <MentionSuggestions onSearchChange={this.onSearchChange} suggestions={this.state.suggestions} onClose={() => this.setState({suggestions: fromJS([])})} /> </div> </div> ) } }