# Code Editor

The primary Monaco Editor React component providing full code editing capabilities with syntax highlighting, IntelliSense, autocomplete, and advanced editing features for any programming language.

## Capabilities

### Editor Component

Main editor component that wraps Monaco Editor with React-friendly props and event handling.

```typescript { .api }
/**
 * Monaco Editor React component with full editing capabilities
 * @param props - Editor configuration and event handlers
 * @returns React component rendering Monaco Editor
 */
declare const Editor: React.ComponentType<EditorProps>;

interface EditorProps {
  /** Default value of the current model */
  defaultValue?: string;
  /** Value of the current model (controlled) */
  value?: string;
  /** Default language of the current model */
  defaultLanguage?: string;
  /** Language of the current model */
  language?: string;
  /** Default path of the current model - passed to monaco.editor.createModel */
  defaultPath?: string;
  /** Path of the current model - passed to monaco.editor.createModel */
  path?: string;
  /** Theme for the monaco editor - 'vs-dark' | 'light' or custom theme name */
  theme?: Theme | string;
  /** Line number to jump to when editor mounts */
  line?: number;
  /** Loading component shown before editor is mounted */
  loading?: ReactNode;
  /** Monaco editor construction options */
  options?: editor.IStandaloneEditorConstructionOptions;
  /** Editor service overrides */
  overrideServices?: editor.IEditorOverrideServices;
  /** Whether to save view states between model changes */
  saveViewState?: boolean;
  /** Whether to keep current model when component unmounts */
  keepCurrentModel?: boolean;
  /** Width of editor wrapper */
  width?: number | string;
  /** Height of editor wrapper */
  height?: number | string;
  /** CSS class name for editor container */
  className?: string;
  /** Props applied to the wrapper element */
  wrapperProps?: object;
  /** Called before editor is mounted with monaco instance */
  beforeMount?: BeforeMount;
  /** Called when editor is mounted with editor and monaco instances */
  onMount?: OnMount;
  /** Called when editor content changes */
  onChange?: OnChange;
  /** Called when model validation completes */
  onValidate?: OnValidate;
}
```

**Usage Examples:**

```typescript
import React, { useState } from "react";
import Editor from "@monaco-editor/react";

// Basic editor
function BasicEditor() {
  return (
    <Editor
      height="400px"
      defaultLanguage="javascript"
      defaultValue="console.log('Hello Monaco!');"
    />
  );
}

// Controlled editor with change handling
function ControlledEditor() {
  const [code, setCode] = useState("const greeting = 'Hello World';");

  const handleEditorChange = (value) => {
    setCode(value || "");
  };

  return (
    <Editor
      height="400px"
      language="javascript"
      value={code}
      onChange={handleEditorChange}
      options={{
        minimap: { enabled: false },
        fontSize: 14,
      }}
    />
  );
}

// Multi-model editor
function MultiModelEditor() {
  const [currentFile, setCurrentFile] = useState("file1.js");
  
  const files = {
    "file1.js": "console.log('File 1');",
    "file2.ts": "const message: string = 'File 2';",
    "file3.py": "print('File 3')"
  };

  return (
    <div>
      <select onChange={(e) => setCurrentFile(e.target.value)}>
        {Object.keys(files).map(filename => (
          <option key={filename} value={filename}>{filename}</option>
        ))}
      </select>
      <Editor
        height="400px"
        path={currentFile}
        defaultLanguage={currentFile.split('.').pop()}
        value={files[currentFile]}
        options={{ readOnly: false }}
      />
    </div>
  );
}
```

### Event Handlers

Event handler functions for responding to editor lifecycle and content changes.

```typescript { .api }
/**
 * Called when editor is mounted - provides access to editor and monaco instances
 * @param editor - The standalone code editor instance
 * @param monaco - The monaco editor namespace
 */
type OnMount = (editor: editor.IStandaloneCodeEditor, monaco: Monaco) => void;

/**
 * Called before editor is mounted - allows monaco configuration
 * @param monaco - The monaco editor namespace
 */
type BeforeMount = (monaco: Monaco) => void;

/**
 * Called when editor content changes
 * @param value - Current editor value (may be undefined)
 * @param event - Monaco content change event with details
 */
type OnChange = (value: string | undefined, ev: editor.IModelContentChangedEvent) => void;

/**
 * Called when model validation completes with error/warning markers
 * @param markers - Array of validation markers (errors, warnings, info)
 */
type OnValidate = (markers: editor.IMarker[]) => void;
```

**Event Handler Examples:**

