Created
March 20, 2018 13:31
-
-
Save markspolakovs/08b522e186905c270b9d9cfdf9020775 to your computer and use it in GitHub Desktop.
side-by-side editor
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.editor-split { | |
flex: 1; | |
display: flex; | |
flex-direction: row; | |
flex-wrap: nowrap; | |
justify-content: center; | |
} | |
@media all and (max-width: 1356px) { | |
.editor-split { | |
flex-wrap: wrap; | |
} | |
} | |
.mde-header .fa { | |
color: #fafafa; | |
} | |
.mde-text { | |
min-width: 600px; | |
color: #212121; | |
flex-grow: 1; | |
flex-shrink: 0; | |
font-size: 18px; | |
line-height: 24px; | |
textarea { | |
resize: none; | |
} | |
} | |
.mde-preview { | |
min-width: 600px; | |
max-width: 50%; | |
flex-grow: 1; | |
flex-shrink: 0; | |
font-size: 18px; | |
line-height: 24px; | |
} | |
.mde-preview img { | |
max-width: 100%; | |
} | |
.textarea--ghost { | |
opacity: 0.3; | |
display: block; | |
white-space: pre-wrap; | |
word-wrap: break-word; | |
visibility: hidden; | |
position: absolute; | |
top: 0; | |
pointer-events: none; | |
font-size: 18px; | |
line-height: 24px; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import * as React from "react"; | |
import 'react-mde/lib/styles/css/react-mde-all.css'; | |
import showdown from "showdown"; | |
const showdownOptions = require("../lib/showdown/showdown.config"); | |
const { imageExtension } = require("../lib/showdown/extensions")(showdown); | |
showdown.extension('imageExtension', imageExtension); | |
const mde = require("react-mde"); | |
const makeImageCommand = (uploadImageRef) => ({ | |
// snip | |
}); | |
export default class MarkdownEditor extends React.Component { | |
constructor(props) { | |
super(props); | |
this.state = {height: 0}; | |
this.textArea = null; | |
this.ghost = null; | |
this.mounted = false; | |
this.commands = [ | |
[mde.ReactMdeCommands.makeHeaderCommand, mde.ReactMdeCommands.makeBoldCommand, mde.ReactMdeCommands.makeItalicCommand], | |
[mde.ReactMdeCommands.makeLinkCommand, mde.ReactMdeCommands.makeQuoteCommand, mde.ReactMdeCommands.makeCodeCommand, makeImageCommand(props.uploadImage)], | |
[mde.ReactMdeCommands.makeUnorderedListCommand, mde.ReactMdeCommands.makeOrderedListCommand], | |
]; | |
} | |
componentDidMount() { | |
this.mounted = true; | |
this.setFilledTextareaHeight(); | |
} | |
setFilledTextareaHeight = () => { | |
if (this.mounted) { | |
const element = this.ghost; | |
this.setState({ | |
height: element.clientHeight + 100, | |
}); | |
} | |
}; | |
handleCommand = async command => { | |
const {value: {text}, onChange} = this.props; | |
let result = command.execute(text, mde.ReactMdeSelectionHelper.getSelection(this.textArea)); | |
if (result instanceof Promise) { | |
result = await result; | |
} | |
// result.scrollTop = this.textArea.scrollTop; | |
onChange(result); | |
}; | |
getGhostField() { | |
return ( | |
<div | |
className="textarea textarea--ghost" | |
ref={(c) => this.ghost = c} | |
aria-hidden="true" | |
> | |
{this.props.value.text} | |
</div> | |
); | |
} | |
render() { | |
const {value, onChange, uploadImage} = this.props; | |
return ( | |
<div> | |
{this.getGhostField()} | |
<mde.ReactMdeToolbar commands={this.commands} onCommand={this.handleCommand}/> | |
<div className="editor-split"> | |
<mde.ReactMdeTextArea | |
value={value} | |
onChange={onChange} | |
textAreaRef={(c) => this.textArea = c} | |
textAreaProps={{ | |
style: { | |
height: this.state.height, | |
resize: null | |
}, | |
onKeyUp: this.setFilledTextareaHeight | |
}} | |
/> | |
<mde.ReactMdePreview markdown={value ? value.text : ""} showdownOptions={showdownOptions}/> | |
</div> | |
</div> | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment