I'm using the menu/menu item from material ui. It seems to have an issue if I try to render it based on a condition. Refer below...
const AddSelectItemButton = () => {
return (
<>
<Fab
aria-controls="simple-menu"
aria-haspopup="true"
onClick={handleClick}
className={classes.addButton}
size="medium"
color="primary"
aria-label="add"
>
<AddIcon />
</Fab>
<Menu
id="simple-menu"
anchorEl={anchorEl}
keepMounted
open={Boolean(anchorEl)}
onClose={handleClose}
>
<MenuItem onClick={handleDelete}>Delete Item</MenuItem>
<MenuItem onClick={handleAddNew}>Add Item</MenuItem>
</Menu>
</>
)
}
Inside the main container I have something like this
return (
<div className='my-5'>
<Paper className="pl-5 pr-5 pb-5 position-relative">
<Typography className="pt-4 mb-4 text-center" variant="h4">My Items</Typography>
{!isAuthMode &&
<AddSelectItemButton />
}
<Grid container spacing={3} justify="center">
{allItems.items.map(item=>
<Grid key={item.id} item xs={5} className={`mt-4`} style={{height: '200px'}}>
<Card className={`${classes.root} d-flex ${classes.packInner}`}>
<CardActionArea className="d-flex">
<CardMedia
className={`${classes.media} ${classes.cardImage}`}
image={item.image}
title={item.brand}
/>
<CardContent className={classes.textContainer}>
<Typography gutterBottom variant="subtitle1">
{item.brand}
</Typography>
<Typography variant="body2" color="textSecondary">
{item.name}
</Typography>
<Typography variant="body2" color="textSecondary">
Weight: {item.weight}
</Typography>
<Typography variant="body2" color="textSecondary" className={classes.itemDescription}>
{packInfo.description.length > 80 ?
(`${packInfo.description.substring(0, 77) + '...'}`)
:
packInfo.description
}
</Typography>
</CardContent>
</CardActionArea>
</Card>
</Grid>
)}
</Grid>
</Paper>
</div>
);
If I don't do the condition and include the code in the original rendering. The menu loads at the position of the button. With the condition, it renders far top left of the page and not at the button.
Anyone have an idea or need more info?
Thanks!
{!isAuthMode && (
<AddSelectItemButton />
)}
Related
I am trying to perform a simple exercise, wherein I am showing the data from the local JSON file saved in my folder, and then reading it to show the data with useState, such that when a user clicks in he can edit the author and location filed and save it.
The issue I get is when I save the data in my group or location it does not populate the new value, however, it just removes the new value, but when I filter and select all values from the dropdown I can see the values in there.
Can anyone please let me know what is the missing part here? I want to achieve the task that when a user updates the value on the author group or location group they should be there with the new group value.
Please the link to the code below and a working demo on codeSandbox
watch the full code and demo here
The source code for the author group component I tried so far;
import { useEffect, useState } from "react";
import {
Container,
Accordion,
AccordionSummary,
AccordionDetails,
Typography,
Button
} from "#mui/material";
import ExpandMoreIcon from "#mui/icons-material/ExpandMore";
import EditIcon from "#mui/icons-material/Edit";
const Authorsgroup = ({
posts,
groupDropdownValue,
setShowForm,
setPostId,
showForm
}) => {
const authorGroup = posts.reduce((group, authorgroup) => {
(group[authorgroup.author.replace(/ +/g, "")] =
group[authorgroup.author.replace(/ +/g, "")] || []).push(authorgroup);
return group;
}, {});
const [authorGroupValues, setAuthorGroupValues] = useState(authorGroup);
useEffect(() => {
setAuthorGroupValues(authorGroup);
console.log(authorGroupValues);
}, [groupDropdownValue, showForm]);
return (
<>
{/* all gorupby authors */}
<Container>
{/* show group of Tapesh */}
<Container style={{ marginTop: "3rem" }}>
{authorGroupValues?.Tapesh.map((post, index) => (
<Accordion key={index}>
<AccordionSummary
expandIcon={<ExpandMoreIcon />}
aria-controls="panel1a-content"
id="panel1a-header"
>
<Typography variant="h6" style={{ color: "#EB1283" }}>
{post.id} {post.author} {post.location}
</Typography>
</AccordionSummary>
<AccordionDetails>
<Typography variant="h4">{post.location}</Typography>
<Typography>{post.text}</Typography>
<Button
variant="outlined"
onClick={() => {
setShowForm(!showForm);
setPostId(post.id);
}}
startIcon={<EditIcon />}
>
Edit
</Button>
</AccordionDetails>
</Accordion>
))}
</Container>
{/* show group of HappyManager */}
<Container style={{ marginTop: "3rem" }}>
{authorGroupValues?.HappyManager.map((post, index) => (
<Accordion key={index}>
<AccordionSummary
expandIcon={<ExpandMoreIcon />}
aria-controls="panel1a-content"
id="panel1a-header"
>
<Typography variant="h6" style={{ color: "orange" }}>
{post.id} {post.author} {post.location}
</Typography>
</AccordionSummary>
<AccordionDetails>
<Typography variant="h4">{post.location}</Typography>
<Typography>{post.text}</Typography>
<Button
variant="outlined"
onClick={() => {
setShowForm(!showForm);
setPostId(post.id);
}}
startIcon={<EditIcon />}
>
Edit
</Button>
</AccordionDetails>
</Accordion>
))}
</Container>
{/* show group of HappyDeveloper */}
<Container style={{ marginTop: "3rem" }}>
{authorGroupValues?.HappyDeveloper.map((post, index) => (
<Accordion key={index}>
<AccordionSummary
expandIcon={<ExpandMoreIcon />}
aria-controls="panel1a-content"
id="panel1a-header"
>
<Typography variant="h6" style={{ color: "green" }}>
{post.id} {post.author} {post.location}
</Typography>
</AccordionSummary>
<AccordionDetails>
<Typography variant="h4">{post.location}</Typography>
<Typography>{post.text}</Typography>
<Button
variant="outlined"
onClick={() => {
setShowForm(!showForm);
setPostId(post.id);
}}
startIcon={<EditIcon />}
>
Edit
</Button>
</AccordionDetails>
</Accordion>
))}
</Container>
{/* show group of HappyUser */}
<Container style={{ marginTop: "3rem" }}>
{authorGroupValues?.HappyUser.map((post, index) => (
<Accordion key={index}>
<AccordionSummary
expandIcon={<ExpandMoreIcon />}
aria-controls="panel1a-content"
id="panel1a-header"
>
<Typography variant="h6" style={{ color: "red" }}>
{post.id} {post.author} {post.location}
</Typography>
</AccordionSummary>
<AccordionDetails>
<Typography variant="h4">{post.location}</Typography>
<Typography>{post.text}</Typography>
<Button
variant="outlined"
onClick={() => {
setShowForm(!showForm);
setPostId(post.id);
}}
startIcon={<EditIcon />}
>
Edit
</Button>
</AccordionDetails>
</Accordion>
))}
</Container>
</Container>
</>
);
};
export default Authorsgroup;
Thanks any suggestions or help are really appreciated.
I am trying to make a card grid where the user can expand the card to view its details. The issue I am facing with the react hooks is that the function is getting called for all cards instead of the particular card I am clicking the button. As a result, all the cards are getting expanded.
Here's my code for reference.
Any help is highly appreciated. Thank you!
function Album(props) {
return (
<div>
<Card className={classes.card}>
<Card.Text >
<p className={classes.heading}>
{props.blogTitle}
</p>
</Card.Text>
<Card.Body>
<Card.Img
src={props.imgsrc}
alt="Card image"
className={classes.cardMedia}
/>
{props.cardOpen &&
<AnimatePresence>
<motion.div
initial={{opacity:0}}
animate={{opacity:1, transition:0.3}}
>
<p className={classes.desc} gutterbottom>
{props.blogDescription}
</p>
<div href={props.blogLink}
style={{color:"gray", fontSize:17, fontFamily:"calibri", fontSmooth: "auto", cursor:"pointer", display:"flex", justifyContent:"center"}}>
<LocalLibraryIcon style={{marginRight:7}}/>Read blog
</div>
</motion.div>
</AnimatePresence>
}
{(props.cardOpen) ?
<div onClick={props.isOpen} style={{float:"right", cursor:"pointer"}}>
<ExpandLessIcon style={{fontSize:40, marginTop:10, color:" #909090"}}/>
</div> : (
<div onClick={props.isOpen} style={{float:"right", cursor:"pointer"}}>
<ExpandMoreIcon style={{fontSize:40, marginTop:10, color:" #909090"}}/>
</div>
)}
</Card.Body>
</Card>
</div>
);
}
export default function ProjectItems() {
const [cardOpen, setCardOpen]= useState(false);
return (
<React.Fragment>
<CssBaseline />
<main>
<div className={classes.heroContent}>
<Container maxWidth="md">
<Typography
variant="h2"
align="center"
color="textPrimary"
className={classes.root}
gutterBottom
>
Blogs
</Typography>
</Container>
</div>
<Container maxWidth="md">
<Grid container spacing={4}>
{blogData.map(post => (
<Grid item xs={12} sm={6} md={4} key={post.id}>
<div>
<Album
blogId={post.id}
blogTitle={post.title}
blogDescription={post.summary}
imgsrc={post.image_link}
blogLink={post.article_link}
isOpen={()=>{
setCardOpen(!cardOpen);
}}
cardOpen={cardOpen}
/>
</div>
</Grid>
))}
</Grid>
</Container>
</main>
</React.Fragment>
);
}
I have an array of news that I'm displaying through Material-ui components, while mapping over it when I click on one dropdown to show more from the description, all the cards opens up instead of only the one I clicked on. I would like to avoid this behaviour. If you can answer my question it will be appreciated. The code is this
{Articles.map((article, index) => {
return (
<>
<Grid item xs={12} sm={6}>
<Card key={index} className={classes.root}>
<CardHeader
action={
<IconButton aria-label="settings">
<MoreVertIcon />
</IconButton>
}
title={article.title}
subheader={new Date(article.publishedAt).toLocaleString(
"it-IT",
options
)}
/>
<CardMedia
className={classes.media}
image={article.urlToImage}
title={article.title}
/>
<CardContent>
<Typography
variant="body2"
color="textSecondary"
component="p"
>
{article.description}
</Typography>
</CardContent>
<CardActions disableSpacing>
<IconButton aria-label="add to favorites">
<FavoriteIcon />
</IconButton>
<IconButton aria-label="share">
<ShareIcon />
</IconButton>
<IconButton
className={clsx(classes.expand, {
[classes.expandOpen]: expanded,
})}
onClick={handleExpandClick}
aria-expanded={expanded}
aria-label="scopri di piu"
>
<ExpandMoreIcon />
</IconButton>
</CardActions>
<Collapse in={expanded} timeout="auto" unmountOnExit>
<CardContent>
<Typography paragraph>{article.content}</Typography>
<Typography>
Per leggere l'intero articolo clicca{" "}
<a
href=""
target="_blank"
rel="noreferrer noopener canonical"
>
qui
</a>
</Typography>
</CardContent>
</Collapse>
</Card>
<br />
<br />
<br />
</Grid>
</>
)
})}
</Grid>
The handleExpandClick function
const [expanded, setExpanded] = useState(false)
const handleExpandClick = () => {
setExpanded(!expanded)
}
I use materiel ui
Interested in putting a text followed by a divider
like this
I tried to do that
<Grid>
<Typography variant="h6" color="primary">
{'text'}
</Typography>
<Divider variant="inset"></Divider>
</Grid>
But this is the result I got
You can use Box component.
// using display grid
<Box
display="grid"
alignItems="center"
gridColumnGap={16}
gridTemplateColumns={"1fr auto"}
>
<Divider />
<Typography variant="h6" color="primary">
hello world
</Typography>
</Box>
// using flex box
<Box display="flex" alignItems="center">
<Divider style={{ flexGrow: 1, marginRight: 16 }} />
<Typography variant="h6" color="primary">
hello world
</Typography>
</Box>
This seems like a basic question, but there is no example of how to accomplish this in the official documentation of Material UI.
I have tried nesting the grid, but the grid element on the right will not span the vertical space. I have tried align-items="stretch".
A screenshot and my code are below. Thanks for any suggestions!
return (
<Container>
<Box>
<Typography>Test</Typography>
</Box>
<Grid container spacing={3} direction="row" justify="center" alignItems="stretch">
<Grid item xs={12}>
<Paper className={classes.paper}>xs=12</Paper>
</Grid>
<Grid item xs={6} spacing={3}>
<Grid>
<Card className={classes.root} variant="outlined">
<CardContent>
<Typography className={classes.title} color="textSecondary" gutterBottom>
Customer Profile
</Typography>
<Typography variant="h5" component="h2">
Sarah Doria
</Typography>
<Typography className={classes.pos} color="textSecondary">
Position
</Typography>
<Typography variant="body2" component="p">
Company
<br />
{'"a benevolent smile"'}
</Typography>
</CardContent>
<CardActions>
<Button size="small">Learn More</Button>
</CardActions>
</Card>
</Grid>
<Grid>
<Card className={classes.root} variant="outlined">
<CardContent>
<Typography className={classes.title} color="textSecondary" gutterBottom>
Preferences
</Typography>
<Typography variant="h5" component="h2">
Color
</Typography>
<Typography className={classes.pos} color="textSecondary">
Size
</Typography>
<Typography variant="body2" component="p">
Style
<br />
{'"a benevolent smile"'}
</Typography>
</CardContent>
<CardActions>
<Button size="small">Learn More</Button>
</CardActions>
</Card>
<Grid>
<Card className={classes.root} variant="outlined">
<CardContent>
<Typography className={classes.title} color="textSecondary" gutterBottom>
Lifestyle
</Typography>
<Typography variant="h5" component="h2">
Destination:
</Typography>
<Typography className={classes.pos} color="textSecondary">
Climate:
</Typography>
<Typography variant="body2" component="p">
Beverages:
<br />
{'"a benevolent smile"'}
</Typography>
</CardContent>
<CardActions>
<Button size="small">Learn More</Button>
</CardActions>
</Card>
</Grid>
</Grid>
</Grid>
<Grid item xs={6}>
<Grid>
<Card className={classes.root} variant="outlined">
<CardContent>
<Typography className={classes.title} color="textSecondary" gutterBottom>
Customer Cart
</Typography>
<Typography variant="h5" component="h2">
Sarah Doria
</Typography>
<Typography className={classes.pos} color="textSecondary">
Position
</Typography>
<Typography variant="body2" component="p">
Company
<br />
{'"a benevolent smile"'}
</Typography>
</CardContent>
<CardActions>
<Button size="small">Learn More</Button>
</CardActions>
</Card>
</Grid>
</Grid>
</Grid>
</Container>
);
}
Simply add height 100% on Card and Grid
<Grid style={{ height: "100%" }}>
<Card style={{ height: "100%" }}>
import React from "react";
import "./styles.css";
import {
Grid,
Typography,
Container,
Box,
Paper,
Card,
CardContent,
CardActions,
Button
} from "#material-ui/core";
const YourCard = () => {
const classes = {};
return (
<Card
className={classes.root}
variant="outlined"
style={{ height: "100%" }}
>
<CardContent>
<Typography
className={classes.title}
color="textSecondary"
gutterBottom
>
Customer Profile
</Typography>
<Typography variant="h5" component="h2">
Sarah Doria
</Typography>
<Typography className={classes.pos} color="textSecondary">
Position
</Typography>
<Typography variant="body2" component="p">
Company
<br />
{'"a benevolent smile"'}
</Typography>
</CardContent>
<CardActions>
<Button size="small">Learn More</Button>
</CardActions>
</Card>
);
};
export default function App() {
const classes = {};
return (
<Container>
<Box>
<Typography>Test</Typography>
</Box>
<Grid
container
spacing={3}
direction="row"
justify="center"
alignItems="stretch"
>
<Grid item xs={12}>
<Paper className={classes.paper}>xs=12</Paper>
</Grid>
<Grid item xs={6}>
<Grid container spacing={3}>
<Grid item xs={12}>
<YourCard />
</Grid>
<Grid item xs={12}>
<YourCard />
</Grid>
<Grid item xs={12}>
<YourCard />
</Grid>
</Grid>
</Grid>
<Grid item xs={6}>
<Grid style={{ height: "100%" }}>
<YourCard />
</Grid>
</Grid>
</Grid>
</Container>
);
}