github.com/replicatedhq/ship@v0.55.0/web/init/src/components/shared/NavItem.jsx (about) 1 import * as React from "react"; 2 import { Link } from "react-router-dom"; 3 import Popover from "./Popover"; 4 import PopoverItem from "./PopoverItem"; 5 6 export default class NavItem extends React.Component { 7 8 componentDidMount() { 9 document.addEventListener("mousedown", this.handleClickOutside); 10 } 11 12 componentWillUnmount() { 13 document.removeEventListener("mousedown", this.handleClickOutside); 14 } 15 16 setWrapperRef = (node) => { 17 this.wrapperRef = node; 18 } 19 20 handleClickOutside = (event) => { 21 if (this.props.isDropDownActive && this.wrapperRef && !this.wrapperRef.contains(event.target)) { 22 if (this.props.dropdownContent) { 23 this.props.onClick(event) 24 } 25 } 26 } 27 28 render() { 29 const { 30 href, 31 isActive, 32 icon, 33 label, 34 className, 35 linkTo, 36 onClick, 37 options, 38 dropdownContent, 39 isDropDownActive, 40 } = this.props; 41 const wrapperClassName = [ 42 "NavItem u-position--relative flex flex-column flex-verticalCenter", 43 className, 44 isActive ? "is-active" : "", 45 ].join(" "); 46 47 function linkify(linkContent, linkClassName, options = {}) { 48 return linkTo 49 ? <Link className={linkClassName} to={linkTo} tabIndex="-1">{linkContent}</Link> 50 : href ? 51 <a href={href} target="_blank" tabIndex="-1" rel="noopener noreferrer">{linkContent}</a> 52 : options.isButton ? 53 <button className={`Button ${options.buttonClassName || ""}`} tabIndex="-1">{linkContent}</button> 54 : <a tabIndex="-1">{linkContent}</a>; 55 } 56 57 const stopPropagation = (e) => e.stopPropagation(); 58 59 return ( 60 <div 61 onClick={(e) => { 62 onClick(e); 63 stopPropagation(e); 64 }} 65 className={wrapperClassName} 66 ref={this.setWrapperRef} 67 > 68 <div className={`HeaderContent-wrapper flex0 ${dropdownContent && isDropDownActive ? "active-dropdown" : ""}`}> 69 {icon 70 ? linkify(icon, "HeaderLink flex0") 71 : null 72 } 73 {label 74 ? linkify(label, "HeaderLink flex0", options) 75 : null 76 } 77 {dropdownContent 78 ? ( 79 <Popover 80 minWidth={this.props.dropdownWidth || "170"} 81 position={this.props.dropdownPosition || "bottom-left"} 82 visible={isDropDownActive} 83 onClick={stopPropagation} 84 content={Array.isArray(dropdownContent) 85 ? ( 86 <ul className="PopoverItem-wrapper"> 87 {dropdownContent 88 .filter(x => x) 89 .map((contents, index) => ( 90 <PopoverItem 91 key={`item-${index}`} 92 {...contents} 93 /> 94 )) 95 } 96 </ul> 97 ) 98 : dropdownContent 99 } 100 /> 101 ) 102 : null 103 } 104 </div> 105 </div> 106 ); 107 } 108 }