How to styling a card from rectangular to square - javascript

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 :)

Related

How can I make the Material UI Chip component not to be displayed when there is no content inside?

I am creating an app that will display some content from an Api.
I have created a Material UI Card component to present the information I get and within that card, I have a mui Chip component.
<Card sx={{ width: "368px" }}>
<CardActionArea>
<CardMedia component="img" height="200" image={image} />
<CardContent>
<Box sx={{ display: "flex", alignItems: "center" }}>
<Typography variant="subtitle2" color="#1976d2">
{center}
<FiberManualRecordIcon sx={{ fontSize: 4 }} />
</Typography>
<Typography variant="subtitle2" color="#1976d2">
{date}
</Typography>
</Box>
<Typography variant="h5" component="div">
{title}
</Typography>
<Typography
sx={{
display: "-webkit-box",
overflow: "hidden",
textOverflow: "ellipsis",
}}
variant="body2"
>
{description}
</Typography>
<Box />
<Box>
<Chip label={keywords} />
</Box>
</CardContent>
</CardActionArea>
</Card>
The labels of the Chip component are some keywords,which I get them from an Api response. But sometimes there are no keywords. In that case, I want the mui Chip component not to be displayed at all, instead of getting one with empty content. Is there a way to make it happen?
Please try this.
<Card sx={{ width: "368px" }}>
<CardActionArea>
<CardMedia component="img" height="200" image={image} />
<CardContent>
<Box sx={{ display: "flex", alignItems: "center" }}>
<Typography variant="subtitle2" color="#1976d2">
{center}
<FiberManualRecordIcon sx={{ fontSize: 4 }} />
</Typography>
<Typography variant="subtitle2" color="#1976d2">
{date}
</Typography>
</Box>
<Typography variant="h5" component="div">
{title}
</Typography>
<Typography
sx={{
display: "-webkit-box",
overflow: "hidden",
textOverflow: "ellipsis",
}}
variant="body2"
>
{description}
</Typography>
<Box />
<Box>
{keywords && ( <Chip label={keywords} />)}
</Box>
</CardContent>
</CardActionArea>
</Card>

Different Appbars in two different lines - width

I'm in my first project with Material UI and React and there's a problem I've encountered in terms of design, I want to make sure that each AppBar is in a separate row, and stays the same size as in the image.
Note that I've already tried changing the container direction to columns'/rows, then it does each in a separate row but each AppBar takes up all the screen width and if I try to change the width to a certain percentage of the screen it loses proportion.
I would appreciate your assistance!
I'm attaching a picture of what my current situation is (I just want to put the slider under the Buttons AppBar )
this is the problem
return (
<main className={classes.content}>
{/* <div className={classes.toolbar} /> */}
<Grid container spacing={2} justify='center'>
<Grid item>
<AppBar
position='static'
sx={{
backgroundColor: '#212121 !important ',
borderRadius: 8,
display: 'flex',
flexDirection: 'row',
justifyContent: 'space-around',
// width: "min",
// margin: "auto",
}}
style={{
border: 'solid white 0.1px',
}}
>
<Toolbar>
<Button
className={classes.btn}
sx={{
m: 2,
textTransform: 'capitalize',
}}
variant='outlined'
size='small'
//onClick={handleCategoryClicked}
>
filter by category
</Button>
<Button
className={classes.btn}
sx={{ m: 2, textTransform: 'capitalize' }}
variant='outlined'
size='small'
onClick={(e) => sortResults(e, 'price')}
>
filter by price
</Button>
<Button
className={classes.btn}
sx={{ m: 2, textTransform: 'capitalize' }}
variant='outlined'
size='small'
onClick={(e) => sortResults(e, 'rating')}
>
filter by rating
</Button>
</Toolbar>
</AppBar>
</Grid>
<Grid>
<AppBar
position='static'
sx={{
backgroundColor: '#212121 !important ',
borderRadius: 8,
}}
style={{ border: 'solid white 0.1px' }}
>
<Box sx={{ width: 300 }}>
<Slider
getAriaLabel={() => 'Temperature range'}
value={value}
onChange={handleChange}
valueLabelDisplay='auto'
getAriaValueText={valuetext}
/>
<Button
className={classes.btn}
sx={{ m: 2, textTransform: 'capitalize' }}
variant='outlined'
size='small'
onClick={(e) => sortResults(e, 'pricerange')}
>
filter by Price Range
</Button>
</Box>
</AppBar>
</Grid>

React MUI: Matching the heights of two grid sections

Using MUI have two separate grids next to each other, both taking up 50% of a larger grid.
As seen in the image below, I am having a hard time matching the heights of the two sections. I would like the smaller grid items (cards) to dynamically fill in the height of the left portion and match the height of the right portion.
How is this possible with Mui?
Here is my current code:
import React from "react";
import Grid from "#mui/material/Grid";
import Box from "#mui/material/Box";
import Card from "#mui/material/Card";
import CardContent from "#mui/material/CardContent";
import Typography from "#mui/material/Typography";
import Chart from "./testChart.js";
function GeneralDashboard(props) {
const defaultStats = [
{ name: "Opportunitys Entered", value: 102 },
{ name: "Wins Reported", value: 23 },
{ name: "Win Rate", value: "60%" },
{ name: "Total Revenue", value: "$20m" },
];
return (
<>
<Box sx={{ flexGrow: 1 }}>
<Grid
container
spacing={{ xs: 1, sm: 2, lg: 2 }}
columns={{ xs: 8, sm: 8, md: 8, lg: 8 }}
>
<Grid item xs={8} sm={8} md={4} lg={4}>
<Box sx={{ flexGrow: 1 }}>
<Grid
container
spacing={{ xs: 1, sm: 2, lg: 2 }}
columns={{ xs: 4, sm: 4, md: 8, lg: 8 }}
>
{defaultStats.map((stat) => {
return (
<>
<Grid item xs={2} sm={4} md={4}>
<Card>
<CardContent>
<Typography
sx={{ fontSize: 14 }}
color="text.secondary"
gutterBottom
>
{stat.name}
</Typography>
<Typography variant="h3" component="div">
{stat.value}
</Typography>
</CardContent>
</Card>
</Grid>
</>
);
})}
</Grid>
</Box>
</Grid>
<Grid item xs={8} sm={8} md={4} lg={4}>
<Box sx={{ flexGrow: 1 }}>
<Grid container spacing={{ xs: 1, sm: 1, lg: 1 }}>
<Grid item xs={12}>
<Card>
<CardContent>
<Typography
sx={{ fontSize: 14 }}
color="text.secondary"
gutterBottom
>
<h5>
<span>
<span className="fw-semi-bold">Re-entry</span>{" "}
timing by industry
</span>
</h5>
</Typography>
<Chart />
</CardContent>
</Card>
</Grid>
</Grid>
</Box>
</Grid>
</Grid>
</Box>
</>
);
}
You need to set the height of all containers and the item to 100%:
<Box sx={{ flexGrow: 1, height: "100%" /* <----------------------- (1) */ }}>
<Grid
sx={{ height: "100%" /* <----------------------- (2) */ }}
container
spacing={{ xs: 1, sm: 2, lg: 2 }}
columns={{ xs: 4, sm: 4, md: 8, lg: 8 }}
>
{defaultStats.map((stat) => {
return (
<>
<Grid item xs={2} sm={4} md={4}>
<Card sx={{ height: "100%" /* <----------------------- (3) */ }}>

How to change the position of a grid item left and right in a map() function

I have a page containing a "Timeline" element from Material Ui, with an "alternate" alignment. So I have a "TimeLineContent" containing several elements: Paper, Typography (For title and description) and an image.
I want to make the text always towards the center of the timeline. That is to say, one time the text is to the left, another to the right ...
Here an example of my problem :
The first TimelineContent is good (Text is to the left)
The second one is not good (Text is not to the right)
I could have used a flex-direction : reverse-row but I have several TimelineContent like this which are created with a .map()
Here the code I have right now :
<Timeline align="alternate">
{result.map((index) => {
return (
<TimelineItem className={classes.timelineStyle}>
<TimelineOppositeContent>
<Typography variant="body2" color="textSecondary">
{index.sif_date}
</Typography>
</TimelineOppositeContent>
<TimelineSeparator>
<TimelineDot className={classes.dot}>
<LaptopMacIcon/>
</TimelineDot>
<TimelineConnector />
</TimelineSeparator>
<TimelineContent>
<Paper elevation={3} className={classes.paper}>
<Grid style={{display: 'flex', flexWrap: 'nowrap'}}>
<Grid item>
<Typography variant="h6" component="h1">
{index.sif_titre}
</Typography>
<Typography style={{fontSize: 'smaller'}}>
{index.sif_msg}
</Typography>
</Grid>
<Grid item>
<Zoom overlayBgColorStart='rgba(73, 80, 87, 67)' overlayBgColorEnd='rgba(73, 80, 87, 67)' zoomMargin={100}>
<img src={index.sif_image} alt={index.sif_image} className={classes.img} style={{maxWidth: 200, maxHeight: 200}}/>
</Zoom>
</Grid>
</Grid>
</Paper>
</TimelineContent>
</TimelineItem>
)
})
}
</Timeline>
const useStyles = makeStyles((theme) => ({
paper: {
padding: '6px 16px',
textAlign: 'center',
backgroundColor: 'white !important',
display: 'flex'
},
secondaryTail: {
backgroundColor: theme.palette.secondary.main,
},
img : {
flex: 1,
resizeMode: 'contain',
},
dot : {
backgroundColor: '#ef9700'
},
timelineStyle: {
padding: '0px 300px !important'
}
}));
EDIT :
Full code of my page :
import React from 'react';
import { makeStyles } from '#material-ui/core/styles';
import Timeline from '#material-ui/lab/Timeline';
import TimelineItem from '#material-ui/lab/TimelineItem';
import TimelineSeparator from '#material-ui/lab/TimelineSeparator';
import TimelineConnector from '#material-ui/lab/TimelineConnector';
import TimelineContent from '#material-ui/lab/TimelineContent';
import TimelineOppositeContent from '#material-ui/lab/TimelineOppositeContent';
import TimelineDot from '#material-ui/lab/TimelineDot';
import {Grid} from "#material-ui/core";
import LaptopMacIcon from '#material-ui/icons/LaptopMac';
import Paper from '#material-ui/core/Paper';
import Typography from '#material-ui/core/Typography';
import {useEffect, useState} from "react";
import {data} from './data.json';
import axios from 'axios';
import Zoom from 'react-medium-image-zoom';
import 'react-medium-image-zoom/dist/styles.css';
const useStyles = makeStyles((theme) => ({
paper: {
padding: '6px 16px',
textAlign: 'center',
backgroundColor: 'white !important',
display: 'flex'
},
secondaryTail: {
backgroundColor: theme.palette.secondary.main,
},
img : {
flex: 1,
resizeMode: 'contain',
},
dot : {
backgroundColor: '#ef9700'
},
timelineStyle: {
padding: '0px 300px !important'
},
Grid: {
display: 'flex',
flexWrap: 'nowrap',
flexDirection: 'row',
'&:nth-child(2n+1)': {
flexDirection: 'row-reverse',
}
}
}));
const index = () =>{
const [result, setResult] = useState([]);
useEffect(()=>{
axios.get('/api/timeLine_siinfra').then((response) => {
setResult(response.data)
});
}, []);
const classes = useStyles();
return (
<Timeline align="alternate">
{result.map((index) => {
return (
<TimelineItem className={classes.timelineStyle}>
<TimelineOppositeContent>
<Typography variant="body2" color="textSecondary">
{index.sif_date}
</Typography>
</TimelineOppositeContent>
<TimelineSeparator>
<TimelineDot className={classes.dot}>
<LaptopMacIcon/>
</TimelineDot>
<TimelineConnector />
</TimelineSeparator>
<TimelineContent>
<Paper elevation={3} className={classes.paper}>
<Grid container className={classes.Grid}>
<Grid item>
<Typography variant="h6" component="h1">
{index.sif_titre}
</Typography>
<Typography style={{fontSize: 'smaller'}}>
{index.sif_msg}
</Typography>
</Grid>
<Grid item>
<Zoom overlayBgColorStart='rgba(73, 80, 87, 67)' overlayBgColorEnd='rgba(73, 80, 87, 67)' zoomMargin={100}>
<img src={index.sif_image} alt={index.sif_image} className={classes.img} style={{maxWidth: 200, maxHeight: 200}}/>
</Zoom>
</Grid>
</Grid>
</Paper>
</TimelineContent>
</TimelineItem>
)
})
}
</Timeline>
)}
export default index;
You can do that with an nth-child selector in CSS and then toggle between your styles / flex direction.
Docs for the nth-child selector: https://developer.mozilla.org/de/docs/Web/CSS/:nth-child
.parent{
display: flex;
flex-directrion: row;
}
.parent:nth-child(2n+1){ /* or: :nth-child(odd) */
flex-direction: row-reverse;
}
<div class="parent">
<div class="img">IMG</div>
<div class="txt">txt</div>
</div>
<div class="parent">
<div class="img">IMG</div>
<div class="txt">txt</div>
</div>
<div class="parent">
<div class="img">IMG</div>
<div class="txt">txt</div>
</div>
<div class="parent">
<div class="img">IMG</div>
<div class="txt">txt</div>
</div>
I would use a modulo to determine if we're on an even or odd iteration, and adjust accordingly. I've also set the title component as a variable so we don't have to duplicate it:
{result.map((index, i) => {
let isEven = i % 2 === 0,
titleComponent = (
<Grid item>
<Typography variant="h6" component="h1">
{index.sif_titre}
</Typography>
<Typography style={{fontSize: 'smaller'}}>
{index.sif_msg}
</Typography>
</Grid>
);
return (
<TimelineItem className={classes.timelineStyle}>
<TimelineOppositeContent>
<Typography variant="body2" color="textSecondary">
{index.sif_date}
</Typography>
</TimelineOppositeContent>
<TimelineSeparator>
<TimelineDot className={classes.dot}>
<LaptopMacIcon/>
</TimelineDot>
<TimelineConnector />
</TimelineSeparator>
<TimelineContent>
<Paper elevation={3} className={classes.paper}>
<Grid style={{display: 'flex', flexWrap: 'nowrap'}}>
{isEven && titleComponent}
<Grid item>
<Zoom overlayBgColorStart='rgba(73, 80, 87, 67)' overlayBgColorEnd='rgba(73, 80, 87, 67)' zoomMargin={100}>
<img src={index.sif_image} alt={index.sif_image} className={classes.img} style={{maxWidth: 200, maxHeight: 200}}/>
</Zoom>
</Grid>
{!isEven && titleComponent}
</Grid>
</Paper>
</TimelineContent>
</TimelineItem>
)
})}
Modulo example:
https://jsfiddle.net/q12yah85/
const MuiTimelineItem = withStyles({
alignAlternate: {
"&:nth-child(even) .MuiTimelineItem-content": {
direction: "rtl"
}
}
})(TimelineItem);

Material Ui card change according to input

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.

Categories