import React from 'react'; import classnames from 'classnames'; import * as monaco from 'monaco-editor'; import EditorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker'; import JsonWorker from 'monaco-editor/esm/vs/language/json/json.worker?worker'; import CssWorker from 'monaco-editor/esm/vs/language/css/css.worker?worker'; import HtmlWorker from 'monaco-editor/esm/vs/language/html/html.worker?worker'; import TsWorker from 'monaco-editor/esm/vs/language/typescript/ts.worker?worker'; import style from './style.module.less'; // eslint-disable-next-line no-restricted-globals (self as any).MonacoEnvironment = { getWorker(_: any, label: any) { if (label === 'json') { return new JsonWorker(); } if (label === 'css' || label === 'scss' || label === 'less') { return new CssWorker(); } if (label === 'html' || label === 'handlebars' || label === 'razor') { return new HtmlWorker(); } if (label === 'typescript' || label === 'javascript') { return new TsWorker(); } return new EditorWorker(); }, }; export interface CodeEditorProp { berforeRender?: React.ReactNode; afterRender?: React.ReactNode; value?: string; language?: string; height?: number | string; readOnly?: boolean; onChange?: (value?: string) => void; } const codeEditorContainerId = 'ET_codeEditorContainerId'; let __prevent_trigger_change_event__: boolean = false; const CodeEditor: React.FC = function ({ berforeRender, afterRender, value, language = 'javascript', height = '300px', readOnly = false, onChange, }) { const codeEditorRef = React.useRef(null); const [editor, setEditor] = React.useState(); React.useEffect(() => { if (!codeEditorRef.current) return; const editor = monaco.editor.create(codeEditorRef.current, { value: '', language, theme: 'vs-dark', readOnly, minimap: { enabled: false, }, }); editor.layout(); setEditor(editor); return () => { editor.dispose(); }; }, [codeEditorRef, language, readOnly]); React.useEffect(() => { if (!editor) return; const model = editor.getModel(); if (!model) return; __prevent_trigger_change_event__ = true; const range = model.getFullModelRange(); editor.pushUndoStop(); model.pushEditOperations( [], [ { range, text: value || '', }, ], () => null, ); editor.popUndoStop(); __prevent_trigger_change_event__ = false; }, [editor, value]); React.useEffect(() => { if (!editor || __prevent_trigger_change_event__) return; editor.onDidChangeModelContent(() => { const changedValue = editor.getValue(); !readOnly && onChange?.(changedValue); }); // eslint-disable-next-line react-hooks/exhaustive-deps }, [editor, readOnly]); return (
{berforeRender}
{afterRender}
); }; export default CodeEditor;