Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 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 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 | 4x 2x 2x 2x 2x 2x 2x 2x 4x 4x | import { BeforeMount, Editor, OnMount } from "@monaco-editor/react";
import { palette } from "@palette";
import { useRef, useState } from "react";
import codeValidator, { TValidator } from "./validators";
import { EditorContainer, ErrorMessage } from "./atoms";
import { BoxProps } from "@mui/material";
import ErrorCatcher from "@common/Error/ErrorCatcher";
interface ICodeEditorProps {
defaultValue: string;
customTheme?: any;
customOptions?: any;
language?: string;
setValue: (newValue: string) => void;
onValidation?: (isValid: boolean) => void;
onBlur?: () => void;
onFocus?: () => void;
customValidator?: TValidator;
containerProps?: BoxProps;
}
const CodeEditor = ({
defaultValue,
customTheme = defaultTheme,
language = "JSON",
setValue,
onValidation,
onBlur,
onFocus,
customOptions,
customValidator,
containerProps,
}: ICodeEditorProps) => {
const [error, setError] = useState<string>("");
const editorRef = useRef<any>(null);
const handleEditorBeforeMount: BeforeMount = (monaco: any) => {
monaco.editor.defineTheme("custom-theme", customTheme);
};
function retrieveEditorValue() {
if (!editorRef.current) return "";
return editorRef.current.getValue();
}
const onValidationError = (err?: Error) => {
if (!err) setError("");
if (err?.message) setError(err.message);
};
const saveValue = () => {
const value = retrieveEditorValue();
if (value === "") {
setError("");
setValue("");
return;
}
const isValid = customValidator
? customValidator(value, onValidationError)
: codeValidator(language, value, onValidationError);
if (onValidation) onValidation(isValid);
setValue(value);
};
const handleEditorDidMount: OnMount = (editor, monaco) => {
editorRef.current = editor;
editorRef.current.onDidBlurEditorWidget(() => {
saveValue();
if (onBlur) onBlur();
});
editorRef.current.onDidFocusEditorWidget(() => {
if (onFocus) onFocus();
});
monaco.editor.remeasureFonts();
};
return (
<ErrorCatcher errorID="Code editor">
<EditorContainer {...containerProps}>
<Editor
height="100%"
defaultLanguage={language}
value={defaultValue}
theme="custom-theme"
onMount={handleEditorDidMount}
beforeMount={handleEditorBeforeMount}
loading={<></>}
options={{
...defaultOptions,
...customOptions,
}}
/>
{error && <ErrorMessage error={error} />}
</EditorContainer>
</ErrorCatcher>
);
};
const defaultOptions = {
fontSize: 14,
fontFamily: "Oxygen Mono",
fontWeight: 400,
lineNumbers: "off",
minimap: { enabled: false },
glyphMargin: false,
folding: false,
lineNumbersMinChars: 0,
lineDecorationsWidth: 0,
quickSuggestions: false,
overviewRulerLanes: 0,
wordWrap: "on",
};
const defaultTheme = {
base: "vs-dark",
inherit: true,
rules: [],
colors: {
"editor.background": palette.black[300],
"editor.foreground": palette.liftedWhite[100],
},
};
export default CodeEditor;
|