코드 정리

This commit is contained in:
현성필
2025-01-31 11:10:11 +09:00
parent c2d7d852d4
commit c7b6e29607
39 changed files with 1403 additions and 255 deletions
@@ -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'
}}
/>
);
});