2019-10-01 12:50:56 +00:00
|
|
|
import React from "react";
|
|
|
|
import PropTypes from "prop-types";
|
|
|
|
import styled from "styled-components";
|
|
|
|
import Backdrop from "../backdrop";
|
|
|
|
import Aside from "../layout/sub-components/aside";
|
2019-12-09 11:47:36 +00:00
|
|
|
import Heading from "../heading";
|
2019-10-01 12:50:56 +00:00
|
|
|
import { desktop } from "../../utils/device";
|
|
|
|
import throttle from "lodash/throttle";
|
2019-09-05 09:00:48 +00:00
|
|
|
|
|
|
|
const Dialog = styled.div`
|
|
|
|
position: relative;
|
|
|
|
width: auto;
|
|
|
|
max-width: 560px;
|
|
|
|
margin: 0 auto;
|
|
|
|
display: flex;
|
|
|
|
align-items: center;
|
|
|
|
min-height: 100%;
|
|
|
|
`;
|
|
|
|
|
|
|
|
const Content = styled.div`
|
|
|
|
position: relative;
|
|
|
|
width: 100%;
|
|
|
|
background-color: #fff;
|
|
|
|
padding: 0 16px 16px;
|
|
|
|
`;
|
2019-06-27 12:47:32 +00:00
|
|
|
|
2019-12-04 09:36:13 +00:00
|
|
|
const StyledHeader = styled.div`
|
2019-06-27 12:47:32 +00:00
|
|
|
display: flex;
|
2019-09-05 09:00:48 +00:00
|
|
|
align-items: center;
|
2019-06-27 12:47:32 +00:00
|
|
|
border-bottom: 1px solid #dee2e6;
|
|
|
|
`;
|
|
|
|
|
2019-12-09 11:47:36 +00:00
|
|
|
const HeaderText = styled(Heading)`
|
2019-09-05 09:00:48 +00:00
|
|
|
max-width: 500px;
|
2019-12-09 16:08:20 +00:00
|
|
|
margin: 0;
|
|
|
|
line-height: 56px;
|
|
|
|
font-weight: 700;
|
2019-06-27 12:47:32 +00:00
|
|
|
`;
|
|
|
|
|
2019-09-05 09:00:48 +00:00
|
|
|
const CloseButton = styled.a`
|
|
|
|
cursor: pointer;
|
|
|
|
position: absolute;
|
|
|
|
right: 16px;
|
|
|
|
top: 20px;
|
|
|
|
width: 16px;
|
|
|
|
height: 16px;
|
2019-06-27 12:47:32 +00:00
|
|
|
|
2019-10-01 12:50:56 +00:00
|
|
|
&:before,
|
|
|
|
&:after {
|
2019-09-05 09:00:48 +00:00
|
|
|
position: absolute;
|
|
|
|
left: 8px;
|
2019-10-01 12:50:56 +00:00
|
|
|
content: " ";
|
2019-09-05 09:00:48 +00:00
|
|
|
height: 16px;
|
|
|
|
width: 1px;
|
2019-10-01 12:50:56 +00:00
|
|
|
background-color: #d8d8d8;
|
2019-09-05 09:00:48 +00:00
|
|
|
}
|
|
|
|
&:before {
|
|
|
|
transform: rotate(45deg);
|
|
|
|
}
|
|
|
|
&:after {
|
|
|
|
transform: rotate(-45deg);
|
2019-06-27 12:47:32 +00:00
|
|
|
}
|
|
|
|
`;
|
|
|
|
|
|
|
|
const Body = styled.div`
|
|
|
|
position: relative;
|
2019-09-05 09:00:48 +00:00
|
|
|
padding: 16px 0;
|
2019-06-27 12:47:32 +00:00
|
|
|
`;
|
|
|
|
|
2019-09-05 09:00:48 +00:00
|
|
|
const Footer = styled.div``;
|
2019-06-27 12:47:32 +00:00
|
|
|
|
2019-10-01 12:50:56 +00:00
|
|
|
class ModalDialog extends React.Component {
|
|
|
|
constructor(props) {
|
|
|
|
super(props);
|
|
|
|
|
|
|
|
this.state = { displayType: this.getTypeByWidth() };
|
|
|
|
|
|
|
|
this.getTypeByWidth = this.getTypeByWidth.bind(this);
|
|
|
|
this.resize = this.resize.bind(this);
|
|
|
|
this.popstate = this.popstate.bind(this);
|
|
|
|
this.throttledResize = throttle(this.resize, 300);
|
|
|
|
}
|
|
|
|
|
|
|
|
getTypeByWidth() {
|
|
|
|
if (this.props.displayType !== "auto") return this.props.displayType;
|
|
|
|
|
|
|
|
return window.innerWidth < desktop.match(/\d+/)[0] ? "aside" : "modal";
|
|
|
|
}
|
|
|
|
|
|
|
|
resize() {
|
|
|
|
if (this.props.displayType !== "auto") return;
|
|
|
|
|
|
|
|
const type = this.getTypeByWidth();
|
|
|
|
if (type === this.state.displayType) return;
|
2019-06-27 12:47:32 +00:00
|
|
|
|
2019-10-01 12:50:56 +00:00
|
|
|
this.setState({ displayType: type });
|
|
|
|
}
|
|
|
|
|
|
|
|
popstate() {
|
|
|
|
window.removeEventListener("popstate", this.popstate, false);
|
|
|
|
this.props.onClose();
|
|
|
|
window.history.go(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
componentDidUpdate(prevProps) {
|
|
|
|
if (this.props.displayType !== prevProps.displayType) {
|
|
|
|
this.setState({ displayType: this.getTypeByWidth() });
|
|
|
|
}
|
|
|
|
if (this.props.visible && this.state.displayType === "aside") {
|
|
|
|
window.addEventListener("popstate", this.popstate, false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
componentDidMount() {
|
|
|
|
window.addEventListener("resize", this.throttledResize);
|
|
|
|
}
|
|
|
|
|
|
|
|
componentWillUnmount() {
|
|
|
|
window.removeEventListener("resize", this.throttledResize);
|
|
|
|
}
|
|
|
|
|
|
|
|
render() {
|
|
|
|
const {
|
|
|
|
visible,
|
|
|
|
scale,
|
|
|
|
headerContent,
|
|
|
|
bodyContent,
|
|
|
|
footerContent,
|
2019-10-02 07:23:58 +00:00
|
|
|
onClose,
|
|
|
|
zIndex
|
2019-10-01 12:50:56 +00:00
|
|
|
} = this.props;
|
|
|
|
|
|
|
|
return this.state.displayType === "modal" ? (
|
2019-10-02 07:23:58 +00:00
|
|
|
<Backdrop visible={visible} zIndex={zIndex}>
|
2019-06-27 12:47:32 +00:00
|
|
|
<Dialog>
|
|
|
|
<Content>
|
2019-12-04 09:36:13 +00:00
|
|
|
<StyledHeader>
|
2019-12-09 11:47:36 +00:00
|
|
|
<HeaderText
|
|
|
|
size='medium'
|
2019-12-09 12:18:51 +00:00
|
|
|
truncate={true}
|
2019-12-09 11:47:36 +00:00
|
|
|
>{headerContent}</HeaderText>
|
2019-09-05 09:00:48 +00:00
|
|
|
<CloseButton onClick={onClose}></CloseButton>
|
2019-12-04 09:36:13 +00:00
|
|
|
</StyledHeader>
|
2019-06-27 12:47:32 +00:00
|
|
|
<Body>{bodyContent}</Body>
|
|
|
|
<Footer>{footerContent}</Footer>
|
|
|
|
</Content>
|
|
|
|
</Dialog>
|
2019-07-15 08:38:11 +00:00
|
|
|
</Backdrop>
|
2019-10-01 12:50:56 +00:00
|
|
|
) : (
|
2019-11-25 07:51:53 +00:00
|
|
|
<div
|
|
|
|
className={this.props.className}
|
|
|
|
id={this.props.id}
|
|
|
|
style={this.props.style}
|
|
|
|
>
|
|
|
|
<Backdrop visible={visible} onClick={onClose} zIndex={zIndex} />
|
|
|
|
<Aside visible={visible} scale={scale} zIndex={zIndex} className="modal-dialog-aside">
|
|
|
|
<Content>
|
2019-12-09 11:47:36 +00:00
|
|
|
<StyledHeader>
|
|
|
|
<HeaderText
|
|
|
|
size='medium'
|
2019-12-09 12:18:51 +00:00
|
|
|
truncate={true}
|
2019-12-09 11:47:36 +00:00
|
|
|
>{headerContent}</HeaderText>
|
2019-11-25 07:51:53 +00:00
|
|
|
{scale ? <CloseButton onClick={onClose}></CloseButton> : ""}
|
2019-12-09 11:47:36 +00:00
|
|
|
</StyledHeader>
|
2019-11-25 07:51:53 +00:00
|
|
|
<Body>{bodyContent}</Body>
|
|
|
|
<Footer className="modal-dialog-aside-footer">{footerContent}</Footer>
|
|
|
|
</Content>
|
|
|
|
</Aside>
|
|
|
|
</div>
|
|
|
|
);
|
2019-10-01 12:50:56 +00:00
|
|
|
}
|
|
|
|
}
|
2019-06-27 12:47:32 +00:00
|
|
|
|
|
|
|
ModalDialog.propTypes = {
|
2019-07-11 15:02:48 +00:00
|
|
|
visible: PropTypes.bool,
|
2019-10-01 12:50:56 +00:00
|
|
|
displayType: PropTypes.oneOf(["auto", "modal", "aside"]),
|
|
|
|
scale: PropTypes.bool,
|
|
|
|
headerContent: PropTypes.oneOfType([
|
|
|
|
PropTypes.arrayOf(PropTypes.node),
|
|
|
|
PropTypes.node
|
|
|
|
]),
|
|
|
|
bodyContent: PropTypes.oneOfType([
|
|
|
|
PropTypes.arrayOf(PropTypes.node),
|
|
|
|
PropTypes.node
|
|
|
|
]),
|
|
|
|
footerContent: PropTypes.oneOfType([
|
|
|
|
PropTypes.arrayOf(PropTypes.node),
|
|
|
|
PropTypes.node
|
|
|
|
]),
|
2019-10-02 07:23:58 +00:00
|
|
|
onClose: PropTypes.func,
|
2019-11-25 07:51:53 +00:00
|
|
|
zIndex: PropTypes.number,
|
|
|
|
className: PropTypes.string,
|
|
|
|
id: PropTypes.string,
|
|
|
|
style: PropTypes.oneOfType([PropTypes.object, PropTypes.array])
|
2019-10-01 12:50:56 +00:00
|
|
|
};
|
2019-09-13 14:02:56 +00:00
|
|
|
|
|
|
|
ModalDialog.defaultProps = {
|
2019-10-02 07:23:58 +00:00
|
|
|
displayType: "auto",
|
|
|
|
zIndex: 310
|
2019-10-01 12:50:56 +00:00
|
|
|
};
|
2019-06-27 12:47:32 +00:00
|
|
|
|
2019-10-01 12:50:56 +00:00
|
|
|
export default ModalDialog;
|