File size: 2,526 Bytes
f909d7c |
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 |
import React from "react";
import styled from "styled-components";
import Editor, { loader, useMonaco } from "@monaco-editor/react";
import { Loading } from "src/layout/Loading";
import useConfig from "src/store/useConfig";
import useFile from "src/store/useFile";
loader.config({
paths: {
vs: "https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.34.0/min/vs",
},
});
const editorOptions = {
formatOnPaste: true,
formatOnType: true,
minimap: {
enabled: false,
},
};
const StyledWrapper = styled.div`
display: grid;
height: calc(100vh - 67px);
grid-template-columns: 100%;
grid-template-rows: minmax(0, 1fr);
`;
export const MonacoEditor = () => {
const monaco = useMonaco();
const contents = useFile(state => state.contents);
const setContents = useFile(state => state.setContents);
const setError = useFile(state => state.setError);
const jsonSchema = useFile(state => state.jsonSchema);
const getHasChanges = useFile(state => state.getHasChanges);
const theme = useConfig(state => (state.darkmodeEnabled ? "vs-dark" : "light"));
const fileType = useFile(state => state.format);
React.useEffect(() => {
monaco?.languages.json.jsonDefaults.setDiagnosticsOptions({
validate: true,
allowComments: true,
enableSchemaRequest: true,
...(jsonSchema && {
schemas: [
{
uri: "http://myserver/foo-schema.json",
fileMatch: ["*"],
schema: jsonSchema,
},
],
}),
});
}, [jsonSchema, monaco?.languages.json.jsonDefaults]);
React.useEffect(() => {
const beforeunload = (e: BeforeUnloadEvent) => {
if (getHasChanges()) {
const confirmationMessage =
"Unsaved changes, if you leave before saving your changes will be lost";
(e || window.event).returnValue = confirmationMessage; //Gecko + IE
return confirmationMessage;
}
};
window.addEventListener("beforeunload", beforeunload);
return () => {
window.removeEventListener("beforeunload", beforeunload);
};
}, [getHasChanges]);
return (
<StyledWrapper>
<Editor
height="100%"
language={fileType}
theme={theme}
value={contents}
options={editorOptions}
onValidate={errors => setError(errors[0]?.message)}
onChange={contents => setContents({ contents, skipUpdate: true })}
loading={<Loading message="Loading Monaco Editor..." loading />}
/>
</StyledWrapper>
);
};
|