코드 정리
This commit is contained in:
@@ -1,5 +1,17 @@
|
||||
import React, { useEffect, useRef, memo } from 'react';
|
||||
import * as monaco from 'monaco-editor';
|
||||
import {loader} from '@monaco-editor/react';
|
||||
|
||||
loader.config({
|
||||
paths: {
|
||||
vs: '/monaco-editor/min/vs'
|
||||
},
|
||||
'vs/nls': {
|
||||
availableLanguages: {},
|
||||
},
|
||||
// Specify which languages to load
|
||||
languages: ['javascript', 'json', 'xml','plaintext']
|
||||
});
|
||||
|
||||
const MonacoEditor = memo(({
|
||||
id,
|
||||
@@ -10,10 +22,12 @@ const MonacoEditor = memo(({
|
||||
onChange = () => {}
|
||||
}) => {
|
||||
const editorRef = useRef(null);
|
||||
const modelRef = useRef(null);
|
||||
const containerRef = useRef(null);
|
||||
const subscriptionRef = useRef(null);
|
||||
|
||||
// Ensure value is always a string
|
||||
const normalizedValue = value ?? '';
|
||||
|
||||
const getEditorOptions = (lang) => {
|
||||
const baseOptions = {
|
||||
automaticLayout: true,
|
||||
@@ -57,63 +71,91 @@ const MonacoEditor = memo(({
|
||||
useEffect(() => {
|
||||
if (!containerRef.current) return;
|
||||
|
||||
const modelUri = monaco.Uri.parse(`inmemory://model-${id}`);
|
||||
modelRef.current = monaco.editor.createModel(value, language, modelUri);
|
||||
|
||||
const options = getEditorOptions(language);
|
||||
editorRef.current = monaco.editor.create(containerRef.current, {
|
||||
const editor = monaco.editor.create(containerRef.current, {
|
||||
...options,
|
||||
model: modelRef.current
|
||||
value: normalizedValue,
|
||||
language: language
|
||||
});
|
||||
|
||||
subscriptionRef.current = editorRef.current.onDidChangeModelContent(() => {
|
||||
onChange(editorRef.current.getValue());
|
||||
editorRef.current = editor;
|
||||
|
||||
const subscription = editor.onDidChangeModelContent(() => {
|
||||
const newValue = editor.getValue();
|
||||
onChange(newValue);
|
||||
});
|
||||
|
||||
if (language === 'json' && value) {
|
||||
subscriptionRef.current = subscription;
|
||||
|
||||
if (language === 'json' && normalizedValue) {
|
||||
try {
|
||||
monaco.languages.json.jsonDefaults.setDiagnosticsOptions({
|
||||
validate: true,
|
||||
allowComments: false,
|
||||
schemas: []
|
||||
});
|
||||
setTimeout(() => {
|
||||
const action = editorRef.current?.getAction('editor.action.formatDocument');
|
||||
if (action) action.run();
|
||||
}, 100);
|
||||
|
||||
const action = editor.getAction('editor.action.formatDocument');
|
||||
if (action) {
|
||||
setTimeout(() => {
|
||||
action.run();
|
||||
}, 100);
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn('Failed to format JSON:', e);
|
||||
}
|
||||
}
|
||||
|
||||
const resizeObserver = new ResizeObserver(() => {
|
||||
editorRef.current?.layout();
|
||||
editor.layout();
|
||||
});
|
||||
|
||||
resizeObserver.observe(containerRef.current);
|
||||
|
||||
return () => {
|
||||
resizeObserver.disconnect();
|
||||
subscriptionRef.current?.dispose();
|
||||
editorRef.current?.dispose();
|
||||
if (modelRef.current && !modelRef.current.isDisposed()) {
|
||||
modelRef.current.dispose();
|
||||
subscription.dispose();
|
||||
|
||||
// Ensure proper cleanup
|
||||
if (editor) {
|
||||
try {
|
||||
const model = editor.getModel();
|
||||
if (model) {
|
||||
model.dispose();
|
||||
}
|
||||
editor.dispose();
|
||||
} catch (e) {
|
||||
console.warn('Editor disposal error:', e);
|
||||
}
|
||||
}
|
||||
};
|
||||
}, [language]);
|
||||
}, [language]); // Only recreate when language changes
|
||||
|
||||
// Handle value updates
|
||||
useEffect(() => {
|
||||
if (modelRef.current && !modelRef.current.isDisposed()) {
|
||||
modelRef.current.setValue(value);
|
||||
if (editorRef.current) {
|
||||
const currentValue = editorRef.current.getValue();
|
||||
if (currentValue !== normalizedValue) {
|
||||
editorRef.current.setValue(normalizedValue);
|
||||
}
|
||||
}
|
||||
}, [value]);
|
||||
}, [normalizedValue]);
|
||||
|
||||
// Convert height to pixel value if it's a number
|
||||
const containerHeight = typeof height === 'number'
|
||||
? `${height}px`
|
||||
: height.endsWith('px') ? height : `${height}px`;
|
||||
|
||||
return (
|
||||
<div
|
||||
id={id}
|
||||
ref={containerRef}
|
||||
className={`h-${height} border mt-2`}
|
||||
style={{ minHeight: '100px' }}
|
||||
style={{
|
||||
minHeight: '100px',
|
||||
height: containerHeight,
|
||||
border: '1px solid #e2e8f0',
|
||||
marginTop: '0.5rem'
|
||||
}}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user