material-ui-popup-state change button color - reactjs

I am using material-ui-popup-state to create a material ui drop down menu
In my Navbar.js i call <HoverMenu /> component
HoverMen.js is as follows
import * as React from 'react';
import withStyles from '#material-ui/core/styles/withStyles';
import Menu from 'material-ui-popup-state/HoverMenu';
import MenuItem from '#material-ui/core/MenuItem';
import ChevronRight from '#material-ui/icons/ChevronRight';
import ClickAwayListener from '#material-ui/core/ClickAwayListener';
import { Link } from 'react-router-dom';
import PopupState, {
bindHover,
bindMenu,
bindToggle
} from 'material-ui-popup-state';
import IconButton from '#material-ui/core/IconButton';
import MenuIcon from '#material-ui/icons/Menu';
const ParentPopupState = React.createContext(null);
const menuStyles = theme => ({
button: {
color: 'white'
}
});
const HoverMenu = () => (
<PopupState variant="popover" popupId="demoMenu">
{popupState => (
<ClickAwayListener onClickAway={popupState.close}>
<div>
<IconButton edge="start" {...bindToggle(popupState)}>
<MenuIcon />
</IconButton>
<ParentPopupState.Provider value={popupState}>
<Menu
{...bindMenu(popupState)}
anchorOrigin={{ vertical: 'bottom', horizontal: 'left' }}
transformOrigin={{ vertical: 'top', horizontal: 'left' }}
getContentAnchorEl={null}
>
<MenuItem onClick={popupState.close} to="/" component={Link}>
Home
</MenuItem>
<MenuItem onClick={popupState.close} to="/about" component={Link}>
About
</MenuItem>
<Submenu popupId="contribute" title="Contribute">
<MenuItem
onClick={popupState.close}
to="/donate"
component={Link}
>
To Samidoun
</MenuItem>
<MenuItem onClick={popupState.close}>To Benificiary</MenuItem>
<MenuItem
onClick={popupState.close}
to="/musicians"
component={Link}
>
To Musicians
</MenuItem>
</Submenu>
<MenuItem onClick={popupState.close} to="/" component={Link}>
Volunteer
</MenuItem>
<MenuItem
onClick={popupState.close}
to="/contact"
component={Link}
>
Contact
</MenuItem>
</Menu>
</ParentPopupState.Provider>
</div>
</ClickAwayListener>
)}
</PopupState>
);
export default HoverMenu;
const submenuStyles = theme => ({
menu: {
marginTop: theme.spacing(-1)
},
title: {
flexGrow: 1
},
moreArrow: {
marginRight: theme.spacing(-1)
}
});
const Submenu = withStyles(submenuStyles)(
// Unfortunately, MUI <Menu> injects refs into its children, which causes a
// warning in some cases unless we use forwardRef here.
React.forwardRef(({ classes, title, popupId, children, ...props }, ref) => (
<ParentPopupState.Consumer>
{parentPopupState => (
<PopupState
variant="popover"
popupId={popupId}
parentPopupState={parentPopupState}
>
{popupState => (
<ParentPopupState.Provider value={popupState}>
<MenuItem
{...bindHover(popupState)}
selected={popupState.isOpen}
ref={ref}
>
<span className={classes.title}>{title}</span>
<ChevronRight className={classes.moreArrow} />
</MenuItem>
<Menu
{...bindMenu(popupState)}
classes={{ paper: classes.menu }}
anchorOrigin={{ vertical: 'top', horizontal: 'right' }}
transformOrigin={{ vertical: 'top', horizontal: 'left' }}
getContentAnchorEl={null}
{...props}
>
{children}
</Menu>
</ParentPopupState.Provider>
)}
</PopupState>
)}
</ParentPopupState.Consumer>
))
);
I need to change the color of the IconButton in the HoverMenu to white (something other than the primary and secondary colors)
<IconButton edge="start" {...bindToggle(popupState)}>
<MenuIcon />
</IconButton>
But i dont know how to use className in this situation.
Thank you

I found the solution as follows.
<IconButton
edge="start"
{...bindToggle(popupState)}
style={{ color: 'white' }}
>
<MenuIcon />
</IconButton>

Related

React MUI Menu does not close

