huridocs/uwazi

View on GitHub
app/react/V2/Components/CodeEditor/CodeEditorComponent.tsx

Summary

Maintainability
A
0 mins
Test Coverage
/* eslint-disable react/no-multi-comp */
import React, { useEffect, useRef, useState } from 'react';
import * as monaco from 'monaco-editor';

type CodeEditorInstance = monaco.editor.IStandaloneCodeEditor;

type CodeEditorProps = {
  language: 'html' | 'javascript' | 'css';
  intialValue?: string;
  onMount?: (editor: CodeEditorInstance) => void;
  fallbackElement?: React.ReactElement;
};

const CodeEditorComponent = ({
  language,
  intialValue,
  onMount,
  fallbackElement,
}: CodeEditorProps) => {
  const container = useRef<HTMLDivElement>(null);
  const editor = useRef<CodeEditorInstance>();
  const [hasError, setHasError] = useState(false);

  useEffect(() => {
    if (container.current && !editor.current) {
      try {
        editor.current = monaco.editor.create(container.current, {
          value: intialValue,
          language,
          tabSize: 2,
          automaticLayout: true,
        });

        editor.current.changeViewZones(accessor => {
          accessor.addZone({
            afterLineNumber: 0,
            heightInPx: 8,
            domNode: document.createElement('SPAN'),
          });
        });
      } catch (_error) {
        setHasError(true);
      }
    }

    return () => {
      if (editor.current) {
        editor.current.dispose();
      }
    };
  }, [language]);

  useEffect(() => {
    if (onMount && editor.current) {
      onMount(editor.current);
    }
  }, []);

  if (hasError) {
    return fallbackElement || <div />;
  }

  return <div className="w-full h-full border" dir="ltr" ref={container} />;
};

export type { CodeEditorProps, CodeEditorInstance };
export { CodeEditorComponent };