Having trouble creating onHover on Grid item component MaterialUI - css

I am creating a Grid layout that has nested Grid components in it. However, for some reason I do not understand, using an inline style in the Grid item component does not work. Please help, I am quite new in using MaterialUI in ReactJS. The Grid is encapsulated inside a Hide component that only shows in mobile devices.
What I am trying to achieve is that the Grid item change color on
hover
Here is what I did:
<Hidden mdUp='hide'>
<Grid
container
xs={12}
style={{
fontFamily: 'Old Newspaper',
background: '#f49275',
'&:hover': { background: 'black' },
marginLeft: '4px',
marginRight: '4px',
}}
>
<Grid
item
xs={4}
style={{
justifyContent: 'center',
display: 'flex',
}}
>
<a href='#'>
♦ Github ♦
</a>
</Grid>
<Grid
item
xs={4}
style={{ justifyContent: 'center', display: 'flex' }}
>
<a
href='#'
target='_blank'
>
♦ LinkedIn ♦
</a>
</Grid>
<Grid
item
xs={4}
style={{ justifyContent: 'center', display: 'flex' }}
>
<a
href='#'
target='_blank'
>
♦ Codewars ♦
</a>
</Grid>
</Grid>
</Hidden>

To get hover style on grid items you've to add hover style on grid items. And you can't add hover styles on an element in inline CSS way. Give a className to grid items and then add hover styles on those.
import React from "react";
import { makeStyles } from "#material-ui/core/styles";
import Grid from "#material-ui/core/Grid";
import { Hidden } from "#material-ui/core";
const useStyles = makeStyles((theme) => ({
item:{
color:'#fff',
justifyContent: "center",
display: "flex",
'&:hover':{
'&>a':{
color:'green'
}
}
}
}));
export default function SpacingGrid() {
const classes = useStyles();
return (
<Hidden mdUp="hide">
<Grid
container
className={classes.container}
xs={12}
style={{
fontFamily: "Old Newspaper",
background: "#f49275",
marginLeft: "4px",
marginRight: "4px"
}}
>
<Grid
item
xs={4}
className={classes.item}
>
♦ Github ♦
</Grid>
<Grid item xs={4} className={classes.item}>
<a href="#" target="_blank">
♦ LinkedIn ♦
</a>
</Grid>
<Grid item xs={4} className={classes.item}>
<a href="#" target="_blank">
♦ Codewars ♦
</a>
</Grid>
</Grid>
</Hidden>
);
}
codesandbox link:- https://codesandbox.io/s/o8b52
And can you please elaborate more your doubt about using inline style in grid item.

Related

Material-UI Grid: Can I apply the background color to only cells, and not the empty spaces outside them?

I'm trying to create a grid system with a gradient background color. However, the background color also applies to the empty spaces not taken up by grid cells. I want just the grid cells to share this gradient. Is there any way to do this?
Image: https://imgur.com/a/WHVhFg1
You should set a linear background color for your container and set background: 'inherit' for your grid item. Inside your grid item, you should use an image with a no background color.
Try this:
import React from "react";
import { makeStyles } from "#material-ui/core/styles";
import Paper from "#material-ui/core/Paper";
import Grid from "#material-ui/core/Grid";
const useStyles = makeStyles(theme => ({
root: {
flexGrow: 1,
background:
"linear-gradient(90deg, rgba(34,193,195,1) 0%, rgba(253,187,45,1) 100%)"
},
paper: {
padding: theme.spacing(2),
textAlign: "center",
color: theme.palette.text.secondary,
background: "inherit"
}
}));
export default function AutoGrid() {
const classes = useStyles();
return (
<div className={classes.root}>
<Grid container spacing={3}>
<Grid item xs={3}>
<Paper className={classes.paper}>
<img
height="100px"
alt="cat"
src="http://assets.stickpng.com/thumbs/584c3c8a1fc21103bb375ba7.png"
/>
</Paper>
</Grid>
<Grid item xs={3}>
<Paper className={classes.paper}>
<img
height="100px"
alt="cat"
src="http://assets.stickpng.com/thumbs/584c3c8a1fc21103bb375ba7.png"
/>
</Paper>
</Grid>
<Grid item xs={3}>
<Paper className={classes.paper}>
<img
height="100px"
alt="cat"
src="http://assets.stickpng.com/thumbs/584c3c8a1fc21103bb375ba7.png"
/>
</Paper>
</Grid>
<Grid item xs={3}>
<Paper className={classes.paper}>
<img
height="100px"
alt="cat"
src="http://assets.stickpng.com/thumbs/584c3c8a1fc21103bb375ba7.png"
/>
</Paper>
</Grid>
</Grid>
<Grid container spacing={3}>
<Grid item xs>
<Paper className={classes.paper}>
<img
height="100px"
alt="cat"
src="http://assets.stickpng.com/thumbs/584c3c8a1fc21103bb375ba7.png"
/>
</Paper>
</Grid>
</Grid>
</div>
);
}

Make Item go the bottom using Flexbox and Material UI

I am trying to add Unassigned Text to the bottom of my Container, as shown in this mockup:
Below is the code, that I have so far. I am struggling to get the border between the play button working too. I have tried the usual css: bottom:0 and position:relevant Along with Flexbox but it doesn't seem to want to go to the very bottom of the container.
const styles = theme => ({
root: {
flexGrow: 1,
overflow: 'hidden',
padding: theme.spacing(0, 3),
},
paper: {
maxWidth: 800,
margin: `${theme.spacing(2)}px auto`,
padding: theme.spacing(2),
},
textField: {
marginLeft: theme.spacing(1),
marginRight: theme.spacing(1),
width: 200,
},
playButton: {
display: "flex",
flexDirection: "column",
justifyContent: "center",
alignItems: "center",
position: "relative",
"& .playButton": {
position: "absolute",
top: "60%",
left: "-55px",
transform: "translateY(-50%)",
},
"& .star-rating": {
"& .fa-star": {
"&:hover": {
"&::before": {
content: "\f005",
color: "yellow"
}
}
}
},
},
});
function Tasks(props) {
const { classes } = props;
return (
<div className={classes.root}>
<Paper className={classes.paper}>
<Grid container spacing={2}>
<Grid item xs={12} sm container>
<Grid item xs container direction="column" spacing={2}>
<Grid item xs>
<div className="name-label">
Name
</div>
<Typography variant="h6" gutterBottom>
{props.name}
</Typography>
<div className="form-divider"></div>
<Typography variant="body2" color="textSecondary">
{props.description}
</Typography>
</Grid>
</Grid>
<Grid item classes={{ root: props.classes.playButton}}>
<Grid item xs={3} className="playButton">
<i class="far fa-play-circle fa-2x"></i>
</Grid>
<div className="workers-assigned-label">
Workers Assigned
</div>
<Typography variant="h6" gutterBottom>
0/25
</Typography>
<div class="star-rating">
<label class="far fa-star fa-2x"></label>
<label class="far fa-star fa-2x"></label>
<label class="far fa-star fa-2x"></label>
</div>
<div className="dropdown-menu">
<h5>Unnassigned</h5>
</div>
</Grid>
</Grid>
</Grid>
</Paper>
</div>
);
}
export default withStyles(styles)(Tasks);
Any input would be great.
I would recommend starting with a Grid 'skeleton' that looks something like:
<Grid container>
<Grid item container xs={8} direction="column" justify="flex-start">
// Left column contents, with each row as a <Grid item>
</Grid>
<Fab className={classes.fab}><PlayIcon /><Fab>
<Grid item container xs={4} direction="column" justify="space-between" className={classes.right}>
// Right column contents, with each row as a <Grid item>
</Grid>
</Grid>
The direction=column will help you position items vertically within each container. The justify=space-between will ensure that your first item is at the top of the container and your last item (the unassigned text) is at the bottom.
The "right" css class looks like:
right: {
borderLeft: `1px solid ${theme.palette.grey[500]}`,
position: "relative"
}
You can give it a position of "relative" to make it easier to position the fab relative to the column. The "fab" class looks like:
fab: {
position: "absolute",
margin: "auto",
top: 0,
bottom: 0,
left: -28
}
The margin, top, and bottom properties help center the fab vertically, and the left is a bit of a hack based on the dimensions of the fab to center it over the border.
Here's a working draft that brings everything together: https://codesandbox.io/s/tender-torvalds-dlbke?fontsize=14
You can try something like this, or give flex: 1 to anything in the column to make it stretch.
const styles = theme => ({
playButton: {
'& .dropdown-menu': {
marginTop: "auto"
}
}
})

How to Add in items in a column using Flexbox and Material UI

