Strange behavior of custom (with withStyle) controlled material-ui TextField - reactjs

I am trying to use a Material-ui TextField in a form.
This Textfield is controlled in a way that only hexadecimal characters are authorized.
<form style={{ flex: '1' }} onSubmit={this.handleSubmit} noValidate autoComplete="off">
<TextField margin='normal' label="Base address" size="small" variant="outlined" fullWidth
InputProps={{ startAdornment: <InputAdornment position="start">0x</InputAdornment> }}
helperText="Please enter 8 hexadecimal digits"
value={this.state.address}
onChange={event => {
if (/^[0-9A-Fa-f]*$/.test(event.target.value))
this.setState({ address: event.target.value })
else this.setState({ address: this.state.address })
}}
/>
</form>
This is working as expected, no problem.
But when I replace the TextField by my custom one called CssTextField
const CssTextField = withStyles({
root: {
'& label': {
color: 'var(--input-foreground)',
'&.Mui-focused': {
color: 'var(--inputValidation-infoBorder)',
},
},
'& input': {
color: 'var(--input-foreground)',
},
'& input:invalid + fieldset': {
borderColor: 'var(--inputValidation-errorBorder)',
},
'& .MuiFormHelperText-contained': {
color: 'var(--input-foreground)',
},
'& .MuiOutlinedInput-notchedOutline': {
borderColor: 'var(--input-foreground)',
},
'& .MuiOutlinedInput-root': {
'&:hover fieldset': {
borderColor: 'var(--thinput-foreground)',
},
'& fieldset': {
borderColor: 'var(--input-foreground)',
},
'&.Mui-focused fieldset': {
borderColor: 'var(--inputValidation-infoBorder)',
},
'& p.MuiTypography-colorTextSecondary': {
color: 'var(--input-foreground)',
},
},
},
})(TextField);
The new style is applied but the behavior (not only the style) of the CssTextField changes compared to TextField.
Indeed, once I enter a simple character, the focus is lost from the CssTextField and I need to click again in the field to enter a new character... which is of course not happening with the "normal" TextField.
BTW this weird behavior does not occur when I remove the control (remove props value & onChange) when using the CssTextField.
So I am in a situation where I can control the input but not the style, or I can style the TextField but not control the input !
Additional info: even with an empty style (setting only root:{} in withStyles) the issue occurs.
Any suggestions is more than welcome.
Thanks

Related

How to remove space between number and sign in OutlinedTextField in Material Ui

I am using material Ui OutlinedTextField here is my code snippet from the TSX file
import { List, styled, Switch, TextField, Theme, withStyles } from '#material-ui/core';
export const OutlinedTextField = withStyles((theme: Theme) => ({
root: {
'& label': {
color: theme.palette.primary.dark,
},
'& label.Mui-focused': {
color: theme.palette.primary.dark,
},
'& .MuiOutlinedInput-root': {
'& fieldset': {
borderColor: theme.palette.primary.light,
},
'&:hover fieldset': {
borderColor: theme.palette.primary.main,
},
'&.Mui-focused fieldset': {
borderColor: theme.palette.primary.dark,
borderWidth: 1,
},
'&.MuiOutlinedInput-input': {
paddingRight: 0,
},
'&.MuiOutlinedInput-adornedStart': {
paddingLeft: 5,
},
},
},
}))(TextField);
Other.tsx:-
<OutlinedTextField
variant="outlined"
id="outlined-basic"
type="number"
size="small"
value={parseFloat(Volatility.toFixed(2))}
onChange={(event) => setVolatility(parseFloat(event.target.value))}
onKeyPress={(event) => onKeyPressVolatility(event.key)}
InputProps={{
className: classes.inputText,
endAdornment: <InputAdornment position="end">%</InputAdornment>,
}}
/>
I want to remove space between number and % sign from the OutlinedTextField
Your suggestions would be helpful
Thanks in Advance
It seems that you need to set text-align: right for the input element inside MuiOutlinedInput-root class name.
Not sure where the OutlinedTextField component come from, but you can do like the following.
...
import OutlinedInput from '#mui/material/OutlinedInput';
import { styled } from '#mui/material/styles';
const OutlinedTextField = styled(OutlinedInput)(() => ({
'& input': {
textAlign: 'right'
...
}
}))
You can do the same if you use makeStyles hook.

How to customize label color of material ui Textfield when out of focus?

