Merge branch '14098-log-view'
[arvados.git] / src / components / context-menu / context-menu.tsx
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4 import * as React from "react";
5 import { Popover, List, ListItem, ListItemIcon, ListItemText, Divider } from "@material-ui/core";
6 import { DefaultTransformOrigin } from "../popover/helpers";
7 import { IconType } from "../icon/icon";
8
9 export interface ContextMenuItem {
10     name?: string | React.ComponentType;
11     icon?: IconType;
12     component?: React.ComponentType<any>;
13 }
14
15 export type ContextMenuItemGroup = ContextMenuItem[];
16
17 export interface ContextMenuProps {
18     anchorEl?: HTMLElement;
19     items: ContextMenuItemGroup[];
20     open: boolean;
21     onItemClick: (action: ContextMenuItem) => void;
22     onClose: () => void;
23 }
24
25 export class ContextMenu extends React.PureComponent<ContextMenuProps> {
26     render() {
27         const { anchorEl, items, open, onClose, onItemClick } = this.props;
28         return <Popover
29             anchorEl={anchorEl}
30             open={open}
31             onClose={onClose}
32             transformOrigin={DefaultTransformOrigin}
33             anchorOrigin={DefaultTransformOrigin}
34             onContextMenu={this.handleContextMenu}>
35             <List dense>
36                 {items.map((group, groupIndex) =>
37                     <React.Fragment key={groupIndex}>
38                         {group.map((item, actionIndex) =>
39                             item.component
40                                 ? <item.component
41                                     key={actionIndex}
42                                     onClick={() => onItemClick(item)} />
43                                 : <ListItem
44                                     button
45                                     key={actionIndex}
46                                     onClick={() => onItemClick(item)}>
47                                     {item.icon &&
48                                         <ListItemIcon>
49                                             <item.icon />
50                                         </ListItemIcon>}
51                                     {item.name &&
52                                         <ListItemText>
53                                             {item.name}
54                                         </ListItemText>}
55                                 </ListItem>)}
56                         {groupIndex < items.length - 1 && <Divider />}
57                     </React.Fragment>)}
58             </List>
59         </Popover>;
60     }
61
62     handleContextMenu = (event: React.MouseEvent<HTMLElement>) => {
63         event.preventDefault();
64         this.props.onClose();
65     }
66 }