2019-10-17 14:52:16 +00:00
|
|
|
import React from "react";
|
|
|
|
import styled, { css } from "styled-components";
|
|
|
|
import PropTypes from "prop-types";
|
|
|
|
import { Icons } from "../icons";
|
|
|
|
import DropDown from "../drop-down";
|
|
|
|
import DropDownItem from "../drop-down-item";
|
|
|
|
import { Text } from "../text";
|
|
|
|
import { handleAnyClick } from "../../utils/event";
|
2019-10-21 08:37:42 +00:00
|
|
|
import isEqual from "lodash/isEqual";
|
2019-10-17 14:52:16 +00:00
|
|
|
|
|
|
|
// eslint-disable-next-line no-unused-vars
|
|
|
|
const SimpleLinkWithDropdown = ({ isBold, fontSize, isTextOverflow, isHovered, isSemitransparent, color, title, dropdownType, data,
|
|
|
|
...props
|
|
|
|
}) => <a {...props}></a>;
|
|
|
|
|
|
|
|
SimpleLinkWithDropdown.propTypes = {
|
|
|
|
isBold: PropTypes.bool,
|
|
|
|
fontSize: PropTypes.number,
|
|
|
|
isTextOverflow: PropTypes.bool,
|
|
|
|
isHovered: PropTypes.bool,
|
|
|
|
isSemitransparent: PropTypes.bool,
|
|
|
|
color: PropTypes.string,
|
|
|
|
title: PropTypes.string,
|
|
|
|
dropdownType: PropTypes.oneOf(["alwaysDashed", "appearDashedAfterHover"]).isRequired,
|
|
|
|
data: PropTypes.array
|
|
|
|
};
|
2019-08-02 12:56:19 +00:00
|
|
|
|
2019-10-17 14:52:16 +00:00
|
|
|
const color = props => props.color;
|
2019-08-02 12:56:19 +00:00
|
|
|
|
2019-12-03 11:31:25 +00:00
|
|
|
// eslint-disable-next-line react/prop-types, no-unused-vars
|
2019-11-07 11:53:02 +00:00
|
|
|
const ExpanderDownIcon = ({ isSemitransparent, dropdownType, isOpen, ...props }) => (<Icons.ExpanderDownIcon {...props} />);
|
2019-08-02 12:56:19 +00:00
|
|
|
|
2019-10-17 14:52:16 +00:00
|
|
|
const Caret = styled(ExpanderDownIcon)`
|
2019-11-07 11:53:02 +00:00
|
|
|
width: 8px;
|
|
|
|
min-width: 8px;
|
|
|
|
height: 8px;
|
|
|
|
min-height: 8px;
|
2019-10-17 14:52:16 +00:00
|
|
|
margin-left: 5px;
|
|
|
|
margin-top: -4px;
|
|
|
|
|
|
|
|
position: absolute;
|
|
|
|
right: 6px;
|
|
|
|
top: 0;
|
|
|
|
bottom: 0;
|
|
|
|
margin: auto;
|
|
|
|
|
|
|
|
path {
|
|
|
|
fill: ${color};
|
|
|
|
}
|
|
|
|
|
|
|
|
${props => props.dropdownType === "appearDashedAfterHover" && `opacity: 0`};
|
2019-11-07 11:53:02 +00:00
|
|
|
|
|
|
|
${props => props.isOpen && `
|
|
|
|
bottom: -1px;
|
|
|
|
transform: scale(1, -1);
|
|
|
|
`}
|
2019-08-02 12:56:19 +00:00
|
|
|
`;
|
|
|
|
|
2019-10-17 14:52:16 +00:00
|
|
|
const StyledLinkWithDropdown = styled(SimpleLinkWithDropdown)`
|
2019-08-02 12:56:19 +00:00
|
|
|
|
2019-10-17 14:52:16 +00:00
|
|
|
cursor: pointer;
|
|
|
|
text-decoration: none;
|
|
|
|
user-select: none;
|
|
|
|
padding-right: 20px;
|
|
|
|
position: relative;
|
|
|
|
display: inline-grid;
|
2019-08-02 12:56:19 +00:00
|
|
|
|
2019-10-17 14:52:16 +00:00
|
|
|
color: ${color};
|
2019-08-02 12:56:19 +00:00
|
|
|
|
2019-10-17 14:52:16 +00:00
|
|
|
${props => props.isSemitransparent && `opacity: 0.5`};
|
|
|
|
${props => props.dropdownType === "alwaysDashed" && `text-decoration: underline dashed`};
|
2019-08-02 12:56:19 +00:00
|
|
|
|
2019-10-17 14:52:16 +00:00
|
|
|
&:not([href]):not([tabindex]) {
|
|
|
|
${props => props.dropdownType === "alwaysDashed" && `text-decoration: underline dashed`};
|
|
|
|
color: ${color};
|
2019-08-02 12:56:19 +00:00
|
|
|
|
2019-10-17 14:52:16 +00:00
|
|
|
&:hover {
|
|
|
|
text-decoration: underline dashed;
|
|
|
|
color: ${color};
|
2019-08-02 12:56:19 +00:00
|
|
|
}
|
2019-10-17 14:52:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
:hover {
|
|
|
|
color: ${color};
|
|
|
|
|
|
|
|
svg {
|
|
|
|
${props => props.dropdownType === "appearDashedAfterHover" && `position: absolute; opacity: 1`};
|
|
|
|
${props => props.isSemitransparent && `opacity: 0.5`};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-08-02 12:56:19 +00:00
|
|
|
`;
|
|
|
|
|
2019-11-07 10:45:36 +00:00
|
|
|
const SimpleText = ({ color, ...props }) => (<Text.Body as="span" {...props} />);
|
|
|
|
const StyledText = styled(SimpleText)`
|
2019-08-02 12:56:19 +00:00
|
|
|
|
2019-10-17 14:52:16 +00:00
|
|
|
color: ${color};
|
|
|
|
|
|
|
|
${props => props.isTextOverflow && css`
|
|
|
|
display: inline-block;
|
|
|
|
max-width: 100%;
|
|
|
|
`}
|
2019-08-02 12:56:19 +00:00
|
|
|
`;
|
|
|
|
|
2019-10-25 08:11:55 +00:00
|
|
|
const StyledSpan = styled.span`
|
|
|
|
position: relative;
|
|
|
|
`;
|
2019-10-21 08:37:42 +00:00
|
|
|
class LinkWithDropdown extends React.Component {
|
2019-08-02 12:56:19 +00:00
|
|
|
|
2019-10-17 14:52:16 +00:00
|
|
|
constructor(props) {
|
|
|
|
super(props);
|
2019-08-02 12:56:19 +00:00
|
|
|
|
2019-10-17 14:52:16 +00:00
|
|
|
this.state = {
|
2019-10-21 08:37:42 +00:00
|
|
|
isOpen: props.isOpen
|
2019-10-17 14:52:16 +00:00
|
|
|
};
|
2019-08-02 12:56:19 +00:00
|
|
|
|
2019-10-17 14:52:16 +00:00
|
|
|
this.ref = React.createRef();
|
2019-08-02 12:56:19 +00:00
|
|
|
|
2019-10-17 14:52:16 +00:00
|
|
|
this.handleClick = this.handleClick.bind(this);
|
|
|
|
this.toggleDropdown = this.toggleDropdown.bind(this);
|
|
|
|
this.onDropDownItemClick = this.onDropDownItemClick.bind(this);
|
2019-08-02 12:56:19 +00:00
|
|
|
|
2019-10-17 14:52:16 +00:00
|
|
|
if (props.isOpen) handleAnyClick(true, this.handleClick);
|
|
|
|
}
|
2019-08-02 12:56:19 +00:00
|
|
|
|
2019-10-17 14:52:16 +00:00
|
|
|
handleClick = e =>
|
|
|
|
this.state.isOpen &&
|
|
|
|
!this.ref.current.contains(e.target) &&
|
|
|
|
this.toggleDropdown(false);
|
2019-08-02 12:56:19 +00:00
|
|
|
|
2019-10-17 14:52:16 +00:00
|
|
|
toggleDropdown = isOpen => this.setState({ isOpen });
|
|
|
|
|
|
|
|
clickToDropdown = () => this.setState({ isOpen: !this.state.isOpen });
|
2019-08-02 12:56:19 +00:00
|
|
|
|
|
|
|
|
2019-10-17 14:52:16 +00:00
|
|
|
componentWillUnmount() {
|
|
|
|
handleAnyClick(false, this.handleClick);
|
|
|
|
}
|
|
|
|
|
|
|
|
componentDidUpdate(prevProps, prevState) {
|
|
|
|
if (this.props.dropdownType !== prevProps.dropdownType) {
|
|
|
|
if (this.props.isOpen !== prevProps.isOpen) {
|
|
|
|
this.toggleDropdown(this.props.isOpen);
|
|
|
|
}
|
|
|
|
} else if (this.props.isOpen !== prevProps.isOpen) {
|
|
|
|
this.toggleDropdown(this.props.isOpen);
|
2019-08-02 12:56:19 +00:00
|
|
|
}
|
|
|
|
|
2019-10-17 14:52:16 +00:00
|
|
|
if (this.state.isOpen !== prevState.isOpen) {
|
|
|
|
handleAnyClick(this.state.isOpen, this.handleClick);
|
2019-09-10 07:03:36 +00:00
|
|
|
}
|
2019-10-17 14:52:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
onDropDownItemClick = item => {
|
|
|
|
this.toggleDropdown(!this.state.isOpen);
|
2019-10-21 08:37:42 +00:00
|
|
|
item.onClick && item.onClick();
|
2019-10-17 14:52:16 +00:00
|
|
|
};
|
|
|
|
|
2019-10-21 08:37:42 +00:00
|
|
|
shouldComponentUpdate(nextProps, nextState) {
|
|
|
|
return !isEqual(this.props, nextProps) || !isEqual(this.state, nextState);
|
|
|
|
}
|
|
|
|
|
2019-10-17 14:52:16 +00:00
|
|
|
render() {
|
2019-10-21 08:37:42 +00:00
|
|
|
// console.log("LinkWithDropdown render");
|
2019-10-17 14:52:16 +00:00
|
|
|
|
|
|
|
const {
|
|
|
|
isSemitransparent,
|
|
|
|
dropdownType,
|
|
|
|
isTextOverflow,
|
|
|
|
fontSize,
|
|
|
|
color,
|
|
|
|
isBold,
|
2019-10-21 08:37:42 +00:00
|
|
|
title,
|
2019-11-07 09:19:34 +00:00
|
|
|
className,
|
2019-10-25 08:15:59 +00:00
|
|
|
data,
|
2019-12-03 11:31:25 +00:00
|
|
|
id,
|
|
|
|
style,
|
2019-10-21 08:37:42 +00:00
|
|
|
...rest
|
2019-10-17 14:52:16 +00:00
|
|
|
} = this.props;
|
|
|
|
return (
|
2019-11-07 09:19:34 +00:00
|
|
|
<StyledSpan
|
2019-12-03 11:31:25 +00:00
|
|
|
className={className}
|
|
|
|
id={id}
|
|
|
|
style={style}
|
|
|
|
>
|
2019-10-18 11:16:53 +00:00
|
|
|
<span
|
2019-10-17 14:52:16 +00:00
|
|
|
ref={this.ref}
|
|
|
|
onClick={this.clickToDropdown}
|
|
|
|
>
|
2019-10-18 11:16:53 +00:00
|
|
|
<StyledLinkWithDropdown
|
2019-10-17 14:52:16 +00:00
|
|
|
|
2019-10-18 11:16:53 +00:00
|
|
|
isSemitransparent={isSemitransparent}
|
2019-10-17 14:52:16 +00:00
|
|
|
dropdownType={dropdownType}
|
2019-10-18 11:16:53 +00:00
|
|
|
color={color}
|
|
|
|
>
|
|
|
|
<StyledText
|
|
|
|
isTextOverflow={isTextOverflow}
|
|
|
|
truncate={isTextOverflow}
|
|
|
|
fontSize={fontSize}
|
|
|
|
color={color}
|
|
|
|
isBold={isBold}
|
|
|
|
title={title}
|
|
|
|
dropdownType={dropdownType}
|
|
|
|
>
|
|
|
|
{this.props.children}
|
|
|
|
</StyledText>
|
|
|
|
|
|
|
|
<Caret
|
|
|
|
color={color}
|
|
|
|
dropdownType={dropdownType}
|
2019-11-07 11:53:02 +00:00
|
|
|
isOpen={this.state.isOpen}
|
2019-10-18 11:16:53 +00:00
|
|
|
/>
|
|
|
|
</StyledLinkWithDropdown>
|
|
|
|
</span>
|
2019-10-17 14:52:16 +00:00
|
|
|
|
2019-10-25 08:15:59 +00:00
|
|
|
<DropDown
|
2019-10-17 14:52:16 +00:00
|
|
|
isOpen={this.state.isOpen}
|
|
|
|
withArrow={false}
|
2019-10-21 08:37:42 +00:00
|
|
|
{...rest}
|
2019-10-17 14:52:16 +00:00
|
|
|
>
|
2019-10-25 08:15:59 +00:00
|
|
|
{data.map(item => (
|
2019-10-17 14:52:16 +00:00
|
|
|
<DropDownItem
|
|
|
|
key={item.key}
|
|
|
|
onClick={this.onDropDownItemClick.bind(this.props, item)}
|
|
|
|
{...item}
|
|
|
|
/>
|
|
|
|
))}
|
2019-10-25 08:15:59 +00:00
|
|
|
</DropDown>
|
2019-10-25 08:11:55 +00:00
|
|
|
</StyledSpan>
|
2019-10-17 14:52:16 +00:00
|
|
|
);
|
|
|
|
}
|
2019-08-02 12:56:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
LinkWithDropdown.propTypes = {
|
2019-10-17 14:52:16 +00:00
|
|
|
color: PropTypes.string,
|
|
|
|
data: PropTypes.array,
|
|
|
|
dropdownType: PropTypes.oneOf(["alwaysDashed", "appearDashedAfterHover"]).isRequired,
|
|
|
|
fontSize: PropTypes.number,
|
|
|
|
isBold: PropTypes.bool,
|
|
|
|
isSemitransparent: PropTypes.bool,
|
|
|
|
isTextOverflow: PropTypes.bool,
|
|
|
|
title: PropTypes.string,
|
|
|
|
isOpen: PropTypes.bool,
|
2019-11-07 09:19:34 +00:00
|
|
|
children: PropTypes.any,
|
2019-12-03 11:31:25 +00:00
|
|
|
className: PropTypes.string,
|
|
|
|
id: PropTypes.string,
|
|
|
|
style: PropTypes.oneOfType([PropTypes.object, PropTypes.array])
|
2019-08-02 12:56:19 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
LinkWithDropdown.defaultProps = {
|
2019-10-17 14:52:16 +00:00
|
|
|
color: "#333333",
|
|
|
|
data: [],
|
|
|
|
dropdownType: "alwaysDashed",
|
|
|
|
fontSize: 13,
|
|
|
|
isBold: false,
|
|
|
|
isSemitransparent: false,
|
2019-10-21 08:37:42 +00:00
|
|
|
isTextOverflow: true,
|
2019-11-07 09:19:34 +00:00
|
|
|
isOpen: false,
|
|
|
|
className: "",
|
2019-10-17 14:52:16 +00:00
|
|
|
};
|
2019-08-02 12:56:19 +00:00
|
|
|
|
|
|
|
export default LinkWithDropdown;
|