Files
cloudbeaver/webapp/packages/plugin-codemirror6/src/ReactCodemirrorPanel.tsx
T
Alexey 01bcf9479d fix: resolve npm dependencies (#2050)
* fix: resolve npm dependencies

* fix: types

* chore: add manual frontend cache actin running

* fix: github workflows

* fix: types

* fix: types

* fix: types
2023-10-09 16:25:07 +03:00

58 lines
1.6 KiB
TypeScript

/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2023 DBeaver Corp and others
*
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
*/
import { Compartment, StateEffect } from '@codemirror/state';
import { showPanel } from '@codemirror/view';
import { observer } from 'mobx-react-lite';
import { useContext, useLayoutEffect, useMemo } from 'react';
import { createPortal } from 'react-dom';
import { ReactCodemirrorContext } from './ReactCodemirrorContext';
interface Props extends React.PropsWithChildren {
className?: string;
incomingView?: boolean;
top?: boolean;
}
export const ReactCodemirrorPanel: React.FC<Props> = observer(function ReactCodemirrorPanel({ className, children, incomingView, top }) {
const dom = useMemo(() => document.createElement('div'), []);
const compartment = useMemo(() => new Compartment(), []);
const context = useContext(ReactCodemirrorContext);
const view = incomingView ? context?.incomingView : context?.view;
useLayoutEffect(() => {
if (view) {
view.dispatch({
effects: [StateEffect.appendConfig.of(compartment.of(showPanel.of(() => ({ top, dom }))))],
});
return () => {
view.dispatch({
effects: compartment.reconfigure([]),
});
};
}
return undefined;
}, [view, top]);
useLayoutEffect(() => {
if (className) {
const classes = className.split(' ');
dom.classList.add(...classes);
return () => {
dom.classList.remove(...classes);
};
}
return undefined;
}, [className]);
return createPortal(children, dom) as any;
});