Skip to content

Instantly share code, notes, and snippets.

@SugarDarius
Last active June 3, 2019 13:51
Show Gist options
  • Save SugarDarius/2cc5937832ef52cd834dfce36bc70e09 to your computer and use it in GitHub Desktop.
Save SugarDarius/2cc5937832ef52cd834dfce36bc70e09 to your computer and use it in GitHub Desktop.
Independent Dropdown React Component
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import map from 'lodash/map';
export default class IndependentDropdown extends Component {
constructor(props) {
super(props);
this.onClickOutside = this.onClickOutside.bind(this);
}
onClickOutside(e) {
const { contentNode } = this;
const { id, display, onClickOutsideAction } = this.props;
if ( display && !contentNode.contains(e.target)) {
onClickOutsideAction(id);
}
}
attachEvent() {
document.addEventListener('click', this.onClickOutside);
}
detachEvent() {
document.removeEventListener('click', this.onClickOutside);
}
setEventState(display) {
display ? this.attachEvent() : this.detachEvent();
}
componentWillReceiveProps(nextProps) {
this.setEventState(nextProps.display);
}
componentWillMount() {
this.setEventState(this.props.display);
}
renderContent() {
const { items } = this.props;
return (
<div className='independent-dropdown' ref={(node) => {this.contentNode = node;}}>
{
map(items, (item, key) => (
<a href='#' className='item' key={key}>
<h3>Some items here</h3>
</a>
))
}
</div>
);
}
render() {
const { display } = this.props;
// the node independent-dropdown-box must have a CSS like
// position: absolute;
// bottom: 0;
// left: 0;
// display: block;
// width: 100%;
// height: 0;
// z-index: 1;
return (
<div className='independent-dropdown-box'>
{display && this.renderContent()}
</div>
);
}
}
IndependentDropdown.propTypes = {
id: PropTypes.string.isRequired,
display: PropTypes.bool.isRequired,
items: PropTypes.array.isRequired,
onClickOutsideAction: PropTypes.func.isRequired
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment