score:1
You can use Material-UI's ClickAwayListener for this. The only tricky part is avoiding an immediate close of your menu after clicking on the button to open the menu (because of the click event being handled by the button opening the menu and then the same click event being handled by the ClickAwayListener closing the menu). Typically you would want to avoid rendering the ClickAwayListener
until the menu is open, but I think that might break the transition on the menu unless you did further changes. My example addresses this problem by calling event.stopPropagation()
in the click handler for the menu button (handleOpen
).
Here's a modified version of your code/sandbox demonstrating this:
import React, { useState } from "react";
import { Link } from "react-router-dom";
import {
AppBar,
Container,
ClickAwayListener,
createStyles,
IconButton,
makeStyles,
Theme,
Toolbar,
Typography
} from "@material-ui/core";
import MenuIcon from "@material-ui/icons/Menu";
import clsx from "clsx";
const useStyles = makeStyles((theme: Theme) =>
createStyles({
root: {
flexGrow: 1,
"& a": {
color: "white",
textDecoration: "none"
}
},
menuButton: {
marginRight: theme.spacing(2),
zIndex: 2
},
title: {
flexGrow: 1,
zIndex: 2
},
toolBar: {
"& div": {
transition: "left .1s"
}
},
menu: {
zIndex: 1,
width: 200,
height: "100%",
position: "fixed",
top: 48,
transition: "left .1s",
marginRight: theme.spacing(2),
left: -200,
background: "#3f51b5",
"& div:first-element": {
marginTop: 100
}
},
menuOpen: {
left: 0,
transition: "left .1s"
},
menuClose: {
left: -200,
transition: "left .1s"
},
topMenu: {
display: "flex",
"& div": {
marginLeft: theme.spacing(1)
}
}
})
);
const UserMenu = () => {
const classes = useStyles();
const [menuOpen, setMenuOpen] = useState(false);
const handleOpen = (event: React.MouseEvent) => {
if (!menuOpen) {
event.stopPropagation();
setMenuOpen(true);
}
};
const handleClose = (event: React.MouseEvent<any, MouseEvent>) => {
if (menuOpen) {
setMenuOpen(false);
}
};
return (
<>
<IconButton
edge="start"
className={classes.menuButton}
color="inherit"
aria-label="menu"
onClick={handleOpen}
>
<MenuIcon />
</IconButton>
<div className={classes.toolBar}>
<ClickAwayListener onClickAway={handleClose}>
<Container
className={clsx(classes.menu, {
[classes.menuOpen]: menuOpen,
[classes.menuClose]: !menuOpen,
[classes.toolBar]: true
})}
onClick={handleClose}
>
<div>
<Link to="#">My Profile</Link>
</div>
<div>
<Link to="#">Account</Link>
</div>
<div>
<Link to="#">Admin</Link>
</div>
</Container>
</ClickAwayListener>
</div>
</>
);
};
const Header: React.FC = ({ children }) => {
const classes = useStyles();
return (
<AppBar position="static" className={classes.root}>
<Toolbar variant="dense">
<UserMenu />
<Typography variant="h6" className={classes.title}>
<Link to="#">Widgets, LLC</Link>
</Typography>
<div className={classes.topMenu}>
<div>
<Link to="#">Sign out</Link>
</div>
<div>
<Link to="#">One more</Link>
</div>
</div>
</Toolbar>
</AppBar>
);
};
export default Header;
Source: stackoverflow.com
Related Query
- How to make a custom menu close when I click somewhere else other than the menu
- How to make dropdown close or open when I click on the button when there is ref used? (React)
- How to make one table record editable on button click in React when the table record is mapped?
- How to make a loading animation that shows up when you click on a button? It should take up the full screen & should be from right to left & disappear
- I'm trying to close the offcanvas menu in React Bootstrap when I click a link
- React Js how to jump whole pages to other pages when click on the navigation button
- Input field (using downshift) is clearing the entered data when click on div other than submit and input field
- When selecting an option in a dropdown, how do I change the state with onChange but with a value other than the one inside the option tags
- How do I add a title and close button to the top of a menu (above the 1st item in a button menu when clicked in material-ui?
- How do I stop the react-select input dropdown menu from opening when click the isClearable icon (mobile only)?
- How to change the menu item's color of sidebar when we click on it with Material-UI in React?
- How Do I make my Nav Menu option change color or background when I click on it using Javascript only?
- How do i access another column from related table other than the foreign key, when creating an API view
- How to close sidenav when I click anywhere of the page in react js
- Insert a component when clicked and remove the componet when click other than that component
- React Hooks. How to make other items(beside current one) deactivate when i click
- How to close mobile menu in react when click on link?
- How to add event listener to a component and remove it when the user click anywhere else in the window?
- How to get Bootstrap menu to close upon click when using NavLinks in React Router?
- How can I see the other users information when I click the button?
- How to show the input field value when we click on the other conversation based on userid using reactjs?
- How do I make the navbar disappear when I click away
- How to change the menu item's color of sidebar when we click on it with css in React pls
- How can I prevent the button from triggering the other button when I click it? &React
- How do I add a transition to my navbar menu in react when I click the toggle button
- how to close the menu when clicked
- How to load the js and css files from other than root when creating a build?
- When i click the menu in drop down, How can i be able to pass value and hit second api?
- How to make a dropdown menu open below the Appbar using Material-UI?
- How can I create a custom page with #react-admin without the menu sidebar like login page?
More Query from same tag
- getting undefined error on useRef() in react-js
- Image from json file is not displayed on the website
- Password validation in reactjs
- React route exact not work if I have child route in React router v5
- React useEffect run conditionally
- React hooks not working when imported from local library
- How to change route without re-rendering in Next.js?
- how to do Validation Require for image field in react js
- React; How to get the width of React-Alert adjust based on the alert text
- Input type number with comma React
- Get linebreaks/indents with react.renderToStaticMarkup?
- Can't get transitions to work in Gatsby using graphQL and createPages
- React - What am i doing wrong about checkbox and axios?
- Why is my axios get call repeating over and over using React.useEffect to fetch from Rails backend?
- Display image with react from strapi
- (React js) Audio src is updating on setState but the audio playing doesn't change
- Date-Picker component not working on a modal in React-js
- How to enforce presence of searchParams on react-router-v6 route?
- Not able to create theme using Material UI's ThemeProvider and createTheme
- Cannot read property 0 of undefined - even with Conditional rendering
- Couldn't use the same classname across components. CSS is not being scoped inside a style component
- component doesn't update after state update
- Page refresh before the express - Node js function ends
- TypeError: Cannot read property 'split' of undefined in nodejs nodemon
- ReactJS: How to create a slider that act as an ON/OFF button
- react testing, userEvent not working properly
- Axios POST does not recognize the data being passed in from react
- How to change colour and position of Navbar using useEffect and useState?
- Cant get the value of <li> tag in my handler function
- SyntaxError: unknown: Namespace tags are not supported by default