Renamed /src to /frontend
This commit is contained in:
41
frontend/scenes/DocumentEdit/components/Editor.js
Normal file
41
frontend/scenes/DocumentEdit/components/Editor.js
Normal file
@@ -0,0 +1,41 @@
|
||||
import React from 'react';
|
||||
import { observer } from 'mobx-react';
|
||||
import { convertToMarkdown } from 'utils/markdown';
|
||||
|
||||
import MarkdownEditor from 'components/MarkdownEditor';
|
||||
import Preview from './Preview';
|
||||
import EditorPane from './EditorPane';
|
||||
|
||||
import styles from '../DocumentEdit.scss';
|
||||
|
||||
const Editor = observer((props) => {
|
||||
const store = props.store;
|
||||
|
||||
return (
|
||||
<div className={ styles.container }>
|
||||
<EditorPane
|
||||
fullWidth={ !store.preview }
|
||||
onScroll={ props.onScroll }
|
||||
>
|
||||
<MarkdownEditor
|
||||
onChange={ store.updateText }
|
||||
text={ store.text }
|
||||
replaceText={ store.replaceText }
|
||||
preview={ store.preview }
|
||||
onSave={ props.onSave }
|
||||
onCancel={ props.onCancel }
|
||||
togglePreview={ props.togglePreview }
|
||||
/>
|
||||
</EditorPane>
|
||||
{ store.preview ? (
|
||||
<EditorPane
|
||||
scrollTop={ props.scrollTop }
|
||||
>
|
||||
<Preview html={ convertToMarkdown(store.text) } />
|
||||
</EditorPane>
|
||||
) : null }
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
export default Editor;
|
||||
9
frontend/scenes/DocumentEdit/components/EditorLoader.js
Normal file
9
frontend/scenes/DocumentEdit/components/EditorLoader.js
Normal file
@@ -0,0 +1,9 @@
|
||||
export default () => {
|
||||
return new Promise(resolve => {
|
||||
require.ensure([], () => {
|
||||
resolve({
|
||||
Editor: require('./Editor').default,
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
62
frontend/scenes/DocumentEdit/components/EditorPane.js
Normal file
62
frontend/scenes/DocumentEdit/components/EditorPane.js
Normal file
@@ -0,0 +1,62 @@
|
||||
import React from 'react';
|
||||
|
||||
import styles from '../DocumentEdit.scss';
|
||||
import classNames from 'classnames/bind';
|
||||
const cx = classNames.bind(styles);
|
||||
|
||||
class EditorPane extends React.Component {
|
||||
static propTypes = {
|
||||
children: React.PropTypes.node.isRequired,
|
||||
onScroll: React.PropTypes.func.isRequired,
|
||||
scrollTop: React.PropTypes.number,
|
||||
fullWidth: React.PropTypes.bool,
|
||||
}
|
||||
|
||||
componentWillReceiveProps = (nextProps) => {
|
||||
|
||||
if (nextProps.scrollTop) {
|
||||
this.scrollToPosition(nextProps.scrollTop)
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount = () => {
|
||||
this.refs.pane.addEventListener('scroll', this.handleScroll);
|
||||
}
|
||||
|
||||
componentWillUnmount = () => {
|
||||
this.refs.pane.removeEventListener('scroll', this.handleScroll);
|
||||
}
|
||||
|
||||
handleScroll = (e) => {
|
||||
setTimeout(() => {
|
||||
const element = this.refs.pane;
|
||||
const contentEl = this.refs.content;
|
||||
this.props.onScroll(element.scrollTop / contentEl.offsetHeight);
|
||||
}, 50);
|
||||
}
|
||||
|
||||
scrollToPosition = (percentage) => {
|
||||
const contentEl = this.refs.content;
|
||||
|
||||
// Push to edges
|
||||
if (percentage < 0.02) percentage = 0;
|
||||
if (percentage > 0.99) percentage = 100;
|
||||
|
||||
this.refs.pane.scrollTop = percentage * contentEl.offsetHeight;
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div
|
||||
className={ cx(styles.editorPane, { fullWidth: this.props.fullWidth }) }
|
||||
ref="pane"
|
||||
>
|
||||
<div ref="content" className={ styles.paneContent }>
|
||||
{ this.props.children }
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export default EditorPane;
|
||||
21
frontend/scenes/DocumentEdit/components/Preview.js
Normal file
21
frontend/scenes/DocumentEdit/components/Preview.js
Normal file
@@ -0,0 +1,21 @@
|
||||
import React from 'react';
|
||||
|
||||
import { DocumentHtml } from 'components/Document';
|
||||
|
||||
import styles from '../DocumentEdit.scss';
|
||||
import classNames from 'classnames/bind';
|
||||
const cx = classNames.bind(styles);
|
||||
|
||||
const Preview = (props) => {
|
||||
return (
|
||||
<div className={ styles.preview }>
|
||||
<DocumentHtml html={ props.html } />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
Preview.propTypes = {
|
||||
html: React.PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
export default Preview;
|
||||
31
frontend/scenes/DocumentEdit/components/SaveAction.js
Normal file
31
frontend/scenes/DocumentEdit/components/SaveAction.js
Normal file
@@ -0,0 +1,31 @@
|
||||
import React from 'react';
|
||||
import { observer } from 'mobx-react';
|
||||
|
||||
@observer
|
||||
class SaveAction extends React.Component {
|
||||
static propTypes = {
|
||||
onClick: React.PropTypes.func.isRequired,
|
||||
disabled: React.PropTypes.bool,
|
||||
}
|
||||
|
||||
onClick = (event) => {
|
||||
if (this.props.disabled) return;
|
||||
|
||||
event.preventDefault();
|
||||
this.props.onClick();
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<a
|
||||
href
|
||||
onClick={ this.onClick }
|
||||
style={{ opacity: this.props.disabled ? 0.5 : 1 }}
|
||||
>Save</a>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export default SaveAction;
|
||||
Reference in New Issue
Block a user