insomnia/packages/insomnia-app/app/ui/components/markdown-editor.js
2018-12-12 12:36:11 -05:00

150 lines
4.4 KiB
JavaScript

import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import autobind from 'autobind-decorator';
import classnames from 'classnames';
import { Tab, TabList, TabPanel, Tabs } from 'react-tabs';
import Button from './base/button';
import CodeEditor from './codemirror/code-editor';
import MarkdownPreview from './markdown-preview';
@autobind
class MarkdownEditor extends PureComponent {
constructor(props) {
super(props);
this.state = {
markdown: props.defaultValue,
};
}
_handleChange(markdown) {
this.props.onChange(markdown);
this.setState({ markdown });
}
_setEditorRef(n) {
this._editor = n;
}
focusEnd() {
this._editor && this._editor.focusEnd();
}
focus() {
this._editor && this._editor.focus();
}
render() {
const {
fontSize,
lineWrapping,
indentSize,
keyMap,
mode,
placeholder,
defaultPreviewMode,
className,
tall,
handleRender,
handleGetRenderContext,
nunjucksPowerUserMode,
isVariableUncovered,
} = this.props;
const { markdown } = this.state;
const classes = classnames('react-tabs', 'markdown-editor', 'outlined', className, {
'markdown-editor--dynamic-height': !tall,
});
return (
<Tabs className={classes} defaultIndex={defaultPreviewMode ? 1 : 0}>
<TabList>
<Tab tabIndex="-1">
<Button value="Write">Write</Button>
</Tab>
<Tab tabIndex="-1">
<Button value="Preview">Preview</Button>
</Tab>
</TabList>
<TabPanel className="react-tabs__tab-panel markdown-editor__edit">
<div className="form-control form-control--outlined">
{isVariableUncovered && (
<CodeEditor
ref={this._setEditorRef}
hideGutters
hideLineNumbers
dynamicHeight={!tall}
manualPrettify
noStyleActiveLine
mode={mode || 'text/x-markdown'}
placeholder={placeholder}
debounceMillis={300}
keyMap={keyMap}
fontSize={fontSize}
lineWrapping={lineWrapping}
indentSize={indentSize}
defaultValue={markdown}
render={handleRender}
getRenderContext={handleGetRenderContext}
nunjucksPowerUserMode={nunjucksPowerUserMode}
isVariableUncovered={isVariableUncovered}
onChange={this._handleChange}
/>
)}
{!isVariableUncovered && (
<CodeEditor
ref={this._setEditorRef}
hideGutters
hideLineNumbers
dynamicHeight={!tall}
manualPrettify
noStyleActiveLine
mode={mode || 'text/x-markdown'}
placeholder={placeholder}
debounceMillis={300}
keyMap={keyMap}
fontSize={fontSize}
lineWrapping={lineWrapping}
indentSize={indentSize}
defaultValue={markdown}
render={handleRender}
getRenderContext={handleGetRenderContext}
nunjucksPowerUserMode={nunjucksPowerUserMode}
isVariableUncovered={isVariableUncovered}
onChange={this._handleChange}
/>
)}
</div>
<div className="txt-sm italic faint">Styling with Markdown is supported</div>
</TabPanel>
<TabPanel className="react-tabs__tab-panel markdown-editor__preview">
<MarkdownPreview markdown={markdown} handleRender={handleRender} />
</TabPanel>
</Tabs>
);
}
}
MarkdownEditor.propTypes = {
// Required
onChange: PropTypes.func.isRequired,
defaultValue: PropTypes.string.isRequired,
fontSize: PropTypes.number.isRequired,
indentSize: PropTypes.number.isRequired,
keyMap: PropTypes.string.isRequired,
lineWrapping: PropTypes.bool.isRequired,
handleRender: PropTypes.func.isRequired,
handleGetRenderContext: PropTypes.func.isRequired,
nunjucksPowerUserMode: PropTypes.bool.isRequired,
isVariableUncovered: PropTypes.bool.isRequired,
// Optional
placeholder: PropTypes.string,
defaultPreviewMode: PropTypes.bool,
className: PropTypes.string,
mode: PropTypes.string,
tall: PropTypes.bool,
};
export default MarkdownEditor;