How to add an overlay text to a blurred react component? - javascript

I am developing an application in React and Material-ui that uses a card component to display some information. However, I am not the best at CSS and I am having trouble creating an overlay for the Card component while it is blurred out. I use the css property filter: blur(2px) in order to accomplish the blur, but whenever I add any CSS for the overlay it either puts the text under the card over above. My goal would be to have it centered in the middle of the card.
Code:
import { Grid, Typography, CardContent, Card } from '#material-ui/core';
import { makeStyles, useTheme } from '#material-ui/core/styles';
const useStyles = makeStyles(theme => ({
root:{
width: 400,
filter: "blur(3px)",
},
textOverlay: {
position: 'absolute',
top: 0,
left: 0
}
}));
const LandingPage = () => {
const classes = useStyles();
return (
<React.Fragment>
<Grid container direction="row" alignItems="center" justify="center">
<Grid item>
<Card className={classes.root}>
<CardContent>
<Typography variant="h4" align="center" >Monday</Typography>
<Typography>Song</Typography>
<Typography>Africa</Typography>
<Typography>Artist</Typography>
<Typography>Toto</Typography>
<Typography>Preview</Typography>
</CardContent>
</Card>
</Grid>
<Grid item>
<div className={classes.textOverlay}> Coming Soon </div>
</Grid>
</Grid>
</React.Fragment>
);
}
export default LandingPage;

That should do the trick. Just set the Grid item to position fixed. You may need to add the z-index. But in your example it wasn't needed.
I would also suggest to add the 'notSelectable' to your blurred content so that the user cant select it.
https://codesandbox.io/s/flamboyant-volhard-72wuh?fontsize=14&hidenavigation=1&theme=dark
import React from "react";
import { Grid, Typography, CardContent, Card } from "#material-ui/core";
import { makeStyles } from "#material-ui/core/styles";
const useStyles = makeStyles((theme) => ({
root: {
width: 400,
filter: "blur(3px)",
},
textOverlay: {
position: "fixed",
}
notSelectable: {
userSelect: "none"
}
}));
const LandingPage = () => {
const classes = useStyles();
return (
<React.Fragment>
<Grid container direction="row" alignItems="center" justify="center">
<Grid item>
<Card className={classes.root}>
<CardContent className={classes.notSelectable}>
<Typography variant="h4" align="center">
Monday
</Typography>
<Typography>Song</Typography>
<Typography>Africa</Typography>
<Typography>Artist</Typography>
<Typography>Toto</Typography>
<Typography>Preview</Typography>
</CardContent>
</Card>
</Grid>
<Grid item className={classes.textOverlay}>
<div> Coming Soon </div>
</Grid>
</Grid>
</React.Fragment>
);
};
export default LandingPage;

Related

How to make card component align in one row (React)

