merge master
[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                             <ListItem
40                                 button
41                                 key={actionIndex}
42                                 onClick={() => onItemClick(item)}>
43                                 {item.icon &&
44                                     <ListItemIcon>
45                                         <item.icon />
46                                     </ListItemIcon>}
47                                 {item.name &&
48                                     <ListItemText>
49                                         {item.name}
50                                     </ListItemText>}
51                                 {item.component &&
52                                     <item.component />}
53                             </ListItem>)}
54                         {groupIndex < items.length - 1 && <Divider />}
55                     </React.Fragment>)}
56             </List>
57         </Popover>;
58     }
59
60     handleContextMenu = (event: React.MouseEvent<HTMLElement>) => {
61         event.preventDefault();
62         this.props.onClose();
63     }
64 }