Created
July 3, 2018 13:07
-
-
Save shelldandy/1f83787138a3745ae4e7e998b4a5fe2b to your computer and use it in GitHub Desktop.
A React Toggle Componer that uses render props
This file contains 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
import { Component, createRef } from 'react'; | |
import PropTypes from 'prop-types'; | |
class Toggle extends Component { | |
state = { | |
on: false, | |
} | |
wrapper = createRef() | |
escapeListener = event => { | |
if (event.keyCode === 27) { | |
this.toggle(); | |
} | |
} | |
clickListener = event => { | |
const { wrapper } = this; | |
const clickedOutside = !wrapper.current.contains(event.target); | |
if (clickedOutside) { | |
this.toggle(); | |
} | |
} | |
toggle = e => { | |
if (e) { | |
e.stopPropagation(); | |
} | |
if (!this.state.on) { | |
window.addEventListener('click', this.clickListener); | |
window.addEventListener('keyup', this.escapeListener); | |
} else { | |
window.removeEventListener('click', this.clickListener); | |
window.removeEventListener('keyup', this.escapeListener); | |
} | |
this.setState(prevState => ({ | |
on: !prevState.on | |
})); | |
} | |
render () { | |
const { on } = this.state; | |
const { toggle, wrapper } = this; | |
const passedProps = { | |
// is the Toggle triggered or not... | |
on, | |
// Use this to toggle it out | |
toggle, | |
// Add this ref to your component to click-out works! | |
wrapper, | |
}; | |
return this.props.children({ ...passedProps }); | |
} | |
} | |
Toggle.propTypes = { | |
children: PropTypes.func.isRequired, | |
}; | |
export default Toggle; |
This file contains 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
<Toggle> | |
{({ on, toggle, wrapper }) => ( | |
<Wrapper> | |
<ShareBtn onClick={toggle} > | |
<ShareIcon /> | |
</ShareBtn> | |
<Links on={on} innerRef={wrapper}> | |
<Link> | |
<Icon> | |
<Messenger /> | |
</Icon> | |
Share in Messenger | |
</Link> | |
</Links> | |
</Wrapper> | |
)} | |
</Toggle> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment