refactor modal and confirm alert

This commit is contained in:
Konstantin Schaper
2020-09-23 14:34:21 +02:00
parent fc534605f0
commit 3e5349d5d1
3 changed files with 93 additions and 67 deletions

View File

@@ -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 => <MemoryRouter initialEntries={["/"]}>{story()}</MemoryRouter>)
.add("Default", () => <ConfirmAlert message={body} title={"Are you sure about that?"} buttons={buttons} />);
.add("Default", () => <ConfirmAlert message={body} title={"Are you sure about that?"} buttons={buttons} />)
.add("WithButton", () => {
const buttonClick = () => {
confirmAlert({ message: body, title: "Are you sure about that?", buttons });
};
return (
<>
<button onClick={buttonClick}>Open ConfirmAlert</button>
<div id="modalRoot" />
</>
);
});

View File

@@ -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,33 +30,34 @@ 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<Props> {
handleClickButton = (button: Button) => {
export const ConfirmAlert: FC<Props> = ({ 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);
}
};
render() {
const { title, message, buttons } = this.props;
const body = <>{message}</>;
const footer = (
@@ -65,7 +67,7 @@ class ConfirmAlert extends React.Component<Props> {
<a
className={classNames("button", "is-info", button.className)}
key={i}
onClick={() => this.handleClickButton(button)}
onClick={() => handleClickButton(button)}
>
{button.label}
</a>
@@ -74,14 +76,25 @@ class ConfirmAlert extends React.Component<Props> {
</div>
);
return <Modal title={title} closeFunction={() => this.close()} body={body} active={true} footer={footer} />;
}
}
return (
(showModal && <Modal title={title} closeFunction={onClose} body={body} active={true} footer={footer} />) || null
);
};
/**
* @deprecated Use the {@link ConfirmAlert} component directly instead.
*/
export function confirmAlert(properties: Props) {
const root = document.getElementById("modalRoot");
if (root) {
ReactDOM.render(<ConfirmAlert {...properties} />, root);
const close = () => {
const container = document.getElementById("modalRoot");
if (container) {
ReactDOM.unmountComponentAtNode(container);
}
};
const props = { ...properties, close };
ReactDOM.render(<ConfirmAlert {...props} />, root);
}
}

View File

@@ -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,16 +34,15 @@ type Props = {
footer?: any;
active: boolean;
className?: string;
headColor: string;
headColor?: string;
};
class Modal extends React.Component<Props> {
static defaultProps = {
headColor: "light"
};
export const Modal: FC<Props> = ({ title, closeFunction, body, footer, active, className, headColor = "light" }) => {
const portalRootElement = usePortalRootElement("modalsRoot");
render() {
const { title, closeFunction, body, footer, active, className, headColor } = this.props;
if (!portalRootElement) {
return null;
}
const isActive = active ? "is-active" : null;
@@ -49,7 +51,7 @@ class Modal extends React.Component<Props> {
showFooter = <footer className="modal-card-foot">{footer}</footer>;
}
return (
const modalElement = (
<div className={classNames("modal", className, isActive)}>
<div className="modal-background" />
<div className="modal-card">
@@ -62,7 +64,8 @@ class Modal extends React.Component<Props> {
</div>
</div>
);
}
}
return ReactDOM.createPortal(modalElement, portalRootElement);
};
export default Modal;