How to reference CSS Classes in a different class in Material UI - css

I want to reference a CSS class in another CSS class present in the same makeStyles hook.
import React from 'react';
import { makeStyles, Typography, Grid } from '#material-ui/core';
const styles = makeStyles((theme) => ({
root: {},
textStyle: {
fontFamily: 'Brandon',
textTransform: 'uppercase',
cursor: 'pointer',
'&:hover': {
color: `${theme.palette.primary.contrastText} !important`,
$dropDown: {
// I want to apply this style to the dropDown class when I hover over the textStyle Class
opacity: 1,
},
},
},
dropDown: {
width: 'max-content',
position: 'absolute',
top: '80px',
backgroundColor: 'tomato',
pointerEvents: 'none',
opacity: 0, // manipulate this
},
dropDownList: {
padding: '30px 0px 50px',
minWidth: '200px',
position: 'relative',
width: 'auto',
},
text: {
// fontFamily: 'Brandon',
padding: '4px 0px',
},
dropDownItem: {
padding: '5px 0px',
},
}));
const Shop: React.FC = () => {
const classes = styles();
const trendingArr = [
'New Arrivals',
'Best Sellers',
'The Summer Edit',
'FRAME & Mejuri',
'New Arrivals',
'Best Sellers',
'The Summer Edit',
'FRAME & Mejuri',
];
return (
<>
<Typography variant='body1' className={classes.textStyle}>
Shop
</Typography>
<Grid container direction='row' className={classes.dropDown}>
<Grid
container
direction='column'
className={classes.dropDownList}
>
<Typography variant='body2' className={classes.text}>
<b>Trending</b>
</Typography>
{trendingArr.map((item, i) => (
<Typography
className={classes.dropDownItem}
variant='body2'
key={i}
>
{item}
</Typography>
))}
</Grid>
{/* another one */}
<Grid
container
direction='column'
className={classes.dropDownList}
>
<Typography variant='body2' className={classes.text}>
<b>Trending</b>
</Typography>
{trendingArr.map((item, i) => (
<Typography
className={classes.dropDownItem}
variant='body2'
key={i}
>
{item}
</Typography>
))}
</Grid>
</Grid>
</>
);
};
export default Shop;
I want to reference the dropDown class inside the hover selector of textStyle to change the opacity whenever I hover over the textStyle class. How can I achieve it ?

Related

How can style the backdrop of a MaterialUI modal?

I have a MUI Modal set up, it's currently working, however the backdrop is being displayed as black. I have styling in place, but for some reason the backdrop is not being updated and remains pitch black.
My code is below, a screenshot is also below of what I see when the Modal is opened. Please let me know how I can fix this issue.
import { Box, Modal, Typography } from "#material-ui/core";
import React from "react";
import { makeStyles } from "#material-ui/core/styles";
const useStyles = makeStyles((theme) => ({
modalStyle: {
position: "absolute",
top: "50%",
left: "50%",
transform: "translate(-50%, -50%)",
width: 300,
bgcolor: "background.paper",
boxShadow: 24,
p: 4,
backgroundColor: "white",
borderRadius: "10px",
},
}));
const PopupModal = ({ postModalOpen, handleClose, children }) => {
const classes = useStyles();
return (
<Modal open={postModalOpen} onClose={handleClose}>
<Box className={classes.modalStyle}>
ModalText
<Typography
id="modal-modal-title"
variant="h6"
component="h2"
style={{
fontSize: "14px",
marginLeft: "5px",
}}
>
{children}
</Typography>
</Box>
</Modal>
);
};
export default PopupModal;
If you'd like to style the backdrop, your styles must be passed to the Modal component directly:
For example:
const useStyles = makeStyles((theme) => ({
/** Changed modalStyle */
modalStyle: { backgroundColor: "rgba(255, 0, 0, 0.5)" },
/** Moved content styling to new class */
contentStyle: {
/** Also removed some invalid attributes **/
position: "absolute",
top: "50%",
left: "50%",
transform: "translate(-50%, -50%)",
width: "300px",
backgroundColor: "white",
borderRadius: "10px"
}
}));
const PopupModal = ({ postModalOpen, handleClose, children }) => {
const classes = useStyles();
return (
// Note the changed className props with your sample code
<Modal
open={postModalOpen}
onClose={handleClose}
className={classes.modalStyle}
>
<Box className={classes.contentStyle}>
<Typography
id="modal-modal-title"
variant="h6"
component="h2"
style={{
fontSize: "14px",
marginLeft: "5px"
}}
>
{children}
</Typography>
</Box>
</Modal>
);
};
Working Example: https://codesandbox.io/s/material-demo-forked-edhqx?file=/demo.js
FYI: You can also override all backdrops in your application, on a global scale, by passing a MuiBackdrop override object to createMuiTheme().
This is how I customized my MUI Backdrop (MUI v5)
<Backdrop open={isOpen} sx={{ backgroundColor: 'rgba(0, 0, 0, 0.25)', zIndex: 1 }} onClick={handleCloseMenu} />

