Margin not working in TextField using MUI makeStyles - reactjs

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"
}
}

Related

Change border color of mui's textfield using style={}

I'm trying to change the color to border of mui's textfield to white. Can I do this somehow by using style={} in component or do I have to use makeStyles?
<TextField
label="Search login"
variant="outlined"
value={searchLogin}
inputProps={{
style: {
color:"white",
},
}}
InputLabelProps={{
style: {
color: "white",
borderColor : "white",
},
}}
onChange={(e) => {
setSearchLogin(e.target.value);
}}
/>
For those nested element you likely won't be able to use direct styling. Try following:
import * as React from "react";
import { ThemeProvider } from "#mui/system";
import TextField from "#mui/material/TextField";
import { createTheme } from "#material-ui/core/styles"
const styles = createTheme({
notchedOutline: {
borderWidth: "1px",
borderColor: "white !important"
}
});
export default function Example() {
return (
<ThemeProvider theme={styles}>
<TextField
label="Search login"
variant="outlined"
value={searchLogin}
onChange={(e) => { setSearchLogin(e.target.value); }}
/>
</ThemeProvider>
);
}

Material-UI: How to add Icons in the TextField label?

I am trying to add Material-UI icons into TextField component, I want to add it to the label not in input Field.
Eg:
through Inputprops we can pass and add icon to input, but I want it in label. How to achieve this..?
<Field label="Name" required /> -> Name*
What I want to achieve is:
<Field label="Name" required /> -> Name*(icon)
It can be achieved by using flex and order properties of CSS, lightweight and effective.
Result:
Full code sample :
Code fragment :
const useStyles = makeStyles({
root: {
"& .MuiFormLabel-root": {
display: "flex",
alignItems: "center",
"& .myIcon": {
paddingLeft: "8px",
order: 999
}
}
}
});
const Demo = () => {
const classes = useStyles();
return (
<TextField
className={classes.root}
required
label={
<Fragment>
I am label
<SettingsRounded className="myIcon" fontSize="small" />
</Fragment>
}
variant="outlined"
/>
);
};
Hope to help you !
Because label can accept a ReactNode, you add an icon component to the TextField like this:
import { makeStyles } from "#material-ui/core/styles";
import TextField from "#material-ui/core/TextField";
import Add from "#material-ui/icons/Add";
const useStyles = makeStyles({
root: {
"& label": {
marginTop: -3, // fix the icon alignment issue
}
},
label: {
display: "inline-flex",
alignItems: "center"
}
});
export default function BasicTextFields() {
const classes = useStyles();
return (
<TextField
className={classes.root}
label={
<div className={classes.label}>
<span>My Label</span>
<Add />
</div>
}
variant="outlined"
/>
);
}
Live Demo

Underline shows when using materal-ui InputBase component

I'm using material-ui InputBase component to create a search bar and it shows an underline. However when I write the same code in another project there is no underline..
Any clues to what the problem might be?
Here is the code for the search bar
import React from 'react';
import { IconButton, InputBase, Paper } from '#material-ui/core';
import { makeStyles } from '#material-ui/core/styles'
import SearchIcon from '#material-ui/icons/Search'
const useStyles = makeStyles((theme) => ({
root: {
padding: '2px 4px',
display: 'flex'
alignItems: 'center'
width: 400
},
input: {
marginLeft: theme.spacing(1),
flex: 1,
},
iconButton: {
padding: 10
}
}));
export default function SearchBar() {
const classes = useStyles();
return (
<Paper className={classes.root}>
<InputBase
className{classes.input}
placeholder='Search..'
inputProps={{ 'aria-label': 'search' }}
/>
<IconButton
type='submit'
className={classes.iconButton}
aria-label='search'
>
<SearchIcon />
</IconButton>
</Paper>
)
}

How can I set an static outlined div similar to Material-UI's outlined textfield?