i recently start to learn react. I made card component using Material UI for react, but this time i'm going to make it with axios and map().
What i expected was, the cards should be in the same row, not vertical.
This is how the cards look when using axios and map()
This the frontend code using React, axios, and map()
import { makeStyles, withStyles } from "#material-ui/styles";
import { BrowserRouter, Route, Routes } from "react-router-dom";
import axios from "axios";
//Material UI
import { Grid } from "#material-ui/core";
import Box from "#mui/material/Box";
import Card from "#mui/material/Card";
import CardActions from "#mui/material/CardActions";
import CardContent from "#mui/material/CardContent";
import Button from "#mui/material/Button";
import Typography from "#mui/material/Typography";
const useStyles = makeStyles({
gridContainer: {
paddingLeft: "40px",
paddingRight: "40px",
},
root: {
minWidth: 200,
},
bullet: {
display: "inline-block",
margin: "0 2px",
transform: "scale(0.8)",
},
title: {
fontSize: 14,
},
pos: {
marginBottom: 12,
},
});
function Home() {
const classes = useStyles();
const [getData, setGetData] = useState([]);
useEffect(() => {
axios.get("http://127.0.0.1:8080/api/get.php").then((x) => {
setGetData(x.data);
});
}, [getData]);
return (
<div>
{getData.map((x) => {
return (
<Grid
container
spacing={4}
className={classes.gridContainer}
justify="center"
style={{ marginTop: "80px" }}
>
<Grid item xs={12} sm={6} md={4}>
<Card className={classes.root} variant="outlined">
<CardContent>
<Typography
className={classes.title}
color="textSecondary"
gutterBottom
>
Word of the Day
</Typography>
<Typography className={classes.pos} color="textSecondary">
adjective
</Typography>
<Typography variant="body2" component="p">
well meaning and kindly.
<br />
{'"a benevolent smile"'}
</Typography>
</CardContent>
<CardActions>
<Button size="small">Learn More</Button>
</CardActions>
</Card>
</Grid>
</Grid>
);
})}
</div>
);
}
export default Home;
Expected output that i looking for before using map() method
Did i miss some configuration? or styling? grid? container?
<Grid container> should be outside the loop. I would also consider using Material UI v5. Don't forget about key prop for looped items.
<Grid
container
spacing={4}
className={classes.gridContainer}
justifyItems="center"
style={{ marginTop: "80px" }}
>
{getData.map((x, index) => (
<Grid key={index} item xs={12} sm={6} md={4}>
...
</Grid>
)}
</Grid>
Move your Grid Container outside of map function. You have to wrap 3 cards inside the Grid Container
The problem you're having is that you are wrapping each component (using map()) inside its own Grid container. You need to put the container element outside of the map() function so it can work as you expect.
return (
<div>
<Grid
container
spacing={4}
className={classes.gridContainer}
justify="center"
style={{ marginTop: "80px" }}
>
{getData.map((x) => {
return (
<Grid item xs={12} sm={6} md={4}>
<Card className={classes.root} variant="outlined">
<CardContent>
<Typography
className={classes.title}
color="textSecondary"
gutterBottom
>
Word of the Day
</Typography>
<Typography className={classes.pos} color="textSecondary">
adjective
</Typography>
<Typography variant="body2" component="p">
well meaning and kindly.
<br />
{'"a benevolent smile"'}
</Typography>
</CardContent>
<CardActions>
<Button size="small">Learn More</Button>
</CardActions>
</Card>
</Grid>
);
})}
</Grid>
</div>
);

How to display Material-UI Grid items not as cards?

I thought Material-UI grid items were just used for quick spacing fixes. My grid items are now showing up as cards? Would just like it to be invisible how it was, however the docs don't explain how to do this. Appreciate any help!
import React, { useState, useEffect } from "react";
import Grid from "#mui/material/Card";
import { Container, TextField, FormControl } from "#mui/material";
export default function MainPage() {
return (
<Container maxWidth="lg" style={{ height: "100vh" }}>
<Grid container>
<Grid item xs={12}>
<img
style={{ width: "800px" }}
src="https://image.shutterstock.com/image-photo/red-apple-fruit-leaf-isolated-260nw-203589940.jpg"
alt="half-title-1"
/>
</Grid>
<Grid item xs={12}>
<img
style={{ width: "800px" }}
src="https://image.shutterstock.com/image-photo/red-apple-fruit-leaf-isolated-260nw-203589940.jpg"
alt="half-title-2"
/>
</Grid>
</Grid>
</Container>
);
}
It's because you're importing a Card!
import Grid from "#mui/material/Card";
What it's supposed to be:
import Grid from "#mui/material/Grid";

Getting Problem in Layout Upon Using Lottie Animation in Gatsby and Material UI

Getting Problem in Layout Upon Using Lottie Animation in Gatsby and Material UI. Heres the code
import React from "react"
import Grid from "#material-ui/core/Grid"
import Typography from "#material-ui/core/Typography"
import Lottie from "react-lottie"
import { makeStyles } from "#material-ui/core/styles"
import useMediaQuery from "#material-ui/core/useMediaQuery"
import data from "../../images/data.json"
const useStyles = makeStyles(theme => ({
textContainer: {
padding: "2rem",
[theme.breakpoints.down("xs")]: {
padding: "1rem",
},
},
heading: {
[theme.breakpoints.down("xs")]: {
fontSize: "3.5rem",
},
},
}))
export default function HeroBlock() {
const animationData = JSON.parse(JSON.stringify(data))
const classes = useStyles()
const matchesLG = useMediaQuery(theme => theme.breakpoints.down("lg"))
const matchesMD = useMediaQuery(theme => theme.breakpoints.down("md"))
const matchesXS = useMediaQuery(theme => theme.breakpoints.down("xs"))
const defaultOptions = {
loop: true,
autoplay: false,
animationData,
}
return (
<Grid container justifyContent="space-around" alignItems="center">
<Grid item classes={{ root: classes.textContainer }}>
<Grid container direction="column">
<Grid item>
<Typography
align="center"
variant="h1"
classes={{ root: classes.heading }}
>
The Premier
<br />
Developer Clothing Line
</Typography>
</Grid>
<Grid item>
<Typography align="center" variant="h3">
high quality, custom-designed shirts, hats, and hoodies
</Typography>
</Grid>
</Grid>
</Grid>
<Grid item>
<Lottie
isStopped
options={defaultOptions}
width={
matchesXS
? "20rem"
: matchesMD
? "30rem"
: matchesLG
? "40rem"
: "50rem"
}
/>
</Grid>
</Grid>
)
}
Here is the SS of My Layout. The Animation Should be in column but it is stacked up.
Here is the SS of my Layout
And when i inspect in the console the Lottie animation generating new div with styles and in that div the lottie animation reside. Here is the div which i have inspected in console
<div style="width: 40rem; height: 100%; overflow: hidden; margin: 0px auto; outline: currentcolor none medium;">
Inside the div the Lottie animation is running.
</div>
So i think the main prbolem is with this div. How to solve this problem.

How to make button stick to bottom in Material UI React Component?

I am working on a building a general layout for a web app. I have hit a problem I am not sure how to solve.
My Grid looks as follows:
What I want is that the each section inside the card start at the same point.
For example, the icons are ok as each their tops are aligned.
The titles are also ok as their tops are aligned.
However, the content text is not ok, as the tops are not aligned amongst the three cards.
In addition, the learn more buttons should also be aligned, and ideally stuck to the bottom of the card. As can be seen they all sit at different heights.
My code looks as follows:
HomeGrid.jsx:
import React, { useState, useEffect, Fragment } from 'react'
import { useStyles } from '../styles'
import SimpleCard from '../card/SimpleCard'
import { Grid, Container, Paper } from '#material-ui/core'
import QuestionAnswerIcon from '#material-ui/icons/QuestionAnswer'
import FindInPageIcon from '#material-ui/icons/FindInPage'
import AccountBalanceWalletIcon from '#material-ui/icons/AccountBalanceWallet'
const HomeGrid = () => {
const classes = useStyles()
return (
<Container disableGutters className={classes.homeGridContainer}>
<Grid
alignItems="stretch"
alignContent="center"
justify="center"
wrap="wrap"
container
spacing={10}
>
<Grid item xs={12} md={4} align="center">
<SimpleCard
icon={<QuestionAnswerIcon fontSize={'large'} />}
title={'Speak'}
content={'Speaking to someone can help blah blah'}
></SimpleCard>
</Grid>
<Grid item xs={12} md={4} align="center">
<SimpleCard
icon={<FindInPageIcon fontSize={'large'} />}
title={'Finding someone like this example can be great'}
content={'Finding to someone can help blah blah'}
></SimpleCard>
</Grid>
<Grid item xs={12} md={4} align="center">
<SimpleCard
icon={<AccountBalanceWalletIcon fontSize={'large'} />}
title={'No Fees Here'}
content={'No Fees shalt find thou'}
></SimpleCard>
</Grid>
</Grid>
</Container>
)
}
export default HomeGrid
SimpleCard.jsx:
import React from 'react'
import { makeStyles } from '#material-ui/core/styles'
import Card from '#material-ui/core/Card'
import CardActions from '#material-ui/core/CardActions'
import CardContent from '#material-ui/core/CardContent'
import Button from '#material-ui/core/Button'
import Typography from '#material-ui/core/Typography'
import { CardActionArea, CardMedia } from '#material-ui/core'
import QuestionAnswerIcon from '#material-ui/icons/QuestionAnswer'
const useStyles = makeStyles({
simpleCard: {
minWidth: 275,
},
bullet: {
display: 'inline-block',
margin: '0 2px',
transform: 'scale(0.8)',
},
title: {
fontSize: 14,
},
pos: {
marginBottom: 12,
},
})
const SimpleCard = (props) => {
const classes = useStyles()
return (
<Card style={{ height: '100%' }}>
<CardContent>
{props.icon}
<Typography variant="h6" component="h2">
{props.title}
</Typography>
<Typography variant="body1" component="p">
{props.content}
</Typography>
</CardContent>
<CardActions className={classes.actions}>
<Button size="small">Learn More</Button>
</CardActions>
</Card>
)
}
export default SimpleCard
I already tried implementing this answer: enter link description here but as you can see it doesn't work.
Can someone please guide / help me out here?
using flex will solve the issue.
set flex style properties display:'flex', justiyContent:'space-between', flexDirection:'column' to Card component.
It'll shift buttons of all the Cards to the bottom of the card.

How do I get the likes length to update in real time after clicking clicking like

If I click to remove the first like on the first goal, I can see the Redux action firing (using Redux DevTools) for the like being updated. But the number beside is not updating. When I check the console it doesn't appear that anything is refreshing. When I refresh the page, it shows the updated number that was previously liked (the 0 becomes a 1), but I have to refresh the page to see this update. How can I get the number to update in real time without having to refresh the page?
import React, { useEffect } from "react";
import Moment from "react-moment";
import PropTypes from "prop-types";
import { Link } from "react-router-dom";
import { connect } from "react-redux";
import { addLike, removeLike } from "../../actions/goal";
import { getGoals } from "../../actions/goal";
import Spinner from "../layout/Spinner";
import Navbar from "../dashboard/Navbar";
import ThumbUpAltIcon from "#material-ui/icons/ThumbUpAlt";
import ThumbDownAltIcon from "#material-ui/icons/ThumbDownAlt";
import ChatIcon from "#material-ui/icons/Chat";
import DeleteIcon from "#material-ui/icons/Delete";
import DoneIcon from "#material-ui/icons/Done";
import {
Typography,
Container,
CssBaseline,
makeStyles,
Grid,
Avatar,
Paper,
Button
} from "#material-ui/core";
const useStyles = makeStyles(theme => ({
paper: {
height: "auto",
marginBottom: theme.spacing(3)
},
actionButtons: {
marginTop: "3vh"
},
profileHeader: {
textAlign: "center",
marginBottom: 20
},
avatar: {
width: theme.spacing(7),
height: theme.spacing(7)
}
}));
const Goals = ({
getGoals,
auth,
addLike,
removeLike,
goal: { goals, user, loading }
}) => {
useEffect(() => {
getGoals();
}, [getGoals]);
const classes = useStyles();
return loading ? (
<>
<Navbar />
<Container component="main" maxWidth="xs">
<CssBaseline />
<div className={classes.paper}>
<Spinner />
</div>
</Container>
</>
) : (
<>
<CssBaseline />
<Navbar />
<main>
<Container>
<Typography variant="h2" className={classes.profileHeader}>
Goals
</Typography>
{/* parent grid */}
<Grid container spacing={4}>
{goals.map(singleGoal => (
<Grid
className={classes.paper}
key={singleGoal._id}
spacing={1}
container
item
direction="row"
alignItems="center"
component={Paper}
>
<Grid
item
container
direction="column"
justify="center"
alignItems="center"
xs={3}
>
<Avatar className={classes.avatar} src={singleGoal.avatar} />
<Typography variant="caption">
{singleGoal.first_name} {singleGoal.last_name}
</Typography>
<Typography variant="caption" className={classes.postedOn}>
Posted on{" "}
<Moment format="MM/DD/YYYY">{singleGoal.date}</Moment>
</Typography>
</Grid>
<Grid container item direction="column" xs={9}>
<Typography variant="body1">{singleGoal.text}</Typography>
<Grid item className={classes.actionButtons}>
<Button size="small" onClick={e => addLike(singleGoal._id)}>
<ThumbUpAltIcon />
</Button>
<Typography variant="caption">
{singleGoal.likes.length}
</Typography>
<Button
size="small"
onClick={e => removeLike(singleGoal._id)}
>
<ThumbDownAltIcon />
</Button>
<Button href={`/goal/${singleGoal._id}`} size="small">
<ChatIcon />
</Button>
{!auth.loading && singleGoal.user === auth.user._id && (
<Button size="small">
<DoneIcon />
</Button>
)}
{!auth.loading && singleGoal.user === auth.user._id && (
<Button size="small">
<DeleteIcon />
</Button>
)}
</Grid>
</Grid>
</Grid>
))}
</Grid>
</Container>
</main>
</>
);
};
Goals.propTypes = {
getGoals: PropTypes.func.isRequired,
goal: PropTypes.object.isRequired
};
const mapStateToProps = state => ({
goal: state.goal,
auth: state.auth
});
export default connect(mapStateToProps, { getGoals, addLike, removeLike })(
Goals
);
I will need to see the rest of your code to be sure, but it seems you are dispatching your action but you are not updating your store, it could be a mistake in your reducer.

Categories

Resources