11import React , {
22 useCallback ,
33 useEffect ,
4+ useImperativeHandle ,
45 useMemo ,
56 useRef ,
67 useState ,
78} from 'react' ;
9+ import type { ForwardRefRenderFunction } from 'react' ;
810import type { EditorRef } from '@mongodb-js/compass-editor' ;
911import {
1012 css ,
@@ -177,29 +179,40 @@ const capLengthStart = (elements: unknown[], maxLength: number) => {
177179 elements . splice ( maxLength ) ;
178180} ;
179181
180- export const Shell = ( {
181- runtime,
182- className,
183- redactInfo,
184- maxOutputLength = 1000 ,
185- maxHistoryLength = 1000 ,
186- onInputChanged,
187- onOutputChanged,
188- onHistoryChanged,
189- onOperationStarted,
190- onOperationEnd,
191- initialEvaluate,
192- initialText,
193- output,
194- history,
195- isOperationInProgress = false ,
196- onEditorChanged,
197- } : ShellProps ) => {
182+ const _Shell : ForwardRefRenderFunction < EditorRef | null , ShellProps > = (
183+ {
184+ runtime,
185+ className,
186+ redactInfo,
187+ maxOutputLength = 1000 ,
188+ maxHistoryLength = 1000 ,
189+ onInputChanged,
190+ onOutputChanged,
191+ onHistoryChanged,
192+ onOperationStarted,
193+ onOperationEnd,
194+ initialEvaluate,
195+ initialText,
196+ output,
197+ history,
198+ isOperationInProgress = false ,
199+ } ,
200+ ref
201+ ) => {
198202 const darkMode = useDarkMode ( ) ;
199203
204+ const editorRef = useRef < EditorRef | null > ( null ) ;
205+
206+ useImperativeHandle (
207+ ref ,
208+ ( ) => {
209+ return editorRef . current as EditorRef ;
210+ } ,
211+ [ ]
212+ ) ;
213+
200214 const shellInputContainerRef = useRef < HTMLDivElement > ( null ) ;
201215
202- const [ editor , setEditor ] = useState < EditorRef | null > ( null ) ;
203216 const [ passwordPrompt , setPasswordPrompt ] = useState ( '' ) ;
204217 const [ shellPrompt , setShellPrompt ] = useState ( '>' ) ;
205218 const [ onFinishPasswordPrompt , setOnFinishPasswordPrompt ] = useState <
@@ -210,16 +223,8 @@ export const Shell = ({
210223 > ( ( ) => noop ) ;
211224
212225 const focusEditor = useCallback ( ( ) => {
213- editor ?. focus ( ) ;
214- } , [ editor ] ) ;
215-
216- const editorChanged = useCallback (
217- ( editor : EditorRef | null ) => {
218- setEditor ( editor ) ;
219- onEditorChanged ?.( editor ) ;
220- } ,
221- [ onEditorChanged ]
222- ) ;
226+ editorRef ?. current ?. focus ( ) ;
227+ } , [ editorRef ] ) ;
223228
224229 const listener = useMemo < RuntimeEvaluationListener > ( ( ) => {
225230 return {
@@ -389,6 +394,10 @@ export const Shell = ({
389394 ]
390395 ) ;
391396
397+ const setEditorRef = useCallback ( ( editor ) => {
398+ editorRef . current = editor ;
399+ } , [ ] ) ;
400+
392401 const scrollToBottom = useCallback ( ( ) => {
393402 if ( ! shellInputContainerRef . current ) {
394403 return ;
@@ -460,7 +469,7 @@ export const Shell = ({
460469 onClearCommand = { listener . onClearCommand }
461470 onInput = { onInput }
462471 operationInProgress = { isOperationInProgress }
463- editorRef = { editorChanged }
472+ editorRef = { setEditorRef }
464473 onSigInt = { onSigInt }
465474 />
466475 ) }
@@ -470,3 +479,5 @@ export const Shell = ({
470479 /* eslint-enable jsx-a11y/no-static-element-interactions */
471480 /* eslint-enable jsx-a11y/click-events-have-key-events */
472481} ;
482+
483+ export const Shell = React . forwardRef ( _Shell ) ;
0 commit comments