diff --git a/scm-ui/ui-components/src/modals/ConfirmAlert.stories.tsx b/scm-ui/ui-components/src/modals/ConfirmAlert.stories.tsx index b450153c3b..6be1ce43ee 100644 --- a/scm-ui/ui-components/src/modals/ConfirmAlert.stories.tsx +++ b/scm-ui/ui-components/src/modals/ConfirmAlert.stories.tsx @@ -25,7 +25,7 @@ import { storiesOf } from "@storybook/react"; import { MemoryRouter } from "react-router-dom"; import * as React from "react"; -import ConfirmAlert from "./ConfirmAlert"; +import ConfirmAlert, { confirmAlert } from "./ConfirmAlert"; const body = "Mind-paralyzing change needed improbability vortex machine sorts sought same theory upending job just allows\n " + @@ -40,11 +40,21 @@ const buttons = [ onClick: () => null }, { - label: "Submit", - onClick: () => {} + label: "Submit" } ]; storiesOf("Modal|ConfirmAlert", module) .addDecorator(story => {story()}) - .add("Default", () => ); + .add("Default", () => ) + .add("WithButton", () => { + const buttonClick = () => { + confirmAlert({ message: body, title: "Are you sure about that?", buttons }); + }; + return ( + <> + +
+ + ); + }); diff --git a/scm-ui/ui-components/src/modals/ConfirmAlert.tsx b/scm-ui/ui-components/src/modals/ConfirmAlert.tsx index e8671a77cb..ee0265d89d 100644 --- a/scm-ui/ui-components/src/modals/ConfirmAlert.tsx +++ b/scm-ui/ui-components/src/modals/ConfirmAlert.tsx @@ -22,6 +22,7 @@ * SOFTWARE. */ import * as React from "react"; +import { FC, useState } from "react"; import ReactDOM from "react-dom"; import Modal from "./Modal"; import classNames from "classnames"; @@ -29,59 +30,71 @@ import classNames from "classnames"; type Button = { className?: string; label: string; - onClick: () => void | null; + onClick?: () => void | null; }; type Props = { title: string; message: string; buttons: Button[]; + close?: () => void; }; -class ConfirmAlert extends React.Component { - handleClickButton = (button: Button) => { +export const ConfirmAlert: FC = ({ title, message, buttons, close }) => { + const [showModal, setShowModal] = useState(true); + + const onClose = () => { + if (typeof close === "function") { + close(); + } else { + setShowModal(false); + } + }; + + const handleClickButton = (button: Button) => { if (button.onClick) { button.onClick(); } - this.close(); + onClose(); }; - close = () => { - const container = document.getElementById("modalRoot"); - if (container) { - ReactDOM.unmountComponentAtNode(container); - } - }; + const body = <>{message}; - render() { - const { title, message, buttons } = this.props; + const footer = ( +
+ {buttons.map((button, i) => ( +

+ handleClickButton(button)} + > + {button.label} + +

+ ))} +
+ ); - const body = <>{message}; - - const footer = ( -
- {buttons.map((button, i) => ( -

- this.handleClickButton(button)} - > - {button.label} - -

- ))} -
- ); - - return this.close()} body={body} active={true} footer={footer} />; - } -} + return ( + (showModal && ) || null + ); +}; +/** + * @deprecated Use the {@link ConfirmAlert} component directly instead. + */ export function confirmAlert(properties: Props) { const root = document.getElementById("modalRoot"); if (root) { - ReactDOM.render(, root); + const close = () => { + const container = document.getElementById("modalRoot"); + if (container) { + ReactDOM.unmountComponentAtNode(container); + } + }; + const props = { ...properties, close }; + ReactDOM.render(, root); } } diff --git a/scm-ui/ui-components/src/modals/Modal.tsx b/scm-ui/ui-components/src/modals/Modal.tsx index 19ce82dea0..87badb5d4b 100644 --- a/scm-ui/ui-components/src/modals/Modal.tsx +++ b/scm-ui/ui-components/src/modals/Modal.tsx @@ -22,7 +22,10 @@ * SOFTWARE. */ import * as React from "react"; +import {FC} from "react"; import classNames from "classnames"; +import usePortalRootElement from "../usePortalRootElement"; +import ReactDOM from "react-dom"; type Props = { title: string; @@ -31,38 +34,38 @@ type Props = { footer?: any; active: boolean; className?: string; - headColor: string; + headColor?: string; }; -class Modal extends React.Component { - static defaultProps = { - headColor: "light" - }; +export const Modal: FC = ({ title, closeFunction, body, footer, active, className, headColor = "light" }) => { + const portalRootElement = usePortalRootElement("modalsRoot"); - render() { - const { title, closeFunction, body, footer, active, className, headColor } = this.props; - - const isActive = active ? "is-active" : null; - - let showFooter = null; - if (footer) { - showFooter =
{footer}
; - } - - return ( -
-
-
-
-

{title}

-
-
{body}
- {showFooter} -
-
- ); + if (!portalRootElement) { + return null; } -} + + const isActive = active ? "is-active" : null; + + let showFooter = null; + if (footer) { + showFooter =
{footer}
; + } + + const modalElement = ( +
+
+
+
+

{title}

+
+
{body}
+ {showFooter} +
+
+ ); + + return ReactDOM.createPortal(modalElement, portalRootElement); +}; export default Modal;