File size: 4,178 Bytes
d2be573
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
'use client';

import { useEffect, useRef } from 'react';
import { Editor } from '@monaco-editor/react';
import { cn } from '@/lib/utils';

interface CodeEditorProps {
  value: string;
  onChange: (value: string) => void;
  className?: string;
  language?: string;
  theme?: string;
}

export function CodeEditor({
  value,
  onChange,
  className,
  language = 'javascript',
  theme = 'vs-dark'
}: CodeEditorProps) {
  const editorRef = useRef<any>(null);

  const handleEditorDidMount = (editor: any) => {
    editorRef.current = editor;
    
    // Configure editor options
    editor.updateOptions({
      fontSize: 14,
      fontFamily: 'JetBrains Mono, Monaco, Consolas, "Courier New", monospace',
      minimap: { enabled: false },
      scrollBeyondLastLine: false,
      wordWrap: 'on',
      automaticLayout: true,
      tabSize: 2,
      insertSpaces: true,
      roundedSelection: false,
      readOnly: false,
      cursorStyle: 'line',
      lineNumbers: 'on',
      renderLineHighlight: 'line',
      selectOnLineNumbers: true,
      roundedSelection: false,
      renderIndentGuides: true,
      colorDecorators: true,
      lineDecorationsWidth: 0,
      lineNumbersMinChars: 3,
      folding: true,
      foldingHighlight: true,
      showFoldingControls: 'mouseover',
      smoothScrolling: true,
      contextmenu: true,
      mouseWheelZoom: true,
    });

    // Add custom key bindings
    editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyS, () => {
      // Handle save action
      console.log('Save action triggered');
    });

    // Add code completion suggestions
    const suggestions = [
      {
        label: 'console.log',
        kind: monaco.languages.CompletionItemKind.Function,
        insertText: 'console.log(${1:message});',
        insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
        documentation: 'Log a message to the console'
      },
      {
        label: 'function',
        kind: monaco.languages.CompletionItemKind.Snippet,
        insertText: 'function ${1:functionName}(${2:params}) {\n\t${3:// function body}\n}',
        insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
        documentation: 'Create a function'
      },
      {
        label: 'if',
        kind: monaco.languages.CompletionItemKind.Snippet,
        insertText: 'if (${1:condition}) {\n\t${2:// code}\n}',
        insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
        documentation: 'Create an if statement'
      }
    ];

    // Register completion provider
    const completionProvider = {
      provideCompletionItems: () => ({
        suggestions: suggestions.map(suggestion => ({
          ...suggestion,
          range: undefined
        }))
      })
    };

    // Register the completion provider
    const disposable = monaco.languages.registerCompletionItemProvider(language, completionProvider);
    
    // Cleanup on unmount
    return () => {
      disposable.dispose();
    };
  };

  const handleEditorChange = (value: string | undefined) => {
    if (value !== undefined) {
      onChange(value);
    }
  };

  return (
    <div className={cn("monaco-editor-container", className)}>
      <Editor
        height="100%"
        defaultLanguage={language}
        theme={theme}
        value={value}
        onChange={handleEditorChange}
        onMount={handleEditorDidMount}
        options={{
          selectOnLineNumbers: true,
          roundedSelection: false,
          readOnly: false,
          cursorStyle: 'line',
          automaticLayout: true,
          wordWrap: 'on',
          minimap: { enabled: false },
          scrollBeyondLastLine: false,
          fontSize: 14,
          fontFamily: 'JetBrains Mono, Monaco, Consolas, "Courier New", monospace',
          tabSize: 2,
          insertSpaces: true,
          renderLineHighlight: 'line',
          lineNumbers: 'on',
          contextmenu: true,
          mouseWheelZoom: true,
          smoothScrolling: true,
          folding: true,
          foldingHighlight: true,
          showFoldingControls: 'mouseover',
        }}
      />
    </div>
  );
}