Last active
April 22, 2018 11:16
-
-
Save condor-bird/3b8c683621cc50bb56316b2f3f46f881 to your computer and use it in GitHub Desktop.
React modal popup example
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
body { | |
background-color: #1B2B34; | |
font-size: 62.5%; | |
font-family: sans-serif; | |
color: #00273B; | |
} | |
.app-cont { | |
display: flex; | |
justify-content: center; | |
height: calc(100vh - 1.25rem); | |
width: 100%; | |
border: 0.1rem solid #CCD4D8; | |
border-radius: 0.2rem; | |
background-color: #EEE; | |
} | |
.app-cont .__center { | |
align-self: center; | |
font-size: 1.5rem; | |
text-align: center; | |
} | |
.app-cont .__center .__btn { | |
padding: .75rem 1.25rem; | |
background-color: #278FBB; | |
border-radius: 0.2rem; | |
border: none; | |
color: #FFF; | |
cursor: pointer; | |
} | |
.app-cont .__center .__btn:hover { | |
background-color: #379CC7; | |
} | |
.modal-wrapper { | |
display: flex; | |
flex-direction: column; | |
align-items: center; | |
height: 100%; | |
} | |
.modal-wrapper .insult { | |
flex: 1; | |
font-size: 1.4rem; | |
color: red; | |
} | |
.modal-wrapper button:first-of-type { | |
margin-right: 1rem; | |
} | |
#modal-container { | |
display: none; | |
} | |
#modal-container.active { | |
display: block; | |
} | |
#modal-container .overlay { | |
position: fixed; | |
top: 0; | |
left: 0; | |
width: 100%; | |
height: 100vh; | |
background-color: #000; | |
opacity: .7; | |
z-index: 1; | |
} | |
#modal-container .modal { | |
position: absolute; | |
top: 0; | |
left: 0; | |
display: flex; | |
align-items: center; | |
justify-content: center; | |
width: 100%; | |
height: 100vh; | |
z-index: 2; | |
} | |
#modal-container .modal .modal-content { | |
width: 50%; | |
height: 50%; | |
padding: 1rem; | |
border-radius: 0.2rem; | |
background-color: #FFF; | |
opacity: 1; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<body> | |
<div id="app"></div> | |
</body> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class MainApp extends React.Component { | |
constructor(...args) { | |
super(...args); | |
this.state = { | |
isModalActive: false, | |
isModalAppendable: true | |
}; | |
this.activateModal = this.activateModal.bind(this); | |
this.deactivateModal = this.deactivateModal.bind(this); | |
this.unmountModal = this.unmountModal.bind(this); | |
} | |
activateModal(){ | |
this.setState({ | |
isModalActive: true | |
}); | |
} | |
deactivateModal(){ | |
this.setState({ | |
isModalActive: false | |
}); | |
} | |
unmountModal(){ | |
this.setState({ | |
isModalActive: false, | |
isModalAppendable: false | |
}); | |
} | |
render(){ | |
//this ugly hunk of trash determines if we should unmount the component by returning the right things | |
let modal = this.state.isModalAppendable | |
? (<Modal isActive={this.state.isModalActive} closeModal={this.deactivateModal}> | |
<div className='modal-wrapper'> | |
<div className='insult'>And he doesn't have that many.....</div> | |
<div className='button-row'> | |
<button onClick={this.deactivateModal}>Close modal bruh</button> | |
<button onClick={this.unmountModal}>Close modal and unmount component bruh</button> | |
</div> | |
</div> | |
</Modal>) | |
: null; | |
return ( | |
<div className={'app-cont'}> | |
<span className={'__center'}> | |
<CenterDiv activateModal={this.activateModal} /> | |
{modal} | |
</span> | |
</div> | |
); | |
} | |
} | |
class Modal extends React.Component { | |
constructor(...args){ | |
super(...args); | |
this.handleClickInside = this.handleClickInside.bind(this); | |
this.handleClickOutside = this.handleClickOutside.bind(this); | |
} | |
componentDidMount(){ | |
//create an element to append | |
this.modal = document.createElement('div'); | |
//append that shit | |
document.body.appendChild(this.modal); | |
//call the render method to add custom styled div and children contents to appended element | |
this.renderModalContent(this.props); | |
} | |
componentWillReceiveProps(newProps){ | |
this.renderModalContent(newProps); | |
} | |
componentWillUnmount(){ | |
//act like this shit was never here ever | |
ReactDOM.unmountComponentAtNode(this.modal); | |
document.body.removeChild(this.modal); | |
} | |
handleClickInside(e){ | |
e.stopPropagation(); | |
} | |
handleClickOutside(){ | |
this.props.closeModal(); | |
} | |
renderModalContent(props){ | |
//put something in the appended shit | |
let cont; | |
ReactDOM.render( | |
<div id='modal-container'> | |
<div className='overlay'></div> | |
<div className='modal' onClick={this.handleClickOutside}> | |
<div className='modal-content' onClick={this.handleClickInside}> | |
{this.props.children} | |
</div> | |
</div> | |
</div>, | |
this.modal | |
); | |
cont = document.getElementById('modal-container'); | |
if (props.isActive){ | |
cont.classList.add('active'); | |
} else { | |
cont.classList.remove('active'); | |
} | |
} | |
render(){ | |
//don't render anything here because we are appending to the body portal style ahhhh yissssss | |
return null; | |
} | |
} | |
const CenterDiv = (props) => { | |
return ( | |
<div> | |
<span>JRU is a jerk that doesn't like his friends.</span><br /> | |
<button className='__btn' onClick={props.activateModal}>PUSH ME</button> | |
</div> | |
); | |
}; | |
ReactDOM.render(<MainApp />, document.getElementById('app')); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment