import { observer } from 'mobx-react-lite' ; import { useCallback , useLayoutEffect , useRef } from 'react' ; import { Controlled as CodeMirror } from 'react-codemirror2' ; import styled , { use } from 'reshadow' ; import 'codemirror/mode/javascript/javascript' ; import 'codemirror/mode/xml/xml' ; import 'codemirror/mode/htmlembedded/htmlembedded' ; import 'codemirror/mode/htmlmixed/htmlmixed' ; import 'codemirror/mode/meta' ; import 'codemirror/addon/hint/show-hint' ; import 'codemirror/addon/selection/mark-selection' ; import 'codemirror/lib/codemirror.css' ; import 'codemirror/addon/hint/show-hint.css' ; import { useStyles } from '@cloudbeaver/core-theming' ; import type { ICodeEditorProps } from './ICodeEditorProps' ; import { SqlEditorStyles } from './theme' ; import { useAutoFormat } from './useAutoFormat' ; export const CodeEditor = observer < ICodeEditorProps > ( function CodeEditor ( props ) { const { readonly , autoFormat , className , editorDidMount } = props ; const formatter = useAutoFormat ( props . options ?. mode ) ; const wrapperRef = useRef < HTMLDivElement | null > ( null ) ; const editorRef = useRef < CodeMirror . Editor | null > ( null ) ; let value = props . value ; if ( autoFormat ) { value = formatter . format ( value ) ; } useLayoutEffect ( ( ) => { const observable = wrapperRef . current ; if ( ! observable ) { return ; } const observer = new ResizeObserver ( ( ) => { editorRef . current ?. refresh ( ) ; } ) ; observer . observe ( observable ) ; return ( ) => observer . unobserve ( observable ) ; } , [ ] ) ; const handleMount = useCallback ( ( editor , value , cb ) => { editorRef . current = editor ; if ( editorDidMount ) { editorDidMount ( editor , value , cb ) ; } } , [ editorDidMount ] ) ; return styled ( useStyles ( SqlEditorStyles ) ) ( < code - editor ref = { wrapperRef } { ... use ( { readonly } ) } className = { className } > < CodeMirror { ... props } value = { value } editorDidMount = { handleMount } options = { { styleSelectedText : true , ... props . options } } / > < /code-editor>); } ) ;