|
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; |
|
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> |
|
); |
|
}; |
|
|