How to build a full-width mega-menu using Material-UI? - reactjs

Currently, my component looks like this:
<Menu
id="customized-menu"
className={classes.root}
anchorEl={blogMenuAnchorEl}
getContentAnchorEl={null}
anchorOrigin={{ vertical: 'bottom', horizontal: 'center' }}
transformOrigin={{ vertical: 'top', horizontal: 'center' }}
open={blogMenu}
onClose={closeBlogDropDown}
>
<MenuItem>
<ListItemText primary="Latest Posts" />
</MenuItem>
<Divider variant="fullWidth" />
<MenuItem>
<ListItemText primary="Learn French" />
</MenuItem>
<MenuItem>
<ListItemText primary="Learn Latin" />
</MenuItem>
<MenuItem>
<ListItemText primary="Learn Italian" />
</MenuItem>
</Menu>
);
This drop-down, of course, shrinks to fit the items it lists. However, what if I want the drop-down to be full-width? They call it a mega menu, I suppose. I tried adding a width: '100%' to the component's style but it had no effect because the actual drop-down div gets generated at runtime, to which I have no access during scripting.
The repo is up at https://github.com/amitschandillia/proost/tree/master/web_SO and the component in question is https://github.com/amitschandillia/proost/blob/master/web_SO/components/BlogDropDown.jsx.
REFERENCE: Here's an image of what I'm looking to emulate:

You need to change the Popover paper width to 100% (the drop down is actually a popover):
const styles = (theme) => ({
popoverPaper: {
width: '100%',
height: '100%',
maxHeight: 'unset',
maxWidth: 'unset',
},
});
And than apply the style to popover paper:
<Menu
PopoverClasses={{paper: props.classes.popoverPaper}}
id="customized-menu"
anchorEl={anchorEl}
open={Boolean(anchorEl)}
onClose={handleClose}
>
You can check this CodeSandbox example: https://codesandbox.io/s/material-demo-fmy64?fontsize=14

For benefit of people who came here because of google search.
The props needed if you want the full width ( like a mega menu ) is with the following minimum settings of marginThreshold and PaperProps. These are props which will be pass to Popover API.
<Menu
anchorEl={anchorEl}
marginThreshold={0}
PaperProps={{
style: {
width: "100%",
maxWidth: "100%",
left: 0,
right: 0,
}
}}
anchorOrigin={{ vertical: "bottom" }}
transformOrigin={{ vertical: "top" }}>
fork of the selected answer

Related

DropDown menu is not aligning correctly in AppBar

I am using MUI with react. The dropdown menu is not aligning correctly. I am following https://mui.com/material-ui/react-menu/#account-menu document.
My text code:
//** A styled component **//
const StyledToolbar = styled(Toolbar)({
display: "flex",
justifyContent: "space-between",
backgroundColor: "#1e8e3e",
});
//** States **//
const [anchorEl, setAnchorEl] = useState(false);
const open = Boolean(anchorEl);
//** Actual Menu code **//
<Menu
id="account-menu"
anchorEl={anchorEl}
keepMounted
open={open}
getContentAnchorEl={null}
onClose={(e) => setAnchorEl(false)}
onClick={(e) => setAnchorEl(false)}
anchorOrigin={{ horizontal: 'right', vertical: 'bottom' }}
transformOrigin={{ horizontal: 'right', vertical: 'top' }}
PaperProps={{
elevation: 0,
sx: {
overflow: 'visible',
filter: 'drop-shadow(0px 2px 8px rgba(0,0,0,0.32))',
mt: 1.5,
'& .MuiAvatar-root': {
width: 32,
height: 32,
ml: -0.5,
mr: 1,
},
'&:before': {
content: '""',
display: 'block',
position: 'absolute',
top: 0,
right: 14,
width: 10,
height: 10,
bgcolor: 'background.paper',
transform: 'translateY(-50%) rotate(45deg)',
zIndex: 0,
},
},
}}
>
<MenuItem>
<Typography variant="span">John K.</Typography>
</MenuItem>
<Divider />
<MenuItem>
<Avatar
sx={{ bgcolor: green[500], margin: ".5rem", width: 24, height: 24 }}
/>
Profile
</MenuItem>
<MenuItem>
<ListItemIcon sx={{ color: green[500], margin: ".5rem" }}>
<Settings fontSize="small" />
</ListItemIcon>
Settings
</MenuItem>
<Divider />
<MenuItem onClick={handleSignOut}>
<ListItemIcon sx={{ color: "#f50057", margin: ".5rem" }}>
<Logout fontSize="small" />
</ListItemIcon>
Logout
</MenuItem>
{error && <span className="span">Something went wrong!</span>}
</Menu>
If I am using the anchorOrigin={{ horizontal: 'right', vertical: 'bottom' }} the Menu is starting from the bottom of the window:
If I am using the anchorOrigin={{ horizontal: 'right', vertical: 'top' }} the Menu is starting from the top of the window but from the middle of the user profile image:
For many people, applying getContentAnchorEl={null} fixed the issue but for me its not working. I am using MUI v5.10.0
You need to specify an element to work as a reference, like an anchor, for the Menu to open from it. Or else it will just show in an edge of the page depending the anchorOrigin property settings you specify on the Menu component.
<>
<Button
id="basic-button"
aria-controls={open ? "basic-menu" : undefined}
aria-haspopup="true"
aria-expanded={open ? "true" : undefined}
onClick={handleClick}
>
Menu
</Button>
<Menu
id="account-menu"
anchorEl={anchorEl}
keepMounted
open={open}
onClose={(e) => setAnchorEl(false)}
onClick={(e) => setAnchorEl(false)}
anchorOrigin={{ horizontal: "right", vertical: "bottom" }}
transformOrigin={{ horizontal: "right", vertical: "top" }}
PaperProps={{
elevation: 0,
sx: {
overflow: "visible",
filter: "drop-shadow(0px 2px 8px rgba(0,0,0,0.32))",
mt: 1.5,
"& .MuiAvatar-root": {
width: 32,
height: 32,
ml: -0.5,
mr: 1
},
"&:before": {
content: '""',
display: "block",
position: "absolute",
top: 0,
right: 14,
width: 10,
height: 10,
bgcolor: "background.paper",
transform: "translateY(-50%) rotate(45deg)",
zIndex: 0
}
}
}}
>
<MenuItem>
<Typography variant="span">John K.</Typography>
</MenuItem>
<Divider />
<MenuItem>
<Avatar
sx={{ bgcolor: "green", margin: ".5rem", width: 24, height: 24 }}
/>
Profile
</MenuItem>
<MenuItem>
<ListItemIcon sx={{ color: "green", margin: ".5rem" }}>
<Settings fontSize="small" />
</ListItemIcon>
Settings
</MenuItem>
<Divider />
<MenuItem
>
<ListItemIcon sx={{ color: "#f50057", margin: ".5rem" }}>
<Logout fontSize="small" />
</ListItemIcon>
Logout
</MenuItem>
</Menu>
<>
Here is the working codesanbox
Current target was missing in the code. After applying the following code, able to fix it:
const handleClick = (event) => {
setAnchorEl(event.currentTarget);
};
<Button
id="basic-button"
aria-controls={open ? "basic-menu" : undefined}
aria-haspopup="true"
aria-expanded={open ? "true" : undefined}
onClick={handleClick} /* Need to include this to set the target pointer */
>
And remove getContentAnchorEl={null} entry from the <Menu>. Else it may generate the following error:
Warning: React does not recognize the `getContentAnchorEl` prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase `getcontentanchorel` instead. If you accidentally passed it from a parent component, remove it from the DOM element.

How to disable the arrow up and down event on MUI Menu?

In my menu I have a text field and a button. The text field type is number type. So when I click on the text field and click the arrow up and down, I want it to value to increase and decrease. But instead of that happening, it's selecting the menu items. This is the code.
<Menu
anchorEl={anchorEl}
open={open}
onClose={handleClose}
PaperProps={{
elevation: 0,
sx: {
overflow: "visible",
filter: "drop-shadow(0px 2px 8px rgba(0,0,0,0.32))",
mt: 1.5,
"& .MuiAvatar-root": {
width: 32,
height: 32,
ml: -0.5,
mr: 1,
},
"&:before": {
content: '""',
display: "block",
position: "absolute",
top: 0,
right: 14,
width: 10,
height: 10,
bgcolor: "background.paper",
transform: "translateY(-50%) rotate(45deg)",
zIndex: 0,
},
},
}}
transformOrigin={{ horizontal: "right", vertical: "top" }}
anchorOrigin={{ horizontal: "right", vertical: "bottom" }}
>
<MenuItem>
<TextField
label="Quantity"
type="number"
InputProps={{
inputProps: { min: "0", step: "1" },
}}
size="small"
sx={{ width: "120px" }}
value={editingItem.quantity}
onChange={(e) =>
setEditingItem({ ...editingItem, quantity: e.target.value })
}
/>
</MenuItem>
<MenuItem>
<Button
variant="contained"
size="small"
onClick={updateItem}
fullWidth
>
Save
</Button>
</MenuItem>
</Menu>
I tried wrapping the menu items in <MenuList/> and used the option autoFocusItem={false} but it's not working.
I have also investigated ways to disable the behavior of the arrow keys on MUI's and components, but concluded that there are no MUI props or other methods to disable the behavior. Instead, what I did was replace with a regular . The props for and its functionality are very similar to hopefully all you'll need to do is use the List component.

