Material Form Field and TextFieldRoot overwrite theme with useStyles / jss - reactjs

How do I override Material themes for FormControl? It is usually html parent above a Textfield. I want the margin bottom to be 8px, instead of 4px. Below is not working. Currently using MUI version 4
export const useProcedureTableStyles = makeStyles({
overrides: {
'& .MuiTextField-root': {
marginBottom: '8px',
},
},
textField: {
height: '31px',
},
<TextField
{...params}
margin="dense"
value={listItem}
error={listItem.duplicateFlag}
InputProps={{
...params.InputProps,
style: { padding: 0 },
className: procedureStyles.overrides,
classes: {
input: procedureStyles.textField,
},
}}
/>
Researching this resource: material-ui overwrite theme with useStyles / jss

Below is a simplified version of the html structure shown in your screenshot:
<div class="MuiFormControl-root MuiTextField-root">
<div class="MuiOutlinedInput-root">
<input type="text" class="MuiOutlinedInput-input"/>
</div>
</div>
You are passing procedureStyles.textField via the input key of the classes prop in InputProps. That targets the innermost input element (and I assume that is working as intended). That input element can also be targeted using the className property of inputProps (lowercase i).
You are passing procedureStyles.overrides via the className property of InputProps. InputProps targets the second div in the structure above (the one with class="MuiOutlinedInput-root"), and then your margin bottom styles are being applied to any descendants of the div that have a class of MuiTextField-root. Since the div you want to target is an ancestor of that second div and not a descendant, your styles have no effect.
To target the first div in that structure, you can use the className prop directly on TextField. It would also be equivalent to use the root key of the classes prop directly on TextField.
Here's a working example:
import React from "react";
import { makeStyles } from "#material-ui/core/styles";
import TextField from "#material-ui/core/TextField";
const useStyles = makeStyles((theme) => ({
overrides: {
marginBottom: "8px"
}
}));
export default function BasicTextFields() {
const classes = useStyles();
return (
<>
<div>Something before to demonstrate top margin</div>
<TextField
id="outlined-basic"
margin="dense"
label="Outlined"
variant="outlined"
className={classes.overrides}
/>
<div>Something after to demonstrate bottom margin</div>
</>
);
}

Do this in your Material-UI theme:
overrides: {
MuiFormControl:{
marginDense:{
marginBottom:'8px'
}
}
}

Related

Material UI | How to change the font colour of a disabled input text field?

The colour of a disabled input text field created using material UI is light grey by default and it is not very visible against a white background. Is there any way to change the font colour of a disabled input text field?
Below is an example of how to do this showing the customized version next to the default styling.
import React from "react";
import { withStyles } from "#material-ui/core/styles";
import TextField from "#material-ui/core/TextField";
import Button from "#material-ui/core/Button";
const DarkerDisabledTextField = withStyles({
root: {
marginRight: 8,
"& .MuiInputBase-root.Mui-disabled": {
color: "rgba(0, 0, 0, 0.6)" // (default alpha is 0.38)
}
}
})(TextField);
export default function Demo() {
const [disabled, setDisabled] = React.useState(true);
return (
<>
<Button onClick={() => setDisabled(!disabled)}>Toggle Disabled</Button>
<br />
<br />
<DarkerDisabledTextField
disabled={disabled}
id="outlined-basic"
label="Custom"
value={`Disabled = ${disabled}`}
variant="outlined"
/>
<TextField
disabled={disabled}
id="outlined-basic"
label="Default"
value={`Disabled = ${disabled}`}
variant="outlined"
/>
</>
);
}
I think the simplest way is to create an object to define the font color and pass it to the TextField's inputProps.
const fontColor = {
style: { color: 'rgb(50, 50, 50)' }
}
This way you can toggle the font with the components state as you wish or simply keep it constant.
<TextField
label="Title"
onChange={updateTitle}
value={title}
disabled={true}
inputProps={fontColor}/>
import { TextField, styled } from '#mui/material'
const CustomTextField = styled(TextField)({
'& .MuiInputBase-root.Mui-disabled': {
backgroundColor: '#f0f0f0',
},
});
Then use them as standard component
<CustomTextField
name="manual"
label="Manual"
size="small"
disabled={watch({}).platform === 'manual' ? false : true}
/>
if u use RHF with controller, mean u create custom TextField using RHF, u just change the component inside the styled()
For example:
import RHFTextField from "../RHFTextField"
const CustomTextField = styled(RHFTextField)({
'& .MuiInputBase-root.Mui-disabled': {
backgroundColor: '#f0f0f0',
},
});
with background color changes, it will more visible..
In the Mui-v5 above solution is not working.
Below are the solutions for Mui-v5.
Solution 1:
const styles = theme => ({
input: {
"& input.Mui-disabled": {
color: "green"
}
}
});
Solution: 2 (use sx property for the component)
sx={{
"& .MuiInputBase-input.Mui-disabled": {
WebkitTextFillColor: "#000000",
},
}}
eg.
<TextField
fullWidth
disabled=true
variant="outlined"
sx={{
"& .MuiInputBase-input.Mui-disabled": {
WebkitTextFillColor: "#000000",
},
}}
/>
None of all the many answers online worked for me, using MUI v4.
Finally I found a very easy but hacky solution for setting the font color of a disabled TextField component.
The problem is, (at least for Firefox) it will use this weird style cheet:
.css-[...]-MuiInputBase-input-MuiOutlinedInput-input.Mui-disabled {
opacity: 1;
-webkit-text-fill-color: rgba(0, 0, 0, 0.38);
}
I'm too new to this stuff and I don't know how to change it, so my way was to overwrite it:
.css-[...]-MuiFormControl-root-MuiTextField-root input {
-webkit-text-fill-color: rgba(255,255,255,0.6) !important;
color: rgba(255,255,255,0.6);
}
The !important part is important!
In React with MUI v4, it's as simple as that:
const textFieldColor = /*...*/;
const textFieldSX = {
input: {
"-webkit-text-fill-color": `${textFieldColor} !important`,
color: `${textFieldColor} !important`,
},
};
/*...*/
<TextField sx={textFieldSX} />
Just in case, this -webkit-text-fill-color property would turn into color one time, one can use an !important there too.
works (MUIv5):
sx={{
"& .MuiInputBase-input.Mui-disabled": {
WebkitTextFillColor: "#000000",
},
}}

Style Material UI textfield

I'm trying to style a material-ui textfield but I don't get it to work the way I want. I just want a plain simple white input field with standard MUI animations. I want the textfield to always have a white background and text to be black.
You find the code on Code Sandbox: https://codesandbox.io/s/material-demo-2coo8?fontsize=14&hidenavigation=1&theme=dark
Thanks in advance!
You can custom style the TextField font and background color with the following code:
const useStyles = makeStyles((theme) => ({
root: {
"& .MuiInputBase-root": {
color: 'black' //or try theme.palette.primary.main
backgroundColor: 'white' //It should be white by default
}
}
}));
Then simply add the 'root' class to your TextField. As info, the above syntax is called JSS. .MuiInputBase-root is a class applied to the input component, which is a subcomponent of the TextField. This article explores the TextField component with dev tools open, so you can understand how the subcomponents work and get styled by MUI.
One more piece of info about the JSS syntax. Notice the 'space' between the '&' and the '.'. This space is important and acts as part of the selector, informing that .MuiInputBase-root class is on a child component of the parent that receive 'root' class styling.
I would highly suggest you to use functional components since it is the future of React.
Below you can see your example as functional component with regular Material-UI styles.
import React from "react";
import Grid from "#material-ui/core/Grid";
import TextField from "#material-ui/core/TextField";
import { makeStyles } from "#material-ui/core/styles";
const useStyles = makeStyles(theme => ({
root: { backgroundColor: "white" },
box: { backgroundColor: "white" },
input: {
root: { backgroundColor: "white", color: "black" }
}
}));
export default function FunctionalDemo() {
const classes = useStyles();
return (
<Grid
container
direction="row"
justify="center"
alignItems="center"
className={classes.root}
>
<Grid item xs={12} md={6} className={classes.box}>
<form noValidate>
<TextField
id="email"
label="Type here"
variant="filled"
color="secondary"
className={classes.input.root}
/>
</form>
</Grid>
</Grid>
);
}
Code sandbox: https://codesandbox.io/s/material-ui-plain-text-field-x2s48?fontsize=14&hidenavigation=1&theme=dark

Overriding TextField color in MaterialUI

I'm trying to get the border color to change from that default purple to white.
Here's what I have so far:
const useStyles = makeStyles(theme => ({
darkModeColorInput: {
color: WHITE
},
darkModeColorLabel: {
color: WHITE,
"&:after": {
borderColor: WHITE
}
}
}));
<TextField
margin="normal"
inputProps={{
className: classes.darkModeColorInput
}}
InputLabelProps={{
className: classes.darkModeColorLabel
}}
required
fullWidth
id="email"
label="handle or email"
name="email"
autoComplete="email"
autoFocus
color={WHITE}
/>
This renders:
The label also switches from white to that default purple on focus. What am I doing wrong here?
The easiest way to do this is to use the dark theme through the ThemeProvider:
import { ThemeProvider } from '#material-ui/styles';
import { createMuiTheme } from '#material-ui/core/styles';
const darkTheme = createMuiTheme({
palette: {
type: 'dark',
},
});
<ThemeProvider theme={darkTheme}>
<Component />
</ThemeProvider>
Then, you will get a theme for all Material UI components that will show correctly on a dark background.
https://material-ui.com/customization/theming/
https://material-ui.com/customization/palette/
If you still want to fully control the look (and don't want to use a theme), you need to set custom styles for InputLabelProps and InputProps on your TextInput (https://material-ui.com/api/text-field/).

How do I custom style the underline of Material-UI without using theme?

I have success with outline custom styling when variant="outlined" and I use notchedOutline in InputProps.
Otherwise - variant=[anything else] where only a bottom border exists - it doesn't work, even with underline as the key/class in InputProps.
I've even tried root.
export default ({ boxType, classes, value, onChange, style }) => (
<TextField
variant={boxType || "standard"}
value={value}
onChange={onChange}
InputProps={{
classes: {
notchedOutline: classes.notchedOutline,
underline: classes.underline,
root: classes.TextInputField
},
style
}}
/>
)
In order to determine how to do this, it is helpful to look at how the default styling is done within Input.
:before is used for the default and hover styling and :after is used for the focused styling.
Here is a working example of how to style it:
import React from "react";
import ReactDOM from "react-dom";
import TextField from "#material-ui/core/TextField";
import { withStyles } from "#material-ui/core/styles";
const styles = {
underline: {
"&:before": {
borderBottom: "2px solid green"
},
"&:hover:not($disabled):not($focused):not($error):before": {
borderBottom: "2px solid blue"
},
"&:after": {
borderBottom: "3px solid purple"
}
},
disabled: {},
focused: {},
error: {}
};
function App({ classes }) {
return (
<div className="App">
<TextField InputProps={{ classes }} />
</div>
);
}
const StyledApp = withStyles(styles)(App);
const rootElement = document.getElementById("root");
ReactDOM.render(<StyledApp />, rootElement);
You can just use
InputProps={{ disableUnderline: true }}.It will disable the underLine of textField in all cases.
Tested on react-material-ui version 3 and above.
Not sure which version of material-ui you are using, but you can override classes as needed, see the following API documentation:
https://material-ui.com/api/outlined-input/#demos
https://material-ui.com/api/outlined-input/

how to change the asterisk color in required * field

I have two required fields in my form .I want the asterisk color should be red.Currently it is showing black .I am using material UI react library ?
here is my code
https://codesandbox.io/s/r7lq1jnjl4
documents
https://material-ui.com/demos/text-fields/
<FormControl>
<TextField
required
InputLabelProps={{
shrink: true
}}
id="standard-name"
label="Name"
margin="normal"
helperText="Some important text"
/>
</FormControl>
Based on this documentation on how to customize components through theme overrides for a FormLabel (which will also include InputLabel), you should use createMuiTheme and add the following overrides:
const formLabelsTheme = createMuiTheme({
overrides: {
MuiFormLabel: {
asterisk: {
color: '#db3131',
'&$error': {
color: '#db3131'
},
}
}
}
})
Then, you wrap your <form> within a <MuiThemeProvider> like so:
<MuiThemeProvider theme={formLabelsTheme}>
<form noValidate autoComplete="off">
...
...
...
</form>
</MuiThemeProvider>
Here is a forked code sandbox which demonstrates this code in action.
Since you are already creating a theme, you could just put your overrides in that theme, but you'll need to move your <form> to be within the <MuiThemeProvider> that you already have in your code.
The resulting form labels look like this:
As per the latest version of material UI. ie. "#mui/material": "^5.0.1"
We can do it like this:
<FormLabel required>Name:</FormLabel>
And in the theme:
import { createTheme } from "#mui/material";
export const theme = createTheme({
components: {
MuiFormLabel: {
styleOverrides: {
asterisk: {
color: "#db3131",
"&$error": {
color: "#db3131",
},
},
},
},
},
});
In Mui v5 :
const theme = createTheme({
components: {
MuiFormLabel: {
styleOverrides: {
asterisk: {color:"red"},
},
},
},
})
Alvin's answer shows how to do this globally in your theme. You can also do this on a case-by-case basis using the FormLabel asterisk class via the InputLabel props.
Below are the relevant portions from your code that I changed. Also note that the default behavior for the asterisk is for it to be red if the input is in an "error" state. For instance if you add the error property to the TextField the asterisk will be red, but that also has additional effects on styling beyond the asterisk.
const styles = {
labelAsterisk: {
color: "red"
}
};
<InputLabel
FormLabelClasses={{
asterisk: this.props.classes.labelAsterisk
}}
required
shrink
htmlFor="age-native-simple"
>
Age
</InputLabel>
<TextField
required
InputLabelProps={{
shrink: true,
FormLabelClasses: {
asterisk: this.props.classes.labelAsterisk
}
}}
id="standard-name"
label="Name"
margin="normal"
helperText="Some important text"
/>
const StyledApp = withStyles(styles)(App);
//import createTheme and ThemeProvider at the top
import { createTheme, ThemeProvider } from '#mui/material/styles';
const abc = () => {
//add the theme at the top of your arrow function
const theme = createTheme({
components: {
MuiFormLabel: {
styleOverrides: {
asterisk: { color: "red" },
},
},
},
})
return ( // wrap your jsx with <ThemeProvider>
<ThemeProvider theme={theme}>
<TextField required
id="outlined-required"
label="Full Name"
type="text"
size='small'
/>
</ThemeProvider>
)
}
For those who are looking answer for MUI v5 with TextField outlined variant
const theme = createTheme({
components:{
MuiInputLabel:{
styleOverrides:{
asterisk:{
color:"#d32f2f"
}
}
}
}
});
Try this simple and easy
render(){
const name = <p>Name<span style={{ color: "red" } >*</span></p>
const email = <p>Email<span style={{ color: "red" } >*</span></p>
.
.
.
return (
<div>
<TextField type="text" label={name} />//or Input tag
<TextField type="email" label={email} />//or Input tag
.
.
.
</div>
)
}

Resources