Material Ui card change according to input - javascript

I have used material ui card and when i display it. It shows like below image. I want to show my card like that when cards do not fit the page it goes below and all card size must be same. How can i do that?
Here is my code:
const useStyles = makeStyles({ // Styling for my cards
root: {
width: 255,// i changed that line and below line but nothing happened
},
media: {
height: 190,
},
});
export default function AlbumsCard() {
const classes = useStyles();
..... //Some http requests
return (
<div>
<div>
<input
style={{
width: 500,
"margin-left": "auto",
"margin-right": "auto",
"margin-top": "10px",
}}
type="text"
placeholder="Search Album"
onChange={handleChange}
value={input}
/>
</div>
<div style={{ display: "flex" }}> //cardss
{k.map((album) => (
<Link
to={`/albums/${album.album_id}`}
style={{ textDecoration: "none", color: "#15cdfc" }}
>
<Card style={{ margin: "10px" }} className={classes.root}>
<CardActionArea>
<CardMedia
className={classes.media}
image={album.album_pfp}
title={album.album_name}
/>
<CardContent>
<Typography gutterBottom variant="h5" component="h2">
{album.album_name}
</Typography>
<Typography
variant="body2"
color="textSecondary"
component="p"
>
{album.album_song_count}
</Typography>
</CardContent>
</CardActionArea>
</Card>
</Link>
))}
</div>
</div>
);
}
Also the image from my app:
You can see that above. All cards placed in a line and some cards height's are different. Also there is a scroll bar.
I want to display whole card i a same size and when it overflows the page. It goes below.
Updated version:
Now each card has a different size how can i solve that? I think it is from image size.

Related

Skeleton-Avatar and ImageButton in MUI React are forced to oval background shapes

When using mui Stack I get weird side effect of geting all the background shapes of Skeleton Avatar and background area smeared to oval|elipsoid shapes. I tried setting equal width and height for Avatar but id does not help.
How can I fix it throguh sx mui component property or css?
code fragment
<Box
noValidate autoComplete="off"
sx={{ marginLeft: '15%','& .MuiTextField-root': { m: 2, width: '25ch' }}}>
<div>
<form onSubmit={onSubmit} >
{formFields.map((form, index) => {
return (
<Fade in={true} sx = {{width: '95%'}} {...{ timeout: 500 }}>
<Stack direction="row" borderRadius="0" spacing={2} key={index} style ={{marginLeft: '-50px', }}>
{form.img? <Avatar alt="release img" src={form.img} sx={{ width: 56, height: 56 }} /> : <Skeleton animation={false} variant ='circular'> <Avatar sx={{ width: 56, height: 56}} /> </Skeleton>}
<TextField {/* ... */}/>
<IconButton onClick={() => removeFields(index)}><DeleteIcon /</IconButton>
</Stack>
</Fade>
)
})}
</form>
<IconButton onClick={addFields} color={'warning'}> <AddCircleOutlineOutlinedIcon /></IconButton>
<br></br><br></br>
<Button onClick={onSubmit} color={'warning'} variant="contained" endIcon= {<SendIcon/>} > Search links </Button>
Normally, the default value of align-items for flex items will be stretch, that's why you see your icon is stretched in the cross axis
The solution is simple, set alignItems prop in Stack to a different value rather than normal/stretch. Here I use center
<Stack
direction="row"
borderRadius="0"
spacing={2}
alignItems="center" // this line
style={{ marginLeft: "-50px" }}
>
Demo
References
CSS align-items

How to reload a webpage once routed to using react-router-dom