My menu component of material ui is giving my page an extra margin to the right when i click on the menu icon

This is my menu component.
<Menu
id="Menu-Btn"
aria-labelledby="Menu-Btn"
anchorEl={anchorEl}
open={open}
onClose={handleClose}
anchorOrigin={{
vertical: "top",
horizontal: "left",
}}
transformOrigin={{
vertical: "top",
horizontal: "left",
}}
TransitionComponent={Fade}
PaperProps={{
style: {
marginTop: "40px",
},
}}
>
When i click on the menu icon one rendering MenuItems my whole page gets a margin of right
Add this:
disableScrollLock={true}

How to make icon button stick to the left side of the navbar

I have this component here that makes a navbar but as of right now the avatar button is right next to the "home" button. I'm fairly new to react and web programming so I'm not sure what to look for to make the avatar button stick to the right corner of the navbar.
The navbar right now:
The navbar I want to display:
export default function MenuAppBar() {
const [auth, setAuth] = React.useState(true);
const [anchorEl, setAnchorEl] = React.useState(null);
const handleChange = (event) => {
setAuth(event.target.checked);
};
const handleMenu = (event) => {
setAnchorEl(event.currentTarget);
};
const handleClose = () => {
setAnchorEl(null);
};
return (
<Box sx={{ flexGrow: 1 }}>
<AppBar position="static">
<Toolbar>
<IconButton
size="large"
edge="start"
color="inherit"
aria-label="menu"
onClick={handleMenu}
sx={{ mr: 2 }}
>
<MenuIcon />
<Menu
id="menu-appbar"
anchorEl={anchorEl}
anchorOrigin={{
vertical: 'top',
horizontal: 'right',
}}
keepMounted
transformOrigin={{
vertical: 'top',
horizontal: 'right',
}}
open={Boolean(anchorEl)}
onClose={handleClose}
>
<MenuItem onClick={handleClose}>Profile</MenuItem>
<MenuItem onClick={handleClose}>My account</MenuItem>
</Menu>
</IconButton>
<a className="navbar-brand" href="/home" sx={{ flexGrow: 1 }}>
Bookeroo
</a>
{auth && (
<div>
<IconButton
size="large"
aria-label="account of current user"
aria-controls="menu-appbar"
aria-haspopup="true"
onClick={handleMenu}
color="inherit"
>
<AccountCircle />
</IconButton>
<Menu
id="menu-appbar"
anchorEl={anchorEl}
anchorOrigin={{
vertical: 'top',
horizontal: 'right',
}}
keepMounted
transformOrigin={{
vertical: 'top',
horizontal: 'right',
}}
open={Boolean(anchorEl)}
onClose={handleClose}
>
<MenuItem onClick={handleClose}>Profile</MenuItem>
<MenuItem onClick={handleClose}>My account</MenuItem>
</Menu>
</div>
)}
</Toolbar>
</AppBar>
</Box>
);
}
So, I am going to assume your mark up is something like (not necessarily exact)
<div className="wrapper">
<div className="toggle">toggle</div>
<div className="item">Home</div>
<div className="icon">icon</div>
</div>
I would make the wrapper a flex box and make the icon move to the right. Like this
.wrapper {
display: flex;
width: 100%;
}
.icon {
margin-left: auto;
}
The margin: auto forces the item to the end depending on the direction of the margin (margin-left to right end, margin-right to left end, and so on)

How can I fix the anchor tag for the badge?

This is my code for the badge:
<Tab
label={
<Badge
badgeContent={size}
color="secondary"
showZero
className={classes.badge}
anchorOrigin={{
vertical: "top",
horizontal: "right",
}}
>
<Typography>Pending</Typography>
</Badge>
}
{...a11yProps(0)}
/>
This is the styles for the badge. However, this will also move the typography
badge: {
marginLeft: "1rem",
},
It can be displayed, however, the anchor tag for the badge is overlapping the words or the label. How can I fix this?
badge: {
position: absolute;
top: '8px'; //you can change according to your use
},
Else
anchorOrigin={{
vertical: "top",
horizontal: "right",
position: "absolute",
top: "8px"
}}
Please let me know in a comment if not work

Resources