import React , { useEffect , useRef , useImperativeHandle } from 'react' ; import { EditorState , EditorStateConfig , Extension } from '@codemirror/state' ; import { EditorView , ViewUpdate } from '@codemirror/view' ; import { useCodeMirror } from './useCodeMirror' ; export * from '@codemirror/view' ; export * from '@codemirror/basic-setup' ; export * from '@codemirror/state' ; export * from './useCodeMirror' ; export interface ReactCodeMirrorProps extends Omit < EditorStateConfig , 'doc' | 'extensions' > , Omit < React . HTMLAttributes < HTMLDivElement > , 'onChange' | 'placeholder' > { /** value of the auto created model in the editor. */ value ? : string ; height ? : string ; minHeight ? : string ; maxHeight ? : string ; width ? : string ; minWidth ? : string ; maxWidth ? : string ; /** focus on the editor. */ autoFocus ? : boolean ; /** Enables a placeholder—a piece of example content to show when the editor is empty. */ placeholder ? : string | HTMLElement ; default theme ? : 'light' | 'dark' | Extension ; default basicSetup ? : boolean ; default editable ? : boolean ; default indentWithTab ? : boolean ; /** Fired whenever a change occurs to the document. */ onChange ? ( value , viewUpdate ) : void ; /** Fired whenever a change occurs to the document. There is a certain difference with `onChange`. */ onUpdate ? ( viewUpdate ) : void ; /**
     * Extension values can be [provided](https://codemirror.net/6/docs/ref/#state.EditorStateConfig.extensions) when creating a state to attach various kinds of configuration and behavior information.
     * They can either be built-in extension-providing objects,
     * such as [state fields](https://codemirror.net/6/docs/ref/#state.StateField) or [facet providers](https://codemirror.net/6/docs/ref/#state.Facet.of),
     * or objects with an extension in its `extension` property. Extensions can be nested in arrays arbitrarily deep—they will be flattened when processed.
     */ extensions ? : Extension [ ] ; /**
     * If the view is going to be mounted in a shadow root or document other than the one held by the global variable document (the default), you should pass it here.
     * Originally from the [config of EditorView](https://codemirror.net/6/docs/ref/#view.EditorView.constructor%5Econfig.root)
     */ root ? : ShadowRoot | Document ; } export interface ReactCodeMirrorRef { editor ? : HTMLDivElement | null ; state ? : EditorState ; view ? : EditorView ; } const ReactCodeMirror = React . forwardRef < ReactCodeMirrorRef , ReactCodeMirrorProps > ( ( props , ref ) => { const { className , value = '' , selection , extensions = [ ] , onChange , onUpdate , autoFocus , theme = 'light' , height , minHeight , maxHeight , width , minWidth , maxWidth , basicSetup , placeholder , indentWithTab , editable , root , ... other } = props ; const editor = useRef < HTMLDivElement > ( null ) ; const { state , view , container , setContainer } = useCodeMirror ( { container : editor . current , root , value , autoFocus , theme , height , minHeight , maxHeight , width , minWidth , maxWidth , basicSetup , placeholder , indentWithTab , editable , selection , onChange , onUpdate , extensions , } ) ; useImperativeHandle ( ref , ( ) => ( { editor : container , state , view } ) , [ container , state , view ] ) ; useEffect ( ( ) => { setContainer ( editor . current ) ; return ( ) => { if ( view ) { view . destroy ( ) ; } } ; } , [ ] ) ; if ( typeof value !== 'string' ) { throw new Error ( `value must be typeof string but got ${ typeof value }` ) ; } const defaultClassNames = typeof theme === 'string' ? `cm-theme-${ theme }` : 'cm-theme' ; return < div ref = { editor } className = { `${ defaultClassNames }${ className ? ` ${ className }` : '' }` } { ... other } > < /div>; } ) ; ReactCodeMirror . displayName = 'CodeMirror' ; export default ReactCodeMirror ;