import React, { useEffect, useState } from 'react' import * as monaco from 'monaco-editor' import type monacoEditor from 'monaco-editor/esm/vs/editor/editor.api' import MonacoEditor, { MonacoDiffEditor } from 'react-monaco-editor' import { setDiagnosticsOptions } from 'monaco-yaml' import { noop } from 'lodash-es' import { SourceCodeEditorProps, PLAIN_TEXT } from 'utils/Utils' import { useEventListener } from 'hooks/useEventListener' export const MonacoEditorOptions = { ignoreTrimWhitespace: true, minimap: { enabled: false }, codeLens: false, scrollBeyondLastLine: false, // smartSelect: false, tabSize: 2, insertSpaces: true, overviewRulerBorder: false, automaticLayout: true } const diagnosticsOptions = { noSemanticValidation: true, noSyntaxValidation: true } const compilerOptions: monacoEditor.languages.typescript.CompilerOptions = { jsx: monaco.languages.typescript.JsxEmit.ReactJSX, noLib: true, allowNonTsExtensions: true } const toOnOff = (flag: boolean) => (flag ? 'on' : 'off') export default function MonacoSourceCodeEditor({ source, language = PLAIN_TEXT, lineNumbers = true, readOnly = false, height, autoHeight, wordWrap = true, onChange = noop, schema }: SourceCodeEditorProps) { const [editor, setEditor] = useState() const scrollbar = autoHeight ? 'hidden' : 'auto' useEffect(() => { monaco.languages.typescript?.typescriptDefaults?.setDiagnosticsOptions?.(diagnosticsOptions) monaco.languages.typescript?.javascriptDefaults?.setDiagnosticsOptions?.(diagnosticsOptions) monaco.languages.typescript?.typescriptDefaults?.setCompilerOptions?.(compilerOptions) }, []) useEffect(() => { if (language === 'yaml' && schema) { setDiagnosticsOptions({ validate: true, enableSchemaRequest: false, hover: true, completion: true, schemas: [ { fileMatch: ['*'], schema, uri: 'https://github.com/harness/harness-schema' } ] }) } }, [language, schema]) useEventListener('resize', () => { editor?.layout({ width: 0, height: 0 }) window.requestAnimationFrame(() => editor?.layout()) }) return ( { if (autoHeight) { // autoAdjustEditorHeight(_editor) } setEditor(_editor) }} onChange={onChange} /> ) } interface DiffEditorProps extends Omit { original: string } export function DiffEditor({ source, original, language = PLAIN_TEXT, lineNumbers = true, readOnly = false, height, wordWrap = true, onChange = noop }: DiffEditorProps) { const [editor, setEditor] = useState() useEventListener('resize', () => { editor?.layout({ width: 0, height: 0 }) window.requestAnimationFrame(() => editor?.layout()) }) return ( ) }