I'm trying to customize Textfiled of material-ui
I was able to change everything I wanted except the color of the label when out of focus
Here image of my problem
by defualt the color is black (when out of focus)
How could I change that?
here is my code:
const useStyles = makeStyles({
notchedOutline: {
color: "red !important", // label foucus color
borderWidth: "1px",
borderColor: "red !important" // border color when out of focus
},
cssOutlinedInput: {
color: "green !important", // text color when out of focus
"&$cssFocused $notchedOutline": {
borderColor: `yellow !important` // border color when Focused
}
},
cssFocused: {
color: "red !important" // text and label color when focued
},
});
<TextField
id="outlined-basic"
label="Username"
variant="outlined"
type="text"
name="username"
error={usernameError.isInvalid ? true : false}
helperText={usernameError.errorHelper}
onChange={e => setUser({ ...user, username: e.target.value })}
InputLabelProps={{
classes: {
root: classes.cssLabel,
focused: classes.cssFocused
}
}}
InputProps={{
classes: {
root: classes.cssOutlinedInput,
focused: classes.cssFocused,
notchedOutline: classes.notchedOutline
},
startAdornment: (
<InputAdornment position="start">
<AccountCircleSharpIcon />
</InputAdornment>
),
}}
/>
I think you already selecting the correct class root: classes.cssLabel in InputLabelProps, but your shared styles doesn't have the styles for it.
InputLabelProps={{
classes: {
root: classes.cssLabel,
focused: classes.cssFocused
}
}}
Adding below in the makeStyles should fix the problem.
cssLabel: {
color: "red"
}

Reactjs material-UI TextField apply css properties

I have a similar login page made with material-UI but in my code there are differences with original one. Actually, the problem is starting when I click on the TextField.
The old inputs will shown and I select one of them the background of TextField become white.
In addition, if there are passwords saved on chrome when entering the login page for the first time, it automatically makes the background white by auto-filling.
My login page theme is dark and it is looking bad. How can I make textField background same with Material-UI login page?
Here is my code part:
const CssTextField = withStyles({
root: {
'& .MuiInput-underline:after': {
borderBottomColor: 'yellow',
},
'& .MuiOutlinedInput-root': {
'& fieldset': {
borderColor: 'white',
},
'&:hover fieldset': {
borderColor: 'white',
},
'&.Mui-focused fieldset': {
borderColor: 'yellow',
},'&.Mui-focused ': {
},
},
},
})(TextField);
export default function SignIn(props) {
return (
<form className={classes.form} noValidate>
<CssTextField
focused={true}
variant="outlined"
margin="normal"
required
fullWidth
id="email"
label="userName"
name="text"
type="text"
{...username}
autoComplete="text"
autoFocus
InputLabelProps={{
style: { color: '#fff' },
}}
InputProps={{
style: {
color: "red"
}
}}
/>
</form>
)
}
It is look like this:
This is the solution:
const styles = { WebkitBoxShadow: "0 0 0 1000px white inset" };
<CssTextField inputProps={{ style: inputStyle }} />
Keep in mind, that in material-ui there is a difference between inputProps and InputProps. The capital I changes the component, that is wrapped around the native input and the lowercase i manipulates the native input.

how to convert FormControl to TextField Material Ui

this is the old Code from some project:
<FormControl fullWidth><InputLabel className = {classes.inputLabel} >نوع فرم نامه</InputLabel>
<Select TabIndicatorProps={{style: {backgroundColor: themeStyle.placeHolderTextColor}}}
native autoFocus id="letILetTvCodeInt" onChange={this.handleChange} >
{Tools.GetSelectOptions(this.state.LetType, 'LetTVCodeInt', 'LetTNameStr')}</Select>
</FormControl>
I want to change the underline color of this select, I know I should use TextField, but this is working fine and I just want to change underline color of this, this is the style I use for underline color in TextField
const styles = theme => ({
cssLabel: {
color: themeStyle.textFieldUnderLineColor,
"&.Mui-focused": {
color: themeStyle.tabIndicatorProps,
}
},
cssFocused: {},
underline: {
'&:before': {
borderBottomColor: themeStyle.textFieldUnderLineColor,
},
'&:after': {
borderBottomColor: themeStyle.tabIndicatorProps,
color: themeStyle.tabIndicatorProps,
},
'&:hover:before': {
borderBottomColor: [themeStyle.appBarRDbgk, '!important'],
},
color: themeStyle.dialogContentColor,
},
notchedOutline: {
},
outlinedInput: {
'&$focused $notchedOutline': {
border: `2px solid ${themeStyle.tabIndicatorProps}`
},
backgroundColor: themeStyle.bkgBodyColor
},
focused: {},
notchedOutline: {},
})

