zepio/app/components/dropdown.js

110 lines
2.5 KiB
JavaScript
Raw Normal View History

2018-12-10 12:51:22 -08:00
// @flow
import React, { type Node, Component } from 'react';
import styled from 'styled-components';
/* eslint-disable import/no-extraneous-dependencies */
// $FlowFixMe
import { darken } from 'polished';
import Popover from 'react-popover';
import ClickOutside from 'react-click-outside';
import { TextComponent } from './text';
/* eslint-disable max-len */
const MenuWrapper = styled.div`
2018-12-15 07:10:39 -08:00
background-image: ${props => `linear-gradient(to right, ${darken(
0.05,
props.theme.colors.activeItem,
)}, ${props.theme.colors.activeItem})`};
2018-12-10 16:52:45 -08:00
padding: 10px 20px;
2018-12-10 12:51:22 -08:00
border-radius: 10px;
margin-left: -10px;
`;
const MenuItem = styled.button`
outline: none;
background-color: transparent;
border: none;
border-bottom-style: solid;
border-bottom-color: ${props => props.theme.colors.text};
border-bottom-width: 1px;
padding: 15px 0;
cursor: pointer;
width: 100%;
2018-12-10 16:52:45 -08:00
text-align: left;
2018-12-10 12:51:22 -08:00
&:hover {
opacity: 0.9;
}
2018-12-10 16:52:45 -08:00
&:disabled {
cursor: default;
&:hover {
opacity: 1;
}
}
2018-12-10 12:51:22 -08:00
`;
const PopoverWithStyle = styled(Popover)`
& > .Popover-tip {
fill: ${props => props.theme.colors.activeItem};
}
`;
type Props = {
2018-12-10 13:23:04 -08:00
renderTrigger: (toggleVisibility: () => void, isOpen: boolean) => Node,
2018-12-10 12:51:22 -08:00
options: Array<{ label: string, onClick: () => void }>,
2018-12-10 16:52:45 -08:00
label?: string | null,
2018-12-10 12:51:22 -08:00
};
type State = {
isOpen: boolean,
};
2018-12-10 13:23:04 -08:00
export class DropdownComponent extends Component<Props, State> {
2018-12-10 12:51:22 -08:00
state = {
isOpen: false,
};
2018-12-10 16:52:45 -08:00
static defaultProps = {
label: null,
};
2018-12-10 12:51:22 -08:00
render() {
const { isOpen } = this.state;
const { label, options, renderTrigger } = this.props;
2018-12-10 12:51:22 -08:00
return (
<PopoverWithStyle
isOpen={isOpen}
2018-12-10 12:51:22 -08:00
preferPlace='below'
enterExitTransitionDurationMs={0}
2018-12-10 12:51:22 -08:00
body={[
2018-12-15 07:10:39 -08:00
<ClickOutside
onClickOutside={() => this.setState(() => ({ isOpen: false }))}
>
2018-12-10 12:51:22 -08:00
<MenuWrapper>
{label && (
2018-12-10 16:52:45 -08:00
<MenuItem disabled>
<TextComponent value={label} isBold />
2018-12-10 16:52:45 -08:00
</MenuItem>
)}
{options.map(({ label: optionLabel, onClick }) => (
2018-12-19 05:49:30 -08:00
<MenuItem onClick={onClick} key={optionLabel}>
<TextComponent value={optionLabel} />
2018-12-10 12:51:22 -08:00
</MenuItem>
))}
</MenuWrapper>
</ClickOutside>,
]}
2018-12-10 16:52:45 -08:00
tipSize={7}
2018-12-10 12:51:22 -08:00
>
2018-12-15 07:10:39 -08:00
{renderTrigger(
() => this.setState(state => ({ isOpen: !state.isOpen })),
isOpen,
)}
2018-12-10 12:51:22 -08:00
</PopoverWithStyle>
);
}
}