-
Notifications
You must be signed in to change notification settings - Fork 0
/
code-editor.tsx
98 lines (88 loc) · 2.59 KB
/
code-editor.tsx
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
94
95
96
97
98
import "./code-editor.css";
import "./syntax.css";
import { useRef, useState } from "react";
import MonacoEditor, { EditorDidMount } from "@monaco-editor/react";
import prettier from "prettier";
import parser from "prettier/parser-babel";
import codeShift from "jscodeshift";
import Highlighter from "monaco-jsx-highlighter";
interface CodeEditorProps {
initialValue: string;
onChange(value: string): void;
}
const CodeEditor: React.FC<CodeEditorProps> = ({ onChange, initialValue }) => {
const [shareButtonLabel, setShareButtonLabel] = useState("Share");
const editorRef = useRef<any>();
const onEditorDidMount: EditorDidMount = (getValue, monacoEditor) => {
editorRef.current = monacoEditor;
monacoEditor.onDidChangeModelContent(() => {
onChange(getValue());
});
monacoEditor.getModel()?.updateOptions({ tabSize: 2 });
const highlighter = new Highlighter(
// @ts-ignore
window.monaco,
codeShift,
monacoEditor
);
highlighter.highLightOnDidChangeModelContent(
() => {},
() => {},
undefined,
() => {}
);
};
const onFormatClick = () => {
// get current value from editor
const unformatted = editorRef.current.getModel().getValue();
// format that value
const formatted = prettier
.format(unformatted, {
parser: "babel",
plugins: [parser],
useTabs: false,
semi: true,
singleQuote: true,
})
.replace(/\n$/, "");
// set the formatted value back in the editor
editorRef.current.setValue(formatted);
};
return (
<div className="editor-wrapper">
<button className="button button-format is-small is-primary is-light is-rounded" onClick={onFormatClick}>
Format
</button>
<button
className="button button-share is-small is-primary is-light is-rounded"
onClick={() => {
navigator.clipboard.writeText(window.location.href);
setShareButtonLabel("Copied!");
setTimeout(() => {
setShareButtonLabel("Share");
}, 1000);
}}
>
{shareButtonLabel}
</button>
<MonacoEditor
editorDidMount={onEditorDidMount}
value={initialValue}
theme="dark"
language="javascript"
height="100%"
options={{
wordWrap: "on",
minimap: { enabled: false },
showUnused: false,
folding: false,
lineNumbersMinChars: 3,
fontSize: 16,
scrollBeyondLastLine: false,
automaticLayout: true,
}}
/>
</div>
);
};
export default CodeEditor;