Material UI: Remove up/down arrow dials from TextView

I have this TextView in Material UI:
<TextField
id="contact phone number"
label="Contact phone number"
type="number"
value={this.state.contactPhoneNumber}
onChange={this.handleChange('contactPhoneNumber')}
placeholder="Contact phone number"
margin="normal"
/>
It looks like this:
How would I remove the up and down arrow dials from the TextView?
You can try css approach for that.
input[type=number]::-webkit-inner-spin-button,
input[type=number]::-webkit-outer-spin-button {
-webkit-appearance: none;
margin: 0;
}
From the TextField docs, the type prop accepts valid HTML input types. I believe the reason the up and down arrows are present is because you specified number as the type.
Try type="tel" instead, as it seems to be the standard input type for phone numbers.
Here is a reference to the tel type and why it's a good idea to use it. Note that if the current browser doesn't support it, it will fall back to being a regular text field.
In React v 17.0.2 and Material-UI v 4.11.4, this works for me:
import { makeStyles } from '#material-ui/core/styles';
import TextField from '#material-ui/core/TextField';
const useStyles = makeStyles({
input: {
'& input[type=number]': {
'-moz-appearance': 'textfield'
},
'& input[type=number]::-webkit-outer-spin-button': {
'-webkit-appearance': 'none',
margin: 0
},
'& input[type=number]::-webkit-inner-spin-button': {
'-webkit-appearance': 'none',
margin: 0
}
},
});
export default function MyComponent() {
const classes = useStyles();
return <TextField className={classes.input} />;
}
This works for me (css help: https://www.w3schools.com/howto/howto_css_hide_arrow_number.asp)
input: {
background: theme.palette.secondary.main,
border: `1px solid white`,
flex: 1,
padding: '8px',
'&[type=number]': {
'-moz-appearance': 'textfield',
},
'&::-webkit-outer-spin-button': {
'-webkit-appearance': 'none',
margin: 0,
},
'&::-webkit-inner-spin-button': {
'-webkit-appearance': 'none',
margin: 0,
},
},
For Material UI version 5
const Input = styled(MuiInput)(({ theme }) => ({
"& input::-webkit-outer-spin-button, & input::-webkit-inner-spin-button": {
display: "none",
},
"& input[type=number]": {
MozAppearance: "textfield",
},
}));
And then use it as
<Input
id="contact phone number"
label="Contact phone number"
type="number"
value={this.state.contactPhoneNumber}
onChange={this.handleChange('contactPhoneNumber')}
placeholder="Contact phone number"
margin="normal"
/>
The question is old but maybe this answer may help those who are still seeking a valid answer.
If you use an outlined textfield you can create a class like,
textfieldClass: {
'& .MuiOutlinedInput-input': {
'&::-webkit-outer-spin-button, &::-webkit-inner-spin-button': {
'-webkit-appearance': 'none',
},
}
},
If you use underlined textfield;
textfieldClass: {
'& .MuiInput-input': {
'&::-webkit-outer-spin-button, &::-webkit-inner-spin-button': {
'-webkit-appearance': 'none',
},
}
},
then you can use it in TextField like:
<TextField
className={classes.textfieldClass}
id="contact phone number"
label="Contact phone number"
type="number"
value={this.state.contactPhoneNumber}
onChange={this.handleChange('contactPhoneNumber')}
placeholder="Contact phone number"
margin="normal"
/>
Material-Ui v5 beta
MuiInput: {
styleOverrides: {
root: {
'& input::-webkit-outer-spin-button, & input::-webkit-inner-spin-button':
{
display: 'none',
},
'& input[type=number]': {
MozAppearance: 'textfield',
},
},
},
},
Just change the type="number" to type="tel"
In my case, if I set it as type=tel then, I will be able to type letters also inside the field which I do not want it. Instead, I did the below one and it worked for me
const StyledInput= styled(OutlinedInput)`
input[type='number']::-webkit-inner-spin-button,
input[type='number']::-webkit-outer-spin-button {
display: none;
}`;
<StyledInput
type="number"
inputProps={{ min: 0 }}
onChange={event => {
...
}}
/>
Change TextField attribute type from number to tel
For Example:
<TextField label="Phone No" type="number" required />
To
<TextField label="Phone No" type="tel" required />

Resources