1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
5 import React, { useState, useMemo, ReactElement, JSXElementConstructor } from 'react';
6 import { DoubleRightArrows } from 'components/icon/icon';
7 import classnames from 'classnames';
8 import { CustomStyleRulesCallback } from 'common/custom-theme';
9 import { IconButton, Menu, MenuItem, Tooltip } from '@mui/material';
10 import { WithStyles } from '@mui/styles';
11 import withStyles from '@mui/styles/withStyles';
12 import { ArvadosTheme } from 'common/custom-theme';
14 type CssRules = 'inOverflowMenu' | 'openMenuButton' | 'menu' | 'menuItem' | 'menuElement';
16 const styles: CustomStyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
19 backgroundColor: 'transparent',
30 backgroundColor: 'white',
42 export type OverflowChild = ReactElement<{ className: string; }, string | JSXElementConstructor<any>>
44 type OverflowMenuProps = {
45 children: OverflowChild[]
50 export const OverflowMenu = withStyles(styles)((props: OverflowMenuProps & WithStyles<CssRules>) => {
51 const { children, className, visibilityMap, classes } = props;
52 const [anchorEl, setAnchorEl] = useState(null);
53 const open = Boolean(anchorEl);
54 const handleClick = (event) => {
55 setAnchorEl(event.currentTarget);
58 const handleClose = () => {
62 const shouldShowMenu = useMemo(() => Object.values(visibilityMap).some((v) => v === false), [visibilityMap]);
63 if (!shouldShowMenu) {
67 <div className={className}>
68 <Tooltip title="More options" disableFocusListener>
71 aria-controls='long-menu'
74 className={classes.openMenuButton}
75 data-cy='overflow-menu-button'
87 className={classes.menu}
88 data-cy='overflow-menu'
90 {React.Children.map(children, (child: any) => {
91 if (!visibilityMap[child.props['data-targetid']]) {
95 className={classes.menuItem}
97 {React.cloneElement(child, {
98 className: classnames(classes.menuElement),