I am looking for some advice as I can't seem to get these items positioned on the modal. I am looking to get add the item counter as text and stars underneath. With the unassigned text at the bottom. I have tried many layouts. This is my code so far:
const styles = theme => ({
root: {
flexGrow: 1,
overflow: 'hidden',
padding: theme.spacing(0, 3),
},
paper: {
maxWidth: 800,
margin: `${theme.spacing(2)}px auto`,
padding: theme.spacing(2),
},
textField: {
marginLeft: theme.spacing(1),
marginRight: theme.spacing(1),
width: 200,
},
playButton: {
display: "flex",
flexDirection: "column",
justifyContent: "center",
alignItems: "center",
"& .rating": {
flex: 1
},
}
});
function Tasks(props) {
const { classes } = props;
return (
<div className={classes.root}>
<Paper className={classes.paper}>
<Grid container spacing={2}>
<Grid item xs={12} sm container>
<Grid item xs container direction="column" spacing={2}>
<Grid item xs>
<div className="name-label">
Name
</div>
<Typography variant="h6">
Order cofee beans
</Typography>
<div className="form-divider"></div>
<Typography variant="body2" color="textSecondary">
Process of Description
</Typography>
</Grid>
</Grid>
<Grid item classes={{ root: props.classes.playButton}}>
<Grid item xs={3} className="playButton">
<i class="far fa-play-circle fa-2x"></i>
</Grid>
<div className="workers-assigned-label">
Workers Assigned
</div>
<div>
count / total
</div>
<div className="rating">
Stars go here
</div>
<div>
unassigned
</div>
</Grid>
</Grid>
</Grid>
</Paper>
</div>
);
}
export default withStyles(styles)(Tasks);
I have added an image of a screenshot of the design so that it is clear what I am trying to achieve.
Image: enter image description here
You're going to want something like this, where the flex: 1 is whatever you want to be stretching and taking up any extra space.
const styles = theme => ({
playButton: {
display: "flex",
flexDirection: "column",
justifyContent: "center",
alignItems: "center",
position: "relative",
"& .playButton": {
position: "absolute",
top: "80%",
left: "-55px",
transform: "translateY(-50%)",
},
"& .rating": {
flex: 1
}
}
});
const YourComponent = props => (
{...}
<Grid item classes={{ root: props.classes.playButton}}>
<Grid item xs={3} className="playButton">
<i class="far fa-play-circle fa-2x"></i>
</Grid>
<div className="workers-assigned-label">
Workers Assigned
</div>
<div>
count / total
</div>
<div className="rating">
stars go here
</div>
<div>
unassigned
</div>
</Grid>
{...}
);
I suggest you checkout this resource to see what you can do with flex.

Add Hover effect to Font Awesome Stars

I would like a simple method, whereby you hover over them and they are a solid yellow.
const styles = theme => ({
root: {
flexGrow: 1,
overflow: 'hidden',
padding: theme.spacing(0, 3),
},
paper: {
maxWidth: 800,
margin: `${theme.spacing(2)}px auto`,
padding: theme.spacing(2),
},
textField: {
marginLeft: theme.spacing(1),
marginRight: theme.spacing(1),
width: 200,
},
playButton: {
display: "flex",
flexDirection: "column",
justifyContent: "center",
alignItems: "center",
position: "relative",
"& .playButton": {
position: "absolute",
top: "60%",
left: "-55px",
transform: "translateY(-50%)",
},
}
});
function Tasks(props) {
const { classes } = props;
return (
<div className={classes.root}>
<Paper className={classes.paper}>
<Grid container spacing={2}>
<Grid item xs={12} sm container>
<Grid item xs container direction="column" spacing={2}>
<Grid item xs>
<div className="name-label">
Name
</div>
<Typography variant="h6" gutterBottom>
{props.name}
</Typography>
<div className="form-divider"></div>
<Typography variant="body2" color="textSecondary">
{props.description}
</Typography>
</Grid>
</Grid>
<Grid item classes={{ root: props.classes.playButton}}>
<Grid item xs={3} className="playButton">
<i class="far fa-play-circle fa-2x"></i>
</Grid>
<div className="workers-assigned-label">
Workers Assigned
</div>
<Typography variant="h6" gutterBottom>
0/25
</Typography>
<div class="star-rating">
<label class="far fa-star fa-2x"></label>
<label class="far fa-star fa-2x"></label>
<label class="far fa-star fa-2x"></label>
</div>
<div>
unassigned
</div>
</Grid>
</Grid>
</Grid>
</Paper>
</div>
);
}
export default withStyles(styles)(Tasks);
If anyone has any suggestions as to how to get them to change from https://fontawesome.com/v4.7.0/icon/star-o to having the centre fill with yellow that would be much appreciated. Whether it be best done with CSS or something using React.
Taking a look at the content of that particular font, the 2 you'll use are content: "\f006" and content: "\f005". f005 is the filled star that you'll want to turn yellow.
const styles = theme => ({
playButton: {
"& .rating": {
"& .fa-star-o": {
"&:hover": {
"&::before": {
content: "\f005",
color: "yellow"
}
}
}
},
},
});
And like the other person said, make sure the package is working.
Did you check the version of Font Awesome you use? This icon seems to be in the 4.7.0. I've had multiple problems with icons not showing and usually it was because I was using an outdated version or the icon I wanted to use was in a newer version of Font Awesome.
And if you use a newer one, check if the icon still exists for this version, it may have been removed or renamed.

