Combined documents and collections in the sidepanel

This commit is contained in:
Jori Lallo
2017-09-17 23:45:40 -07:00
parent 53c0c9180b
commit 0a5f5712ef
13 changed files with 254 additions and 223 deletions

View File

@ -1,80 +1,98 @@
// @flow
import React from 'react';
import invariant from 'invariant';
import { observable } from 'mobx';
import { observer } from 'mobx-react';
import keydown from 'react-keydown';
import styled from 'styled-components';
import Portal from 'react-portal';
import Flex from 'components/Flex';
import { color } from 'styles/constants';
import { fadeAndScaleIn } from 'styles/animations';
type DropdownMenuProps = {
label: React.Element<any>,
onShow?: Function,
onClose?: Function,
children?: React.Element<any>,
style?: Object,
};
@observer class DropdownMenu extends React.Component {
props: DropdownMenuProps;
actionRef: Object;
@observable open: boolean = false;
@observable top: number;
@observable left: number;
@observable right: number;
handleClick = () => {
this.open = !this.open;
handleClick = (ev: SyntheticEvent) => {
ev.preventDefault();
ev.stopPropagation();
invariant(document.body, 'why you not here');
const bodyRect = document.body.getBoundingClientRect();
// $FlowIssue it's there
const targetRect = ev.currentTarget.getBoundingClientRect();
this.open = true;
this.top = targetRect.bottom - bodyRect.top;
this.right = bodyRect.width - targetRect.left - targetRect.width;
if (this.props.onShow) this.props.onShow();
};
@keydown('esc')
handleEscape() {
this.open = false;
}
handleClickOutside = (ev: SyntheticEvent) => {
ev.stopPropagation();
handleClose = (ev: SyntheticEvent) => {
this.open = false;
if (this.props.onClose) this.props.onClose();
};
render() {
const openAction = (
<Label
onClick={this.handleClick}
innerRef={ref => (this.actionRef = ref)}
>
{this.props.label}
</Label>
);
return (
<MenuContainer onClick={this.handleClick}>
{this.open && <Backdrop onClick={this.handleClickOutside} />}
<Label>
{this.props.label}
</Label>
{this.open &&
<Menu style={this.props.style}>
<div>
{openAction}
<Portal
closeOnEsc
closeOnOutsideClick
isOpened={this.open}
onClose={this.handleClose}
>
<Menu
style={this.props.style}
left={this.left}
top={this.top}
right={this.right}
>
{this.props.children}
</Menu>}
</MenuContainer>
</Menu>
</Portal>
</div>
);
}
}
const Backdrop = styled.div`
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 999;
`;
const Label = styled(Flex).attrs({
justify: 'center',
align: 'center',
})`
width: 22px;
height: 22px;
z-index: 1000;
cursor: pointer;
`;
const MenuContainer = styled.div`
position: relative;
`;
const Menu = styled.div`
animation: ${fadeAndScaleIn} 250ms ease;
transform-origin: 75% 0;
position: absolute;
right: 0;
right: ${({ right }) => right}px;
top: ${({ top }) => top}px;
z-index: 1000;
border: ${color.slateLight};
background: ${color.white};