-
Notifications
You must be signed in to change notification settings - Fork 18
Expand file tree
/
Copy pathmarkdown-editor.component.tsx
More file actions
93 lines (83 loc) · 2.68 KB
/
markdown-editor.component.tsx
File metadata and controls
93 lines (83 loc) · 2.68 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
import React from 'react';
import { basicSetup, EditorView } from 'codemirror';
import { EditorState } from '@codemirror/state';
import { markdown } from '@codemirror/lang-markdown';
import { languages } from '@codemirror/language-data';
import { tags } from '@lezer/highlight';
import { syntaxHighlighting, HighlightStyle } from '@codemirror/language';
import * as classes from './markdown-editor.styles';
const editorStyles = HighlightStyle.define([
{ tag: tags.heading1, class: classes.headerH1 },
{ tag: tags.heading2, class: classes.headerH2 },
{ tag: tags.heading3, class: classes.headerH3 },
]);
interface Props {
value: string;
onChange?: (value: string) => void;
className?: string;
onAppendTrainerTextInternal?: () => void;
}
export const MarkdownEditor: React.FC<Props> = (props) => {
const { value, onChange, className, onAppendTrainerTextInternal } = props;
const refContainer = React.useRef(null);
const editorView = React.useRef<EditorView>();
React.useEffect(() => {
if (!refContainer.current) return;
editorView.current = new EditorView({
state: EditorState.create({
doc: value,
extensions: [
basicSetup,
markdown({
codeLanguages: languages,
}),
syntaxHighlighting(editorStyles),
EditorView.lineWrapping,
EditorView.updateListener.of((update) => {
onChange(update.state.doc.toString());
}),
EditorView.theme({
'&': {
border: '2px solid #070707',
height: '300px',
},
}),
],
}),
parent: refContainer.current,
});
return () => editorView.current?.destroy();
}, []);
const scrollToEnd = () => {
if (!refContainer.current) return;
const scrollHeight = refContainer.current.scrollHeight;
const clientHeight = refContainer.current.clientHeight;
editorView.current.scrollDOM.scrollTop = scrollHeight - clientHeight;
};
React.useEffect(() => {
const state = editorView.current?.state;
const currentValue = state?.doc.toString();
if (state && currentValue !== value) {
const update = state.update({
changes: { from: 0, to: state.doc.length, insert: value },
});
editorView.current?.update([update]);
scrollToEnd();
}
}, [value]);
// TODO HAY QUE ARREGLARLO PARA EL SESION
// ?. si existe llama a la función, de lo contrario, se ignora
return (
<div
role="log"
id="session"
ref={refContainer}
className={className}
onKeyDown={(event) => {
if (event.key === 'Enter' && event.ctrlKey) {
onAppendTrainerTextInternal?.();
}
}}
/>
);
};