21317: added menu types Arvados-DCO-1.1-Signed-off-by: Lisa Knox <lisa.knox@curii...
[arvados.git] / services / workbench2 / src / components / multiselect-toolbar / ms-toolbar-overflow-menu.tsx
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 import React, { useState, useMemo, ReactElement, JSXElementConstructor } from 'react';
6 import { DoubleRightArrows } from 'components/icon/icon';
7 import classnames from 'classnames';
8 import { IconButton, Menu, MenuItem, StyleRulesCallback, Tooltip, WithStyles, withStyles } from '@material-ui/core';
9 import { ArvadosTheme } from 'common/custom-theme';
10
11 type CssRules = 'inOverflowMenu' | 'openMenuButton' | 'menu';
12
13 const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
14     inOverflowMenu: {
15         '&:hover': {
16             backgroundColor: 'transparent',
17         },
18     },
19     openMenuButton: {
20         right: '10px',
21     },
22     menu: {
23     }
24 });
25
26 export type OverflowChild = ReactElement<{ className: string; }, string | JSXElementConstructor<any>>
27
28 type OverflowMenuProps = {
29     children: OverflowChild[]
30     className: string
31     visibilityMap: {}
32 }
33
34 export const OverflowMenu = withStyles(styles)((props: OverflowMenuProps & WithStyles<CssRules>) => {
35     const { children, className, visibilityMap, classes } = props;
36     const [anchorEl, setAnchorEl] = useState(null);
37     const open = Boolean(anchorEl);
38     const handleClick = (event) => {
39         setAnchorEl(event.currentTarget);
40     };
41
42     const handleClose = () => {
43         setAnchorEl(null);
44     };
45
46     const shouldShowMenu = useMemo(() => Object.values(visibilityMap).some((v) => v === false), [visibilityMap]);
47     if (!shouldShowMenu) {
48         return null;
49     }
50     return (
51         <div className={className}>
52             <Tooltip title="More Options" disableFocusListener>
53                 <IconButton
54                     aria-label='more'
55                     aria-controls='long-menu'
56                     aria-haspopup='true'
57                     onClick={handleClick}
58                     className={classes.openMenuButton}
59                 >
60                         <DoubleRightArrows />
61                 </IconButton>
62             </Tooltip>
63             <Menu
64                 id='long-menu'
65                 anchorEl={anchorEl}
66                 keepMounted
67                 open={open}
68                 onClose={handleClose}
69             >
70                 {React.Children.map(children, (child: any) => {
71                     if (!visibilityMap[child.props['data-targetid']]) {
72                         return (
73                             <MenuItem
74                                 key={child}
75                                 onClick={handleClose}
76                             >
77                                 {React.cloneElement(child, {
78                                     className: classnames(child.className, classes.inOverflowMenu),
79                                 })}
80                             </MenuItem>
81                         );
82                     }
83                     return null;
84                 })}
85             </Menu>
86         </div>
87     );
88 });