-
Notifications
You must be signed in to change notification settings - Fork 70
/
Copy pathshell-content.tsx
65 lines (60 loc) · 1.74 KB
/
shell-content.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
import React, { useEffect, useRef, useState } from 'react';
import { ShellOutputLine, type ShellOutputEntry } from './shell-output-line';
import {
rafraf,
VirtualList,
type VirtualListRef,
} from '@mongodb-js/compass-components';
export const ShellContent = ({
output,
InputPrompt,
__TEST_LIST_HEIGHT,
}: {
output: ShellOutputEntry[];
InputPrompt: JSX.Element;
__TEST_LIST_HEIGHT?: number;
}) => {
const [inputEditorHeight, setInputEditorHeight] = useState(24);
const shellInputContainerRef = useRef<HTMLDivElement>(null);
const listRef: VirtualListRef = useRef();
useEffect(() => {
const lastIndex = output.length - 1;
listRef.current?.resetAfterIndex(lastIndex);
const abortFn = rafraf(() => {
listRef.current?.scrollToItem(lastIndex, 'end');
});
return abortFn;
}, [output.length]);
useEffect(() => {
if (!shellInputContainerRef.current) {
return;
}
const observer = new ResizeObserver(([input]) => {
setInputEditorHeight(input.contentRect.height);
});
observer.observe(shellInputContainerRef.current);
return () => {
observer.disconnect();
};
}, []);
return (
<>
<div style={{ height: `calc(100% - ${inputEditorHeight}px)` }}>
<VirtualList
dataTestId="shell-output-virtual-list"
items={output}
overScanCount={10}
listRef={listRef}
renderItem={(item, ref) => (
<div ref={ref} data-testid="shell-output-line">
<ShellOutputLine entry={item} />
</div>
)}
estimateItemInitialHeight={() => 0}
__TEST_LIST_HEIGHT={__TEST_LIST_HEIGHT}
/>
</div>
<div ref={shellInputContainerRef}>{InputPrompt}</div>
</>
);
};