UNPKG

optimizely-oui

Version:

Optimizely's Component Library.

152 lines (138 loc) 5.18 kB
import classNames from "classnames"; import Icon from "react-oui-icons"; import PropTypes from "prop-types"; import React from "react"; import Link from "../../Link"; import Poptip from "../../Poptip"; const LINK = "link"; const PUSH_STATE = "pushstate"; const BUTTON = "button"; // Should have a main component on its own. class IconLink extends React.PureComponent { static propTypes = { /* Boolean, whether an external icon should show */ hasExternalIcon: PropTypes.bool, /* Boolean, Should show a separator line before this link */ hasSeparator: PropTypes.bool, /* Navigates to this URL when clicked */ href: PropTypes.string, /* String, name of Icon */ iconName: PropTypes.string.isRequired, /* Boolean, whether the link is highlighted * blue as the current active nav link */ isActive: PropTypes.bool, /* Boolean, whether navbar is open or closed */ isOpen: PropTypes.bool, /* Boolean, whether link is primary or secondary */ isSecondaryLink: PropTypes.bool, /* String or Node, description of url */ linkLabel: PropTypes.oneOfType([PropTypes.string, PropTypes.node]).isRequired, /* Function called when IconLink is clicked */ onClick: PropTypes.func, /* String, name of test data section */ testSection: PropTypes.string.isRequired, /* IconLink can be one of these types * LINK * PUSH_STATE * BUTTON */ type: PropTypes.oneOf([LINK, PUSH_STATE, BUTTON]), }; static defaultProps = { hasSeparator: false, href: "", isActive: false, isOpen: true, isSecondaryLink: false, hasExternalIcon: false, onClick: () => null, type: LINK, }; renderNavLink = () => { const { isActive, iconName, isOpen, isSecondaryLink, hasSeparator, hasExternalIcon, linkLabel } = this.props; const iconSize = isSecondaryLink ? "medium" : "large"; return ( <React.Fragment> {hasSeparator && <hr className="oui-rule push-double--sides" />} <Poptip content={linkLabel} disable={isOpen} isAnimated={false} position="right"> <div className={classNames("root-nav__link", { "is-active": isActive, "root-nav__link--primary": !isSecondaryLink, "root-nav__link--secondary": isSecondaryLink, "has-external-icon": hasExternalIcon, })} > <div className="flex"> <Icon name={iconName} size={iconSize} /> </div> <div className={classNames("root-nav__link__text", " truncate", { "root-nav-fader": !isOpen })}> {linkLabel} </div> {isOpen && hasExternalIcon && ( <div className="flex anchor--right root-nav__link-external-icon"> <Icon name={"external"} size={"small"} /> </div> )} </div> </Poptip> </React.Fragment> ); }; onAppRouteLinkClick = event => { const { href, onClick } = this.props; return onClick(href, event); }; renderAppRouteLink = () => { const { testSection, href } = this.props; return ( <Link style="reverse" href={href} onClick={this.onAppRouteLinkClick} testSection={`${testSection}-internal-link`} > {this.renderNavLink()} </Link> ); }; renderExternalLink = () => { const { testSection, href } = this.props; return ( <Link href={href} style="reverse" testSection={`${testSection}-external-link`}> {this.renderNavLink()} </Link> ); }; renderButton = () => { const { testSection, onClick } = this.props; return ( <Link onClick={onClick} style="reverse" testSection={`${testSection}-button`}> {this.renderNavLink()} </Link> ); }; render() { const { testSection, type } = this.props; let linkToRender; switch (type) { case PUSH_STATE: linkToRender = this.renderAppRouteLink(); break; case LINK: linkToRender = this.renderExternalLink(); break; case BUTTON: linkToRender = this.renderButton(); break; default: // Should never reach here linkToRender = null; } return ( <li className="display--inline-block" data-test-section={testSection}> {linkToRender} </li> ); } } export default IconLink;