Material ui conditional rendering styles - reactjs

I have 2 grids and I want one of them to be a black background and one to be a white background, both of these backgrounds are set in a theme in the app.js. Im wanting to use theme.palette.common.black or theme.palette.common.white if i pass in a white tag prop inside the second grid. Im trying to use a ternary statement but not sure how to implement it.
const styles = (theme) => ({
root: {
background: theme => theme.palette.common ? "black" : "white",
// background: theme.palette.common.black,
// background: theme.palette.common.white,
},
});
const HomePage = ({ classes }) => (
<>
<FullScreenBanners>
<Grid
className={classes.root}
container
spacing={0}
alignItems="center"
justify="center"
direction="column"
>
<Typography>iPhone SE</Typography>
<Typography>From £10.99/mo. or £279 with trade-in.</Typography>
<LearnMoreBuy />
<img src="./images/iphone-se.jpg" />
</Grid>
<Grid
white
className={classes.root}
container
spacing={0}
alignItems="center"
justify="center"
direction="column"
>
<Typography>iPhone 7</Typography>
<Typography>From £7/mo. or £200 with trade-in.</Typography>
<LearnMoreBuy />
<img src="./images/iphone-se.jpg" />
</Grid>
</FullScreenBanners>
</>
);

I hope I haven't misunderstood your question.
Wouldn't it be easier to just have two different classes - a standard one (root) and one for the white background (e.g. white)? Then, instead of passing in a 'white' prop to one of your Grid elements, you can just apply the second class name.
const useStyles = makeStyles({
root: {
background: theme.palette.common.black,
},
white: {
background: theme.palette.common.white,
},
});
const HomePage = () => {
const classes = useStyles();
return (
<>
<FullScreenBanners>
<Grid
//give this one just the root class
className={classes.root}
container
spacing={0}
alignItems="center"
justify="center"
direction="column"
>
<Typography>iPhone SE</Typography>
<Typography>From £10.99/mo. or £279 with trade-in.</Typography>
<LearnMoreBuy />
<img src="./images/iphone-se.jpg" />
</Grid>
<Grid
//give this one the root class and the white class
className={`${classes.root} ${classes.white}`}
container
spacing={0}
alignItems="center"
justify="center"
direction="column"
>
<Typography>iPhone 7</Typography>
<Typography>From £7/mo. or £200 with trade-in.</Typography>
<LearnMoreBuy />
<img src="./images/iphone-se.jpg" />
</Grid>
</FullScreenBanners>
</>
);
};

Related

Different color in a custom component React

