Material UI: Remove up/down arrow dials from TextView - reactjs

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 />

Related

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.

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

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

Material UI - Overide disabled styles for InputBase

I can't seem to find a way to override the following rule on an InputBase:
.MuiInputBase-root.Mui-disabled {
color: rgba(0, 0, 0, 0.38);
}
The rule I want to apply is: color: "rgba(0, 0, 0, 0.75)"
I've tried using classname and classes but nothing is working. Any ideas?
textField: {
marginLeft: theme.spacing(1),
marginRight: theme.spacing(1),
'&:disabled': {
color: "rgba(0, 0, 0, 0.75)"
}
},
disabled: {
color: "rgba(0, 0, 0, 0.75)",
'&:disabled': {
color: "rgba(0, 0, 0, 0.75)"
}
}
<TextField
disabled
id="outlined-disabled"
label="Disabled"
defaultValue="Hello World"
className={classes.textField}
classes={{
root: classes.disabled,
disabled: classes.disabled
}}
margin="normal"
variant="outlined"
/>
Codesandbox: https://codesandbox.io/s/material-demo-3xb7n
TextField doesn't support disabled rule name.
You need to provide InputProps to TextField, and there you can provide disabled rule name:
import React from "react";
import { makeStyles } from "#material-ui/core/styles";
import TextField from "#material-ui/core/TextField";
const useStyles = makeStyles(theme => ({
container: {
display: "flex",
flexWrap: "wrap"
},
textField: {
marginLeft: theme.spacing(1),
marginRight: theme.spacing(1)
},
inputRoot: {
'&$disabled': {
color:'red'
},
},
disabled: {}
}));
export default function OutlinedTextFields() {
const classes = useStyles();
return (
<form className={classes.container} noValidate autoComplete="off">
<TextField
disabled
id="outlined-disabled"
label="Disabled"
defaultValue="Hello World"
InputProps={{
classes:{
root: classes.inputRoot,
disabled: classes.disabled
}
}}
margin="normal"
variant="outlined"
/>
</form>
);
}
I want to provide another answer to this question. I found it while I was using the InputBase component, but it also works for TextField and the other input components provided by Material UI.
You are able to use nested selectors to style these types of components. When you create a TextField, by default it creates an HTML input element on the webpage. This is what you want to style.
For example, if you wanted to alter the color of the text from black to gray when the TextField is disabled, you could use this for your theme:
const useStyles = theme => ({
textField: {
'& input': {
color: '#000000',
},
'& input:disabled': {
color: '#CCCCCC',
},
},
});
And then, for the element, you would only need to set its class. There are no InputProps needed.
<TextField
disabled
id="outlined-disabled"
label="Disabled"
defaultValue="Hello World"
className={classes.textField}
margin="normal"
variant="outlined"
/>
Below is the code snippet that should work for you...
import { createMuiTheme, ThemeProvider } from "#material-ui/core/styles";
import TextField from "#material-ui/core/TextField";
export default function DisabledTextInput (props) {
const disabledFlag = true;
const theme = createMuiTheme({
overrides: {
MuiInputBase: {
root: {
"&$disabled": {
color: "rgba(0, 0, 0, 0.75)"
}
}
},
},
});
return (
<ThemeProvider theme={theme}>
<TextField
variant="outlined"
disabled={disabledFlag}
...
/>
</ThemeProvider>
);
}
This is what worked for me with MaterialUI version 5.x.
The new version of MaterialUI has a different way of defining overrrides.
import { createTheme, ThemeProvider } from '#mui/material/styles';
export default createTheme({
palette: {
components: {
MuiInputBase: {
styleOverrides: {
root: {
'&.Mui-disabled': {
color: red[500],
backgroundColor: grey[400],
}
}
}
}
},
});

How Do I Refactor Common React Components?

I am styling a required TextField like this
const styles = theme => ({
labelAsterisk: {
color: "red"
},
cssLabel: {
color: "orange"
},
cssRequired: {
"&:before": {
borderBottom: "2px solid orange"
}
},
});
<TextField
id="requiredField"
label="Required Field"
value="Custom Text"
required
InputLabelProps={{
classes: {
root: classes.cssLabel
},
FormLabelClasses: {
asterisk: classes.labelAsterisk
}
}}
InputProps={{
classes: {
underline: classes.cssRequired
}
}}
margin="normal"
/>
I have lots of these required fields in my forms and would like to standardise it instead of copying and pasting large chunks of code.
What is the best way refactor this so that I only need to specify id, label and value each time I use it?
Do I extend TextField?
Create a new component that extends React.Component?
Use a function or a constant?
Here's how you would define your custom TextField component:
const RequiredTextField = ({id, label, value}) => (
<TextField
id={id}
label={label}
value={value}
required
InputLabelProps={{
classes: {
root: classes.cssLabel
},
FormLabelClasses: {
asterisk: classes.labelAsterisk
}
}}
InputProps={{
classes: {
underline: classes.cssRequired
}
}}
margin="normal"
/>
)
And here's how you would use it:
<RequiredTextField id="some-id" label="some-label" value="some-value">

How to change outline color of Material UI React input component?

I've searched high and low for an answer, in both the docs and other SO questions.
I'm using the createMuiTheme option in a separate JS file to override certain default styling, but am having a hard time understanding how the overrides option works.
Currently my button looks like this:
The code I've got to get this far looks like this:
const theme = createMuiTheme({
...other code,
overrides: {
MuiFormControlLabel: {
focused: {
color: '#4A90E2'
}
},
MuiOutlinedInput: {
focused: {
border: '1px solid #4A90E2'
},
notchedOutline: {
border: '1px solid #4A90E2'
},
},
MuiFormLabel: {
focused: {
color: '1px solid #4A90E2'
}
}
}
)};
Then in my component, I'm using it as such:
import theme from './styles/ThemeStyles';
import { withStyles } from '#material-ui/core/styles';
class SignInForm extends Component {
render() {
const { classes } = this.props;
<form className={classes.container} noValidate autoComplete='off'>
<TextField
id="outlined-email-input"
label="Email"
className={classes.textField}
type="email"
name="email"
autoComplete="email"
margin="normal"
variant="outlined"
/>
</form>
}}
My question is, what am I missing to make my component look so funky? And in the future, how do I know what to target in the overrides option of the ThemeProvider so that I don't run into similar situations?
Thanks to Rudolf Olah's help and pointing me in the right direction! I was able to solve the issue with the following code:
overrides: {
MuiOutlinedInput: {
root: {
position: 'relative',
'& $notchedOutline': {
borderColor: 'rgba(0, 0, 0, 0.23)',
},
'&:hover:not($disabled):not($focused):not($error) $notchedOutline': {
borderColor: '#4A90E2',
// Reset on touch devices, it doesn't add specificity
'#media (hover: none)': {
borderColor: 'rgba(0, 0, 0, 0.23)',
},
},
'&$focused $notchedOutline': {
borderColor: '#4A90E2',
borderWidth: 1,
},
},
},
MuiFormLabel: {
root: {
'&$focused': {
color: '#4A90E2'
}
}
}
To find the class names and CSS properties that you can change, the documentation for the Component API shows a list.
TextField is a special case though, because it combines and renders multiple sub-components, it allows you to pass CSS properties to the Input component and the FormHelperText component.
And the OutlinedInput is a very special case, because it actually uses NotchedInput for the input element which has its own CSS properties.
Looking at the code for the OutlinedInput you can see child selectors being used:
root: {
position: 'relative',
'& $notchedOutline': {
borderColor,
},
// ...
It looks like the issue is that the OutlinedInput doesn't set the styles for the NotchedOutline correctly
You may have some luck with this:
const theme = createMuiTheme({
// ...other code,
overrides: {
// ...
MuiOutlinedInput: {
focused: {
border: '1px solid #4A90E2'
},
'& $notchedOutline': {
border: '1px solid #4A90E2'
},
},
// ...
}
});
This is covered in the docs pretty well here.
Click inside the field labelled "Custom CSS" for a demo.
Here's how this could be done using your original TextField component:
import React from 'react'
import PropTypes from 'prop-types'
import { withStyles } from '#material-ui/core/styles'
import TextField from '#material-ui/core/TextField'
const styles = theme => ({
textField: {
marginLeft: theme.spacing.unit * 3,
marginBottom: '0px',
},
label: {
'&$focused': {
color: '#4A90E2'
},
},
focused: {},
outlinedInput: {
'&$focused $notchedOutline': {
border: '1px solid #4A90E2'
},
},
notchedOutline: {},
})
const CustomOutline = ({classes}) => (
<TextField
id="outlined-email-input"
label="Email"
className={classes.textField}
type="email"
name="email"
autoComplete="email"
margin="normal"
variant="outlined"
InputLabelProps={{
classes: {
root: classes.label,
focused: classes.focused,
},
}}
InputProps={{
classes: {
root: classes.outlinedInput,
focused: classes.focused,
notchedOutline: classes.notchedOutline,
},
}}
/>
)
CustomOutline.propTypes = {
classes: PropTypes.object.isRequired,
}
export default withStyles(styles)(CustomOutline)
I found the solution here: The authors of the framework did not really cover this in the docs that well.
https://github.com/mui-org/material-ui/issues/13557

Resources