github.com/argoproj/argo-cd/v2@v2.10.9/ui/src/app/shared/components/monaco-editor.tsx (about) 1 import * as React from 'react'; 2 3 import * as monacoEditor from 'monaco-editor'; 4 5 export interface EditorInput { 6 text: string; 7 language?: string; 8 } 9 10 export interface MonacoProps { 11 minHeight?: number; 12 vScrollBar: boolean; 13 editor?: { 14 options?: monacoEditor.editor.IEditorOptions; 15 input: EditorInput; 16 getApi?: (api: monacoEditor.editor.IEditor) => any; 17 }; 18 } 19 20 function IsEqualInput(first?: EditorInput, second?: EditorInput) { 21 return first && second && first.text === second.text && (first.language || '') === (second.language || ''); 22 } 23 24 const DEFAULT_LINE_HEIGHT = 18; 25 26 const MonacoEditorLazy = React.lazy(() => 27 import('monaco-editor').then(monaco => { 28 const Component = (props: MonacoProps) => { 29 const [height, setHeight] = React.useState(0); 30 31 return ( 32 <div 33 style={{ 34 height: `${Math.max(props.minHeight || 0, height + 100)}px`, 35 overflowY: 'hidden' 36 }} 37 ref={el => { 38 if (el) { 39 const container = el as { 40 editorApi?: monacoEditor.editor.IEditor; 41 prevEditorInput?: EditorInput; 42 }; 43 if (props.editor) { 44 if (!container.editorApi) { 45 const editor = monaco.editor.create(el, { 46 ...props.editor.options, 47 scrollBeyondLastLine: props.vScrollBar, 48 scrollbar: { 49 handleMouseWheel: false, 50 vertical: props.vScrollBar ? 'visible' : 'hidden' 51 } 52 }); 53 54 container.editorApi = editor; 55 } 56 57 const model = monaco.editor.createModel(props.editor.input.text, props.editor.input.language); 58 const lineCount = model.getLineCount(); 59 setHeight(lineCount * DEFAULT_LINE_HEIGHT); 60 61 if (!IsEqualInput(container.prevEditorInput, props.editor.input)) { 62 container.prevEditorInput = props.editor.input; 63 container.editorApi.setModel(model); 64 } 65 container.editorApi.updateOptions(props.editor.options); 66 container.editorApi.layout(); 67 if (props.editor.getApi) { 68 props.editor.getApi(container.editorApi); 69 } 70 } 71 } 72 }} 73 /> 74 ); 75 }; 76 77 return { 78 default: Component 79 }; 80 }) 81 ); 82 83 export const MonacoEditor = (props: MonacoProps) => ( 84 <React.Suspense fallback={<div>Loading...</div>}> 85 <MonacoEditorLazy {...props} /> 86 </React.Suspense> 87 );