Portal: optimizations (#37459) (#37510)

Co-authored-by: An Le <an.le@grafana.com>
(cherry picked from commit 0b7253406b)

Co-authored-by: Leon Sorokin <leeoniya@gmail.com>
This commit is contained in:
Grot (@grafanabot)
2021-08-03 16:55:06 -05:00
committed by GitHub
co-authored by Leon Sorokin
parent e3a270a041
commit 6f40b883e1
@@ -1,4 +1,4 @@
import React, { PropsWithChildren, useEffect, useState } from 'react';
import React, { PropsWithChildren, useLayoutEffect, useRef } from 'react';
import ReactDOM from 'react-dom';
import { useTheme2 } from '../../themes';
@@ -9,25 +9,30 @@ interface Props {
}
export function Portal(props: PropsWithChildren<Props>) {
const { children, className, root = document.body, forwardedRef } = props;
const { children, className, root: portalRoot = document.body, forwardedRef } = props;
const theme = useTheme2();
const [node] = useState(document.createElement('div'));
const portalRoot = root;
if (className) {
node.classList.add(className);
const node = useRef<HTMLDivElement | null>(null);
if (!node.current) {
node.current = document.createElement('div');
if (className) {
node.current.className = className;
}
node.current.style.position = 'relative';
node.current.style.zIndex = `${theme.zIndex.portal}`;
}
node.style.position = 'relative';
node.style.zIndex = `${theme.zIndex.portal}`;
useEffect(() => {
portalRoot.appendChild(node);
useLayoutEffect(() => {
if (node.current) {
portalRoot.appendChild(node.current);
}
return () => {
portalRoot.removeChild(node);
if (node.current) {
portalRoot.removeChild(node.current);
}
};
}, [node, portalRoot]);
}, [portalRoot]);
return ReactDOM.createPortal(<div ref={forwardedRef}>{children}</div>, node);
return ReactDOM.createPortal(<div ref={forwardedRef}>{children}</div>, node.current);
}
export const RefForwardingPortal = React.forwardRef<HTMLDivElement, Props>((props, ref) => {