I'm doing some practice with material on react but i've encountered a problem with menu.
The weird thing is that i have two IconButton components,
if I put the onClick that set the anchor element on the first IconButton, all works well.
If I put the onClick that set the anchor element on the second IconButton, the menu will never close..
why it happens? and how to solve it?
here is the code:
import React from 'react';
import AppBar from '#mui/material/AppBar';
import Toolbar from '#mui/material/Toolbar';
import Avatar from '#mui/material/Avatar';
import Menu from '#mui/material/Menu';
import MenuItem from '#mui/material/MenuItem';
import IconButton from '#mui/material/IconButton';
import MenuIcon from '#mui/icons-material/Menu';
import AccountIcon from '#mui/icons-material/AccountCircle';
function TopComp(props) {
const [anchorEl, setAnchorEl] = React.useState(null);
const isMenuOpen = Boolean(anchorEl);
const handleMenuClick = (event) => {
setAnchorEl(event.currentTarget);
};
const handleMenuClose = () => {
setAnchorEl(null);
};
return (
<div style={{ marginBottom: '30px' }}>
<AppBar position="static" color="primary">
<Toolbar>
<IconButton
size="large"
edge="start"
color="inherit"
aria-label="menu"
sx={{ mr: 2 }}
//onClick={(event) => handleMenuClick(event)}
>
<MenuIcon />
</IconButton>
<div style={{ marginLeft: 'auto' }}>
<IconButton
size="large"
edge="end"
color="inherit"
aria-label="menu"
sx={{ mr: 2 }}
onClick={(event) => handleMenuClick(event)}
>
<Menu
id="basic-menu"
anchorEl={anchorEl}
open={isMenuOpen}
onClose={handleMenuClose}
>
<MenuItem onClick={handleMenuClose}>Profile</MenuItem>
<MenuItem onClick={handleMenuClose}>My account</MenuItem>
<MenuItem onClick={handleMenuClose}>Logout</MenuItem>
</Menu>
<Avatar>
<AccountIcon />
</Avatar>
</IconButton>
</div>
</Toolbar>
</AppBar>
</div>
);
}
export default TopComp;
Put your Menu component out of the IconButtons :-
import React from 'react';
import AppBar from '#mui/material/AppBar';
import Toolbar from '#mui/material/Toolbar';
import Avatar from '#mui/material/Avatar';
import Menu from '#mui/material/Menu';
import MenuItem from '#mui/material/MenuItem';
import IconButton from '#mui/material/IconButton';
import MenuIcon from '#mui/icons-material/Menu';
import AccountIcon from '#mui/icons-material/AccountCircle';
function TopComp(props) {
const [anchorEl, setAnchorEl] = React.useState(null);
const isMenuOpen = Boolean(anchorEl);
const handleMenuClick = (event) => {
setAnchorEl(event.currentTarget);
};
const handleMenuClose = () => {
setAnchorEl(null);
};
return (
<div style={{ marginBottom: '30px' }}>
<AppBar position="static" color="primary">
<Toolbar>
<IconButton
size="large"
edge="start"
color="inherit"
aria-label="menu"
sx={{ mr: 2 }}
onClick={(event) => handleMenuClick(event)}
>
<MenuIcon />
</IconButton>
<Menu
id="basic-menu"
anchorEl={anchorEl}
open={isMenuOpen}
onClose={handleMenuClose}
>
<MenuItem onClick={handleMenuClose}>Profile</MenuItem>
<MenuItem onClick={handleMenuClose}>My account</MenuItem>
<MenuItem onClick={handleMenuClose}>Logout</MenuItem>
</Menu>
<div style={{ marginLeft: 'auto' }}>
<IconButton
size="large"
edge="end"
color="inherit"
aria-label="menu"
sx={{ mr: 2 }}
onClick={(event) => handleMenuClick(event)}
>
<Avatar>
<AccountIcon />
</Avatar>
</IconButton>
</div>
</Toolbar>
</AppBar>
</div>
);
}
export default TopComp;
On codesandbox.io

Material UI - Menu Component locks body scrollbar

