Implement better pattern for hanling actions in context menu
[arvados-workbench2.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
8 export interface ContextMenuItem {
9     name: string;
10     icon: string;
11 }
12
13 export type ContextMenuItemGroup = ContextMenuItem[];
14
15 export interface ContextMenuProps {
16     anchorEl?: HTMLElement;
17     items: ContextMenuItemGroup[];
18     onItemClick: (action: ContextMenuItem) => void;
19     onClose: () => void;
20 }
21
22 export default class ContextMenu extends React.PureComponent<ContextMenuProps> {
23     render() {
24         const { anchorEl, items, onClose, onItemClick } = this.props;
25         return <Popover
26             anchorEl={anchorEl}
27             open={!!anchorEl}
28             onClose={onClose}
29             transformOrigin={DefaultTransformOrigin}
30             anchorOrigin={DefaultTransformOrigin}
31             onContextMenu={this.handleContextMenu}>
32             <List dense>
33                 {items.map((group, groupIndex) =>
34                     <React.Fragment key={groupIndex}>
35                         {group.map((item, actionIndex) =>
36                             <ListItem
37                                 button
38                                 key={actionIndex}
39                                 onClick={() => onItemClick(item)}>
40                                 <ListItemIcon>
41                                     <i className={item.icon} />
42                                 </ListItemIcon>
43                                 <ListItemText>
44                                     {item.name}
45                                 </ListItemText>
46                             </ListItem>)}
47                         {groupIndex < items.length - 1 && <Divider />}
48                     </React.Fragment>)}
49             </List>
50         </Popover>;
51     }
52
53     handleContextMenu = (event: React.MouseEvent<HTMLElement>) => {
54         event.preventDefault();
55         this.props.onClose();
56     }
57 }