import React from "react"; import Editor, { loader, Monaco } from "@monaco-editor/react"; import debounce from "lodash.debounce"; import { Loading } from "src/components/Loading"; import useJson from "src/store/useJson"; import useStored from "src/store/useStored"; import styled from "styled-components"; loader.config({ paths: { vs: "https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.34.0/min/vs", }, }); const editorOptions = { formatOnPaste: true, minimap: { enabled: false, }, }; const StyledWrapper = styled.div` display: grid; height: calc(100vh - 36px); grid-template-columns: 100%; grid-template-rows: minmax(0, 1fr); `; export const MonacoEditor = () => { const json = useJson(state => state.json); const setJson = useJson(state => state.setJson); const setError = useJson(state => state.setError); const [loaded, setLoaded] = React.useState(false); const [value, setValue] = React.useState(json); const hasError = useJson(state => state.hasError); const lightmode = useStored(state => (state.lightmode ? "light" : "vs-dark")); const handleEditorWillMount = React.useCallback( (monaco: Monaco) => { monaco.languages.json.jsonDefaults.setDiagnosticsOptions({ allowComments: true, comments: "ignore", }); monaco.editor.onDidChangeMarkers(([uri]) => { const markers = monaco.editor.getModelMarkers({ resource: uri }); setError(!!markers.length); }); }, [setError] ); const debouncedSetJson = React.useMemo( () => debounce(value => { if (hasError) return; setJson(value || "[]"); }, 1200), [hasError, setJson] ); React.useEffect(() => { if ((value || !hasError) && loaded) debouncedSetJson(value); setLoaded(true); return () => debouncedSetJson.cancel(); // eslint-disable-next-line react-hooks/exhaustive-deps }, [debouncedSetJson, hasError, value]); return ( } beforeMount={handleEditorWillMount} defaultLanguage="json" height="100%" /> ); };