Material-UI dark opacity background image - javascript

I'm wrapping all the widgets in a CardMedia component, and setting an image.
return (
<CardMedia image={bg} className={classes.bg}>
<main className={classes.content}>
<div className={classes.toolbar} />
<Grid container justify="center" spacing={4}>
{products.map((product) => (
<Grid item key={product.id} xs={12} sm={12} md={12} lg={6}>
<Product product={product}></Product>
</Grid>
))}
</Grid>
</main>
</CardMedia>);
I need to make the image a little darker.
Here is the code for the styles:
export default makeStyles((theme) => ({
toolbar: theme.mixins.toolbar,
content: {
flexGrow: 1,
backgroundColor: "transparent",
/* backgroundColor: theme.palette.background.default, */
padding: theme.spacing(3),
[theme.breakpoints.down("lg")]: {
paddingRight: 200,
paddingLeft: 200,
},
[theme.breakpoints.down("xl")]: {
paddingRight: 200,
paddingLeft: 200,
},
[theme.breakpoints.down("sm")]: {
padding: theme.spacing(3),
},
},
root: {
flexGrow: 1,
},
bg: {
backgroundRepeat: "no-repeat",
backgroundAttachment: "fixed",
},
}));
Maybe there is even a simpler way to create a background image with a darker tint?
Also, I don't know if this has to do with anything, but when I set the image with CardMedia, every time I scroll to the bottom of the page there is a short annoying lag. Thanks in advance.

Hi you should try to use this for made your image darker is a simple CSS function :
.img { filter: “brightness(50%)”; }
Also change your component if you not rendering any childrens inside :
<Product><\Product>
to
<Product />

Related

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

How to make a Grid item clickable with Link component?

PostsList component renders list of posts, I want to make it such that when clicked over the div item of a post it gets redirected to that specific post's link
const PostsListView = ({ posts, setError, isloggedin }) => {
const [redirectCreatePost, setRedirectCreatePost] = React.useState(false)
if (redirectCreatePost) return (<Navigate to='createPost' />)
return (
<Grid container
align="center"
alignItems="center"
justify="center"
direction="column"
>
{
posts.map(({ category, username, postHeading, createdAt, postid }) => {
return (
<Link to={`post/${postid}`} style={{ textDecoration: 'none', color: 'black' }}>
<Grid
key={postid}
item container
alignItems="center"
style={{
width: 600,
borderRadius: 10,
margin: 5,
backgroundColor: '#D3D3D3'
}}>
<Grid container direction="column">
<Grid item container justify="flex-end">
<Grid item style={{ marginTop: 5, marginLeft: 20 }}> <b>{`c/${category}`}</b> </Grid>
<Grid item style={{ marginTop: 5, marginLeft: 5 }}> {` posted by u/${username} ${getTime(createdAt)}`} </Grid>
</Grid>
</Grid>
<Grid item container alignItems="center" align="left">
<Typography variant="h6" style={{ width: 600, marginLeft: 20, marginRight: 20 }}>{postHeading}</Typography>
</Grid>
</Grid>
</Link>
)
})
}
</Grid>
)
}
Although this seems to create an <a> tag around the grid item <div> in the DOM it is not clickable. I have tried giving the <Link> as component prop to the Grid item and yet no luck. Weirdly enough, it works fine when I replace the <Link> with <a>, but on doing so on clicking the link it refreshes the entire page losing all the state of the App. Appreciate any help. Thanks!

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

How to customize Material UI autocomplete dropdown menu

I am using Material UI v5 beta1 and I have been trying to customize their Autocomplete component so that the Typography color on the options changes from black to white whenever the item is selected, however, I can't figure out how to pass the style to it.
So far I have tried passing my styles on .MuiAutocomplete-option either through a styled component or a global override (see code attached) and tried every state I can think of, hover, selected, focused, even tried the Material classes for those but none of them worked. I have also tried using a custom Popper with a MenuList inside but with no luck. I have been pulling my hair with this for a couple of days now, and not being able to inspect the DOM makes it even harder, any help or tip would be highly appreciated.
Thank you in advance.
MuiAutocomplete: {
styleOverrides: {
root: {
// ...
},
option: {
padding: '5px 12px',
backgroundColor: theme.palette.background.paper,
display: 'flex',
height: 42,
borderRadius: theme.borderRadius.s,
'&:hover': {
backgroundColor: theme.palette.action.hover,
'& .Mui-Typography-root': { color: theme.palette.text.contrast },
},
'& .Mui-selected': {
backgroundColor: theme.palette.action.hover,
'& .Mui-Typography-root': { color: theme.palette.text.contrast },
},
'&.disabled': {
opacity: 0.5,
'& .Mui-Typography-root': {
color: theme.palette.text.disabled,
},
},
},
renderOption={(props, option) => {
return (
<li {...props}>
<Box display={'flex'} flexDirection={'row'}>
<Avatar size={'32'} variant={'circular'} />
<Box display={'flex'} ml={3} flexDirection={'column'}>
<Typography color={'text.primary'}>
{option.label}
</Typography>
<Typography color={'text.secondary'}>
Extra Information
</Typography>
</Box>
</Box>
</li>
);
}}
I would pass in { selected } to your renderOption, then use it to toggle your styling inline
For example:
renderOption={(props, option, { selected }) => {
return (
<li {...props}>
<Box display={'flex'} flexDirection={'row'} style={{ backgroundColor: selected ? 'red' : 'green' }}>
<Avatar size={'32'} variant={'circular'} />
<Box display={'flex'} ml={3} flexDirection={'column'}>
<Typography color={'text.primary'}>
{option.label}
</Typography>
<Typography color={'text.secondary'}>
Extra Information
</Typography>
</Box>
</Box>
</li>
);
}}

justifyContent with createStyles in TypeScript

I have a toolbar where I am using 2 icons that appear on the left end. Currently, I am using this styling method:
const useStyles = makeStyles((theme: Theme) =>
createStyles({
root: {
display: 'flex',
},
appBar: {
width: `calc(100% - ${drawerWidth}px)`,
marginLeft: drawerWidth,
},
drawer: {
width: drawerWidth,
flexShrink: 0,
},
drawerPaper: {
width: drawerWidth,
},
panelheaderRight: {
marginRight: 0,
right: 0,
},
toolbar: theme.mixins.toolbar,
content: {
flexGrow: 1,
// justifyContent: spaceBetween,
backgroundColor: theme.palette.background.default,
padding: theme.spacing(3),
},
}),
);
I want the icons to appear on the right end. If I add a separate css file with this, it works:
.toolbar-class{
justify-content:space-between;
}
but I want to use it inside the createStyles. There's no 'space-between' option in createStyles. This is how a portion of my component looks like:
<AppBar position="fixed" className={classes.appBar}>
<Toolbar className="toolbar-class">
<Typography variant="h6" noWrap>
Al
</Typography>
<div className="panelheaderRight">
<NotificationsIcon />
{/* <ExitToAppIcon onClick={() =>
<ExitToAppIcon onClick={logout}></ExitToAppIcon>
</div>
</Toolbar>
</AppBar>
Is there any way I can move the icons to the left using createStylesand without adding a separate css file?
Some notice points:
Change justify-content to justifyContent, and value as string.
No need to use createStyels for makeStyles
const useStyles = makeStyles((theme: Theme) => ({
toolBar: {
justifyContent: 'space-between'
},
...
...
<Toolbar className={classes.toolBar}>

Categories