Implement better pattern for hanling actions in context menu
[arvados.git] / src / components / popover / popover.tsx
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 import * as React from 'react';
6 import { Popover as MaterialPopover } from '@material-ui/core';
7
8 import { PopoverOrigin } from '@material-ui/core/Popover';
9 import IconButton, { IconButtonProps } from '@material-ui/core/IconButton';
10
11 export interface PopoverProps {
12     triggerComponent?: React.ComponentType<{ onClick: (event: React.MouseEvent<any>) => void }>;
13     closeOnContentClick?: boolean;
14 }
15
16
17 class Popover extends React.Component<PopoverProps> {
18
19     state = {
20         anchorEl: undefined
21     };
22
23     transformOrigin: PopoverOrigin = {
24         vertical: "top",
25         horizontal: "right",
26     };
27
28     render() {
29         const Trigger = this.props.triggerComponent || DefaultTrigger;
30         return (
31             <>
32                 <Trigger onClick={this.handleTriggerClick} />
33                 <MaterialPopover
34                     anchorEl={this.state.anchorEl}
35                     open={Boolean(this.state.anchorEl)}
36                     onClose={this.handleClose}
37                     onClick={this.handleSelfClick}
38                     transformOrigin={this.transformOrigin}
39                     anchorOrigin={this.transformOrigin}
40                 >
41                     {this.props.children}
42                 </MaterialPopover>
43             </>
44         );
45     }
46
47     handleClose = () => {
48         this.setState({ anchorEl: undefined });
49     }
50
51     handleTriggerClick = (event: React.MouseEvent<any>) => {
52         this.setState({ anchorEl: event.currentTarget });
53     }
54
55     handleSelfClick = () => {
56         if (this.props.closeOnContentClick) {
57             this.handleClose();
58         }
59     }
60
61 }
62
63 export const DefaultTrigger: React.SFC<IconButtonProps> = (props) => (
64     <IconButton {...props}>
65         <i className="fas" />
66     </IconButton>
67 );
68
69 export default Popover;