I have made a dropdown menu using Material-ui Menu component.
The problem is once that dropdown menu is open, the body scrollbar disappears and can not scroll over the page.
I tried to find answers but there are only a few answers for Popper, Popover or Select component but seems like no answer for Menu component.
DropDownMenu component is like this.
import React from 'react'
import Menu from '#material-ui/core/Menu'
import MuiMenuItem from '#material-ui/core/MenuItem'
import styled from 'styled-components'
import MoreVertIcon from '#material-ui/icons/MoreVert'
import IconButton from '#material-ui/core/IconButton'
import SendIcon from '#material-ui/icons/Send'
import ListItemIcon from '#material-ui/core/ListItemIcon'
import ListItemText from '#material-ui/core/ListItemText'
const MenuItem = styled(MuiMenuItem)`
justify-content: flex-end;
`
export default function DropDownMenu() {
const [anchorEl, setAnchorEl] = React.useState(null)
const handleClick = (event) => {
setAnchorEl(event.currentTarget)
}
const handleClose = () => {
setAnchorEl(null)
}
return (
<div>
<IconButton
style={{ padding: 0 }}
aria-label="more"
aria-controls="long-menu"
aria-haspopup="true"
onClick={handleClick}
>
<MoreVertIcon style={{ fontSize: 15 }} />
</IconButton>
<Menu
id="simple-menu"
anchorEl={anchorEl}
keepMounted
open={Boolean(anchorEl)}
onClose={handleClose}
getContentAnchorEl={null}
anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}
transformOrigin={{ vertical: 'top', horizontal: 'right' }}
>
<MenuItem onClick={handleClose}>
<ListItemIcon>
<SendIcon fontSize="small" />
</ListItemIcon>
<ListItemText primary="Sent mail" />
</MenuItem>
<MenuItem onClick={handleClose}>
<ListItemIcon>
<SendIcon fontSize="small" />
</ListItemIcon>
<ListItemText primary="Sent mail" />
</MenuItem>
<MenuItem onClick={handleClose}>
<ListItemIcon>
<SendIcon fontSize="small" />
</ListItemIcon>
<ListItemText primary="Sent mail" />
</MenuItem>
</Menu>
</div>
)
}
Sharpening code to Menu props is as following.
<Menu
id="simple-menu"
anchorEl={anchorEl}
keepMounted
open={Boolean(anchorEl)}
onClose={handleClose}
getContentAnchorEl={null}
anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}
transformOrigin={{ vertical: 'top', horizontal: 'right' }}
>
<MenuItem onClick={handleClose}>
<ListItemIcon>
<SendIcon fontSize="small" />
</ListItemIcon>
<ListItemText primary="Sent mail" />
</MenuItem>
The working example can be seen https://codesandbox.io/s/billowing-cache-042j1?file=/src/App.js
Thanks in advance.
Set the disableScrollLock prop to true. This prop is from the Material UI Modal component but it is also made available for the Menu component.
<Menu
...others
disableScrollLock={true}
>
</Menu>
You should use Popper instead of Menu. You should also create ref and use it for IconButton or Button.
import React from 'react'
import ClickAwayListener from '#material-ui/core/ClickAwayListener'
import Grow from '#material-ui/core/Grow'
import Paper from '#material-ui/core/Paper'
import Popper from '#material-ui/core/Popper'
import MenuItem from '#material-ui/core/MenuItem'
import MenuList from '#material-ui/core/MenuList'
import IconButton from '#material-ui/core/IconButton'
import MoreVertIcon from '#material-ui/icons/MoreVert'
import SendIcon from '#material-ui/icons/Send'
import ListItemIcon from '#material-ui/core/ListItemIcon'
import ListItemText from '#material-ui/core/ListItemText'
export default function DropDownMenu(props) {
const [open, setOpen] = React.useState(false)
const anchorRef = React.useRef(null)
const handleToggle = () => {
setOpen((prevOpen) => !prevOpen)
}
const handleClose = (event) => {
if (anchorRef.current && anchorRef.current.contains(event.target)) {
return
}
setOpen(false)
}
function handleListKeyDown(event) {
if (event.key === 'Tab') {
event.preventDefault()
setOpen(false)
}
}
const handleClick = () => {
// handle menu click here
setOpen(false)
}
return (
<div>
<IconButton
ref={anchorRef}
aria-controls={open ? 'menu-list-grow' : undefined}
aria-haspopup="true"
onClick={handleToggle}
size="small"
>
<MoreVertIcon fontSize="small" />
</IconButton>
<Popper open={open} anchorEl={anchorRef.current} transition disablePortal>
{({ TransitionProps, placement }) => (
<Grow
{...TransitionProps}
style={{ transformOrigin: placement === 'bottom' ? 'center top' : 'center bottom' }}
>
<Paper>
<ClickAwayListener onClickAway={handleClose}>
<MenuList autoFocusItem={open} id="menu-list-grow" onKeyDown={handleListKeyDown}>
<MenuItem onClick={handleClick}>
<ListItemIcon>
<SendIcon fontSize="small"/>
</ListItemIcon>
<ListItemText primary="Sent mail" />
</MenuItem>
<MenuItem onClick={handleClick}>
<ListItemIcon>
<SendIcon fontSize="small"/>
</ListItemIcon>
<ListItemText primary="Sent mail" />
</MenuItem>
</MenuList>
</ClickAwayListener>
</Paper>
</Grow>
)}
</Popper>
</div>
)
}
There is also an example code of it at Material UI Menus Documentation.