```typescript
import Editor from "@monaco-editor/react";

function EditorWithHandlers() {
  const handleBeforeMount = (monaco) => {
    // Configure monaco before editor creation
    monaco.languages.typescript.javascriptDefaults.setEagerModelSync(true);
    
    // Define custom theme
    monaco.editor.defineTheme('myTheme', {
      base: 'vs-dark',
      inherit: true,
      rules: [],
      colors: {
        'editor.background': '#1e1e1e',
      }
    });
  };

  const handleMount = (editor, monaco) => {
    // Configure editor after mount
    editor.focus();
    editor.setPosition({ lineNumber: 1, column: 1 });
    
    // Add custom commands
    editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyS, () => {
      console.log('Save command triggered');
    });
  };

  const handleChange = (value, event) => {
    console.log('Content changed:', value);
    console.log('Change details:', event);
  };

  const handleValidate = (markers) => {
    // Handle validation errors/warnings
    const errors = markers.filter(m => m.severity === 8); // Error severity
    const warnings = markers.filter(m => m.severity === 4); // Warning severity
    
    console.log(`Validation: ${errors.length} errors, ${warnings.length} warnings`);
  };

  return (
    <Editor
      height="400px"
      defaultLanguage="javascript"
      beforeMount={handleBeforeMount}
      onMount={handleMount}
      onChange={handleChange}
      onValidate={handleValidate}
      theme="myTheme"
    />
  );
}
```

### Editor Configuration Options

Configuration options for customizing editor behavior and appearance.

```typescript { .api }
// Core configuration props
interface EditorSizingProps {
  /** Width of editor wrapper - default "100%" */
  width?: number | string;
  /** Height of editor wrapper - default "100%" */
  height?: number | string;
  /** CSS class name for editor container */
  className?: string;
  /** Props applied to wrapper element */
  wrapperProps?: object;
}

interface EditorContentProps {
  /** Initial editor content */
  defaultValue?: string;
  /** Controlled editor content */
  value?: string;
  /** Initial language mode */
  defaultLanguage?: string;
  /** Current language mode */
  language?: string;
  /** Initial model path/URI */
  defaultPath?: string;
  /** Current model path/URI */
  path?: string;
}

interface EditorBehaviorProps {
  /** Editor theme name */
  theme?: Theme | string;
  /** Line to jump to on mount */
  line?: number;
  /** Loading component during initialization */
  loading?: ReactNode;
  /** Save view state between model changes */
  saveViewState?: boolean;
  /** Keep model when unmounting */
  keepCurrentModel?: boolean;
}

// Monaco editor native options (from monaco-editor package)
interface EditorMonacoOptions {
  /** Monaco editor construction options */
  options?: editor.IStandaloneEditorConstructionOptions;
  /** Service overrides for advanced customization */
  overrideServices?: editor.IEditorOverrideServices;
}
```

**Configuration Examples:**

```typescript
import Editor from "@monaco-editor/react";

// Customized editor appearance and behavior
function CustomizedEditor() {
  const editorOptions = {
    fontSize: 16,
    lineHeight: 24,
    minimap: { enabled: true },
    scrollBeyondLastLine: false,
    wordWrap: 'on',
    automaticLayout: true,
    tabSize: 2,
    insertSpaces: true,
    renderLineHighlight: 'all',
    selectOnLineNumbers: true,
    glyphMargin: true,
    folding: true,
    lineNumbers: 'on',
    scrollbar: {
      vertical: 'visible',
      horizontal: 'visible',
    },
  };

  return (
    <Editor
      height="500px"
      width="100%"
      language="typescript"
      theme="vs-dark"
      options={editorOptions}
      className="custom-editor"
      wrapperProps={{ style: { border: '1px solid #ccc' } }}
      saveViewState={true}
      keepCurrentModel={false}
    />
  );
}
```

## Model Management

The editor supports multi-model functionality for working with multiple files or code snippets.

```typescript { .api }
// Model-related props
interface ModelProps {
  /** Path identifies the model - models are cached by path */
  path?: string;
  /** Whether to dispose model when component unmounts */
  keepCurrentModel?: boolean;
  /** Save editor view state (cursor, scroll) when switching models */
  saveViewState?: boolean;
}
```

**Multi-Model Example:**

```typescript
// File tab editor with model persistence
function FileTabEditor() {
  const [activeFile, setActiveFile] = useState('main.js');
  
  const files = {
    'main.js': { language: 'javascript', content: 'console.log("main");' },
    'utils.ts': { language: 'typescript', content: 'export const util = () => {};' },
    'styles.css': { language: 'css', content: 'body { margin: 0; }' },
  };

  return (
    <div>
      <div>
        {Object.keys(files).map(filename => (
          <button 
            key={filename}
            onClick={() => setActiveFile(filename)}
            style={{ 
              fontWeight: activeFile === filename ? 'bold' : 'normal' 
            }}
          >
            {filename}
          </button>
        ))}
      </div>
      <Editor
        height="400px"
        path={activeFile}
        language={files[activeFile].language}
        defaultValue={files[activeFile].content}
        saveViewState={true}  // Preserves cursor position per file
        keepCurrentModel={true}  // Keeps models in memory
      />
    </div>
  );
}
```