You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
96 lines
3.8 KiB
JavaScript
96 lines
3.8 KiB
JavaScript
import React, {Component} from "react";
|
|
import {Editor, EditorState, RichUtils} from "draft-js";
|
|
import {FontAwesomeIcon} from '@fortawesome/react-fontawesome'
|
|
import * as fa from "@fortawesome/free-solid-svg-icons"
|
|
import "draft-js/dist/Draft.css"
|
|
|
|
export default class LoreEditor extends Component {
|
|
constructor(props) {
|
|
super(props);
|
|
this.state = {editorState: EditorState.createEmpty()};
|
|
this.onChange = editorState => {
|
|
this.setState({editorState});
|
|
}
|
|
this.handleKeyCommand = this.handleKeyCommand.bind(this);
|
|
}
|
|
|
|
handleKeyCommand(command, editorState) {
|
|
// Allows the use of key binds like Ctrl + B
|
|
const newState = RichUtils.handleKeyCommand(editorState, command);
|
|
if (newState) {
|
|
this.onChange(newState);
|
|
return 'handled';
|
|
}
|
|
|
|
return 'not-handled';
|
|
}
|
|
|
|
blockTypeButton(name, blockType) {
|
|
const selection = this.state.editorState.getSelection();
|
|
const currentBlockType = this.state.editorState
|
|
.getCurrentContent()
|
|
.getBlockForKey(selection.getStartKey())
|
|
.getType();
|
|
|
|
return <span className={currentBlockType === blockType ? "active" : ""}
|
|
onMouseDown={(e) => {
|
|
// Don't do system mouse down event,
|
|
// because we'll be unfocused from the text editor
|
|
e.preventDefault()
|
|
|
|
this.onChange(RichUtils.toggleBlockType(this.state.editorState, blockType))
|
|
}}>{name}</span>
|
|
}
|
|
|
|
styleButton(name, style) {
|
|
const currentStyle = this.state.editorState.getCurrentInlineStyle();
|
|
|
|
return <span className={currentStyle.contains(style) ? "active" : ""}
|
|
onMouseDown={(e) => {
|
|
// Don't do system mouse down event,
|
|
// because we'll be unfocused from the text editor
|
|
e.preventDefault()
|
|
|
|
|
|
this.onChange(RichUtils.toggleInlineStyle(this.state.editorState, style))
|
|
}}>{name}</span>
|
|
}
|
|
|
|
render() {
|
|
return (
|
|
<div className="lore-editor">
|
|
<div className="title">
|
|
<input type="text" value={this.state.title} onChange={() => this.setState({title: this.titleInput.value})}
|
|
ref={el => this.titleInput = el}/>
|
|
</div>
|
|
<div className="bar">
|
|
<span className="group">
|
|
{this.blockTypeButton("H1", "header-one")}
|
|
{this.blockTypeButton("H2", "header-two")}
|
|
{this.blockTypeButton("H3", "header-three")}
|
|
{this.blockTypeButton("H4", "header-four")}
|
|
{this.blockTypeButton("H5", "header-five")}
|
|
{this.blockTypeButton(<FontAwesomeIcon title="Block quote" icon={fa.faIndent}/>, "blockquote")}
|
|
{this.blockTypeButton(<FontAwesomeIcon title="Unordered list" icon={fa.faListUl}/>, "unordered-list-item")}
|
|
{this.blockTypeButton(<FontAwesomeIcon title="Ordered list" icon={fa.faListOl}/>, "ordered-list-item")}
|
|
{this.blockTypeButton(<FontAwesomeIcon title="Code block" icon={fa.faCode}/>, "code-block")}
|
|
</span>
|
|
<span className="group">
|
|
{this.styleButton(<FontAwesomeIcon title="Bold" icon={fa.faBold}/>, "BOLD")}
|
|
{this.styleButton(<FontAwesomeIcon title="Italic" icon={fa.faItalic}/>, "ITALIC")}
|
|
{this.styleButton(<FontAwesomeIcon title="Underline" icon={fa.faUnderline}/>, "UNDERLINE")}
|
|
{this.styleButton(<FontAwesomeIcon title="Strike-through" icon={fa.faStrikethrough}/>, "STRIKETHROUGH")}
|
|
{this.styleButton(<FontAwesomeIcon title="Monospace" icon={fa.faTextWidth}/>, "CODE")}
|
|
</span>
|
|
</div>
|
|
<div className="container">
|
|
<Editor
|
|
editorState={this.state.editorState}
|
|
handleKeyCommand={this.handleKeyCommand}
|
|
onChange={this.onChange}
|
|
/>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
} |