How I can collapse only the click item?, I am using customize in material ui Customization
what I want is to show only the list of item in the select item this code will show all the list item not the list of the clicked item. I am only following the customization in the nested list in material ui and also I use the nested list it will show also the same output.
const [open, setOpen] = React.useState(false)
const handleToggle = () => {
setOpen((toggleOpen) => !toggleOpen)
}
const drawer = (
<Paper elevation={0} sx={{maxWidth: 256}}>
<StyledNav component="nav" disablePadding>
<ListItemButton component="a" href="/app/profile">
{loading ? (
<Typography>loading...</Typography>
) : data ? (
<Fragment>
<ListItemIcon
sx={{
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
minHeight: 'fit-content',
padding: theme.spacing(0.5),
}}
>
<Avatar sx={useStyles.avatar} alt="User">
{getinitials(`${data.me?.lastname} ${data.me?.firstname}`)}
</Avatar>
</ListItemIcon>
<Stack>
<ListItemText
sx={{my: 0}}
primary={`${data.me?.lastname} ${data.me?.firstname}`}
primaryTypographyProps={{
fontSize: 20,
fontWeight: 'medium',
letterSpacing: 0,
}}
/>
<ListItemText
sx={{my: -1}}
primary={`${data.me?.username}`}
primaryTypographyProps={{
fontSize: 15,
fontWeight: 'medium',
letterSpacing: 0,
}}
/>
</Stack>
</Fragment>
) : null}
</ListItemButton>
<Divider />
{!loadingGetUserPagesAccess &&
dataGetUserPagesAccess &&
dataGetUserPagesAccess.userPagesAccess.map((pagegroup) => {
return (
<Fragment key={pagegroup.name}>
<List
sx={{
width: '100%',
maxWidth: 360,
bgcolor: open ? 'rgba(71, 98, 130, 0.2)' : null,
}}
subheader={<ListSubheader>{pagegroup.name}</ListSubheader>}
>
{pagegroup.pages?.map((page) => {
return (
<Fragment key={page.name}>
<ListItemButton
alignItems="flex-start"
onClick={handleToggle}
sx={{
px: 3,
pt: 2.5,
pb: open ? 0 : 2.5,
'&:hover, &:focus': {
'& svg': {opacity: open ? 1 : 0},
},
}}
disableGutters
>
<ListItemText
primary={page.name}
primaryTypographyProps={{
fontSize: 15,
fontWeight: 'medium',
lineHeight: '20px',
mb: '2px',
}}
secondaryTypographyProps={{
noWrap: true,
fontSize: 12,
lineHeight: '16px',
color: open
? 'rgba(0,0,0,0)'
: 'rgba(255,255,255,0.5)',
}}
sx={{my: 0}}
/>
<KeyboardArrowDown
sx={{
mr: -1,
opacity: 100,
transform: open ? 'rotate(-180deg)' : 'rotate(0)',
transition: '0.2s',
}}
/>
</ListItemButton>
{open &&
page.subpages &&
page.subpages.map((subpage) => {
return (
<ListItemButton
sx={{
py: 0,
minHeight: 32,
}}
>
<ListItemText
primary={subpage.name}
primaryTypographyProps={{
fontSize: 14,
fontWeight: 'medium',
}}
onClick={() => {
navigate(`/app/services${subpage.url}`)
}}
/>
</ListItemButton>
)
})}
</Fragment>
)
})}
</List>
</Fragment>
)
})}
</StyledNav>
</Paper>)
what should I do thank you..
Related
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.
I want to customize the Appbar for mobile devices but I don't know why I cant't. Somebody,please help me to do that.
here is the appbar for mobile devices. I want to change the background and width:
I have shared my full code here with inline styles. By the way I am using material using version 5.
import React from 'react';
import {
Button,
Menu,
MenuItem,
AppBar,
Box,
Toolbar,
IconButton,
Typography,
Container,
Fade,
} from '#mui/material';
import MenuIcon from '#mui/icons-material/Menu';
import Link from 'next/link';
import logo from '../../assets/main_logo.png';
import Image from 'next/image';
const Navbar = () = > {
const[anchorElNav, setAnchorElNav] = React.useState(null);
const handleOpenNavMenu = (event) = > {
setAnchorElNav(event.currentTarget);
};
const handleCloseNavMenu = () = > {
setAnchorElNav(null);
};
const[anchorEl, setAnchorEl] = React.useState(null);
const open = Boolean(anchorEl);
const handleClick = (event) = > {
setAnchorEl(event.currentTarget);
};
const handleClose = () = > {
setAnchorEl(null);
};
return ( < AppBar position = 'sticky'
sx = {
{
backgroundColor: '#000000',
opacity: '0.9'
}
} >
<Container maxWidth='xl'>
<Toolbar disableGutters>
<Typography
variant='h6'
noWrap
component='a'
href='/'
sx={{
mr: 2,
display: { xs: 'none', md: 'flex' },
fontFamily: 'monospace',
fontWeight: 700,
letterSpacing: '.3rem',
color: 'inherit',
textDecoration: 'none',
}}
>
<Image src={logo} alt='site_logo' height={40} width={210} />
</Typography>
<Box
sx={{
flexGrow: 1,
display: { xs: 'flex', md: 'none' },
}}
>
<IconButton
size='large'
aria-label='account of current user'
aria-controls='menu-appbar'
aria-haspopup='true'
onClick={handleOpenNavMenu}
color='primary'
>
<MenuIcon />
</IconButton>
<Menu
id='menu-appbar'
anchorEl={anchorElNav}
anchorOrigin={{
vertical: 'bottom',
horizontal: 'left',
}}
keepMounted
transformOrigin={{
vertical: 'top',
horizontal: 'left',
}}
open={Boolean(anchorElNav)}
onClose={handleCloseNavMenu}
>
<MenuItem onClick={handleCloseNavMenu}>
<Typography textAlign='center'>Home</Typography>
</MenuItem>
<Typography
onClick={handleClick}
onMouseEnter={handleClick}
onMouseLeave={handleClick}
textAlign='center'
>
Services
</Typography>
<MenuItem onClick={handleCloseNavMenu}>
<Typography textAlign='center'>Projects</Typography>
</MenuItem>
<MenuItem onClick={handleCloseNavMenu}>
<Typography textAlign='center'>Blog</Typography>
</MenuItem>
<MenuItem onClick={handleCloseNavMenu}>
<Typography textAlign='center'>Career</Typography>
</MenuItem>
<MenuItem onClick={handleCloseNavMenu}>
<Typography textAlign='center'>About</Typography>
</MenuItem>
</Menu>
</Box>
<Typography
variant='h5'
noWrap
component='a'
href='/'
sx={{
mr: 2,
display: { xs: 'flex', md: 'none' },
flexGrow: 1,
fontFamily: 'monospace',
fontWeight: 700,
letterSpacing: '.3rem',
color: 'inherit',
textDecoration: 'none',
}}
>
<Image src={logo} alt='site_logo' height={40} width={200} />
</Typography>
<Box
sx={{
flexGrow: 1,
display: { xs: 'none', md: 'flex' },
margin: '0 2rem',
}}
>
<Button
onClick={handleCloseNavMenu}
sx={{
my: 2,
color: 'white',
display: 'block',
textTransform: 'capitalize',
fontSize: '1rem',
padding: '0 1rem',
}}
>
Home
</Button>
<Button
onMouseOver={handleClick}
sx={{
my: 2,
color: 'white',
display: 'block',
textTransform: 'capitalize',
fontSize: '1rem',
padding: '0 1rem',
}}
>
Services
</Button>
<Menu
id='fade-menu'
MenuListProps={{
'aria-labelledby': 'fade-button',
}}
anchorEl={anchorEl}
open={open}
onClose={handleClose}
TransitionComponent={Fade}
sx={{
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
position: 'absolute',
top: '15',
}}
>
<MenuItem onClick={handleClose}>Web Development</MenuItem>
<MenuItem onClick={handleClose}>E-Commerce Solution</MenuItem>
<MenuItem onClick={handleClose}>Digital Marketing</MenuItem>
<MenuItem onClick={handleClose}>Design & Editing</MenuItem>
</Menu>
<Button
onClick={handleCloseNavMenu}
sx={{
my: 2,
color: 'white',
display: 'block',
textTransform: 'capitalize',
fontSize: '1rem',
padding: '0 1rem',
}}
>
Projects
</Button>
<Button
onClick={handleCloseNavMenu}
sx={{
my: 2,
color: 'white',
display: 'block',
textTransform: 'capitalize',
fontSize: '1rem',
padding: '0 1rem',
}}
>
Blog
</Button>
<Button
onClick={handleCloseNavMenu}
sx={{
my: 2,
color: 'white',
display: 'block',
textTransform: 'capitalize',
fontSize: '1rem',
padding: '0 1rem',
}}
>
Career
</Button>
<Button
onClick={handleCloseNavMenu}
sx={{
my: 2,
color: 'white',
display: 'block',
textTransform: 'capitalize',
fontSize: '1rem',
padding: '0 1rem',
}}
>
About us
</Button>
</Box>
<Button
fontSize='1rem'
variant='outlined'
sx={{ textTransform: 'capitalize' }}
>
Contact us
</Button>
</Toolbar>
</Container> < /AppBar>
);`
};
export default Navbar;
You could use per-breakpoint styling on the AppBar itself.
<AppBar
sx={{
height: 100,
backgroundColor: { xs: 'green', sm: 'red' },
width: { xs: 300, sm: 500 }
}}
/>
Working example: https://codesandbox.io/s/appbar-change-width-and-color-on-mobile-mjgr30?file=/src/App.js
I am attempting to have a single user be able to choose from 1 of 2 options but when I like one they are all liked for some reason.
This is the result. I have an onClick function on the heart so that it adds the red.
https://i.stack.imgur.com/r73UB.png
Below is the code that runs when I click on the heart. I basically set the usersID into a collection called likes and save thier username
const [likes, setLikes] = useState([])
const [hasLiked, setHasLiked] = useState(false)
const likeFighter = async (e) => {
const docRef = doc(db, 'userpicks', value)
const docSnap = await getDoc(docRef)
const picksRef = doc(db, 'picks', value)
const pickSnap = await getDoc(picksRef)
let fighterID = e.target.id.toLowerCase().replace(' ', '-').replace(' ', '-')
if (hasLiked) {
await deleteDoc(doc(db, 'picks', value, 'likes', userInfo.uid))
}
else {
if (fighterID !== ' ') {
await setDoc(doc(db, 'picks', value, 'likes', userInfo.uid), {
username: userInfo.uid
})
}
}
}
This is what the database looks like. The main collection is called 'picks'. The parent collection that is.
https://i.stack.imgur.com/JVrk3.png
I also have these useEffects with snapshot listeners that run every-time a user likes a particular fighter. How can I have it so that they are only able to like one of the two fighters? If they like the left fighter they cannot like the right and vice versa.
useEffect(() => onSnapshot(collection(db, 'picks', value, 'likes'), (snapshot) =>
setLikes(snapshot.docs)
), [db, value])
useEffect(
() =>
setHasLiked(
likes.findIndex((like) => like.id === userInfo.uid) !== -1
),
[likes]
)
This is the logic that gets the fighter information from the database and renders it on the screen. I tried using the fighters name as an id so that on click it likes that particular fighter but It doesn't work.
const renderFights = fight.map((element, idx) => {
return (
<Paper elevation={0} id={element.fightID} key={idx} sx={{ width: '100%', height: '100%', display: 'flex', justifyContent: 'space-evenly' }} >
<Paper elevation={1} key={element.fighterRed} sx={{ display: 'flex', flexDirection: 'column', alignItems: 'center', width: '50%', m: 3 }}>
<Avatar sx={{ mt: 1 }} src={element.fighterRedImage} />
<Typography variant='body1'> {element.fighterRed} </Typography>
<Typography variant='overline' sx={{ fontSize: '14px' }}> {element.fighterRedRecord} </Typography>
<Paper sx={{ display: 'flex' }} elevation={0} name={element.fightID}>
{hasLiked ?
<FavoriteIcon id={element.fighterRed} onClick={likeFighter} sx={{ cursor: 'pointer', color: 'red' }} /> :
<FavoriteBorder id={element.fighterRed} onClick={likeFighter} sx={{ cursor: 'pointer' }} />
}
{likes.length > 0 && (
<Typography>{likes.length}</Typography>)
}
</Paper>
</Paper>
<Paper elevation={0} sx={{ width: '10%', display: 'flex', flexDirection: 'column', mt: 3, mb: 3, justifyContent: 'space-evenly', alignItems: 'center' }} >
<Typography sx={{ fontSize: '10px', textAlign: 'center' }} variant='overline'> {element.weightClass}</Typography>
<Typography sx={{ fontSize: '10px', textAlign: 'center' }} variant='overline'>vs</Typography>
<Chip label="FINAL U DEC" sx={{ fontSize: '8px' }} />
</Paper>
<Paper elevation={1} key={element.fighterBlue} sx={{ display: 'flex', flexDirection: 'column', alignItems: 'center', width: '50%', m: 3 }}>
<Avatar sx={{ mt: 1 }} src={element.fighterBlueImage} />
<Typography variant='body1'> {element.fighterBlue} </Typography>
<Typography variant='overline' sx={{ fontSize: '14px' }}> {element.fighterBlueRecord} </Typography>
<Paper sx={{ display: 'flex' }} elevation={0}>
{hasLiked ?
<FavoriteIcon id={element.fighterBlue} onClick={likeFighter} sx={{ cursor: 'pointer', color: 'red' }} /> :
<FavoriteBorder id={element.fighterBlue} onClick={likeFighter} sx={{ cursor: 'pointer' }} />
}
{likes.length > 0 && (
<Typography>{likes.length}</Typography>)
}
</Paper>
</Paper>
</Paper>
)
})
i have the same names in my data and I want to use unique id which i have .
However . i can not find right place for "key={id}"
<AutoCompleteComp
data={data}
setInputValue={setInputValue}
inputValue={inputValue}
setCurrentEvent={setCurrentEvent}
goToPage={goToPage}
/>
{currentEvent?.name === inputValue && (
<Box sx={{ width: "100%" }}>
{listArray.map((text, index) => (
<ListItem
// selected
onClick={() => addUrlHandler(index, text)}
button
key={text}
sx={{
"& .MuiListItemText-root": {
color: index === currentIndex ? "#6AE05F" : "",
},
"&:hover": {
backgroundColor: "rgba(36, 82, 32, 0.5)",
},
}}>
<ListItemIcon sx={{ color: "#6AE05F" }}>
{index % 2 === 0 ? <InboxIcon /> : <MailIcon />}
</ListItemIcon>
<ListItemText sx={{ color: "white" }} primary={text} />
</ListItem>
))}
It's fine to use index as key when you can't find an id.
This is from the doc:
When you don’t have stable IDs for rendered items, you may use the
item index as a key as a last resort:
<AutoCompleteComp
data={data}
setInputValue={setInputValue}
inputValue={inputValue}
setCurrentEvent={setCurrentEvent}
goToPage={goToPage}
/>
{currentEvent?.name === inputValue && (
<Box sx={{ width: "100%" }}>
{listArray.map((text, index) => (
<ListItem
// selected
onClick={() => addUrlHandler(index, text)}
button
key={index}
sx={{
"& .MuiListItemText-root": {
color: index === currentIndex ? "#6AE05F" : "",
},
"&:hover": {
backgroundColor: "rgba(36, 82, 32, 0.5)",
},
}}>
<ListItemIcon sx={{ color: "#6AE05F" }}>
{index % 2 === 0 ? <InboxIcon /> : <MailIcon />}
</ListItemIcon>
<ListItemText sx={{ color: "white" }} primary={text} />
</ListItem>
))}
I'm new to react and material UI and I've been trying to design my navbar so that my logo, search bar and drawer are in the center. I was able to get help earlier to get space between the components and have my search bar centered, but now i'm struggling to have my logo and drawer to be in the center while observing a minimum width from my searchbar.
I already tried wrapping them into a container with a specified width but they lose their alignment in the center.
here's my code:
const Search = styled('div')(({ theme }) => ({
position: 'relative',
borderRadius: 30,
backgroundColor: alpha(theme.palette.common.white, 0.15),
'&:hover': {
backgroundColor: alpha(theme.palette.common.white, 0.25),
},
// marginLeft: 10,
width: 'auto'
}));
const SearchIconWrapper = styled('div')(({ theme }) => ({
padding: theme.spacing(0, 2),
height: '100%',
position: 'absolute',
pointerEvents: 'none',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
}));
const StyledInputBase = styled(InputBase)(({ theme }) => ({
color: 'inherit',
'& .MuiInputBase-input': {
padding: theme.spacing(1, 1, 1, 0),
// vertical padding + font size from searchIcon
paddingLeft: `calc(1em + ${theme.spacing(4)})`,
transition: theme.transitions.create('width'),
width: 'auto',
},
}));
export default function SearchAppBar({ search, setSearch }) {
return (
<Box sx={{ flexGrow: 1 }}>
<AppBar position="fixed" sx={{ backgroundColor: "#55597d" }}>
<Toolbar sx={{ justifyContent: "space-between" }}>
<Stack direction="row" alignItems="center">
<img
style={{ marginRight: "10px" }}
src={logo}
alt="logo"
className="logotext"
width="38"
height="38"
/>
</Stack>
<Search>
<SearchIconWrapper>
<SearchIcon />
</SearchIconWrapper>
<StyledInputBase
sx={{ width: "auto" }}
value={search}
onChange={(e) => {
setSearch(e.target.value);
}}
placeholder="Search All Games…"
inputProps={{ "aria-label": "search" }}
/>
</Search>
{/*</div>*/}
<IconButton
size="large"
edge="start"
color="inherit"
aria-label="open drawer"
sx={{ mr: 0, ml: 0 }}
>
<MenuIcon />
</IconButton>
</Toolbar>
</AppBar>
</Box>
);
}