Material UI Menu not closing after clicking a menu item

This is code straight from MUI menu - customized menu.. I didn't want to put my code because there are some built in functions that make it more confusing.
In my code (not this) I open a MUI Dialog when a menu item is clicked. The issue is that the menu does not go away after the Dialog is submitted.
I would like to know how to make the menu close as soon as anything on the menu is clicked(menu items).
Thanks
import React from 'react';
import { withStyles } from '#material-ui/core/styles';
import Button from '#material-ui/core/Button';
import Menu, { MenuProps } from '#material-ui/core/Menu';
import MenuItem from '#material-ui/core/MenuItem';
import ListItemIcon from '#material-ui/core/ListItemIcon';
import ListItemText from '#material-ui/core/ListItemText';
import InboxIcon from '#material-ui/icons/MoveToInbox';
import DraftsIcon from '#material-ui/icons/Drafts';
import SendIcon from '#material-ui/icons/Send';
const StyledMenu = withStyles({
paper: {
border: '1px solid #d3d4d5',
},
})((props: MenuProps) => (
<Menu
elevation={0}
getContentAnchorEl={null}
anchorOrigin={{
vertical: 'bottom',
horizontal: 'center',
}}
transformOrigin={{
vertical: 'top',
horizontal: 'center',
}}
{...props}
/>
));
const StyledMenuItem = withStyles((theme) => ({
root: {
'&:focus': {
backgroundColor: theme.palette.primary.main,
'& .MuiListItemIcon-root, & .MuiListItemText-primary': {
color: theme.palette.common.white,
},
},
},
}))(MenuItem);
export default function CustomizedMenus() {
const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);
const handleClick = (event: React.MouseEvent<HTMLElement>) => {
setAnchorEl(event.currentTarget);
};
const handleClose = () => {
setAnchorEl(null);
};
return (
<div>
<Button
aria-controls="customized-menu"
aria-haspopup="true"
variant="contained"
color="primary"
onClick={handleClick}
>
Open Menu
</Button>
<StyledMenu
id="customized-menu"
anchorEl={anchorEl}
keepMounted
open={Boolean(anchorEl)}
onClose={handleClose}
>
<StyledMenuItem>
<ListItemIcon>
<SendIcon fontSize="small" />
</ListItemIcon>
<ListItemText primary="Sent mail" />
</StyledMenuItem>
<StyledMenuItem>
<ListItemIcon>
<DraftsIcon fontSize="small" />
</ListItemIcon>
<ListItemText primary="Drafts" />
</StyledMenuItem>
<StyledMenuItem>
<ListItemIcon>
<InboxIcon fontSize="small" />
</ListItemIcon>
<ListItemText primary="Inbox" />
</StyledMenuItem>
</StyledMenu>
</div>
);
}
You can just assign handleClose handler to the onClick property of the <Menu> itself like this:
<StyledMenu
onClick={handleClose}
onClose={handleClose}
{...yourProps}
>
...
</StyledMenu>
You can put an onClick prop to the MenuItem:
<StyledMenuItem onClick={handleClose}>Text</StyledMenuItem>
I had a similar issue, couldn't apply hangindev.com solution to my problem. Only difference was that my menu items were children passed outside of the menu component.
You could use the onBlur event on StyledMenu.
<StyledMenu
id="customized-menu"
anchorEl={anchorEl}
keepMounted
open={Boolean(anchorEl)}
onClose={handleClose}
onBlur={handleClose}
>{children}<StyledMenu>
Sorry for posting after 2 years, I hope this contributes. I used #mui/material 5.4.0 version.
onBlur={handleClose} works correctly if pass comp as children for other
we may use onClick instead of onClose in
<StyledMenu
id="customized-menu"
anchorEl={anchorEl}
keepMounted
open={Boolean(anchorEl)}
onClick={onClose}
>