I created a custom component called InfoCard, I passed trough props the information, the component is working properly, the only issue I have is that I want to define a diferente color for the Icon prop element when I call it into other components
For ex: I need to be red to be green
Is there any a possibility to do it without using CSS classes ?
InfoCard Component
interface Props {
icon: JSX.Element
title: string
store?: string
price: string
divider?: JSX.Element
}
const Item = styled(Paper)(({ theme }) => ({
padding: theme.spacing(1),
margin: theme.spacing(1),
textAlign: 'center',
color: theme.palette.text.secondary,
}))
const InfoCard = ({ icon, title, store, price, divider }: Props) => {
return (
<>
<Item>
<Stack direction="row" spacing={2} sx={{ justifyContent: 'center' }}>
<Box>{icon}</Box>
<Typography>{title}</Typography>
<Box>{divider}</Box>
<Typography>{store}</Typography>
</Stack>
<Typography variant="h5" sx={{ color: 'primary.main' }}>
{price}
</Typography>
</Item>
</>
)
}
export default InfoCard
Header Component
const Header = () => {
const { t } = useTranslation()
return (
<Box>
<Grid container>
<Grid item xs={12} sm={12} md={6} lg={4}>
<InfoCard
icon={<ArrowDownIcon className="smallIcon" />}
title={t('LOWEST_REGULAR_PRICE')}
store="store 1"
price="1.900"
divider={<Divider orientation="vertical" />}
/>
</Grid>
<Grid item xs={12} sm={12} md={6} lg={4}>
<InfoCard
icon={<ArrowTrendingUpIcon className="smallIcon" />}
title={t('AVERAGE_REGULAR_PRICE')}
price="1.900"
/>
</Grid>
<Grid item xs={12} sm={12} md={12} lg={4}>
<InfoCard
icon={<ArrowPathIcon className="smallIcon" />}
title={t('LAST_UPDATE')}
price="19/07/2022"
/>
</Grid>
</Grid>
</Box>
)
}
```
You can style a react element with the style prop as follows:
<MyComponent style={{color: "red"}} />
https://reactjs.org/docs/faq-styling.html
Hint: careful that passing rendered react components as props like you do in your code example, is usually not desired. icon={<ArrowTrendingUpIcon className="smallIcon" />} You may want to consider using props.children instead. https://reactjs.org/docs/react-api.html#reactchildren

vertical divider not working in material ui

I have this component that contains a card and inside this card there are elements and I want to separate them through a vertical line and the problem is that the vertical line does not work.
const useStyles = makeStyles((theme: Theme) =>
createStyles({
orange: {
color: theme.palette.getContrastText(deepOrange[500]),
backgroundColor: deepOrange[500],
}
}),
);
const SpaceForm: FC = (props) => {
const classes = useStyles()
const workspaceData = useWorkspaceModule((state) => state.workspace)
console.log("inside component 1: ", workspaceData);
return (
<>
<Grid
container
spacing={3}
>
<Grid
item
lg={8}
md={6}
xs={12}
>
<Card>
<CardHeader title="Name your Workspace:"/>
<CardContent>
<Avatar style={{width: '3.4rem', height: '3.4rem'}} className={classes.orange}>N</Avatar>
{/*llll*/}
<Divider style={{ backgroundColor:'red'}} orientation="vertical" flexItem />
</CardContent>
</Card>
</Grid>
</Grid>
</>
);
};
export default SpaceForm;
You just wrap Avatar inside a flex Box and it will show Divider after Avatar:
<Box display="flex">
<Avatar
style={{ width: "3.4rem", height: "3.4rem" }}
className={classes.orange}
>
N
</Avatar>
{/*llll*/}
<Divider
style={{ backgroundColor: "red" }}
orientation="vertical"
flexItem
/>
</Box>

How can I fix the columns of the dynamic card?

How can I make the card appear where there are 2 columns for the 1st card and then another 2 columns far the second card? So for, this is what it shows.
but I wanted it to look like this:
these are my codes for the styling:
const useStyles = makeStyles((theme) => ({
root: {
flexGrow: 1,
padding: theme.spacing(2),
},
media: {
height: 300,
},
}));
and these are my codes for the card:
<div className={classes.root}>
<Grid
container
spacing={12}
direction="row"
justify="flex-start"
alignItems="center"
>
{data.map((elem) => (
<Grid item xs={12} sm={6} md={3} key={data.indexOf(elem)}>
<Card>
<CardHeader title={name} subheader={desc} />
<CardMedia
className={classes.media}
image={img}
title={name}
/>
</Card>
</Grid>
))}
</Grid>
</div>
It seems like the cards are stretched to full width, which prevents them from sharing the same flex-row.
There are lots of possible solutions to this. One could be to set a max-width on the cards so they don't fill the whole row. That way they would have space to sit besides each other like in your example.

How to use theme in styles for custom functional components

When I try compiling the app it displays a certain error "TypeError:undefined has no properties" though I want to render styled components into the grid tags though in function based component method
const styles = theme => ({
root: {
height: '100vh',
},
image: {
},
paper: {
margin: theme.spacing(8, 4),
},
avatar: {
margin: theme.spacing(1),
backgroundColor: theme.palette.secondary.main,
},
form: {
width: '100%',
marginTop: theme.spacing(1),
},
submit: {
margin: theme.spacing(3, 0, 2),
},
});
const SignIn = (props) => {
const classes = this.props;
return(
<Grid container component="main" className={classes.root}>
<CssBaseline />
<Grid item xs={false} sm={4} md={7} className={classes.image} />
<Grid item xs={12} sm={8} md={5} component={Paper} elevation={6} square>
<div className={classes.paper}>
<Typography component="h1" variant="h5">
Welcome to web
</Typography>
<Avatar className={classes.avatar}>
<LockOutlinedIcon />
</Avatar>
<form className={classes.form} noValidate>
//content
</form>
</div>
</Grid>
</Grid>
);
}
export default withStyles(styles)(SignIn);
Access or destructure classes from props, not this.props.
const { classes } = props;
You can also destructure props right in the function definition.
const SignIn = ({ classes }) => {...

reactjs/ occupy 100% height without scrollbar

Well I wanted to leave a page with 100% screen height
without scroll bar:
const SignIn = () => {
const classes = useStyles();
return (
<div className={classes.root}>
<Grid container spacing={2} direction="column" justify="center" alignItems="center" >
<Grid item lg={12} md={12} sm={12} xs={12} >
<img src={require("../nodejs-icon.svg")} alt="bug" height={100} />
</Grid>
</Grid>
</div>
);
}
and my css:
const loginStyle = (muiBaseTheme => ({
root:{
background: "#000",
minHeight: '100vh',
}
}));
But i'm getting a horizontal and vertical scroll bar like this:
enter image description here
Use:
const loginStyle = (muiBaseTheme => ({
root:{
background: "#000",
minHeight: '100vh',
overflow: 'hidden',
}
}));
to hide the scroll bars.

Resources