akhaliq's picture
akhaliq HF Staff
fix code formatting
74052d0
'use client';
import { useEffect, useRef } from 'react';
import Editor from '@monaco-editor/react';
interface CodeEditorProps {
code: string;
language: string;
onChange?: (value: string) => void;
readOnly?: boolean;
}
export default function CodeEditor({ code, language, onChange, readOnly = false }: CodeEditorProps) {
const editorRef = useRef<any>(null);
const lastFormattedCodeRef = useRef<string>('');
const formatTimeoutRef = useRef<NodeJS.Timeout | null>(null);
// Map our language names to Monaco language IDs
const getMonacoLanguage = (lang: string): string => {
const languageMap: Record<string, string> = {
'html': 'html',
'gradio': 'python',
'streamlit': 'python',
'transformers.js': 'html', // Contains HTML, CSS, and JavaScript - HTML is primary
'react': 'javascriptreact', // JSX syntax highlighting
'comfyui': 'json',
};
return languageMap[lang] || 'plaintext';
};
const handleEditorDidMount = (editor: any) => {
editorRef.current = editor;
};
// Format code intelligently - only when generation appears complete
useEffect(() => {
if (editorRef.current && code && code.length > 100) {
// Clear existing timeout
if (formatTimeoutRef.current) {
clearTimeout(formatTimeoutRef.current);
}
// Only format if code hasn't been formatted yet or if it's different
if (code !== lastFormattedCodeRef.current) {
// Wait 1 second after code stops changing before formatting
formatTimeoutRef.current = setTimeout(() => {
if (editorRef.current) {
editorRef.current.getAction('editor.action.formatDocument')?.run();
lastFormattedCodeRef.current = code;
}
}, 1000);
}
}
return () => {
if (formatTimeoutRef.current) {
clearTimeout(formatTimeoutRef.current);
}
};
}, [code]);
return (
<div className="h-full overflow-hidden bg-[#1e1e1e]">
<Editor
height="100%"
language={getMonacoLanguage(language)}
value={code}
onChange={(value) => onChange && onChange(value || '')}
theme="vs-dark"
options={{
readOnly,
minimap: { enabled: true },
fontSize: 14,
fontFamily: "'SF Mono', 'JetBrains Mono', 'Menlo', 'Monaco', 'Courier New', monospace",
wordWrap: 'off',
lineNumbers: 'on',
lineNumbersMinChars: 3,
glyphMargin: false,
folding: true,
lineDecorationsWidth: 10,
scrollBeyondLastLine: false,
automaticLayout: true,
tabSize: 2,
insertSpaces: true,
padding: { top: 16, bottom: 16 },
lineHeight: 22,
letterSpacing: 0.5,
renderLineHighlight: 'line',
formatOnPaste: true,
formatOnType: false,
scrollbar: {
verticalScrollbarSize: 10,
horizontalScrollbarSize: 10,
},
}}
onMount={handleEditorDidMount}
/>
</div>
);
}