Skip to content

Instantly share code, notes, and snippets.

@shelldandy
Created July 3, 2018 13:07
Show Gist options
  • Save shelldandy/1f83787138a3745ae4e7e998b4a5fe2b to your computer and use it in GitHub Desktop.
Save shelldandy/1f83787138a3745ae4e7e998b4a5fe2b to your computer and use it in GitHub Desktop.
A React Toggle Componer that uses render props
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;
<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