@fluent-windows/core
Version:
React components that inspired by Microsoft's Fluent Design System.
40 lines (34 loc) • 1.25 kB
JavaScript
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { PortalPropTypes } from './Portal.type';
import { useGlobal } from '@fluent-windows/hooks';
function getContainer(container) {
container = typeof container === 'function' ? container() : container; // eslint-disable-next-line
return ReactDOM.findDOMNode(container);
}
const Portal = React.forwardRef(({
children,
container,
disablePortal = false,
...rest
}, ref) => {
const [mountNode, setMountNode] = React.useState(() => container);
React.useEffect(() => {
const global = useGlobal();
if (!disablePortal) {
setMountNode(getContainer(container) || global && global.document.body);
}
}, [container, disablePortal]);
React.useImperativeHandle(ref, () => mountNode, [mountNode]);
if (disablePortal) {
// Verify that children has only one child node (a React element) and return it if it exists,
// otherwise this method will throw an error.
React.Children.only(children);
return React.cloneElement(children);
}
return mountNode ? ReactDOM.createPortal(React.cloneElement(children, { ...rest
}), mountNode) : null;
});
Portal.displayName = 'FPortal';
Portal.propTypes = PortalPropTypes;
export default Portal;