how to perform a proper redirect in reactjs(16.13.0) code for a custom material ui component?

I'm using react Material UI in an application, but found some missing logic with my react code.
My complete App.js source file is written below
import React from 'react';
import { fade,makeStyles } from '#material-ui/core/styles';
import Paper from '#material-ui/core/Paper';
import Grid from '#material-ui/core/Grid';
import Icon from '#material-ui/core/Icon';
// import { browserHistory, Router, Route } from 'react-router';
import { BrowserRouter as Router, Route,Redirect } from "react-router-dom";
import './App.css';
/* AppBar*/
//import { fade, makeStyles } from '#material-ui/core/styles';
import AppBar from '#material-ui/core/AppBar';
import Toolbar from '#material-ui/core/Toolbar';
import IconButton from '#material-ui/core/IconButton';
import Typography from '#material-ui/core/Typography';
import InputBase from '#material-ui/core/InputBase';
import Badge from '#material-ui/core/Badge';
import MenuItem from '#material-ui/core/MenuItem';
import Menu from '#material-ui/core/Menu';
import MenuIcon from '#material-ui/icons/Menu';
import SearchIcon from '#material-ui/icons/Search';
import AccountCircle from '#material-ui/icons/AccountCircle';
import MailIcon from '#material-ui/icons/Mail';
import NotificationsIcon from '#material-ui/icons/Notifications';
import MoreIcon from '#material-ui/icons/MoreVert';
/*App bar */
import ImgMediaCard from './ImgMediaCard';
import GridList from '#material-ui/core/GridList';
import GridListTile from '#material-ui/core/GridListTile';
import DemoCarousel from './MCarousel'
import Register from './Register'
var gridListStyle = {
marginLeft: "40px"
};
const useStyles = makeStyles(theme => ({
grow: {
flexGrow: 1,
},
menuButton: {
marginRight: theme.spacing(2),
},
title: {
display: 'none',
[theme.breakpoints.up('sm')]: {
display: 'block',
},
},
search: {
position: 'relative',
borderRadius: theme.shape.borderRadius,
backgroundColor: fade(theme.palette.common.white, 0.15),
'&:hover': {
backgroundColor: fade(theme.palette.common.white, 0.25),
},
marginRight: theme.spacing(2),
marginLeft: 0,
width: '100%',
[theme.breakpoints.up('sm')]: {
marginLeft: theme.spacing(3),
width: 'auto',
},
},
searchIcon: {
width: theme.spacing(7),
height: '100%',
position: 'absolute',
pointerEvents: 'none',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
},
inputRoot: {
color: 'inherit',
},
inputInput: {
padding: theme.spacing(1, 1, 1, 7),
transition: theme.transitions.create('width'),
width: '100%',
[theme.breakpoints.up('md')]: {
width: 200,
},
},
sectionDesktop: {
display: 'none',
[theme.breakpoints.up('md')]: {
display: 'flex',
},
},
sectionMobile: {
display: 'flex',
[theme.breakpoints.up('md')]: {
display: 'none',
},
}
}));
/*end App bar work*/
const useGridStyles = makeStyles(theme => ({
root: {
flexGrow: 1,
},
paper: {
// padding: theme.spacing(2),
// textAlign: 'center',
// color: theme.palette.text.secondary,
},
}));
function App() {
const Gridclasses = useGridStyles();
const classes = useStyles();
const [anchorEl, setAnchorEl] = React.useState(null);
const [mobileMoreAnchorEl, setMobileMoreAnchorEl] = React.useState(null);
const isMenuOpen = Boolean(anchorEl);
const isMobileMenuOpen = Boolean(mobileMoreAnchorEl);
const handleProfileMenuOpen = event => {
setAnchorEl(event.currentTarget);
};
const handleMobileMenuClose = () => {
setMobileMoreAnchorEl(null);
};
const handleMenuClose = () => {
setAnchorEl(null);
handleMobileMenuClose();
};
const handleMobileMenuOpen = event => {
setMobileMoreAnchorEl(event.currentTarget);
};
const onRegisterClick = () => {
debugger;
//if(userFound){
<Router>
<Route exact path="/Register" component={Register} />
return <Redirect to="/Register" />
</Router>
// }
};
// const addRoutes = () =>{
// };
let nums = Array.from(Array(40).keys());
const menuId = 'primary-search-account-menu';
const renderMenu = (
<Menu
anchorEl={anchorEl}
anchorOrigin={{ vertical: 'top', horizontal: 'right' }}
id={menuId}
keepMounted
transformOrigin={{ vertical: 'top', horizontal: 'right' }}
open={isMenuOpen}
onClose={handleMenuClose}
>
<MenuItem onClick={handleMenuClose}>Profile</MenuItem>
<MenuItem onClick={handleMenuClose}>My account</MenuItem>
</Menu>
);
const mobileMenuId = 'primary-search-account-menu-mobile';
const renderMobileMenu = (
<Menu
anchorEl={mobileMoreAnchorEl}
anchorOrigin={{ vertical: 'top', horizontal: 'right' }}
id={mobileMenuId}
keepMounted
transformOrigin={{ vertical: 'top', horizontal: 'right' }}
open={isMobileMenuOpen}
onClose={handleMobileMenuClose}
>
<MenuItem>
<Icon className="fa fa-plus-circle" />
</MenuItem>
<MenuItem>
<IconButton aria-label="show 4 new mails" color="inherit">
<Badge badgeContent={4} color="secondary">
<MailIcon />
</Badge>
</IconButton>
<p>Messages</p>
</MenuItem>
<MenuItem>
<IconButton aria-label="show 11 new notifications" color="inherit">
<Badge badgeContent={11} color="secondary">
<NotificationsIcon />
</Badge>
</IconButton>
<p>Notifications</p>
</MenuItem>
<MenuItem onClick={handleProfileMenuOpen}>
<IconButton
aria-label="account of current user"
aria-controls="primary-search-account-menu"
aria-haspopup="true"
color="inherit"
>
<AccountCircle />
</IconButton>
<p>Profile</p>
</MenuItem>
</Menu>
);
return (
<div className={Gridclasses.root}>
<Grid container spacing={3}>
<Grid item xs={12}>
<Paper className={Gridclasses.paper}>
<div className={classes.grow}>
<AppBar position="static">
<Toolbar>
<IconButton
edge="start"
className={classes.menuButton}
color="inherit"
aria-label="open drawer"
>
<MenuIcon />
</IconButton>
<Typography className={classes.title} variant="h6" noWrap>
Shopping Center
</Typography>
<div className={classes.search}>
<div className={classes.searchIcon}>
<SearchIcon />
</div>
<InputBase
placeholder="Search…"
classes={{
root: classes.inputRoot,
input: classes.inputInput,
}}
inputProps={{ 'aria-label': 'search' }}
/>
</div>
<div className={classes.grow} />
<div className={classes.sectionDesktop}>
<IconButton aria-label="" color="inherit" onClick={onRegisterClick}> Sign Up
</IconButton>
<IconButton aria-label="show 4 new mails" color="inherit">
<Badge badgeContent={4} color="secondary">
<MailIcon />
</Badge>
</IconButton>
<IconButton aria-label="show 17 new notifications" color="inherit">
<Badge badgeContent={17} color="secondary">
<NotificationsIcon />
</Badge>
</IconButton>
<IconButton
edge="end"
aria-label="account of current user"
aria-controls={menuId}
aria-haspopup="true"
onClick={handleProfileMenuOpen}
color="inherit"
>
<AccountCircle />
</IconButton>
</div>
<div className={classes.sectionMobile}>
<IconButton
aria-label="show more"
aria-controls={mobileMenuId}
aria-haspopup="true"
onClick={handleMobileMenuOpen}
color="inherit"
>
<MoreIcon />
</IconButton>
</div>
</Toolbar>
</AppBar>
{renderMobileMenu}
{renderMenu}
</div>
</Paper>
</Grid>
<GridList cols={3} style={gridListStyle} cellHeight={"auto"}>
{nums.map(n => {
return (
<GridListTile key={n}>
<ImgMediaCard key={n} num={n} />
</GridListTile>
);
})}
</GridList>
<Grid item xs={6} sm={3}>
<Paper className={Gridclasses.paper}> <DemoCarousel />
</Paper>
</Grid>
</Grid>
</div>
);
}
export default App;
and following function don't take me into the second component. I don't know why.
const onRegisterClick = () => {
debugger;
//if(userFound){
<Router>
<Route exact path="/Register" component={Register} />
return <Redirect to="/Register" />
</Router>
// }
};
As I'm a newbie with react. What should I do in my code?
I've grabbed the example code for a menus and cards from here: https://material-ui.com
Application built with
{
"react": "16.13.0",
"react-dom": "^16.13.0",
"react-redux": "^7.2.0",
"react-router-dom": "^5.1.2",
"redux": "^4.0.4"
"#material-ui/core": "^4.9.5"
}
The Signup button don't allow me to navigate to Register react component.
Output: Sign Up button should allow me to redirect.
I tried to follow guides and looked up example implementations but could not solve the issue.
Only the render and functions called directly from render function are supposed to return JSX because these are the functions that render UI.
When you consider something like onRegisterClick function, this function is called in response to a button being clicked. Here you should be adding the imperative code to redirect the user to /redirect page. But the Route for redirect should be setup before this function is ever called so React Router knows which component to render.
Your whole app (generally) requires a single Router component and your whole App is wrapped into it, in you case consider something like:
import { BrowserRouter as Router } from "react-router-dom";
ReactDOM.render(<Router>
<Route path="/Register" component={Register} />
<Route exact path="/" component={App />
</Router>, document.getElementById("root") />
After this, you can navigate with:
function App({ history }) {
const onRegisterClick = () => {
history.push('/register');
}
}
There is a lot of assumptions here and I do think you need to check out React Router docs and understand the routing a little better before you can get started.

how to handle multiple popover (material ui)

I tried to use multiple popover within a component. For ex, in below code I have two popovers, but when clicking any of the two button, both the popovers are opened. How can we handle the onclick to open corresponding popover?
const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);
const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
setAnchorEl(event.currentTarget);
};
const handleClose = () => {
setAnchorEl(null);
};
<Tabs variant="fullWidth" value={value} onChange={onNavChange} indicatorColor="transparent">
<Tab label="Menu 1" className={classes.navTab} component={Link} to="./Menu1"></Tab>
<Tab label="Menu 2" onClick={handleClick} aria-describedby="menu2Popover" aria-haspopup="true"></Tab>
<Tab label="Menu 3" component={Link} to="./Menu3"></Tab>
<Tab label="Menu 4"onClick={handleClick} aria-describedby="menu4Popover" aria-haspopup="true"></Tab>
</Tabs>
<Popover
id="menu2Popover" open={Boolean(anchorEl)} onClose={handleClose}
anchorEl = {anchorEl}
anchorOrigin={{
vertical: 'top',
horizontal: 'left',
}}
transformOrigin={{
vertical: 'bottom',
horizontal: 'left',
}}>
<MenuList>
<MenuItem>Submenu 1</MenuItem>
<MenuItem>Submenu 2</MenuItem>
</MenuList>
</Popover>
<Popover
id="menu4Popover" open={Boolean(anchorEl)} onClose={handleClose}
anchorEl = {anchorEl}
anchorOrigin={{
vertical: 'top',
horizontal: 'left',
}}
transformOrigin={{
vertical: 'bottom',
horizontal: 'left',
}}>
<MenuList>
<MenuItem>Submenu 3</MenuItem>
<MenuItem>Submenu 4</MenuItem>
</MenuList>
</Popover>
You need to use different anchorEl's for each Popover:
import * as React from "react";
import { render } from "react-dom";
import { MenuList, MenuItem, Popover, Tabs, Tab } from "#material-ui/core";
import "./styles.css";
interface CustomMenuItem {
anchorEl: null | HTMLElement;
child: any;
}
function Popover1() {
return (
<MenuList>
<MenuItem>Submenu 1</MenuItem>
<MenuItem>Submenu 2</MenuItem>
</MenuList>
);
}
function Popover2() {
return (
<MenuList>
<MenuItem>Submenu 3</MenuItem>
<MenuItem>Submenu 4</MenuItem>
</MenuList>
);
}
function App() {
const [popover1, setPopover1] = React.useState<CustomMenuItem>({
anchorEl: null,
child: <Popover1 />
});
const [popover2, setPopover2] = React.useState<CustomMenuItem>({
anchorEl: null,
child: <Popover2 />
});
return (
<div className="App">
<Tabs variant="fullWidth" indicatorColor="transparent">
<Tab label="Menu 1" />
<Tab
value="Tab2"
label="Menu 2"
onClick={(event: React.MouseEvent<HTMLButtonElement>) =>
setPopover1({ ...popover1, anchorEl: event.currentTarget })
}
aria-describedby="menu2Popover"
aria-haspopup="true"
/>
<Tab label="Menu 3" />
<Tab
label="Menu 4"
onClick={(event: React.MouseEvent<HTMLButtonElement>) =>
setPopover2({ ...popover2, anchorEl: event.currentTarget })
}
aria-describedby="menu4Popover"
aria-haspopup="true"
/>
</Tabs>
<Popover
id="menu2Popover"
open={Boolean(popover1.anchorEl)}
onClose={() => setPopover1({ ...popover1, anchorEl: null })}
anchorEl={popover1.anchorEl}
anchorOrigin={{
vertical: "top",
horizontal: "left"
}}
transformOrigin={{
vertical: "bottom",
horizontal: "left"
}}
>
{popover1.child}
</Popover>
<Popover
id="menu4Popover"
open={Boolean(popover2.anchorEl)}
onClose={() => setPopover2({ ...popover2, anchorEl: null })}
anchorEl={popover2.anchorEl}
anchorOrigin={{
vertical: "top",
horizontal: "left"
}}
transformOrigin={{
vertical: "bottom",
horizontal: "left"
}}
>
{popover2.child}
</Popover>
</div>
);
}
const rootElement = document.getElementById("root");
render(<App />, rootElement);
Look at the codesandbox. If you have any further questions let me know and I can update my answer.
another sample with one Popover
import React from "react";
import { withStyles } from "#material-ui/core/styles";
import AppBar from "#material-ui/core/AppBar";
import Tabs from "#material-ui/core/Tabs";
import Tab from "#material-ui/core/Tab";
import Popover from "#material-ui/core/Popover";
import MenuList from "#material-ui/core/MenuList";
import MenuItem from "#material-ui/core/MenuItem";
const styles = theme => ({
root: {
flexGrow: 1,
backgroundColor: theme.palette.background.paper,
textTransform: "none"
}
});
class SimpleTabs extends React.Component {
state = {
value: 0,
anchorEl: null,
popno: -1
};
handlePopoverClose = () => {
this.setState({ anchorEl: null, popno: -1 });
};
handleClick = (e, _popno) => {
this.setState({ anchorEl: e.currentTarget, popno: _popno });
};
handleChange = (event, value) => {
this.setState({ value });
};
render() {
const { classes } = this.props;
const { value } = this.state;
return (
<div className={classes.root}>
<AppBar position="static">
<Tabs value={value} onChange={this.handleChange}>
<Tab label="Tab 1" onClick={e => this.handleClick(e, 1)} />
<Tab label="Tab 2" onClick={e => this.handleClick(e, 2)} />
<Tab label="Tab 3" onClick={e => this.handleClick(e, 3)} />
</Tabs>
<Popover
id="menu2Popover"
open={this.state.anchorEl !== null}
onClose={this.handlePopoverClose}
anchorEl={this.state.anchorEl}
>
{this.state.popno === 1 && (
<MenuList>
<MenuItem>Tab 1 - Submenu 1</MenuItem>
<MenuItem>Tab 1 - Submenu 2</MenuItem>
</MenuList>
)}
{this.state.popno === 2 && (
<MenuList>
<MenuItem>Tab 2 - Submenu 1</MenuItem>
<MenuItem>Tab 2 - Submenu 2</MenuItem>
</MenuList>
)}
{this.state.popno === 3 && (
<MenuList>
<MenuItem>Tab 3 - Submenu 1</MenuItem>
<MenuItem>Tab 3 - Submenu 2</MenuItem>
</MenuList>
)}
</Popover>
</AppBar>
</div>
);
}
}
export default withStyles(styles)(SimpleTabs);
answer output https://codesandbox.io/s/material-tabs-demo-tpugw

Resources