Detect screen break point inside the component jsx itself - javascript

I have the following component:
<Stack direction="row" spacing={2}>
<Skeleton variant="rounded" animation="wave" sx={{ width: 1 }} />
<Loading
text="Loading..."
sx={{ position: 'relative', background: 'none', color: 'grey' }}
recommendedSolutions={
<LoadingBtn
onClick={refetch}
variant="outlined"
loadingIndicator="Refetching data..."
loading={loading}
>
Try again
</LoadingBtn>
}
/>
</Stack>
I want to be able to change the direction prop of the Stack component based on the screen breakpoint. The question is:
I can use the grid component to solve this problem as follows:
<Grid container>
<Grid item sx={{ display: { xs: 'none', md: 'block' } }}>
<Stack direction="row" spacing={2}>
<Skeleton variant="rounded" animation="wave" sx={{ width: 1 }} />
<Loading
text="Loading..."
sx={{ position: 'relative', background: 'none', color: 'grey' }}
recommendedSolutions={
<LoadingBtn
onClick={refetch}
variant="outlined"
loadingIndicator="Refetching data..."
loading={loading}
>
Try again
</LoadingBtn>
}
/>
</Stack>
</Grid>
<Grid item sx={{ display: { xs: 'block', md: 'none' } }}>
<Stack direction="vertical" spacing={2}>
<Skeleton variant="rounded" animation="wave" sx={{ width: 1 }} />
<Loading
text="Loading..."
sx={{ position: 'relative', background: 'none', color: 'grey' }}
recommendedSolutions={
<LoadingBtn
onClick={refetch}
variant="outlined"
loadingIndicator="Refetching data..."
loading={loading}
>
Try again
</LoadingBtn>
}
/>
</Stack>
</Grid>
</Grid>
but this makes me repeat similar code, is there a way I can do it within the direction prop of the Stack component itself? it's a tough task to write that much code

Related

How do I make the width of my html elements fixed?

I have a user registration form that renders error messages when the input fields fail the validation. When the error messages are rendered, all the elements become wider. How can I prevent them from becoming wider?
It seems that the following lines are causing it to expand:
{errors.name && <p>{errors.name.message}</p>}
{errors.email && <p>{errors.email.message}</p>}
{errors.password && <p>{errors.password.message}</p>}
I'm also using Material UI, and react-hook-form.
Before error:
After error:
My code:
return (
<Box
sx={{
marginTop: 8,
display: "flex",
flexDirection: "column",
alignItems: "center"
}}>
<Typography
variant="h2"
sx={{
color: theme.palette.text.primary,
fontWeight: "bold"
}}
>
{Constants.Create.REGISTER_HEADER}
</Typography>
<Typography
variant="h4"
sx={{
color: theme.palette.text.secondary
}}
>
{Constants.Create.REGISTER_SUBHEADER}
</Typography>
<Box component="form" noValidate onSubmit={handleSubmit(onSubmit)} sx={{ mt: 2 }}>
<Grid container spacing={1}>
<Grid item xs={12}>
<Typography
variant="subtitle1"
sx={{
color: theme.palette.text.secondary
}}
>
{Constants.Create.NAME_HEADER}
</Typography>
</Grid>
<Grid item xs={12}>
<Controller
name="name"
control={control}
render={({ field }) => (<TextField
{...field}
margin="normal"
required
fullWidth
id="name"
label="Required"
variant="filled"
size="small"
sx={{
marginTop: "0px"
}}
/>
)}
/>
{errors.name && <p>{errors.name.message}</p>}
</Grid>
<Grid item xs={12}>
<Typography
variant="subtitle1"
sx={{
color: theme.palette.text.secondary
}}
>
{Constants.Create.EMAIL_HEADER}
</Typography>
</Grid>
<Grid item xs={12}>
<Controller
name="email"
control={control}
render={({ field }) => (<TextField
{...field}
margin="normal"
required
fullWidth
id="email"
label="Required"
variant="filled"
size="small"
sx={{
marginTop: "0px"
}}
/>
)}
/>
{errors.email && <p>{errors.email.message}</p>}
</Grid>
<Grid item xs={12}>
<Typography
variant="subtitle1"
sx={{
color: theme.palette.text.secondary
}}
>
{Constants.Create.PASSWORD_HEADER}
</Typography>
</Grid>
<Grid item xs={12}>
<Controller
name="password"
control={control}
render={({ field }) => (<TextField
{...field}
type="password"
margin="normal"
required
fullWidth
id="password"
label="Required"
variant="filled"
size="small"
sx={{
marginTop: "0px"
}}
/>
)}
/>
<Box>
{errors.password && <p>{errors.password.message}</p>}
</Box>
</Grid>
<Grid item xs={12}>
<FormControlLabel
...
/>
</Grid>
</Grid>
<Button
type="submit"
fullWidth
variant="contained"
size="large"
sx={{ mt: 2, mb: 2 }}
>
{Constants.Create.CREATE_ACCOUNT}
</Button>
</Box>
</Box >
)
How can I sort of fix the width of the elements? Or prevent the error messages from increasing the width?
Use CSS for this. Make sure your HTML elements <input> have the following styling:
input {
display: block;
width: 100%
}
CSS should keep the size of your HTML elements, before and after the JS validation.

MUI CardContent and flexBox doesn't work with typography and chip

Below is react code made with MUI. The aim is to create a Card that displays Character Information.
const CharacterPreview = ({ characterKey }: CharacterPreviewProps) => {
return (
<Card sx={{ maxWidth: 256, borderRadius: 4 }}>
<Box
component="a"
href={`/#/${characterKey}`}
display="flex"
position="relative"
sx={{
"&::before": {
content: '""',
display: "block",
position: "absolute",
left: 0,
top: 0,
width: "100%",
height: "100%",
opacity: 0.7,
backgroundImage: `url(${bannerImgUrl})`,
backgroundPosition: "center",
backgroundSize: "cover",
},
}}
width="100%"
>
<Box
flexShrink={1}
sx={{ maxWidth: { xs: "40%", lg: "40%" } }}
alignSelf="flex-end"
display="flex"
flexDirection="column"
zIndex={1}
>
<Box
component="img"
src={iconImgUrl}
width="100%"
height="auto"
maxWidth={256}
sx={{ mt: "auto" }}
/>
</Box>
</Box>
<CardContent>
<Typography variant="h5" component="div">
{characterName}
</Typography>
{/* <Typography variant="body2" color="text.secondary"> */}
{/* {characterInfo.title as string} */}
{/* </Typography> */}
<Chip
label={characterChipInfo}
size="small"
/>
</CardContent>
</Card>
);
};
This is what the final result looks like:
I want the chip component (reads as CRYO in the image and is characterChipInfo in the above code) to be on the same line as the characterName and be separated like a space-between flexbox, however using the Box component with flex-box and justifyContent="space-between" to encase the name Typography and Chip doesn't work. I've also tried along with it changing the Typography display to inline-flex and inline-block, which makes them on the same line but the Box's justifyContent=space-between doesn't work.
You need to use a Stack component of Material UI like so:
CodeSandBox
<Stack
direction="row"
spacing={2}
justifyContent="space-between"
alignItems="center"
>
<Typography variant="h5" component="div">
{characterName}
</Typography>
{/* <Typography variant="body2" color="text.secondary"> */}
{/* {characterInfo.title as string} */}
{/* </Typography> */}
<Chip
label={characterChipInfo}
size="small"
/>
</Stack>

I am passing the state to a function component via history (react-router-dom) but it says the state is 'undefined'

I need to pass the state value to a different component and I want to use it in the different component.
Code in the first component:
const handleFormSubmit = async (event) => {
event.preventDefault()
console.log(formData)
try {
await axios
.post(`http://localhost:4000/accounts/register`, formData)
.then(function (response) {
console.log(response)
console.log(response.data)
setServerMessage(response.data)
})
} catch (error) {
console.log(error)
}
history({
pathname: '/session/verifyotp',
state: { serverMessage: serverMessage.message },
})
}
The second component where I am trying to access the state.
const navigate = useNavigate()
let data = useLocation()
console.log(data)
I have tried to log the current state value in the console using this:
useEffect(() => {
console.log(serverMessage)
}, [serverMessage])
I have tried to set the state in useffect like this:
useEffect(() => {
setServerMessage(serverMessage)
}, [serverMessage])
The output I am getting in the browser console is:
Object { pathname: "/session/verifyotp", search: "", hash: "", state: null, key: "n1jhatdj" }
This is the complete code in the page :
import React, { useEffect, useState } from 'react'
import { Box, styled } from '#mui/system'
import { Grid, Button } from '#mui/material'
import { ValidatorForm, TextValidator } from 'react-material-ui-form-validator'
import Typography from '#mui/material/Typography'
import { FormLabel } from '#mui/material'
import Link from '#mui/material/Link'
import axios from 'axios'
import Appbar from '../Appbar'
import Alert from '#mui/material/Alert'
import Snackbar from '#mui/material/Snackbar'
import { useNavigate } from 'react-router-dom'
const FlexBox = styled(Box)(() => ({
display: 'flex',
alignItems: 'center',
}))
const JustifyBox = styled(FlexBox)(() => ({
justifyContent: 'center',
}))
const IMG = styled('img')(() => ({
width: '100%',
}))
const JWTRegister = styled(JustifyBox)(() => ({
background: '#ffffff',
minHeight: '100vh !important',
input: {
background: 'white',
borderRadius: 25,
},
}))
const JwtRegister = (props) => {
const [serverMessage, setServerMessage] = useState('')
const [open, setOpen] = useState(false)
const history = useNavigate()
const [formData, setFormData] = useState({
name: '',
mobile: '',
email: '',
password: '',
})
const handleClick = () => {
setOpen(true)
}
const handleClose = (event, reason) => {
if (reason === 'clickaway') {
return
}
setOpen(false)
}
const { name, mobile, email, password } = formData
const handleChange = (event) => {
setFormData({
...formData,
[event.target.name]: event.target.value,
})
}
const handleFormSubmit = async (event) => {
event.preventDefault()
console.log(formData)
try {
await axios
.post(`http://localhost:4000/accounts/register`, formData)
.then(function (response) {
console.log(response)
console.log(response.data)
const newValue = response.data
setServerMessage(newValue)
})
} catch (error) {
console.log(error)
}
history({
pathname: '/session/verifyotp',
state: { serverMessage: serverMessage },
})
}
useEffect(() => {
console.log(serverMessage)
setServerMessage(serverMessage)
console.log(serverMessage)
}, [serverMessage])
return (
<JWTRegister>
<Grid container>
<Appbar />
<Grid
pt={0}
pl={10}
pr={10}
item
lg={6}
md={6}
sm={6}
xs={12}
sx={{ height: '100vh', backgroundColor: '#3E8BFF' }}
>
<Typography
component="h1"
variant="h3"
sx={{ textTransform: 'none', color: '#000' }}
>
Sign up
</Typography>
<Typography component="h1" variant="h5">
Register now to get 100 free credits
</Typography>
{serverMessage ? (
<>
<Alert
variant="filled"
autohideduration={6000}
severity="success"
>
{serverMessage.message}
</Alert>
<Snackbar
open={open}
autoHideDuration={3000}
onClose={handleClose}
>
<Alert
onClose={handleClose}
severity="success"
sx={{ width: '100%' }}
>
{serverMessage.message}
</Alert>
</Snackbar>
</>
) : null}
<ValidatorForm id="Register" onSubmit={handleFormSubmit}>
<Grid container spacing={2}>
<Grid
item
lg={6}
md={6}
sm={12}
xs={12}
sx={{ mt: 2 }}
>
<FormLabel sx={{ color: '#000000' }}>
Name
</FormLabel>
<TextValidator
sx={{ mb: 3, width: '100%' }}
size="small"
type="text"
name="name"
value={name}
autoFocus
onChange={handleChange}
validators={['required']}
errorMessages={['Name field is required']}
inputProps={{
style: {
borderRadius: 25,
backgroundColor: 'white',
disableUnderline: true,
},
}}
/>
</Grid>
<Grid
item
lg={6}
md={6}
sm={12}
xs={12}
sx={{ mt: 2 }}
>
<FormLabel sx={{ color: '#000000' }}>
Mobile
</FormLabel>
<TextValidator
sx={{ mb: 3, width: '100%' }}
size="small"
type="text"
name="mobile"
value={mobile}
onChange={handleChange}
validators={['required']}
errorMessages={[
'Mobile Number field is required',
]}
inputProps={{
style: {
borderRadius: 25,
backgroundColor: 'white',
disableUnderline: true,
},
}}
/>
</Grid>
</Grid>
<FormLabel sx={{ color: '#000000' }}>Email</FormLabel>
<TextValidator
sx={{ mb: 3, width: '100%' }}
size="small"
type="email"
name="email"
value={email}
onChange={handleChange}
validators={['required', 'isEmail']}
inputProps={{
style: {
borderRadius: 25,
backgroundColor: 'white',
disableUnderline: true,
},
}}
errorMessages={[
'Email field is required',
'Email is not valid',
]}
/>
<FormLabel sx={{ color: '#000000' }}>
Password
</FormLabel>
<TextValidator
sx={{ mb: '16px', width: '100%' }}
size="small"
name="password"
type="password"
value={password}
onChange={handleChange}
validators={['required']}
errorMessages={['Password field is required']}
inputProps={{
style: {
borderRadius: 25,
disableUnderline: true,
backgroundColor: 'white',
},
}}
/>
<FlexBox pb={2}>
<Button
type="submit"
variant="contained"
sx={{
borderRadius: 25,
textTransform: 'none',
background: '#C7FF80',
color: '#000000',
}}
onClick={handleClick}
>
Verify OTP
</Button>
</FlexBox>
</ValidatorForm>
<Typography
variant="subtitle1"
display="inline"
sx={{
textTransform: 'none',
color: '#000000',
}}
>
Already a member?
<Link
href="/session/signin"
sx={{
textTransform: 'none',
color: '#FFFFFF',
}}
>
Sign in
</Link>
instead.
</Typography>
</Grid>
<Grid
pt={1}
pl={10}
item
lg={6}
md={6}
sm={6}
xs={12}
sx={{ height: '100vh', backgroundColor: '#3E8BFF' }}
>
<Typography pb={3} variant="body">
or sign up with
</Typography>
<Grid
pb={3}
pt={3}
container
alignItems="center"
spacing={2}
>
<Grid item>
<IMG
src="/assets/images/signup-linkedin.svg"
height={55}
width={55}
/>
</Grid>
<Grid item>
<Typography pb={1} component="h6" variant="h6">
Linkedin
</Typography>
</Grid>
</Grid>
<Grid pb={3} container alignItems="center" spacing={2}>
<Grid item>
<IMG
src="/assets/images/signup-google.svg"
height={55}
width={55}
/>
</Grid>
<Grid item>
<Typography pb={1} component="h6" variant="h6">
Google
</Typography>
</Grid>
</Grid>
<Grid pb={3} container alignItems="center" spacing={2}>
<Grid item>
<IMG
src="/assets/images/signup-facebook.svg"
height={55}
width={55}
/>
</Grid>
<Grid item>
<Typography pb={1} component="h6" variant="h6">
Facebook
</Typography>
</Grid>
</Grid>
<Grid pb={3} container alignItems="center" spacing={2}>
<Grid item>
<IMG
src="/assets/images/signup-email.svg"
height={55}
width={55}
/>
</Grid>
<Grid item>
<Typography component="h6" variant="h6">
Corporate Email ID
</Typography>
<span pb={1} component="h6" variant="h6">
(Use only Business email)
</span>
</Grid>
</Grid>
</Grid>
</Grid>
</JWTRegister>
)
}
export default JwtRegister
No matter what I try I am not able to pass the state to the different component. I have followed this question but does not solve my problem.
How can I access the state value? Why is it coming as null?
I have found the answer to this question. react-router v6 In You need to use your history like this for react-router v6.
This is not the right way to pass state:
history({
pathname: '/session/verifyotp',
state: { serverMessage: serverMessage.message },
})
Correct way to pass state in react-router v6 is the following:
history("/session/verifyotp", {
state: { serverMessage: serverMessage },
});

How do I change the zAxis of a Paper from MUI?

Hello I want to know how do you change the zAxis of a paper from MUI
As you can see the carousel overlaps my menu and I would like my menu to be on top of everything.
This is how I have it wrapped:
<Box sx={{ background: '#272A31', flexGrow: 0, display: { xs: 'none', md: 'flex' } }}>
<StyledIconButton size="small" edge="start" color="inherit" aria-label="menu" sx={{ mr: 2 }} onClick={handleToggle} ref={anchorRef} >
<GamesIcon />
<Typography variant="h6" component="div" sx={{ flexGrow: 1 }}> GAMES </Typography>
<Popper open={open} anchorEl={anchorRef.current} role={undefined} placement="bottom-start" transition disablePortal >
{({ TransitionProps, placement }) => (
<Grow {...TransitionProps}
style={{
transformOrigin: placement === 'bottom-start' ? 'left top' : 'left bottom',
}}
>
<StyledPaper sx = {{zIndex: 1600}} >
<ClickAwayListener onClickAway={handleClose}>
<MenuList autoFocusItem={open} id="composition-menu" aria-labelledby="composition-button" onKeyDown={handleListKeyDown}>
<StyledMenuItem onClick={handleClose}>JUNGLE RAIDER</StyledMenuItem>
<StyledMenuItem onClick={handleClose}>MEGAMAN TEMPLATE</StyledMenuItem>
<StyledMenuItem onClick={handleClose}>TOWER DEFENSE</StyledMenuItem>
<StyledMenuItem onClick={handleClose}>BLADES AND DUNGEON</StyledMenuItem>
<StyledMenuItem onClick={handleClose}>FIXSPACE</StyledMenuItem>
</MenuList>
</ClickAwayListener>
</StyledPaper>
</Grow>
)}
</Popper>
</StyledIconButton>
</Box>
While my Carousel is wraped in the following way:
<Box mb = {2} mt = {2} sx={{display: 'flex', justifyContent: 'center', alignItems: 'center', zIndex: -1}}>
<Card sx={{ width: 1500, backgroundColor: "transparent"}} >
<Carousel fullHeightHover={false} navButtonsAlwaysVisible={true} duration={500} animation="slide"
navButtonsProps={{
style: {
backgroundColor: '#FF5917',
borderRadius: 0,
}
}} >
{items.map( (item, i) => <Item key={i} item={item} />)}
</Carousel>
</Card>
</Box>
Even though the paper is at z-(1600) and the carousel box at z-(-1) it still overlaps the paper for some reason
https://mui.com/customization/z-index/ check this link. tooptip has highest zindex value. you can add it to your popper

Remove Padding From Material UI Grid System

I hope your day is going well. I am a new user of material UI and I am working on building my first profile page (image below).
As I am getting closer to building this page, I am struggling to create a grid system that allows the about section to be directly under the three panels (see image below).
How do I remove the padding between the about section and three pannels (code below)?
return (
<>
<Helmet>
<title>Dashboard: Project Details | Material Kit Pro</title>
</Helmet>
<Box
sx={{
backgroundColor: 'background.default',
minHeight: '100%',
py: 8
}}
>
<Container >
<AppBar></AppBar>
<Grid container spacing={1}>
<Grid item xs={12} md={3}>
<Box
style={{ height: '100%', width: '100%'}}
>
<WritersSidePanel />
</Box>
</Grid>
<Grid item xs={12} md={9}>
<WritersPageTopPanel />
</Grid>
<Box style={{ marginDown: '90%'}}>
<Grid item xs={12} container
direction="column"
alignItems="flex-end"
justify="flex-end">
<Box
style={{ width: '75%', height: '100%'}}
>
<AboutSection description={description} />
</Box>
</Grid>
<Grid item xs={12} container
direction="column"
alignItems="flex-end"
justify="flex-end">
<Box
style={{ width: '75%'}}
>
<SampleStory description={description} />
</Box>
</Grid>
</Box>
</Grid>
</Container>
</Box>
</>
);
};

Categories

Resources