I want wrap some TextFields in a outlined container and I found this answer. This work as i want:
But when I click in an inside textfield all the texfields focused:
This is my code:
import React from "react";
import ReactDOM from "react-dom";
import OutlinedDiv from "./OutlinedDiv";
import TextField from "#material-ui/core/TextField";
import Grid from "#material-ui/core/Grid";
function App() {
return (
<div className="App">
<OutlinedDiv label="DIV">
<Grid container justify="center" alignItems="center" spacing={3}>
<Grid item sm={4} xs={12}>
<TextField label="Text1" variant="outlined" />
</Grid>
<Grid item sm={4} xs={12}>
<TextField label="Text2" variant="outlined" />
</Grid>
<Grid item sm={4} xs={12}>
<TextField label="Text3" variant="outlined" />
</Grid>
<Grid item sm={4} xs={12}>
<TextField label="Text4" variant="outlined" />
</Grid>
<Grid item sm={4} xs={12}>
<TextField label="Text5" variant="outlined" />
</Grid>
<Grid item sm={4} xs={12}>
<TextField label="Text6" variant="outlined" />
</Grid>
</Grid>
</OutlinedDiv>
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
How I can achive this style and when click in an inside component only focus the selected component?
A response with another approach and the similar solution for outlined div is welcome.
Thanks in advance.
Below is an approach that does not leverage TextField or FormControl and thus can be safely used to wrap other inputs. This copies some styles from OutlinedInput and the InputLabel styles applied when within a FormControl.
import React from "react";
import ReactDOM from "react-dom";
import InputLabel from "#material-ui/core/InputLabel";
import NotchedOutline from "#material-ui/core/OutlinedInput/NotchedOutline";
import { withStyles } from "#material-ui/core/styles";
import clsx from "clsx";
const styles = {
root: {
position: "relative",
marginTop: "8px"
},
contentWrapper: {
position: "relative"
},
content: {
padding: "18.5px 14px"
},
inputLabel: {
position: "absolute",
left: 0,
top: 0,
// slight alteration to spec spacing to match visual spec result
transform: "translate(0, 24px) scale(1)"
},
notchedOutline: {}
};
const LabelledOutline = ({ classes, id, label, children, className }) => {
const [labelWidth, setLabelWidth] = React.useState(0);
const labelRef = React.useRef(null);
React.useEffect(() => {
const labelNode = ReactDOM.findDOMNode(labelRef.current);
setLabelWidth(labelNode != null ? labelNode.offsetWidth : 0);
}, [label]);
return (
<div className={clsx(className, classes.root)}>
<InputLabel
ref={labelRef}
htmlFor={id}
variant="outlined"
className={classes.inputLabel}
shrink
>
{label}
</InputLabel>
<div className={classes.contentWrapper}>
<div id={id} className={classes.content}>
{children}
<NotchedOutline
className={classes.notchedOutline}
notched
labelWidth={labelWidth}
/>
</div>
</div>
</div>
);
};
export default withStyles(styles)(LabelledOutline);
And below is an example using it both without customization and once with customized colors for the label, outline, and content that changes on hover.
import React from "react";
import ReactDOM from "react-dom";
import { withStyles } from "#material-ui/core/styles";
import LabelledOutline from "./LabelledOutline";
const CustomColorLabelledOutline = withStyles({
root: {
"& $notchedOutline": {
borderColor: "purple"
},
"&:hover $notchedOutline": {
borderColor: "orange"
},
"& $inputLabel": {
color: "green"
},
"&:hover $inputLabel": {
color: "blue"
},
"& $content": {
color: "black"
},
"&:hover $content": {
color: "purple"
}
},
notchedOutline: {},
inputLabel: {},
content: {}
})(LabelledOutline);
function App() {
return (
<div>
<LabelledOutline id="myID" label="My Label">
My Content
</LabelledOutline>
<CustomColorLabelledOutline label="My Label">
My Content with custom label and outline color
</CustomColorLabelledOutline>
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
And the obligatory TS version (deeply inspired by #Ryan Cogswell's version):
import React, { ReactElement, ReactNode } from "react";
import InputLabel from "#material-ui/core/InputLabel";
import NotchedOutline from "#material-ui/core/OutlinedInput/NotchedOutline";
import { makeStyles, Theme } from "#material-ui/core/styles";
import clsx from "clsx";
const useStyles = makeStyles((theme: Theme) => ({
root: {
position: "relative",
marginTop: "8px",
},
contentWrapper: {
position: "relative",
},
content: {
// padding: "18.5px 14px",
padding: theme.spacing(1),
},
inputLabel: {
position: "absolute",
left: 0,
top: 0,
// slight alteration to spec spacing to match visual spec result
transform: "translate(0, 24px) scale(1)",
},
notchedOutline: { borderRadius: theme.shape.borderRadius },
}));
interface Props {
id: string;
label: string;
children: ReactNode;
className?: string;
}
export default function Conftainer({ id, label, children, className }: Props): ReactElement {
const [labelWidth, setLabelWidth] = React.useState(0);
const labelRef = React.useRef(null);
React.useEffect(() => {
if (labelRef && labelRef.current && (labelRef.current as any).offsetWidth) {
setLabelWidth((labelRef.current as any).offsetWidth);
}
}, [label]);
const classes = useStyles();
return (
<div className={clsx(className, classes.root)}>
<InputLabel
ref={labelRef}
htmlFor={id}
variant="outlined"
className={classes.inputLabel}
shrink
>
{label}
</InputLabel>
<div className={classes.contentWrapper}>
<div id={id} className={classes.content}>
{children}
<NotchedOutline className={classes.notchedOutline} notched labelWidth={labelWidth} />
</div>
</div>
</div>
);
}
(any edits to get rid of the any more than welcome)
I don't have enough point to post a comment on #AntonOfTheWoods answer (I signed up SO today especially for this question).
Just use const labelRef = React.useRef<HTMLLabelElement>(null); and you should be able to get rid of the any

Drawer not opening

Good evening. I have a problem that I think is simple to solve but I could not get it because I was just a beginner in react. The problem is that the drawer that I put in my appbar just does not open, and there is no error on the console about it, so I would like the help of you guys.
PS: sorry for the bad English, I'm Brazilian.
import React from 'react';
import PropTypes from 'prop-types';
import { withStyles } from 'material-ui/styles';
import Drawer from 'material-ui/Drawer';
import AppBar from 'material-ui/AppBar';
import Button from 'material-ui/Button';
import IconButton from 'material-ui/IconButton';
import Toolbar from 'material-ui/Toolbar';
import MenuIcon from 'material-ui-icons/Menu';
import TextField from 'material-ui/TextField';
import Paper from 'material-ui/Paper';
import Grid from 'material-ui/Grid';
import '../assets/scss/main.scss';
import img from '../assets/images/react.png';
const styles = theme => ({
root: {
width: '100%',
},
flex: {
flex: 1,
},
menuButton: {
marginLeft: -12,
marginRight: 20,
},
inputProps: {
step: 300,
},
button: {
margin: theme.spacing.unit,
},
input: {
display: 'none',
},
paper: {
padding: 50,
textAlign: 'center',
border: '5px solid black',
width: '100%',
},
paper1: {
backgroundColor: 'red',
marginTop: '13%',
},
img: {
width: '45%',
},
appbar: {
marginLeft: '-20.20%',
marginTop: '-20%',
width: '139.99%',
},
});
function ButtonAppBar(props) {
const { classes } = props;
const handleSubmit = (event) => {
event.preventDefault();
const data = {
email: document.getElementById('email').value,
password: document.getElementById('password').value,
};
console.log(data);
};
return (
<div className={styles.root}>
<Grid container spacing={8} alignItems="center" justify="center">
<Paper className={classes.paper}>
<div>
<AppBar position="static" className={classes.appbar}>
<Drawer />
<Toolbar>
<IconButton className={classes.menuButton} color="contrast" aria-label="Menu">
<MenuIcon />
</IconButton>
</Toolbar>
</AppBar>
</div>
<img src={img} alt="React" className={classes.img} /><br />
<form onSubmit={handleSubmit} noValidate>
<TextField id="email" type="email" label="Usuário" className={classes.user} /><br />
<TextField id="password" type="password" label="Senha" className={classes.senha} />
<div>
<AppBar position="static" className={classes.paper1} >
<Button type="submit" color="contrast">Login</Button>
</AppBar>
</div>
</form>
</Paper>
</Grid>
</div>
);
}
ButtonAppBar.propTypes = {
classes: PropTypes.object.isRequired,
};
export default withStyles(styles)(ButtonAppBar);
Take a look at the Drawer demos in the documentation. You’ll see that the Drawer uses an open prop to specify whether it is open or not. In the demos, this is controlled my state.
The way this is usually handled is by using a button, like IconButton, in the AppBar with an onClick handler that issues a state change, resulting in a re-render.
The demos should help you reconfigure your app and get rolling. The most straightforward example of using component state to open and close the Drawer is the mobile portion of the Responsive Drawer demo.
It initializes state to false and renders the open prop using this.state.mobileOpen. The AppBar has an IconButton with handleDrawerToggle as it’s onClick handler, which changes state, causing the component to re-render.

Resources