How to make the DropDown Menu Stay when I unhover the targeted element in Material-UI

import React from 'react';
import { makeStyles, Typography, Grid } from '#material-ui/core';
const styles = makeStyles((theme) => ({
root: {},
textStyle: {
fontFamily: 'brandon-grotesque-black',
textTransform: 'uppercase',
cursor: 'pointer',
'& + $dropDown': {
visibility: 'hidden',
transition: 'all 0s ease 1s',
},
'&:hover': {
'& + $dropDown': {
transitionDelay: '0s',
visibility: 'visible',
},
},
},
dropDown: {
width: 'max-content',
position: 'absolute',
top: '100px',
pointerEvents: 'none',
'& ul': {
listStyleType: 'none',
padding: '0px 0px',
'& li': {
backgroundColor: 'purple !important',
},
'&:hover': {},
// visibility: 'hidden',
},
},
}));
const Shop: React.FC = () => {
const classes = styles();
const trendingArr = [
'New Arrivals',
'Best Sellers',
'The Summer Edit',
'FRAME & Mejuri',
'New Arrivals',
'Best Sellers',
'The Summer Edit',
'FRAME & Mejuri',
];
return (
<>
<Typography variant='body1' className={classes.textStyle}>
Shop
</Typography>
<Grid className={classes.dropDown} container direction='row'>
<ul>
<li>
<a>
<Typography variant='body2'>
<b>Trending</b>
</Typography>
</a>
</li>
{trendingArr.map((item, i) => (
<li>
<a>
<Typography variant='body2' key={i}>
{item}
</Typography>
</a>
</li>
))}
</ul>
</Grid>
</>
);
};
export default Shop;
When I hover over the Shop text, my drop down appears but as I move towards the drop down menu, it becomes invisible. How can I make the dropDown stay even when I unhover the Shop so that I can interact with the drop down elements. I just want the Drop Down menu to stay as I unhover over the Shop text and moves towards the it (Drop Down Menu).
import React from 'react';
import { makeStyles, Typography, Grid } from '#material-ui/core';
const styles = makeStyles((theme) => ({
root: {
'& $dropDown': {
visibility: 'hidden',
transition: 'all 0s ease 0.2s',
display: 'inline-flex',
},
'&:hover $dropDown': {
transitionDelay: '0s',
visibility: 'visible',
},
},
textStyle: {
fontFamily: 'brandon-grotesque-light',
textTransform: 'uppercase',
cursor: 'pointer',
'&:hover': {
color: theme.palette.primary.light,
},
},
dropDown: {
top: '80px',
position: 'absolute',
width: '100%',
height: 'auto',
left: '0',
backgroundColor: theme.palette.primary.main,
'& ul': {
listStyleType: 'none',
padding: '0px 0px',
'& li': {
padding: '5px 0px 5px 30px',
'& a': {
display: 'block',
},
},
},
},
rowsStyle: {
paddingLeft: '80px !important',
position: 'relative',
},
columnStyle: {
fontFamily: 'brandon-grotesque-black',
},
linkStyle: {
fontFamily: 'brandon-grotesque-light',
cursor: 'pointer',
'&:hover': {
color: theme.palette.primary.light,
},
},
}));
const Shop: React.FC = () => {
const classes = styles();
const trendingArr = [
'New Arrivals',
'Best Sellers',
'The Summer Edit',
'FRAME & Mejuri',
'New Arrivals',
'Best Sellers',
'The Summer Edit',
'FRAME & Mejuri',
];
return (
<Grid className={classes.root}>
<Typography variant='body1' className={classes.textStyle}>
Shop
</Typography>
<Grid className={classes.dropDown} container direction='row'>
<ul>
<li>
<a>
<Typography
variant='body2'
className={classes.columnStyle}
>
Trending
</Typography>
</a>
</li>
{trendingArr.map((item, i) => (
<li>
<a>
<Typography
className={classes.linkStyle}
variant='body2'
key={i}
>
{item}
</Typography>
</a>
</li>
))}
</ul>
</Grid>
</Grid>
);
};
export default Shop;
Instead of targeting the text, targeting the container fixed the dropdown problem.

How can I scroll on my Page when my Dialog Component has been opened

I want to scroll on the background, when my dialog component opens up. By default, you cannot scroll when the dialog appears. How can I scroll in the background ?
Following is the Code:-
import React, { useState } from 'react';
import {
makeStyles,
Grid,
Button,
Dialog,
DialogActions,
DialogTitle,
} from '#material-ui/core';
import ShoppingCartIcon from '#material-ui/icons/ShoppingCart';
import CloseIcon from '#material-ui/icons/Close';
const styles = makeStyles((theme) => ({
root: {
position: 'fixed',
bottom: '0 ',
left: '0',
right: '0',
boxShadow: '0 0 6px rgb(0 0 0 / 70%)',
backgroundColor: 'white',
height: '63px',
},
textStyle: {
fontFamily: 'Comfortaa',
},
icon: {
color: theme.palette.primary.dark,
},
btn: {
backgroundColor: theme.palette.primary.dark,
color: 'white',
fontFamily: 'Comfortaa',
'&:hover': {
backgroundColor: theme.palette.primary.dark,
},
},
title: {
display: 'flex',
justifyContent: 'flex-end',
borderBottom: '1px solid #e5e5e5',
},
closeIcon: {
color: theme.palette.primary.light,
'&:hover': {
color: 'black',
},
},
dialogStyle: {
backgroundColor: 'white',
position: 'absolute',
top: 0,
},
dialogContainer: {
opacity: 0,
},
dialogTitle: {
display: 'flex',
justifyContent: 'flex-end',
borderBottom: '1px solid #e5e5e5',
},
}));
const CartAppBar: React.FC = () => {
const classes = styles();
const [open, setOpen] = useState(false);
const handleClickOpen = () => {
setOpen(true);
};
const handleClose = () => {
setOpen(false);
};
return (
<>
<Grid
item
container
direction='row'
justify='space-around'
alignItems='center'
className={classes.root}
xs={12}
>
<div>
<ShoppingCartIcon
fontSize='large'
classes={{ root: classes.icon }}
onClick={handleClickOpen}
/>
</div>
<div>
<Button
className={classes.btn}
type='submit'
onClick={() => {
return (window.location.href = '/checkout');
}}
>
Checkout
</Button>
</div>
</Grid>
<Dialog
open={open}
onClose={handleClose}
aria-labelledby='alert-dialog-title'
aria-describedby='alert-dialog-description'
maxWidth='md'
fullWidth
classes={{
paper: classes.dialogStyle,
container: classes.dialogContainer,
}}
scroll='paper'
>
<DialogTitle className={classes.dialogTitle}>
<CloseIcon
onClick={handleClose}
classes={{ root: classes.closeIcon }}
/>
</DialogTitle>
{/* Footer */}
{/* <DialogActions className={classes.footer}>
<Button classes={{ root: classes.btn }}>Add To Cart</Button>
</DialogActions> */}
</Dialog>
</>
);
};
export default CartAppBar;
As you can see in the photo, there's opacity in the background and you cannot scroll. I want to override this and make the background scrollable
use disableScrollLock as prop will help

Can't Make MouseEnter and MouseLeave Animation on React

I'm new at react. I'm using media cards to present some picture and small text and have been trying to give small sliding animation to my text and background layer. However I failed. Codes are below:
import React, { useState, Component } from 'react';
import { makeStyles } from '#material-ui/core/styles';
import CardActionArea from '#material-ui/core/CardActionArea';
import CardContent from '#material-ui/core/CardContent';
import CardMedia from '#material-ui/core/CardMedia';
import Typography from '#material-ui/core/Typography';
import Grid from '#material-ui/core/Grid';
import Paper from '#material-ui/core/Paper';
export default function SectionCard(props) {
const [areaHeight, setAreaHeight] = useState(100);
const [imgSize, setImgSize] = useState(1);
const [lineColor, setLineColor] = useState('dodgerblue');
const [textPosition, setTextPosition] = useState(0);
const useStyles = makeStyles((theme) => ({
root: {
maxWidth: 345,
},
media: {
height: 400,
scale: imgSize,
},
greyCover: {
backgroundColor: 'rgba(0, 0, 0, 0.5)',
height: areaHeight,
width: '100%',
bottom: 0,
position: 'absolute',
},
line: {
backgroundColor: lineColor,
height: 5,
width: '100%',
borderRadius: 0,
},
textPosition: {
paddingTop: textPosition,
fontFamily: 'Quicksand !important',
color: 'white !important',
},
body: {
fontFamily: 'Quicksand !important',
},
}));
const classes = useStyles();
return (
<Grid item xs={12} sm={4} onMouseEnter={() => (setAreaHeight('100%'), setLineColor('red'), setImgSize(1.2), setTextPosition('150px!important'))} onMouseLeave={() => (setAreaHeight(100), setLineColor('dodgerblue'), setImgSize(1), setTextPosition('0px !important'))}>
<CardActionArea>
<CardMedia
className={classes.media}
image={props.img}
/>
<CardContent className={classes.greyCover} style={{ fontFamily: 'Quicksand', }}>
<div className={classes.textPosition}>
<Typography gutterBottom variant="h5" component="h2" align="center">
{props.title}
</Typography>
<Typography component="p" align="center">
{props.text}
</Typography>
</div>
</CardContent>
</CardActionArea>
<Paper className={classes.line} />
</Grid>
);
}
Codes are probably messy. Sorry for that. onMouseEnter and onMouseLeave are working fine. I just want to see that greyCover class and text moves slowly to height 100% and text to mid of the frame.
I didn't want to use another packages yet I don't know how to use too to be honest.
What I'm doing wrong?

CSS icon button half going offscreen on mobile view

I was able to make it so that the search bar stays to the right of the search bar. Not mandatory of course. I can be inside the right side of the search bar. This is the gitHub link for this: https://github.com/strawberries73/telescope/tree/Issue-1226
What I did try was an InputAdornment method. https://material-ui.com/components/text-fields/#input-adornments. This code can be found here: https://github.com/strawberries73/telescope/tree/Issue-1225
import React from 'react';
import { makeStyles } from '#material-ui/core/styles';
import PropTypes from 'prop-types';
import SearchIcon from '#material-ui/icons/Search';
import {
Grid,
MenuItem,
TextField,
FormControl,
Paper,
IconButton,
Box,
Typography,
Fab,
} from '#material-ui/core';
const useStyles = makeStyles((theme) => ({
root: {
overflow: 'visible',
maxWidth: '785px',
padding: 0,
marginTop: '10rem',
marginLeft: 'auto',
marginRight: 'auto',
},
card: {
padding: theme.spacing(2, 4, 2, 4),
backgroundColor: theme.palette.background.default,
},
input: {
fontSize: '1.6rem',
'& > *': {
fontSize: '1.6rem !important',
color: theme.palette.text.default,
},
},
header: {
padding: 0,
marginBottom: theme.spacing(2),
backgroundColor: theme.palette.primary.main,
},
h1: {
display: 'block',
transition: 'all linear 350ms',
fontWeight: 600,
color: theme.palette.text.secondary,
[theme.breakpoints.between('xs', 'sm')]: {
fontSize: '3rem',
},
[theme.breakpoints.between('md', 'lg')]: {
fontSize: '4rem',
},
[theme.breakpoints.up('xl')]: {
fontSize: '5rem',
},
},
iconButton: {
backgroundColor: theme.palette.secondary.main,
'&:hover': {
backgroundColor: theme.palette.secondary.dark,
},
'& * > .MuiSvgIcon-root': {
fontSize: '2rem',
color: theme.palette.text.primary,
},
margin: 0,
marginRight: theme.spacing(-1.45),
bottom: theme.spacing(-2),
float: 'right',
marginBottom: theme.spacing(-5.5),
[theme.breakpoints.only('xs')]: {
marginTop: theme.spacing(6),
marginRight: theme.spacing(-8),
},
},
selectControl: {
'& > *': {
fontSize: '1.2rem',
textTransform: 'capitalize',
color: theme.palette.primary.main,
},
},
selectItem: {
fontSize: '1.4rem',
textTransform: 'capitalize',
color: theme.palette.primary.main,
},
}));
function CustomizedInputBase(props) {
const classes = useStyles();
const { searchText, onChangeHandler, onFilterChangeHandler, filter, onFormSubmit } = props;
const onFilterChange = (event) => {
onFilterChangeHandler(event.target.value);
};
const onTextChange = (event) => {
onChangeHandler(event.target.value);
};
const onSubmit = (event) => {
event.preventDefault();
onFormSubmit();
};
const searchOptions = ['post', 'author'];
return (
<Box className={classes.root} boxShadow={2}>
<Paper component="form" className={classes.card} elevation={0}>
<Grid
container
className={classes.header}
direction="row"
spacing={8}
alignItems="center"
justify="flex-start"
>
<Grid item xs={12}>
<Typography variant="h1" className={classes.h1}>
Search
</Typography>
</Grid>
</Grid>
<Fab size="large" className={classes.iconButton}>
<FormControl>
<IconButton type="submit" onClick={(event) => onSubmit(event)} aria-label="search">
<SearchIcon />
</IconButton>
</FormControl>
</Fab>
<Grid container direction="row" spacing={2} alignItems="center" justify="flex-start">
<Grid item xs={12} sm={2} lg={2}>
<FormControl fullWidth={true}>
<TextField
id="standard-select-search-type"
select
label="Filter"
value={filter}
variant="outlined"
className={classes.selectControl}
onChange={(event) => onFilterChange(event)}
>
{searchOptions.map((option) => (
<MenuItem key={option} value={option} className={classes.selectItem}>
{option}
</MenuItem>
))}
</TextField>
</FormControl>
</Grid>
<Grid item xs={12} sm={10} lg={10}>
<FormControl fullWidth={true}>
<TextField
className={classes.input}
placeholder="How to Get Started in Open Source"
inputProps={{ 'aria-label': 'search telescope' }}
variant="outlined"
value={searchText}
onChange={(event) => onTextChange(event)}
/>
</FormControl>
</Grid>
</Grid>
</Paper>
</Box>
);
}
CustomizedInputBase.propTypes = {
searchText: PropTypes.string,
onChangeHandler: PropTypes.func,
onFilterChangeHandler: PropTypes.func,
onFormSubmit: PropTypes.func,
filter: PropTypes.string,
};
export default CustomizedInputBase;
Solved! My solution to my answer.
import React from 'react';
import PropTypes from 'prop-types';
import { makeStyles } from '#material-ui/core/styles';
import SearchIcon from '#material-ui/icons/Search';
import InputAdornment from '#material-ui/core/InputAdornment';
import {
Grid,
MenuItem,
TextField,
FormControl,
Paper,
IconButton,
Box,
Typography,
} from '#material-ui/core';
import SearchHelp from '../SearchHelp';
const useStyles = makeStyles((theme) => ({
root: {
overflow: 'visible',
maxWidth: '785px',
padding: 0,
marginTop: '10rem',
marginLeft: 'auto',
marginRight: 'auto',
marginBottom: theme.spacing(6),
},
card: {
padding: theme.spacing(2, 4, 2, 4),
backgroundColor: theme.palette.background.default,
},
header: {
padding: 0,
marginBottom: theme.spacing(2),
backgroundColor: theme.palette.primary.main,
},
h1: {
display: 'block',
transition: 'all linear 350ms',
fontWeight: 600,
color: theme.palette.text.secondary,
[theme.breakpoints.between('xs', 'sm')]: {
fontSize: '3rem',
},
[theme.breakpoints.between('md', 'lg')]: {
fontSize: '4rem',
},
[theme.breakpoints.up('xl')]: {
fontSize: '5rem',
},
},
iconButton: {
backgroundColor: theme.palette.secondary.main,
'&:hover': {
backgroundColor: theme.palette.secondary.dark,
},
'& * > .MuiSvgIcon-root': {
fontSize: '2rem',
color: theme.palette.primary.contrastText,
},
margin: 0,
position: 'relative',
bottom: theme.spacing(6),
float: 'right',
marginBottom: theme.spacing(-12),
},
selectControl: {
'& > *': {
fontSize: '1.2rem',
textTransform: 'capitalize',
color: theme.palette.primary.main,
},
},
selectItem: {
fontSize: '1.4rem',
textTransform: 'capitalize',
color: theme.palette.primary.main,
},
}));
function CustomizedInputBase(props) {
const classes = useStyles();
const { text, onTextChange, onFilterChange, filter, onSubmit } = props;
const searchOptions = ['post', 'author'];
return (
<Box className={classes.root} boxShadow={2}>
<Paper component="form" className={classes.card} elevation={0}>
<Grid
container
className={classes.header}
direction="row"
spacing={8}
alignItems="center"
justify="flex-start"
>
<Grid item>
<Typography variant="h1" className={classes.h1}>
Search
</Typography>
</Grid>
<SearchHelp />
</Grid>
<Grid container direction="row" spacing={2} alignItems="center" justify="flex-start">
<Grid item xs={12} sm={2} lg={2}>
<FormControl fullWidth={true}>
<TextField
id="standard-select-search-type"
select
label="Filter"
value={filter}
variant="outlined"
className={classes.selectControl}
onChange={(event) => onFilterChange(event.target.value)}
>
{searchOptions.map((option) => (
<MenuItem key={option} value={option} className={classes.selectItem}>
{option}
</MenuItem>
))}
</TextField>
</FormControl>
</Grid>
<Grid item xs={12} sm={10} lg={10}>
<FormControl fullWidth={true}>
<TextField
className={classes.input}
placeholder="How to Get Started in Open Source"
inputProps={{ 'aria-label': 'search telescope' }}
variant="outlined"
value={text}
InputProps={{
endAdornment: (
<InputAdornment>
<IconButton type="submit" className={classes.iconButton} onClick={onSubmit}>
<SearchIcon />
</IconButton>
</InputAdornment>
),
}}
onChange={(event) => onTextChange(event.target.value)}
/>
</FormControl>
</Grid>
</Grid>
</Paper>
</Box>
);
}
CustomizedInputBase.propTypes = {
text: PropTypes.string,
onTextChange: PropTypes.func,
filter: PropTypes.string,
onFilterChange: PropTypes.func,
onSubmit: PropTypes.func,
};
export default CustomizedInputBase;

Resources