src/platform/site-wide/user-nav/components/DropDownPanel/DropDownPanel.jsx
import PropTypes from 'prop-types';
import React from 'react';
import classNames from 'classnames';
export default class DropDownPanel extends React.Component {
componentDidMount() {
document.body.addEventListener('click', this.handleDocumentClick, false);
}
componentWillUnmount() {
document.body.removeEventListener('click', this.handleDocumentClick, false);
}
handleDocumentClick = event => {
// If this dropdown is open, and it's not an element within this dropdown being clicked,
// then the user clicked elsewhere and we should invoke the click handler to toggle this
// dropdown to closed.
if (this.props.isOpen && !this.dropdownDiv.contains(event.target)) {
this.toggleDropDown();
}
};
toggleDropDown = () => {
this.props.clickHandler();
};
render() {
const buttonClasses = classNames(
this.props.cssClass,
{ 'va-btn-withicon': this.props.icon },
'va-dropdown-trigger',
);
return (
<div
className="va-dropdown"
ref={div => {
this.dropdownDiv = div;
}}
>
<button
className={buttonClasses}
aria-controls={this.props.id}
aria-expanded={this.props.isOpen}
disabled={this.props.disabled}
onClick={this.toggleDropDown}
>
<span>
{this.props.icon}
{this.props.buttonText}
</span>
</button>
<div
className={`va-dropdown-panel ${this.props.dropdownPanelClassNames}`}
id={this.props.id}
hidden={!this.props.isOpen}
>
{this.props.children}
</div>
</div>
);
}
}
DropDownPanel.propTypes = {
/**
* The text of the drop down button.
*/
buttonText: PropTypes.string.isRequired,
/**
* A function called when the drop down button is clicked. This is often used
* to set the open state in the parent component, which passes down the new
* isOpen prop.
*/
clickHandler: PropTypes.func.isRequired,
/**
* Any CSS classes to apply to the button itself.
*/
cssClass: PropTypes.string,
/**
* The string of classnames for the dropdown panel container.
*/
dropdownPanelClassNames: PropTypes.string,
/**
* An SVG icon to render before the button text.
*/
icon: PropTypes.node,
/**
* The ID of the <div> surrounding the children.
*/
id: PropTypes.string,
/**
* Whether the drop down panel is open.
*/
isOpen: PropTypes.bool.isRequired,
/**
* The disabled state of the drop down button.
*/
disabled: PropTypes.bool,
};
DropDownPanel.defaultProps = {
dropdownPanelClassNames: '',
disabled: false,
};