text: import * as monaco from "monaco-editor/esm/vs/editor/editor.api";
  import PropTypes from "prop-types";
  import React from "react";
  import { noop, processSize } from "./utils";
  
  class MonacoEditor extends React.Component {
    constructor(props) {
      super(props);
      this.containerElement = undefined;
    }
  
    componentDidMount() {
      this.initMonaco();
    }
  
    componentDidUpdate(prevProps) {
      const {
        value,
        language,
        theme,
        height,
        optionsWithoutModel,
        width,
      } = this.props;
  
      const { editor } = this;
      const model = editor.getModel();
  
      if (this.props.value != null && this.props.value !== model.getValue()) {
        this.__prevent_trigger_change_event = true;
        this.editor.pushUndoStop();
        model.pushEditOperations(
          [],
          [
            {
              range: model.getFullModelRange(),
              text: value,
            },
          ]
        );
        this.editor.pushUndoStop();
        this.__prevent_trigger_change_event = false;
      }
      if (prevProps.language !== language) {
        monaco.editor.setModelLanguage(model, language);
      }
      if (prevProps.theme !== theme) {
        monaco.editor.setTheme(theme);
      }
      if (editor && (width !== prevProps.width || height !== prevProps.height)) {
        editor.layout();
      }
      if (prevProps.optionsWithoutModel !== optionsWithoutModel) {
        editor.updateOptions(optionsWithoutModel);
      }
    }
  
    componentWillUnmount() {
      this.destroyMonaco();
    }
  
    assignRef = (component) => {
      this.containerElement = component;
    };
  
    destroyMonaco() {
      if (this.editor) {
        this.editor.dispose();
        const model = this.editor.getModel();
        if (model) {
          model.dispose();
        }
      }
      if (this._subscription) {
        this._subscription.dispose();
      }
    }
  
    initMonaco() {
      const value =
        this.props.value != null ? this.props.value : this.props.defaultValue;
      const {
        language,
        theme,
        optionsWithoutModel,
        model,
        overrideServices,
      } = this.props;
      if (this.containerElement) {
        const options = { ...optionsWithoutModel, model };
  
        // Before initializing monaco editor
        Object.assign(options, this.editorWillMount());
        this.editor = monaco.editor.create(
          this.containerElement,
          {
            value,
            language,
            ...options,
            ...(theme ? { theme } : {}),
          },
          overrideServices
        );
        // After initializing monaco editor
        this.editorDidMount(this.editor);
      }
    }
  
    editorWillMount() {
      const { editorWillMount } = this.props;
      const options = editorWillMount(monaco);
      return options || {};
    }
  
    editorDidMount(editor) {
      this.props.editorDidMount(editor, monaco);
  
      this._subscription = editor.onDidChangeModelContent((event) => {
        if (!this.__prevent_trigger_change_event) {
          this.props.onChange(editor.getValue(), event);
        }
      });
    }
  
    render() {
      const { width, height } = this.props;
      const fixedWidth = processSize(width);
      const fixedHeight = processSize(height);
      const style = {
        width: fixedWidth,
        height: fixedHeight,
      };
  
      return (
        <div
          ref={this.assignRef}
          style={style}
          className="react-monaco-editor-container"
        />
      );
    }
  }
  
  MonacoEditor.propTypes = {
    width: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
    height: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
    value: PropTypes.string,
    defaultValue: PropTypes.string,
    language: PropTypes.string,
    theme: PropTypes.string,
    optionsWithoutModel: PropTypes.object,
    model: PropTypes.object,
    overrideServices: PropTypes.object,
    editorDidMount: PropTypes.func,
    editorWillMount: PropTypes.func,
    onChange: PropTypes.func,
  };
  
  MonacoEditor.defaultProps = {
    width: "100%",
    height: "100%",
    value: null,
    defaultValue: "",
    language: "javascript",
    theme: null,
    optionsWithoutModel: {},
    model: undefined,
    overrideServices: {},
    editorDidMount: noop,
    editorWillMount: noop,
    onChange: noop,
  };
  
  export default MonacoEditor;
  