// @flow import * as React from "react"; import { observable, action } from "mobx"; import { observer } from "mobx-react"; import { withRouter, NavLink } from "react-router-dom"; import { CollapsedIcon } from "outline-icons"; import styled, { withTheme } from "styled-components"; import Flex from "components/Flex"; type Props = { to?: string | Object, href?: string | Object, onClick?: (SyntheticEvent<>) => void, children?: React.Node, icon?: React.Node, expanded?: boolean, label?: React.Node, menu?: React.Node, menuOpen?: boolean, hideDisclosure?: boolean, iconColor?: string, active?: boolean, theme: Object, exact?: boolean, depth?: number, }; @observer class SidebarLink extends React.Component { @observable expanded: ?boolean = this.props.expanded; style = { paddingLeft: `${(this.props.depth || 0) * 16 + 16}px`, }; componentWillReceiveProps(nextProps: Props) { if (nextProps.expanded !== undefined) { this.expanded = nextProps.expanded; } } @action handleClick = (ev: SyntheticEvent<>) => { ev.preventDefault(); ev.stopPropagation(); this.expanded = !this.expanded; }; @action handleExpand = () => { this.expanded = true; }; render() { const { icon, children, onClick, to, label, active, menu, menuOpen, hideDisclosure, exact, href, } = this.props; const showDisclosure = !!children && !hideDisclosure; const activeStyle = { color: this.props.theme.text, background: this.props.theme.sidebarItemBackground, fontWeight: 600, ...this.style, }; return ( {icon && {icon}} {menu && {menu}} {this.expanded && children} ); } } // accounts for whitespace around icon const IconWrapper = styled.span` margin-left: -4px; margin-right: 4px; height: 24px; `; const Action = styled.span` display: ${props => (props.menuOpen ? "inline" : "none")}; position: absolute; top: 4px; right: 4px; color: ${props => props.theme.textTertiary}; svg { opacity: 0.75; } &:hover { svg { opacity: 1; } } `; const StyledNavLink = styled(NavLink)` display: flex; position: relative; overflow: hidden; text-overflow: ellipsis; padding: 4px 16px; border-radius: 4px; color: ${props => props.theme.sidebarText}; font-size: 15px; cursor: pointer; &:hover { color: ${props => props.theme.text}; } &:focus { color: ${props => props.theme.text}; background: ${props => props.theme.black05}; outline: none; } &:hover { > ${Action} { display: inline; } } `; const Wrapper = styled(Flex)` position: relative; `; const Label = styled.div` position: relative; width: 100%; max-height: 4.8em; line-height: 1.6; `; const Disclosure = styled(CollapsedIcon)` position: absolute; left: -24px; ${({ expanded }) => !expanded && "transform: rotate(-90deg);"}; `; export default withRouter(withTheme(SidebarLink));