react-modal-view
Version:
156 lines (135 loc) • 3.29 kB
JavaScript
import React from 'react'
import ReactDOM from 'react-dom'
import PropTypes from 'prop-types'
import styled from 'styled-components'
export default class Modal extends React.Component {
static get defaultProps () {
return {
type: 'notice',
message: null
}
}
constructor(props) {
super()
this.state = { visible: false }
}
componentWillMount() {
this.handleBeforeComponentUpdate(this.props)
}
componentDidMount() {
this.handleComponentUpdate(this.props, this.state)
}
componentDidUpdate(prevProps, prevState) {
this.handleComponentUpdate(prevProps, prevState)
}
componentWillUnmount() {
this.setBodyOverflowVisible(true)
}
handleBeforeComponentUpdate(props) {
if (props.hasOwnProperty('visible') && props.visible !== this.state.visible) {
this.setState({ visible: props.visible });
}
}
handleComponentUpdate(prevProps, prevState) {
if (prevState.visible !== this.state.visible) {
if (this.state.visible) {
this.props.onShow &&
this.props.onShow()
} else {
this.props.onHide &&
this.props.onHide()
}
this.setBodyOverflowVisible(!this.state.visible);
}
}
setBodyOverflowVisible(visible) {
if (!visible) {
document.body.style.overflow = 'hidden';
} else {
document.body.style.overflow = '';
}
}
handleCloseBtnClick(e) {
e.preventDefault()
e.stopPropagation()
this.toggleVisibility()
}
handleOverlayClick(e) {
if (e.target === ReactDOM.findDOMNode(this.refs.overlay) && this.props.closable) {
e.preventDefault()
e.stopPropagation()
this.toggleVisibility()
}
}
toggleVisibility() {
var visible = !this.state.visible
this.setState({ visible: visible })
}
show() {
this.setState({ visible: true })
}
hide() {
this.setState({ visible: false })
}
render() {
const { visible } = this.state
let closeBtn = (
<ModalTop>
<ModalClose onClick={this.handleCloseBtnClick.bind(this)}>
×
</ModalClose>
</ModalTop>
)
if (this.props.closable === false) {
closeBtn = (<div></div>)
}
let closeClass = `overlay ${visible ? '' : ' hidden'}`
return (
<ModalWrapper ref='overlay' visible={visible} onClick={this.handleOverlayClick.bind(this)}>
{closeBtn}
<ModalContent>
{this.props.children}
</ModalContent>
</ModalWrapper>
)
}
}
const ModalWrapper = styled.div`
opacity: ${props => props.visible ? 1 : 0};
position: fixed;
top: 0;
left: 0;
bottom: 0;
right: 0;
overflow: auto;
z-index: 100;
`
const ModalTop = styled.div`
margin: 5% auto;
position: relative;
top: 5rem;
max-width: 90%;
`
const ModalContent = styled.div`
background-color: #fff;
box-shadow: 0.1rem 0.1rem 3rem rgba(0, 0, 0, 0.25);
margin-bottom: 4%;
margin: 0 auto;
padding: 22px 30px;
position: relative;
top: 5rem;
max-width: 90%;
`
const ModalClose = styled.div`
box-sizing: content-box;
position: absolute;
top: 15px;
right: 0px;
cursor: pointer;
z-index: 100;
padding: 0;
font-size: 30px;
line-height: 1em;
border-top-right-radius: 4px;
border-bottom-left-radius: 4px;
`