insomnia/packages/insomnia-app/app/ui/components/markdown-editor.tsx

127 lines
3.5 KiB
TypeScript
Raw Normal View History

import { autoBindMethodsForReact } from 'class-autobind-decorator';
import classnames from 'classnames';
2021-07-22 23:04:56 +00:00
import React, { PureComponent } from 'react';
2018-06-25 17:42:50 +00:00
import { Tab, TabList, TabPanel, Tabs } from 'react-tabs';
2021-07-22 23:04:56 +00:00
import { AUTOBIND_CFG } from '../../common/constants';
import { HandleGetRenderContext, HandleRender } from '../../common/render';
import { Button } from './base/button';
import { CodeEditor, UnconnectedCodeEditor } from './codemirror/code-editor';
import { MarkdownPreview } from './markdown-preview';
interface Props {
onChange: Function;
defaultValue: string;
fontSize: number;
indentSize: number;
keyMap: string;
lineWrapping: boolean;
handleRender?: HandleRender;
handleGetRenderContext?: HandleGetRenderContext;
nunjucksPowerUserMode: boolean;
isVariableUncovered: boolean;
placeholder?: string;
defaultPreviewMode?: boolean;
className?: string;
mode?: string;
tall?: boolean;
}
interface State {
markdown: string;
}
@autoBindMethodsForReact(AUTOBIND_CFG)
export class MarkdownEditor extends PureComponent<Props, State> {
_editor: UnconnectedCodeEditor | null = null;
constructor(props: Props) {
super(props);
this.state = {
markdown: props.defaultValue,
};
}
2018-06-25 17:42:50 +00:00
_handleChange(markdown) {
this.props.onChange(markdown);
this.setState({
markdown,
});
}
_setEditorRef(n: UnconnectedCodeEditor) {
this._editor = n;
}
2018-06-25 17:42:50 +00:00
focusEnd() {
2021-07-30 03:32:08 +00:00
this._editor?.focusEnd();
}
2018-06-25 17:42:50 +00:00
focus() {
2021-07-30 03:32:08 +00:00
this._editor?.focus();
2017-06-16 22:21:41 +00:00
}
2018-06-25 17:42:50 +00:00
render() {
const {
fontSize,
lineWrapping,
indentSize,
keyMap,
mode,
placeholder,
defaultPreviewMode,
className,
tall,
handleRender,
handleGetRenderContext,
nunjucksPowerUserMode,
isVariableUncovered,
} = this.props;
2018-06-25 17:42:50 +00:00
const { markdown } = this.state;
2018-10-17 16:42:33 +00:00
const classes = classnames('react-tabs', 'markdown-editor', 'outlined', className, {
'markdown-editor--dynamic-height': !tall,
2018-10-17 16:42:33 +00:00
});
return (
2017-08-10 01:56:27 +00:00
<Tabs className={classes} defaultIndex={defaultPreviewMode ? 1 : 0}>
<TabList>
<Tab tabIndex="-1">
2018-05-23 04:28:25 +00:00
<Button value="Write">Write</Button>
</Tab>
<Tab tabIndex="-1">
2018-05-23 04:28:25 +00:00
<Button value="Preview">Preview</Button>
</Tab>
</TabList>
2017-08-10 01:56:27 +00:00
<TabPanel className="react-tabs__tab-panel markdown-editor__edit">
<div className="form-control form-control--outlined">
<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>
2018-10-17 16:42:33 +00:00
<div className="txt-sm italic faint">Styling with Markdown is supported</div>
</TabPanel>
2017-08-10 01:56:27 +00:00
<TabPanel className="react-tabs__tab-panel markdown-editor__preview">
2018-06-25 17:42:50 +00:00
<MarkdownPreview markdown={markdown} handleRender={handleRender} />
</TabPanel>
</Tabs>
);
}
}