Re-asking from a previous questions as this could be a work around.
I have a widget I'm using from a software provider (Mindbody) it needs to load some data using a <script> tag which I have in the head of my app. The page is being routed to using react-router-dom. The problem the js data only loads when you refresh the page.
What is a good method to reloading a page as soon as the page is routed to. I tried window.location.refresh(); but this loads infinite time.
import * as React from 'react';
import { Stack, Box, Typography, Modal, Backdrop } from '#mui/material';
import ButtonV2 from './ButtonV2';
import PurchaseWidget from './PurchaseWidget';
const style = {
position: 'absolute',
top: '50%',
left: '50%',
transform: 'translate(-50%, -50%)',
width: 400,
bgcolor: 'background.paper',
boxShadow: 24,
borderRadius: 3,
transition: "5s ease-in-out"
};
const PurchaseLanding = () => {
const [show, setShow] = React.useState(true);
const handleClose = () => setShow(false);
return (
<div>
<Modal
open={show}
onClose={handleClose}
aria-labelledby="modal-modal-title"
aria-describedby="modal-modal-description"
disableAutoFocus="true"
BackdropComponent={Backdrop}
BackdropProps={{
timeout: 500,
}}>
<Box sx={style}>
<div>
{/* full width image */}
<img style={{borderRadius: "10px 10px 0 0"}} src="https://res.cloudinary.com/djjb1vyjm/image/upload/v1660541084/1_uxhi8p.png" width="100%" alt="" />
</div>
<Box p={2}>
{/* title */}
<Typography align="center" id="modal-modal-title" variant="h5" component="h2">
<span className='space-font-heavy'>Buy your [10-pack]</span>
</Typography>
{/* onboarding message */}
<Stack pb={3} alignItems="center" justifyContent="center" direction="row" spacing={2}>
<Typography px={1} align="center" id="modal-modal-description" sx={{ mt: 2 }}>
<span className='space-font-light'>Once completed download the Mindbody app to add, update, and book your workouts!</span>
</Typography>
</Stack>
{/* button group left/right */}
<Stack direction="row" justifyContent="center" alignItems="center">
<ButtonV2 />
</Stack>
</Box>
</Box>
</Modal>
</div>
);
}
export default PurchaseLanding

How to styling a card from rectangular to square

everyone, i have a frontend code that displaying card with rectangular but i want to display it in square, please help since i have tried so many time and didn't change to square
const useStyles = makeStyles({
gridContainer: {
paddingLeft: "40px",
paddingRight: "40px",
// borderWidth:100
},
root: {
// minWidth:50,
flex:1
},
bullet: {
display: "inline-block",
margin: "0 2px",
transform: "scale(0.8)",
},
title: {
fontSize: 14,
},
pos: {
marginBottom: 12,
},
});
function Home() {
return (
<div>
<div>
<h1>Product List</h1>
</div>
<Grid
container
spacing={4}
className={classes.gridContainer}
justify="center"
>
{getData.map((x, index) => {
return (
<Grid key={index} item xs={12} sm={6} md={4} style={{
flex: 1,
flexDirection: "row",
justifyContent: "center",
alignItems: "stretch",
}}
>
<Card className={classes.root} variant="outlined">
<CardContent>
<Typography className={classes.pos} color="textSecondary">
<center>
{x.sku}
</center>
</Typography>
<Typography className={classes.pos} color="textSecondary">
<center>
{x.name}
</center>
</Typography>
<Typography className={classes.pos} color="textSecondary">
<center>
{x.price}
</center>
</Typography>
</CardContent>
</Card>
</Grid>
);
})}
</Grid>
</div>
);
}
From above, it shows that card will display in rectangular
Current output
I'm struggle with the styling issue so please advise and correct me if i'm wrong, thanks :)

Set Material UI card to max height

