go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/analysis/frontend/ui/src/components/top_bar/collapsed_menu/collapsed_menu.tsx (about) 1 // Copyright 2022 The LUCI Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 import React, { useContext } from 'react'; 16 import { Link } from 'react-router-dom'; 17 18 import MenuIcon from '@mui/icons-material/Menu'; 19 import Box from '@mui/material/Box'; 20 import IconButton from '@mui/material/IconButton'; 21 import ListItemIcon from '@mui/material/ListItemIcon'; 22 import ListItemText from '@mui/material/ListItemText'; 23 import Menu from '@mui/material/Menu'; 24 import MenuItem from '@mui/material/MenuItem'; 25 import Typography from '@mui/material/Typography'; 26 27 import Logo from '@/components/top_bar/logo/logo'; 28 import { AppBarPage } from '@/components/top_bar/top_bar'; 29 import { TopBarContext } from '@/components/top_bar/top_bar_context'; 30 import { DynamicComponentNoProps } from '@/tools/rendering_tools'; 31 32 interface Props { 33 pages: AppBarPage[]; 34 } 35 36 // A menu that is collapsed on mobile. 37 const CollapsedMenu = ({ pages }: Props) => { 38 const { anchorElNav, setAnchorElNav } = useContext(TopBarContext); 39 40 const handleOpenNavMenu = (event: React.MouseEvent<HTMLElement>) => { 41 setAnchorElNav(event.currentTarget); 42 }; 43 44 const handleCloseNavMenu = () => { 45 setAnchorElNav(null); 46 }; 47 48 return ( 49 <> 50 <Box sx={{ flexGrow: 1, display: { xs: 'flex', md: 'none' } }}> 51 <IconButton 52 size="large" 53 aria-label="pages menu" 54 aria-controls="menu-appbar" 55 aria-haspopup="true" 56 onClick={handleOpenNavMenu} 57 color="inherit" 58 data-testid="collapsed-menu-button" 59 > 60 <MenuIcon /> 61 </IconButton> 62 <Menu 63 id="menu-appbar" 64 keepMounted 65 anchorEl={anchorElNav} 66 anchorOrigin={{ 67 vertical: 'bottom', 68 horizontal: 'left', 69 }} 70 transformOrigin={{ 71 vertical: 'top', 72 horizontal: 'left', 73 }} 74 open={Boolean(anchorElNav)} 75 onClose={handleCloseNavMenu} 76 sx={{ 77 display: { xs: 'block', md: 'none' }, 78 }} 79 data-testid="collapsed-menu" 80 > 81 {pages.map((page) => ( 82 <MenuItem 83 component={Link} 84 to={page.url} 85 key={page.title} 86 onClick={handleCloseNavMenu}> 87 <ListItemIcon> 88 <DynamicComponentNoProps component={page.icon} /> 89 </ListItemIcon> 90 <ListItemText>{page.title}</ListItemText> 91 </MenuItem> 92 ))} 93 </Menu> 94 </Box> 95 <Box sx={{ 96 display: { 97 xs: 'flex', 98 md: 'none' }, 99 mr: 1, 100 width: '3rem', 101 }}> 102 <Logo /> 103 </Box> 104 <Typography 105 variant="h5" 106 noWrap 107 component="a" 108 href="" 109 sx={{ 110 mr: 2, 111 display: { xs: 'flex', md: 'none' }, 112 flexGrow: 1, 113 color: 'inherit', 114 textDecoration: 'none', 115 }} 116 > 117 LUCI Analysis 118 </Typography> 119 </> 120 ); 121 }; 122 123 export default CollapsedMenu;