ReactJS: Menu with submenu (nested) - javascript

I have created a menu with submenu nested like:
- Example1 >
Example1.1
Example1.2
- Example2 >
Example2.1
So if I click on Example, it opens a submenu with two fields Example1 and Example2.
This is the code that I use: (with reactstrap)
export const ExampleMenu = props => {
const [dropDownOpen, setDropDownOpen] = useState(false);
const toggle = () => setDropDownOpen(prevState => !prevState);
useEffect( () => {
setDropDownOpen(false)
})
return (
<NavDropdown
icon="th-list"
name="Example"
id="example-menu"
data-cy="example"
style={{ maxHeight: '80vh', minWidth: '300px', minHeight: '150px', overflow: 'auto' }}
>
<Dropdown isOpen={dropDownOpen} toggle={toggle} rigth>
<UncontrolledDropdown nav direction="right">
<DropdownToggle nav caret style={{ color: '#000000' }}>
Example1
</DropdownToggle>
<DropdownMenu right style={{ marginLeft: 90, border: '0px', outline: 'none' }}>
<DropdownItem>
<MenuItem icon="asterisk" to="/example1_1">
Example1.1
</MenuItem>
</DropdownItem>
<DropdownItem>
<MenuItem icon="asterisk" to="/example1_2">
Example1.2
</MenuItem>
</DropdownItem>
</DropdownMenu>
</UncontrolledDropdown>
<UncontrolledDropdown nav direction="right">
<DropdownToggle nav caret style={{ color: '#000000' }}>
Example2
</DropdownToggle>
<DropdownMenu right style={{ marginLeft: 90, border: '0px', outline: 'none' }}>
<DropdownItem>
<MenuItem icon="asterisk" to="/example2_1">
Example2.1
</MenuItem>
</DropdownItem>
</DropdownMenu>
</UncontrolledDropdown>
</Dropdown>
</NavDropdown>
Now my problem is that if i click on submenu like Example1.2, I change the page but the parent menu ( the menu with Example1 and Example2) remains open and i need to click anyway out of the menu to close it.
How can I do to close automatically when I click in submenu category?

Related

Implementing a Modal inside a Drawer in Material UI

I'm using Material UI and im trying to make a Modal pop up from a Responsive Drawer component. The problem is that when i click on the button, the Modal is rendered and instantly closed. I think that is because of the closing animation of the modal.
I tried a lot of workarounds, played with the z-index a little bit but nothing is working. Any ideas? This is the Modal code:
<div>
<Button
onClick={handleOpen}
sx={{
backgroundColor: "black",
color: "white",
borderBottom: "1px solid #f14d59",
borderRadius: "0px",
}}
>
Log In
</Button>
<Modal
open={open}
onClose={handleClose}
aria-labelledby="modal-modal-title"
aria-describedby="modal-modal-description"
>
<Box sx={style} className="modal-box">
<button className="close-popup" onClick={handleClose}>
x
</button>
<Validations />
</Box>
</Modal>
</div>
and this is the Drawer:
const toggleDrawer = (anchor, open) => (event) => {
if (
event.type === "keydown" &&
(event.key === "Tab" || event.key === "Shift")
) {
return;
}
setState({ ...state, [anchor]: open });
};
const list = (anchor) => (
<Box
sx={{
width: 250,
}}
role="presentation"
onClick={toggleDrawer(anchor, false)}
onKeyDown={toggleDrawer(anchor, false)}
>
<List>
{icons.map((icon) => (
<a to={icon.route} key={icon.title} href={icon.href}>
<ListItem disablePadding>
<ListItemButton>
<ListItemIcon sx={{ color: "#f14d59" }}>
<icon.icon />
</ListItemIcon>
<ListItemText
primary={icon.title}
sx={{ color: "#f14d59", fontWeight: "700" }}
/>
</ListItemButton>
</ListItem>
</a>
))}
</List>
<Divider sx={{ backgroundColor: "lightgrey" }} />
<List>
<ListItem disablePadding>
<ListItemButton>
<Modal />
</ListItemButton>
</ListItem>
</List>
</Box>
);
<nav>
<React.Fragment key={"left"}>
<Button onClick={toggleDrawer("left", true)}>
<MenuIcon sx={{ color: "white" }} />
</Button>
<Drawer
anchor={"left"}
open={state["left"]}
onClose={toggleDrawer("left", false)}
>
{list("left")}
</Drawer>
</React.Fragment>
</nav>

How do I change the zAxis of a Paper from MUI?

Hello I want to know how do you change the zAxis of a paper from MUI
As you can see the carousel overlaps my menu and I would like my menu to be on top of everything.
This is how I have it wrapped:
<Box sx={{ background: '#272A31', flexGrow: 0, display: { xs: 'none', md: 'flex' } }}>
<StyledIconButton size="small" edge="start" color="inherit" aria-label="menu" sx={{ mr: 2 }} onClick={handleToggle} ref={anchorRef} >
<GamesIcon />
<Typography variant="h6" component="div" sx={{ flexGrow: 1 }}> GAMES </Typography>
<Popper open={open} anchorEl={anchorRef.current} role={undefined} placement="bottom-start" transition disablePortal >
{({ TransitionProps, placement }) => (
<Grow {...TransitionProps}
style={{
transformOrigin: placement === 'bottom-start' ? 'left top' : 'left bottom',
}}
>
<StyledPaper sx = {{zIndex: 1600}} >
<ClickAwayListener onClickAway={handleClose}>
<MenuList autoFocusItem={open} id="composition-menu" aria-labelledby="composition-button" onKeyDown={handleListKeyDown}>
<StyledMenuItem onClick={handleClose}>JUNGLE RAIDER</StyledMenuItem>
<StyledMenuItem onClick={handleClose}>MEGAMAN TEMPLATE</StyledMenuItem>
<StyledMenuItem onClick={handleClose}>TOWER DEFENSE</StyledMenuItem>
<StyledMenuItem onClick={handleClose}>BLADES AND DUNGEON</StyledMenuItem>
<StyledMenuItem onClick={handleClose}>FIXSPACE</StyledMenuItem>
</MenuList>
</ClickAwayListener>
</StyledPaper>
</Grow>
)}
</Popper>
</StyledIconButton>
</Box>
While my Carousel is wraped in the following way:
<Box mb = {2} mt = {2} sx={{display: 'flex', justifyContent: 'center', alignItems: 'center', zIndex: -1}}>
<Card sx={{ width: 1500, backgroundColor: "transparent"}} >
<Carousel fullHeightHover={false} navButtonsAlwaysVisible={true} duration={500} animation="slide"
navButtonsProps={{
style: {
backgroundColor: '#FF5917',
borderRadius: 0,
}
}} >
{items.map( (item, i) => <Item key={i} item={item} />)}
</Carousel>
</Card>
</Box>
Even though the paper is at z-(1600) and the carousel box at z-(-1) it still overlaps the paper for some reason
https://mui.com/customization/z-index/ check this link. tooptip has highest zindex value. you can add it to your popper

ReactJS: Close automatically the menu when change page

I have a create a nested menu, but I have a problem with it.
I have :
Parent_Menu
Parent1
> Child_Menu1
> Child_Menu2
Parent2
Now if I click for example in Child_Menu1, i'm redirect to the page correctly and also the Parent1 menu is closed, but the Parent_Menu reamins opened (So i can click another time or in parent1 or in parent2).
I would to close all the menu (the parent_menu) when I change page.
import React, { useState } from 'react';
import MenuItem from 'app/shared/layout/menus/menu-item';
import { Dropdown, DropdownToggle, DropdownMenu, UncontrolledDropdown, DropdownItem, NavLink } from 'reactstrap';
import { NavDropdown } from './menu-components';
export const EntitiesMenu = props => {
const [dropDownOpen, setDropDownOpen] = useState(false);
const toggle = () => setDropDownOpen(prevState => !prevState);
return (
<NavDropdown
icon="th-list"
name="Parent_Menu"
id="parent-menu"
data-cy="parent_menu"
style={{ maxHeight: '80vh', minWidth: '150px', minHeight: '250px' }}
>
<Dropdown isOpen={dropDownOpen} toggle={toggle} direction="right">
<DropdownToggle nav caret style={{ color: '#000000', marginLeft: 25 }}>
Parent1
</DropdownToggle>
<DropdownMenu right style={{ border: '0px', outline: 'none', marginTop: 20 }}>
<DropdownItem>
<MenuItem icon="asterisk" to="/child_menu1">
Child_Menu1
</MenuItem>
</DropdownItem>
<DropdownItem>
<MenuItem icon="asterisk" to="/child_menu2">
Child_Menu2
</MenuItem>
</DropdownItem>
</DropdownMenu>
<NavLink href="/parent2" style={{ color: '#000000', marginLeft: 25 }}>
Parent2
</NavLink>
</Dropdown>
</NavDropdown>
);
};
How can I do to close automatically all the menu?
have you try the onBlur?
or you can even use the onClick
import React, { useState } from 'react';
import MenuItem from 'app/shared/layout/menus/menu-item';
import { Dropdown, DropdownToggle, DropdownMenu, UncontrolledDropdown, DropdownItem, NavLink } from 'reactstrap';
import { NavDropdown } from './menu-components';
export const EntitiesMenu = props => {
const [dropDownOpen, setDropDownOpen] = useState(false);
const toggle = () => setDropDownOpen(prevState => !prevState);
return (
<NavDropdown
icon="th-list"
name="Parent_Menu"
id="parent-menu"
data-cy="parent_menu"
style={{ maxHeight: '80vh', minWidth: '150px', minHeight: '250px' }}
>
<Dropdown isOpen={dropDownOpen} toggle={toggle} direction="right">
<DropdownToggle nav caret style={{ color: '#000000', marginLeft: 25 }}>
Parent1
</DropdownToggle>
<DropdownMenu onBlur={e=>{
toggle()
}} right style={{ border: '0px', outline: 'none', marginTop: 20 }}>
<DropdownItem>
<MenuItem onClick={()=>{
toggle()
}} icon="asterisk" to="/child_menu1">
Child_Menu1
</MenuItem>
</DropdownItem>
<DropdownItem>
<MenuItem onClick={()=>{
toggle()
}} icon="asterisk" to="/child_menu2">
Child_Menu2
</MenuItem>
</DropdownItem>
</DropdownMenu>
<NavLink onClick={()=>{
toggle()
}} href="/parent2" style={{ color: '#000000', marginLeft: 25 }}>
Parent2
</NavLink>
</Dropdown>
</NavDropdown>
);
};
import React, { useState } from 'react';
import MenuItem from 'app/shared/layout/menus/menu-item';
import { Dropdown, DropdownToggle, DropdownMenu, UncontrolledDropdown, DropdownItem, NavLink } from 'reactstrap';
import { NavDropdown } from './menu-components';
export const EntitiesMenu = props => {
const [dropDownOpen, setDropDownOpen] = useState(false);
const [dropDownStyle, setStyle] = useState('80px');
const toggle = () => setDropDownOpen(prevState => !prevState);
useEffect(()=>{
dropDownOpen ? setStyle('0'); : setStyle('80px');
},[dropDownOpen]);
return (
<NavDropdown
icon="th-list"
name="Parent_Menu"
id="parent-menu"
data-cy="parent_menu"
style={{ maxHeight: customHeight, minWidth: '150px', minHeight: '250px' }}
>
<Dropdown isOpen={dropDownOpen} toggle={toggle} direction="right">
<DropdownToggle nav caret style={{ color: '#000000', marginLeft: 25 }}>
Parent1
</DropdownToggle>
<DropdownMenu right style={{ border: '0px', outline: 'none', marginTop: 20 }}>
<DropdownItem>
<MenuItem icon="asterisk" to="/child_menu1">
Child_Menu1
</MenuItem>
</DropdownItem>
<DropdownItem>
<MenuItem icon="asterisk" to="/child_menu2">
Child_Menu2
</MenuItem>
</DropdownItem>
</DropdownMenu>
<NavLink href="/parent2" style={{ color: '#000000', marginLeft: 25 }}>
Parent2
</NavLink>
</Dropdown>
</NavDropdown>
);
};

How to align Material-UI Menu items?

I use the menu and menu item of material-ui to build a select dropdown menu, but I found one thing strange: the dropdown menu always expand to the left side of the box, as the image shown below:
I've tried to use the alignItems property inside my <MenuItem> but it didn't work.
My code is shown below. Can anybody help me to fix this problem? I really appreciate your help!
<Menu
id="order-menu"
anchorEl={anchorEl}
keepMounted
open={Boolean(anchorEl)}
onClose={() => setAnchorEl(null)}
>
{options.map((option, index) => (
<MenuItem
key={option}
selected={index === selectedIndex}
onClick={(event) => handleMenuItemClick(event, index)}
>
{option}
</MenuItem>
))}
</Menu>
The default styles controlling this are in ListItem where it specifies justifyContent: 'flex-start'.
You can change this to be right aligned with:
const MenuItem = withStyles({
root: {
justifyContent: "flex-end"
}
})(MuiMenuItem);
Here's a full working example:
import React from "react";
import Button from "#material-ui/core/Button";
import Menu from "#material-ui/core/Menu";
import MuiMenuItem from "#material-ui/core/MenuItem";
import { withStyles } from "#material-ui/core/styles";
const MenuItem = withStyles({
root: {
justifyContent: "flex-end"
}
})(MuiMenuItem);
export default function SimpleMenu() {
const [anchorEl, setAnchorEl] = React.useState(null);
const handleClick = event => {
setAnchorEl(event.currentTarget);
};
const handleClose = () => {
setAnchorEl(null);
};
return (
<div>
<Button
aria-controls="simple-menu"
aria-haspopup="true"
onClick={handleClick}
>
Open Menu
</Button>
<Menu
id="simple-menu"
anchorEl={anchorEl}
keepMounted
open={Boolean(anchorEl)}
onClose={handleClose}
>
<MenuItem onClick={handleClose}>1</MenuItem>
<MenuItem onClick={handleClose}>2</MenuItem>
<MenuItem onClick={handleClose}>3</MenuItem>
<MenuItem onClick={handleClose}>10</MenuItem>
<MenuItem onClick={handleClose}>20</MenuItem>
<MenuItem onClick={handleClose}>300</MenuItem>
</Menu>
</div>
);
}
Related documentation:
https://developer.mozilla.org/en-US/docs/Web/CSS/justify-content
https://css-tricks.com/snippets/css/a-guide-to-flexbox/
A more flexible solution to your problem,
use <ListItemText> inside <MenuItem>
In this way you can style parts of the element.
<MenuItem onClick={handleClose}>
<ListItemText style={{ paddingRight: 50 }}>undo</ListItemText>
<ListItemText style={{ textAlign: "right" }}>ctrl+z</ListItemText>
</MenuItem>
example : shortcut hint on the right.
You can use this code to align the menu
anchorOrigin={{
vertical: 'bottom',
horizontal: 'center',
}}
transformOrigin={{
vertical: 'bottom',
horizontal: 'center',
}}
Example
<Menu
id="order-menu"
anchorEl={anchorEl}
keepMounted
open={Boolean(anchorEl)}
onClose={() => setAnchorEl(null)}
anchorOrigin={{
vertical: 'bottom',
horizontal: 'center',
}}
transformOrigin={{
vertical: 'bottom',
horizontal: 'center',
}}
style={{top: 170}} // you can set top position so that it will show under the selection
>
{options.map((option, index) => (
<MenuItem
key={option}
selected={index === selectedIndex}
onClick={(event) => handleMenuItemClick(event, index)}
>
{option}
</MenuItem>
))}
mui 5 could use sx.
<MenuItem sx={{ justifyContent: 'flex-end' }}>

How to split material-ui toolbar into left and right part

How to split material-ui toolbar into left and right part. For example, this is my toolbar
let EnhancedTableToolbar = props => {
const { numSelected, classes ,deletefunc} = props;
return (
<Toolbar
className={classNames(classes.root, {
[classes.highlight]: numSelected > 0,
})}
>
<div className={classes.title}>
{numSelected > 0 ? (
<Typography color="inherit" variant="subtitle1">
{numSelected} selected
</Typography>
) : (
<Typography variant="h6" id="tableTitle">
User List
</Typography>
)}
</div>
<div className={classes.actions}>
{numSelected > 0 ? (
<div >
<div style={{ display: 'inline-block' }}>
<Tooltip title="Delete">
<IconButton aria-label="Delete">
<DeleteIcon onClick={() => { if (window.confirm('Are you sure you wish to delete '+numSelected +' item?')) {deletefunc()} } }>
</DeleteIcon>
</IconButton>
</Tooltip>
</div>
<div style={{ display: 'inline-block' }}>
<Tooltip title="Edit">
<IconButton aria-label="Edit">
<EditIcon>
</EditIcon>
</IconButton>
</Tooltip>
</div>
</div>
) : (
<Tooltip title="Filter list">
<IconButton aria-label="Filter list">
<FilterListIcon />
</IconButton>
</Tooltip>
)}
</div>
</Toolbar>
);
};
I want to show the numSelected in my left side of toolbar and the delete button and edit button at my right side of toolbar. However, my example output show the delete button and edit button just beside the numSelected. Anyone has any solution regarding this issue?
The solution is add
flex: '0 0 auto'
in my actions class and a
<div className={classes.spacer}>
between title class and action class.
This is how I setup spacer, title and action classes.
const toolbarStyles = theme => ({
root: {
paddingRight: theme.spacing.unit,
},
highlight:
theme.palette.type === 'light'
? {
color: theme.palette.secondary.main,
backgroundColor: lighten(theme.palette.secondary.light, 0.85),
}
: {
color: theme.palette.text.primary,
backgroundColor: theme.palette.secondary.dark,
},
spacer: {
flex: '1 1 100%',
},
actions: {
color: theme.palette.text.secondary,
flex: '0 0 auto',
},
title: {
flex: '0 0 auto',
},
});

Categories

Resources