import { action } from "mobx"; import { observer } from "mobx-react"; import { FC, useEffect } from "react"; import ReactDOM from "react-dom"; import ViewState from "../../ReactViewModels/ViewState"; import { useViewState } from "../Context"; type PortalProps = { /** * id of the new portal. * * The id value is used as the id of the DOM element for the portal, * it must be a DOM unique value. */ id: string; className?: string; }; /** * Defines a portal with given id that can be attached by calling */ export const Portal: FC = ({ id, className }) => { const viewState = useViewState(); /* eslint-disable-next-line react-hooks/exhaustive-deps */ useEffect( action(() => { viewState.portals.set(id, document.getElementById(id)); return action(() => { viewState.portals.delete(id); }); }), [id, className] ); return
; }; export type PortalChildProps = { viewState: ViewState; portalId: string; children: React.ReactNode; }; /** * Attach children to the identified by portalId */ export const PortalChild: FC = observer( ({ viewState, portalId, children }) => { const container = viewState.portals.get(portalId); return container ? ReactDOM.createPortal(children, container) : null; } );