How to center a button in Material-UI

I couldn't figure out how to center buttons in Material-UI. This is the code I have:
function BigCard(props) {
const { classes } = props;
return (
<div>
<Card className={classes.card}>
<CardContent>
<Typography variant="display1" className={classes.title}>
Start Funding!
</Typography>
</CardContent>
<CardActions >
<Button size="small" color="primary" className={classes.actions}>
Share
</Button>
<Button size="small" color="primary">
Learn More
</Button>
</CardActions>
</Card>
</div>
);
How can I center my button?
You can use Box element
<Box textAlign='center'>
<Button variant='contained'>
My button
</Button>
</Box>
you could use the override with classes in the material ui doc,
FIRST WAY
You can do something like :
//Add your justify css in your styles const
const styles = {
...
root: {
justifyContent: 'center'
}
};
And use the classes props to add this to your CardActions component :
<CardActions classes={{root: classes.root}}>
SECOND WAY (easier)
OR You can use the style directly on your component, but i advise you to train how to use classes if you're working alot with material-ui
Just do something like :
<CardActions style={{justifyContent: 'center'}}>
For use cases that avoid defining css
<Grid container justify="center">
{props.children}
</Grid>
Here is how I did it with Material - UI
import {Typography, Button} from '#material-ui/core';
<Typography align='center'>
<Button
color='primary'
size='large'
type='submit'
variant='contained'
>
Sign Up
</Button>
</Typography>
Quick and dirty:
<Button style={{margin: '0 auto', display: "flex"}}>
NEXT
</Button>
From MUI v5, you can apply the custom styles using the sx props. Because CardActions layout is already flex, you only need to set its justify-content to center.
Using sx instead of inline styles like the other answer help reduce the CSS specificity, and make it easier to override the CSS in the future
<CardActions sx={{ justifyContent: "center" }}>
<Button size="small">Learn More</Button>
</CardActions>
Live Demo
What I tried is below and is also shown in official videos of material ui on youtube.
<Grid item xs={12} sm={12} md={4} lg={4}
style={{
textAlign:'center' // this does the magic
}}
>
<Button>
NEXT
</Button>
</Grid>
Thanks and best wishes
You have to use two properties: display and justify-content
<CardActions display='flex' justifyContent='center'>
This will centre your button horizontally
<Button
size="medium"
variant="contained"
color="primary"
style={{
display: "flex",
flexDirection: "row",
justifyContent:"center",
backgroundColor: purple[500],
'&:hover': {
backgroundColor: purple[700],
},
}}
>
Get Hired
</Button>
The easiest way is to use a Box wrapping around the button
<Box
sx={{
display: 'flex',
flexDirection: { xs: 'column', md: 'row' },
alignItems: 'center',
justifyContent: 'center',
}}
>
<Button>Click me</Button>
</Box>
This may sound counter-intuitive but what worked for my case (slightly different than yours) was to use the fullWidth attribute in the Button element.
Here is my scenario (MUI v5):
<Grid container alignItems={'center'} >
<Grid item>
<Button fullWidth variant='contained' >Click Me!</Button>
</Grid>
</Grid>
wrap element in this center
.center{
width: 100%;
height: 100%;
display: flex;
justify-content: center;
}

Resources