import React from 'react'; import type { ModalProps } from 'react-bootstrap'; import { Modal } from 'react-bootstrap'; import ReactDOM from 'react-dom'; import type { IModalComponentProps } from './modal'; /** An imperative service for showing a react component as a modal */ export class ReactModal { /** * example: * const MyComponent = ({ closeModal, dismissModal }) => { *

Modal Contents!

* * * * } * * ... * * ModalService.show(MyComponent).then(result => { * this.setState({ result }); * }); * * @param ModalComponent the component to be rendered inside a modal * @param componentProps to pass to the ModalComponent * @param modalProps to pass to the Modal * @returns {Promise} */ public static show

( ModalComponent: React.ComponentType

, componentProps?: P, modalProps?: Partial, ): Promise { const modalPromise = new Promise((resolve, reject) => { let mountNode = document.createElement('div'); let show = true; function onExited() { if (!mountNode) { return; } ReactDOM.unmountComponentAtNode(mountNode); mountNode = null; } const destroy = (resultHandler: (result: any) => void) => (result: any) => { if (!mountNode) { return; } resultHandler(result); // Use react-bootstrap modal lifecycle, i.e. show=false, which triggers onExited show = false; render(); }; const handleClose = destroy(resolve); const handleDismiss = destroy(reject); function render() { ReactDOM.render( , mountNode, ); } render(); }); modalPromise.catch(() => {}); return modalPromise; } }