I am using Material UI Card as seen here.
I want to set these cards to a maximum height, nicely handling the text and pictures inside. How would I do this?
Here is some code:
<Card className={classes.card} >
<CardHeader
avatar={
<Avatar aria-label={authorAvatar} src={authorImg} className={classes.avatar}/>
}
action={
<Fieldset className={classes.date}>
{postDate}
</Fieldset>
}
title={post.title}
subheader={
<Link to={userUrl}>
{authorName}
</Link>
}
/>
<CardContent>
<div className="content" dangerouslySetInnerHTML={{__html: DOMPurify.sanitize(bodyHtml)}}></div>
</CardContent>
<CardActions className={classes.actions} disableActionSpacing>
<IconButton
className={classnames(classes.unliked, {
[classes.liked]: this.state.liked,
})}
aria-label="Add to favorites"
onClick={this.handleFavourite}
>
I am trying to use sizing and maxHeight, but I cannot get the syntax right.
import maxHeight from '#material-ui/system/sizing';
<CardContent maxHeight = "10">
This gives several errors.
Do I put it here?
const styles = theme => ({
card: {
marginTop: 20,
maxHeight: 300,
},
I got this working in the following way:
import { sizing } from '#material-ui/system/';
const styles = theme => ({
card: {
marginTop: 20,
sizing, maxHeight: 300,
},

Using a ternary operator in a map function is rendering both results

I'm creating a vertical timeline with cards alternating sides as you move along the timeline, I'm trying to include a Popover effect to show more info about a person/event that fills the opposite whitespace on the timeline.
I'm trying to achieve this by using a ternary operator (using modulus to alternate sides in order) in my map callback, but it's rendering/returning both possible Popover results, onClick leads to a Popover popping on both sides of the card.
render() {
const cards = timelineObjects.map((card, i) => (
<React.Fragment key={i}>
{i % 2 === 0 ? (
<VerticalTimelineElement
className="vertical-timeline-element--work"
key={i}
iconStyle={{
background: "rgb(40,49,72)",
color: "#000"
}}
paddingTop="0em"
//icon={<Print/>}
>
<div>
<Card className="card">
<CardActionArea>
<CardMedia
style={{ height: 0, paddingTop: "100%" }}
image={card.image}
/>
<CardContent>
<Typography gutterBottom variant="h5" component="h2">
{card.title}
</Typography>
<Typography component="p">{card.subtitle}</Typography>
</CardContent>
</CardActionArea>
<Button
size="small"
color="primary"
component={Link}
//to={card.path}
onClick={this.handlePop}
>
Learn More, index: {i}, RIGHT
</Button>
<Popover
open={this.state.popped}
anchorEl={this.state.anchorEl}
anchorOrigin={{
horizontal: "right",
vertical: "center "
}}
transformOrigin={{
horizontal: "right",
vertical: "bottom"
}}
onClose={this.handleRequestClose}
>
Right popover text
</Popover>
</Card>
</div>
</VerticalTimelineElement>
)
:
(
<VerticalTimelineElement
className="vertical-timeline-element--work"
key={i}
iconStyle={{
background: "rgb(40,49,72)",
color: "#000"
}}
paddingTop="0em"
//icon={<Print/>}
>
<div>
<Card className="card">
<CardActionArea>
<CardMedia
style={{ height: 0, paddingTop: "100%" }}
image={card.image}
/>
<CardContent>
<Typography gutterBottom variant="h5" component="h2">
{card.title}
</Typography>
<Typography component="p">{card.subtitle}</Typography>
</CardContent>
</CardActionArea>
<Button
size="small"
color="primary"
component={Link}
//to={card.path}
onClick={this.handlePop}
>
Learn More, index : {i}, LEFT
</Button>
<Popover
open={this.state.popped}
anchorEl={this.state.anchorEl}
anchorOrigin={{
horizontal: "left",
vertical: "center "
}}
transformOrigin={{
horizontal: "left",
vertical: "bottom"
}}
onClose={this.handleRequestClose}
>
Left popover text
</Popover>
</Card>
</div>
</VerticalTimelineElement>
)}
</React.Fragment>
));
Here's a screen grab of the result.
Your popovers are all anchored to the same element (this.state.anchorEl) and are all configured to open based upon the same boolean (this.state.popped). This means if you have 2+ objects in your timeline, you render a popover for each object, and all popovers will be opened or closed together and all will be to the left/right of the only anchor element (whatever that is).
You should probably create a new TimelineObject component that renders a single timeline object and can have its own local state and assigns its own local anchorEl to anchor its popover to. Possibly its own popped state as well. Then your map function would be more like:
timelineObjects.map((card, i) => <TimelineObject key={i} card={card} onLeft={i%2==0} />)
Alternatively, instead of using this.state.popped as a boolean, use it as the card index to show the popup for. And in your Popover code do:
<Popover open={this.state.popped === i} ...
And when you set popped set it like this.setState({popped: indexOfCardToShowPopover, anchorEl: elementOfCardToAnchorPopover });
That way only 1 popover is ever open at a time.

Categories