2020-10-28 15:26:30 +00:00
|
|
|
import EditorJS, { OutputData } from "@editorjs/editorjs";
|
2020-11-05 13:56:29 +00:00
|
|
|
import FormControl from "@material-ui/core/FormControl";
|
|
|
|
import FormHelperText from "@material-ui/core/FormHelperText";
|
|
|
|
import InputLabel from "@material-ui/core/InputLabel";
|
2019-08-09 11:14:35 +00:00
|
|
|
import classNames from "classnames";
|
2020-11-05 16:32:55 +00:00
|
|
|
import Undo from "editorjs-undo";
|
2019-08-09 10:26:22 +00:00
|
|
|
import React from "react";
|
2019-06-19 14:40:52 +00:00
|
|
|
|
2020-11-05 16:30:38 +00:00
|
|
|
import { RichTextEditorContentProps, tools } from "./RichTextEditorContent";
|
|
|
|
import useStyles from "./styles";
|
|
|
|
|
2020-11-03 11:35:36 +00:00
|
|
|
export type RichTextEditorChange = (data: OutputData) => void;
|
2020-11-05 16:30:38 +00:00
|
|
|
export interface RichTextEditorProps extends RichTextEditorContentProps {
|
2019-06-19 14:40:52 +00:00
|
|
|
disabled: boolean;
|
|
|
|
error: boolean;
|
|
|
|
helperText: string;
|
|
|
|
label: string;
|
|
|
|
name: string;
|
2020-11-03 11:35:36 +00:00
|
|
|
onChange: RichTextEditorChange;
|
2019-06-19 14:40:52 +00:00
|
|
|
}
|
|
|
|
|
2020-10-28 15:26:30 +00:00
|
|
|
const RichTextEditor: React.FC<RichTextEditorProps> = ({
|
2020-11-03 11:35:36 +00:00
|
|
|
data,
|
2020-11-05 13:56:29 +00:00
|
|
|
disabled,
|
2020-10-28 15:26:30 +00:00
|
|
|
error,
|
|
|
|
helperText,
|
2020-11-03 11:35:36 +00:00
|
|
|
label,
|
2020-11-05 13:56:29 +00:00
|
|
|
name,
|
2020-11-03 13:53:17 +00:00
|
|
|
onChange,
|
|
|
|
onReady
|
2020-10-28 15:26:30 +00:00
|
|
|
}) => {
|
|
|
|
const classes = useStyles({});
|
2019-10-30 14:34:24 +00:00
|
|
|
|
2020-10-28 15:26:30 +00:00
|
|
|
const [isFocused, setFocus] = React.useState(false);
|
|
|
|
const editor = React.useRef<EditorJS>();
|
|
|
|
const editorContainer = React.useRef<HTMLDivElement>();
|
2020-11-03 11:35:36 +00:00
|
|
|
React.useEffect(
|
|
|
|
() => {
|
|
|
|
if (data) {
|
|
|
|
editor.current = new EditorJS({
|
|
|
|
data,
|
|
|
|
holder: editorContainer.current,
|
|
|
|
onChange: async api => {
|
|
|
|
const savedData = await api.saver.save();
|
|
|
|
onChange(savedData);
|
2020-10-28 15:26:30 +00:00
|
|
|
},
|
2020-11-05 16:32:55 +00:00
|
|
|
onReady: () => {
|
|
|
|
const undo = new Undo({ editor });
|
|
|
|
undo.initialize(data);
|
|
|
|
if (onReady) {
|
|
|
|
onReady();
|
|
|
|
}
|
|
|
|
},
|
2020-11-05 13:56:29 +00:00
|
|
|
readOnly: disabled,
|
2020-11-05 16:30:38 +00:00
|
|
|
tools
|
2020-11-03 11:35:36 +00:00
|
|
|
});
|
2020-10-28 15:26:30 +00:00
|
|
|
}
|
2020-11-03 11:35:36 +00:00
|
|
|
|
|
|
|
return editor.current?.destroy;
|
|
|
|
},
|
|
|
|
// Rerender editor only if changed from undefined to defined state
|
|
|
|
[data === undefined]
|
|
|
|
);
|
|
|
|
React.useEffect(() => editor.current?.destroy, []);
|
2020-11-05 13:56:29 +00:00
|
|
|
React.useEffect(() => {
|
|
|
|
if (editor.current?.readOnly) {
|
|
|
|
editor.current.readOnly.toggle(disabled);
|
|
|
|
}
|
|
|
|
}, [disabled]);
|
2019-10-30 14:34:24 +00:00
|
|
|
|
|
|
|
return (
|
2020-11-05 13:56:29 +00:00
|
|
|
<FormControl
|
|
|
|
data-test="richTextEditor"
|
|
|
|
data-test-id={name}
|
|
|
|
disabled={disabled}
|
|
|
|
error={error}
|
|
|
|
fullWidth
|
|
|
|
variant="outlined"
|
|
|
|
>
|
|
|
|
<InputLabel focused={true} shrink={true}>
|
|
|
|
{label}
|
|
|
|
</InputLabel>
|
2020-10-28 15:26:30 +00:00
|
|
|
<div
|
2020-11-05 16:30:38 +00:00
|
|
|
className={classNames(classes.editor, classes.root, {
|
2020-11-05 13:56:29 +00:00
|
|
|
[classes.rootActive]: isFocused,
|
|
|
|
[classes.rootDisabled]: disabled,
|
|
|
|
[classes.rootError]: error
|
2020-10-28 15:26:30 +00:00
|
|
|
})}
|
|
|
|
ref={editorContainer}
|
|
|
|
onFocus={() => setFocus(true)}
|
|
|
|
onBlur={() => setFocus(false)}
|
2020-11-05 13:56:29 +00:00
|
|
|
/>
|
|
|
|
<FormHelperText>{helperText}</FormHelperText>
|
|
|
|
</FormControl>
|
2019-10-30 14:34:24 +00:00
|
|
|
);
|
|
|
|
};
|
|
|
|
|
2019-06-19 14:40:52 +00:00
|
|
|
RichTextEditor.displayName = "RichTextEditor";
|
|
|
|
export default RichTextEditor;
|