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