Reputation: 31
i monaco-editor/react in my project . Somewhere in the project, I want to add a view zone to the editor, but the addZone method in Monaco does not accept the react component (jsx) editor. I asked gpt chat and he suggested using ReactDOM?.render. code:
const onMouseDown = useCallback((e: monacoEditor.editor.IEditorMouseEvent) => {
if (e.event.target.classList.contains('myGlyphMarginClass')) {
const zone = document.createElement('div');
zone.className = 'my-custom-zone';
zone.style.zIndex = '1000';
editorRef.current?.getModifiedEditor().changeViewZones(accessor => {
const zoneId = accessor.addZone({
afterLineNumber: e.target.position?.lineNumber ?? 0,
domNode: zone,
heightInPx: 5
});
setZoneId(zoneId);
});
ReactDOM?.render(
<CommentForm
onMount={(height) => {
setZone({ height: 1, domNode: zone, line: e.target.position?.lineNumber });
}}
/>,
zone
);
}
}, []);
My main problem is that I want the height of the view zone to be dynamic (the height of its content), and for this I have to render it once on the page, calculate its height, delete the previous one and render it again with the correct height. This is the code I wrote to delete and re-render. But zone?.domNode.children[0].clientHeight is sometimes 0
useEffect(() => {
console.log('maybe null', zone , zoneId);
if (zone && zoneId) {
const height = zone?.domNode.children[0].clientHeight
editorRef.current?.getModifiedEditor().changeViewZones(accessor => {
accessor.removeZone(zoneId)
const newZoneId = accessor.addZone({
afterLineNumber: zone?.line ?? 0,
domNode: zone.domNode,
heightInPx: height
});
accessor.layoutZone(newZoneId)
setZone(undefined)
setZoneId(undefined)
});
}
}, [zone, zoneId]);
CommentForm.tsx:
const CommentForm = ({ onMount }: { onMount: (height: number) => void }) => {
const ref = useRef<HTMLDivElement>(null);
const [height, setHeight] = useState<number>();
useEffect(() => {
if (ref.current)
setHeight(ref?.current.offsetHeight);
}, []);
useEffect(() => {
console.log('use effect call', height);
if (height)
onMount(height);
}, [height, onMount]);
return (
<div ref={ref} style={{ backgroundColor: 'red', width: '100%', height: 'fit-content' }}>
<textarea
rows={4}
style={{
width: '100%',
padding: '18px',
height: 'fit-content',
color: 'black',
backgroundColor: 'rgba(0,146,250,0.5)'
}}
onChange={(e) => console.log(e.target.value)}
>
</textarea>
</div>
);
};
DiffEditor:
<DiffEditor
height={'100%'}
width={'100%'}
originalLanguage={'json'}
modifiedLanguage={'json'}
original={oldDash}
modified={newDash}
language="json"
theme={'light'}
onMount={editor => {
editorRef.current = editor;
editor.getModifiedEditor().onMouseMove(onMouseMove);
editor.getModifiedEditor().onMouseLeave(onMouseLeave);
editor.getModifiedEditor().onMouseDown(onMouseDown);
}}
options={{
fontSize: 20,
glyphMargin: true,
readOnly: true,
folding: true,
hideUnchangedRegions: {
enabled: true,
revealLineCount: 20,
minimumLineCount: 1,
contextLineCount: 1
}
}}
/>
I looked everywhere but there was no documentation for monaco editor in react (except the npm package home page but that was also very incomplete)
Upvotes: 0
Views: 57