Popover
Summary: _typescript_ Reviewed By: priteshrnandgaonkar Differential Revision: D16828816 fbshipit-source-id: e90852fcebd02416c3d5cfd8011bb96d2ea0d672
This commit is contained in:
committed by
Facebook Github Bot
parent
f8e357d2c1
commit
aee3ab86cf
102
src/ui/components/Popover.tsx
Normal file
102
src/ui/components/Popover.tsx
Normal file
@@ -0,0 +1,102 @@
|
||||
/**
|
||||
* Copyright 2018-present Facebook.
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
* @format
|
||||
*/
|
||||
|
||||
import React, {PureComponent} from 'react';
|
||||
import FlexColumn from './FlexColumn.js';
|
||||
import styled from 'react-emotion';
|
||||
import {colors} from './colors';
|
||||
|
||||
const Anchor = styled('img')({
|
||||
zIndex: 6,
|
||||
position: 'absolute',
|
||||
bottom: 0,
|
||||
left: '50%',
|
||||
transform: 'translate(-50%, calc(100% + 2px))',
|
||||
});
|
||||
|
||||
type Opts = {
|
||||
minWidth?: number;
|
||||
skewLeft?: boolean;
|
||||
};
|
||||
|
||||
const PopoverContainer = styled(FlexColumn)((props: {opts?: Opts}) => ({
|
||||
backgroundColor: colors.white,
|
||||
borderRadius: 7,
|
||||
border: '1px solid rgba(0,0,0,0.3)',
|
||||
boxShadow: '0 2px 10px 0 rgba(0,0,0,0.3)',
|
||||
position: 'absolute',
|
||||
zIndex: 5,
|
||||
bottom: 0,
|
||||
marginTop: 15,
|
||||
left: '50%',
|
||||
minWidth: props.opts.minWidth || 'auto',
|
||||
transform: props.opts.skewLeft
|
||||
? 'translate(calc(-100% + 22px), calc(100% + 15px))'
|
||||
: 'translate(-50%, calc(100% + 15px))',
|
||||
overflow: 'hidden',
|
||||
'&::before': {
|
||||
content: '""',
|
||||
display: 'block',
|
||||
position: 'absolute',
|
||||
left: '50%',
|
||||
transform: props.opts.skewLeft
|
||||
? 'translateX(calc(-100% + 22px))'
|
||||
: 'translateX(-50%)',
|
||||
height: 13,
|
||||
top: -13,
|
||||
width: 26,
|
||||
backgroundColor: colors.white,
|
||||
},
|
||||
}));
|
||||
|
||||
type Props = {
|
||||
children: React.ReactNode;
|
||||
onDismiss: Function;
|
||||
forceOpts?: Opts;
|
||||
};
|
||||
|
||||
export default class Popover extends PureComponent<Props> {
|
||||
_ref: Element | undefined;
|
||||
|
||||
componentDidMount() {
|
||||
window.document.addEventListener('click', this.handleClick);
|
||||
window.document.addEventListener('keydown', this.handleKeydown);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
window.document.addEventListener('click', this.handleClick);
|
||||
window.document.addEventListener('keydown', this.handleKeydown);
|
||||
}
|
||||
|
||||
handleClick = (e: KeyboardEvent) => {
|
||||
if (this._ref && !this._ref.contains(e.target as Node)) {
|
||||
this.props.onDismiss();
|
||||
}
|
||||
};
|
||||
|
||||
handleKeydown = (e: KeyboardEvent) => {
|
||||
if (e.key === 'Escape') {
|
||||
this.props.onDismiss();
|
||||
}
|
||||
};
|
||||
|
||||
_setRef = (ref: Element | undefined) => {
|
||||
this._ref = ref;
|
||||
};
|
||||
|
||||
render() {
|
||||
return [
|
||||
<Anchor src="./anchor.svg" key="anchor" />,
|
||||
<PopoverContainer
|
||||
innerRef={this._setRef}
|
||||
key="popup"
|
||||
opts={this.props.forceOpts || {}}>
|
||||
{this.props.children}
|
||||
</PopoverContainer>,
|
||||
];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user