Skip to content

Instantly share code, notes, and snippets.

@chantastic
Created December 21, 2016 22:57
Show Gist options
  • Save chantastic/96fa78d1d48434b61fab1cec2cc0f4bb to your computer and use it in GitHub Desktop.
Save chantastic/96fa78d1d48434b61fab1cec2cc0f4bb to your computer and use it in GitHub Desktop.
super-dumb-thing
import React, { Children, Component } from 'react';
import ReactDOM from 'react-dom';
class SetOverflowHidden extends Component {
componentDidMount() {
this.previousOverflow = document.body.style.overflow
document.body.style.overflow = "hidden"
}
componentWillUnmount() {
document.body.style.overflow = this.previousOverflow
}
render() {
return Children.only(this.props.children)
}
}
class ModalPortal extends Component {
// add way to interact with node
componentDidMount() {
this.node = document.createElement("div")
this.props.mountSelector().appendChild(this.node)
ReactDOM.render(
Children.only(this.props.children),
this.node
)
}
componentWillUnmount() {
ReactDOM.unmountComponentAtNode(this.node)
this.props.mountSelector().removeChild(this.node)
}
render() {
console.log(this.props.children)
return null
}
}
ModalPortal.defaultProps = {
mountSelector: () => document.body
}
ModalPortal.propTypes = {
children: React.PropTypes.node.isRequired
}
class OnEscapeClick extends Component {
handleKeyDown = () => {
if (event.keyCode == 27) {
event.preventDefault();
return this.props.onEscapePress()
}
}
componentDidMount() {
document.addEventListener("keyup", this.handleKeyDown)
}
componentWillUnmount() {
document.removeEventListener("keyup", this.handleKeyDown)
}
render() {
return Children.only(this.props.children)
}
}
const ModalBackdrop = ({ style, ...props }) =>
<div
style={{
position: "fixed",
top: 0,
right: 0,
bottom: 0,
left: 0,
backgroundColor: "red",
overflowY: "scroll",
...style,
}}
{...props}
/>
class FetchData extends Component {
state = { data: null }
componentDidMount() {
this.setState({data: "blah blah blah"})
}
render() {
return Children.only(
this.props.children(this.state)
)
}
}
class App extends Component {
state = {
modalShown: true
}
render() {
return (
<div>
Sample App with composed Modal
<button
type="button"
onClick={() => this.setState({modalShown: true})}
>show modal</button>
{this.state.modalShown &&
<FetchData>
{({ data }) =>
<SetOverflowHidden>
<OnEscapeClick onEscapePress={() => this.setState({modalShown: false})}>
<ModalPortal>
<ModalBackdrop style={{ backgroundColor: "hsla(0, 0%, 0%, .25)"}}>
<div>
<div>
{data}
</div>
<footer>
<button
type="button"
onClick={() => this.setState({modalShown: !this.state.modalShown})}
>Cancel</button>
</footer>
</div>
</ModalBackdrop>
</ModalPortal>
</OnEscapeClick>
</SetOverflowHidden>
}
</FetchData>
}
</div>
);
}
}
export default App;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment