the styling rules inside my makeStyle Materiel UI not working - reactjs

I want to apply the field class on the TextField Components. but the margins do not apply.
My code is like below:
import React from 'react';
import { Typography, Button, Container, TextField } from '#mui/material';
import SendIcon from '#mui/icons-material/Send';
import { makeStyles } from '#mui/styles';
const useStyles = makeStyles({
field : {
marginTop: 20,
marginBottom: 20,
display: 'block'
}
});
export default function Create() {
const classes = useStyles();
return (
<Container>
<Typography
variant="h6"
component="h2"
color="textSecondary"
gutterBottom
>
Create new page
</Typography>
<form noValidate autoComplete='off'>
<TextField
className={classes.field}
label='Note title'
variant='outlined'
color='secondary'
fullWidth
required
/>
<TextField
className={classes.field}
label='Note Details'
variant='outlined'
color='secondary'
fullWidth
multiline
rows={4}
required
/>
</form>
<Button
type = 'sybmit'
variant = 'contained'
color = 'secondary'
endIcon = {<SendIcon />}
>
Submit
</Button>
</Container>
)
}

On v5 MUI deprecated the #mui/styles styling solutions. On the documentation, they put this message,
⚠️ #mui/styles is the legacy styling solution for MUI. It is deprecated in v5. It depends on JSS as a styling solution, which is not used in the #mui/material anymore. If you don't want to have both emotion & JSS in your bundle, please refer to the #mui/system documentation which is the recommended alternative.
And here is their new solution for styling components - https://mui.com/system/styled/

Related

Margin not working in TextField using MUI makeStyles

I am trying to add margin to my TextField component by making an object of makestyles using MUI v5.
The background color is reflecting in the component but not margin and padding. Here is my code
import React, { useState } from 'react'
import { Typography } from '#mui/material'
import { Button } from '#mui/material'
import { ButtonGroup } from '#mui/material'
import { Container } from '#mui/material'
import { makeStyles } from '#mui/styles';
import TextField from '#mui/material/TextField';
Here I have used makeStyles
const useStyles = makeStyles({
field: {
// paddingTop: '20px',
padding: '100px',
backgroundColor: 'red',
marginBottom: '100px',
// margin: 100
// display: 'block'
},
});
export default function Create() {
const classes = useStyles()
return (
<Container>
<Typography
variant="h6"
component="h2"
gutterBottom
color="textSecondary"
>
Create a New Note
</Typography>
<form noValidate autoComplete="off" >
<TextField
className={classes.field}
label="Note Title"
variant="outlined"
color="secondary"
fullWidth
required
error={titleError}
>
</TextField>
<Button
type="submit"
color="secondary"
variant="outlined"
onClick={() => console.log("you clicked me")}
endIcon={<KeyboardArrowRightOutlinedIcon />}
>Submit </Button>
</form>
</Container>
)
}
All of this is in a single file
Here is the screenshot.
TextField is just a wrapper component of the Input inside it, to target the input for styling, you can use InputProps:
<TextField
InputProps={{
className: classes.field
}}
EDIT: The margin doesn't work in your TextField because of the CSS specificity. Your style is overrode by the other one from emotion, to fix it, double the className using this technique:
const useStyles = makeStyles({
field: {
// append the same classname to increase the specificity
// output has something like: .makeStyles-field-5.makeStyles-field-5
"&&": {
marginBottom: "100px"
}
}

I wanna to add a little gap on two TextField in Material-UI

Here is my js file, I wanna add a little gap between them like padding. Many people are using box property to declare margin and padding but I don't know why I can't use the box property perfectly. If I use box property like ml={1} then the TextField is upside down. Don't forget the most important part is I wanna use this on a class component, not on a functional component.
<Grid item
xs={12}
sm={6}
md={6}
lg={6}
xl={6}>
<TextField label="Name"
variant="outlined"
color="primary"
size="small"
autoFocus />
<TextField label="Address"
variant="outlined"
color="primary"
size="small"
multiline
rowsMax={1} />
</Grid>
One of the ways to solve is using makeStyles. I have given the complete code. Please review. I have referred to Material UI: Use theme in React Class Component sample for Class Component.
Complete Code using Function Component:
import './App.css';
import React from 'react';
import Grid from '#material-ui/core/Grid';
import { TextField } from '#material-ui/core';
import { makeStyles } from '#material-ui/core/styles';
const useStyles = makeStyles((theme) => ({
control: {
padding: theme.spacing(2),
},
}));
const App = () => {
const classes = useStyles();
return (
<div className="App">
<h1>Hello MERN !!</h1>
<br />
<Grid item xs={12} sm={6} md={6} lg={6} xl={6}>
<TextField label="Name"
className={classes.control}
variant="outlined"
color="primary"
size="small"
autoFocus />
<TextField label="Address"
variant="outlined"
className={classes.control}
color="primary"
size="small"
multiline
rowsMax={1} />
</Grid>
</div >
);
}
export default App;
Complete Code using Class Component:
import React from 'react';
import Grid from '#material-ui/core/Grid';
import { TextField } from '#material-ui/core';
import { withStyles } from "#material-ui/core/styles";
const styles = theme => ({
root: {
padding: theme.spacing(2),
}
});
class Car extends React.Component {
render() {
const { classes } = this.props;
return (
<>
<Grid item xs={12} sm={6} md={6} lg={6} xl={6}>
<TextField label="Name"
variant="outlined"
className={classes.root}
spacing={3}
color="primary"
size="small"
autoFocus />
<TextField label="Address"
variant="outlined"
className={classes.root}
spacing={3}
color="primary"
size="small"
multiline
rowsMax={1} />
</Grid>
</>
);
}
}
export default withStyles(styles, { withTheme: true })(Car);
Make sure your Grid item property in a Grid container.You have to wrap the Grid item property in a Grid Container Property.

Create MUI TextField Next to Label

I've searched all over, but I can't make it work. I want to create a TextField Element Next to a label
(and not anywhere inside or touching the border of a TextField) like this one:
Desired Result
Labe <____> TextField
Such a scenario is not covered in the documentation.
The best i could get was to use the startAdornment in the TextField Component.
InputProps={{
startAdornment: (
<InputAdornment position="start">Name</InputAdornment>
)
}}
Also I tried, to use the FormControlLabel component and pass inside the TextField as a Control, although TextField can't be anymore fullWidth
<FormControlLabel
control={<TextField
variant="standard"
margin="normal"
id="tags"
helperText="service."
fullWidth
/>}
label="Start"
labelPlacement="start"
/>
But it doesn't seem to work properly and I'm not even sure if I should use a FormControlLabel with a TextField.
Thank you in advance. This seems as something very basic but I can't get it to work and I find no other relative problems posted.
you can apply a flex style to your Form or wrap your Textfield in a div with an InputLabelin it like and add style to match the desire result for example like this:
import React from "react";
import { makeStyles } from "#material-ui/core/styles";
import TextField from "#material-ui/core/TextField";
import InputLabel from "#material-ui/core/InputLabel";
import { FormHelperText } from "#material-ui/core";
const useStyles = makeStyles((theme) => ({
root: {
display: "flex"
},
TextFieldDiv: {
marginLeft: "15px"
},
labelName: {
paddingTop: "10px"
},
optionalTag: {
fontSize: "13px"
},
labelTag: {
textAlign: "right"
}
}));
export default function BasicTextFields() {
const classes = useStyles();
return (
<form className={classes.root} noValidate autoComplete="off">
<InputLabel className={classes.labelName}>
<div className={classes.labelTag}>Name</div>{" "}
<div className={classes.optionalTag}>(optional)</div>
</InputLabel>
<div className={classes.TextFieldDiv}>
<TextField id="standard-basic" />
<FormHelperText>The service name</FormHelperText>
</div>
</form>
);
}
here a sandBox Example
I tried the above solutions and these are not working in Mui-v5.
You can use Grid.
<Grid container direction="row" alignItems="center" spacing={2}>
<Grid item>
<div>Label</div>
</Grid>
<Grid item>
<div>Input</div>
</Grid>
</Grid>
You can adjust spacing and alignment accordingly.

How to invoke a hook from React class component?

Question from React newbie!
I have Material UI React login form and am trying to use hook within login form. But getting invalid hook call error. No luck so far. Help please.. loginformstyles.js is the hook I am trying to use in the signin.js file.. The login page has two text fields - username and password and a Submit button.
import React from 'react';
import Avatar from '#material-ui/core/Avatar';
import Button from '#material-ui/core/Button';
import CssBaseline from '#material-ui/core/CssBaseline';
import TextField from '#material-ui/core/TextField';
import FormControlLabel from '#material-ui/core/FormControlLabel';
import Checkbox from '#material-ui/core/Checkbox';
import Link from '#material-ui/core/Link';
import Grid from '#material-ui/core/Grid';
import Box from '#material-ui/core/Box';
import LockOutlinedIcon from '#material-ui/icons/LockOutlined';
import Typography from '#material-ui/core/Typography';
import Container from '#material-ui/core/Container';
import { ValidatorForm, TextValidator} from 'react-material-ui-form-validator';
import { useStyles } from './loginformstyles';
export default class MyForm extends React.Component {
Copyright() {
return (
<Typography variant="body2" color="textSecondary" align="center">
{'Copyright © '}
<Link color="inherit" href="https://material-ui.com/">
Task Manager
</Link>{' '}
{new Date().getFullYear()}
{'.'}
</Typography>
);
}
handleChange (event) {
const email = event.target.value;
this.setState({ email });
}
render() {
const classes = useStyles();
return (
<Container component="main" maxWidth="xs">
<CssBaseline />
<div className={classes.paper}>
<Avatar className={classes.avatar}>
<LockOutlinedIcon />
</Avatar>
<Typography component="h1" variant="h5">
Sign in
</Typography>
<form className={classes.form} >
<TextField
variant="outlined"
margin="normal"
required
fullWidth
id="email"
label="Email Address"
name="email"
autoComplete="email"
autoFocus
validators={['required', 'isEmail']}
errorMessages={['this field is required', 'email is not valid']}
onChange={this.handleChange}
/>
<TextField
variant="outlined"
margin="normal"
required
fullWidth
name="password"
label="Password"
type="password"
id="password"
autoComplete="current-password"
/>
<FormControlLabel
control={<Checkbox value="remember" color="primary" />}
label="Remember me"
/>
<Button
type="submit"
fullWidth
variant="contained"
color="primary"
className={classes.submit}
>
Sign In
</Button>
<Grid container>
<Grid item xs>
<Link href="#" variant="body2">
Forgot password?
</Link>
</Grid>
<Grid item>
<Link href="#" variant="body2">
{"Don't have an account? Sign Up"}
</Link>
</Grid>
</Grid>
</form>
</div>
<Box mt={8}>
<this.Copyright />
</Box>
</Container>
);
}
}
import React from 'react';
import { makeStyles } from '#material-ui/core/styles';
export const useStyles = makeStyles((theme) => ({
paper: {
marginTop: theme.spacing(8),
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
},
avatar: {
margin: theme.spacing(1),
backgroundColor: theme.palette.secondary.main,
},
form: {
width: '100%', // Fix IE 11 issue.
marginTop: theme.spacing(1),
},
submit: {
margin: theme.spacing(3, 0, 2),
},
}));
If you just want to make this work, you could wrap the it and then expose the styles into child component, ex.
const Wrapper = ({ children }) => {
const classes = useStyles()
return children(classes)
}
and then you can do
<Wrapper>
{classes => <Copyright classes={classes} />}
</Wrapper>
Of course, this is just to get it working. In general you shouldn't mix class and hook, but as long as you can turn them into components, then you can mix and match.

Target nested material component in JSS style definition

I have this JSX layout currently
<div className={classes.bottomArea}>
<Box display="flex" flexDirection="column">
<Typography variant="h1" component="span">1982</Typography>
<Typography variant="h5" component="span">Bed Count</Typography>
</Box>
</div>
And in my styles I'm trying to change the color of the h5 Typography element
bottomArea: {
$h5: {
color: "red"
}
}
I think I understand why this isn't working but is there an easy way to target that h5 variant?
Here is a codesandbox to show
https://codesandbox.io/s/material-demo-wb7ts
Assuming that you want to retain <span> as your component, you can target the h5 variant by targeting the CSS class added by Typography which is MuiTypography-h5.
In the syntax shown below, the & refers to the class generated for bottomArea and then the space indicates targeting .MuiTypography-h5 as a descendant.
import React from "react";
import Typography from "#material-ui/core/Typography";
import Box from "#material-ui/core/Box";
import { makeStyles } from "#material-ui/core/styles";
const useStyles = makeStyles({
bottomArea: {
"& .MuiTypography-h5": {
color: "red"
}
}
});
export default function Types() {
const classes = useStyles();
return (
<div className={classes.bottomArea}>
<Box display="flex" flexDirection="column">
<Typography variant="h1" component="span">
1982
</Typography>
<Typography variant="h5" component="span">
Bed Count
</Typography>
</Box>
</div>
);
}
JSS Documentation: https://cssinjs.org/jss-plugin-nested/?v=v10.3.0#use--to-reference-selector-of-the-parent-rule
Related answer: How do you change a style of a child when hovering over a parent using material-ui jss styles
You are using the Typography props the wrong way. The variant props only defines the style applied to the component whereas the component props defines which tag will be used to render this component.
If you want your Typography component to be a h5:
<Typography variant="h5" component="h5">Bed Count</Typography>
And then for the styling:
bottomArea: {
'& h5': {
color: "red"
}
}
CodeSanbox: https://codesandbox.io/s/material-demo-6i1lq?file=/demo.js
Great day !
you can use withStyle to update the specific component classes
check this Typography API
const Typography = withStyles(() => ({
h5: {
color: "red",
},
}))(MuiTypography);
export default function Types() {
return (
<div>
<Box display="flex" flexDirection="column">
<Typography variant="h1" component="span">
1982
</Typography>
<Typography variant="h5" component="span">
Bed Count
</Typography>
</Box>
</div>
);
}

Resources