Adding ErrorText to material-ui Textfield moves other elements - reactjs

I have a signup form in a React app. I am using material-ui TextField and use the errorText property to add a message if there is an error in the input.
errorText={this.state.messages.emailMessage}
The state.messages.emailMessage is initially set to null and so TextField does not have the extra space for the message when the input is first rendered.
When the message is added it moves the other elements.
How can I allow space for the new node if it is needed so that the other elements are not moved? I tried setting the initial state of the message to ' ' but this colours the input red for error and doesn't work anyway!

You could just use the errorStyle property setting an absolute position..
That's how I fix those problems in my projects.

In the end I passed a style parameter to the material-ul component that set the errorText to display: table. This then stopped it from affecting the other elements when it was added.

To where should this style added?
It needs to be added for the HelperText styles. Here is an example:
const helperStyles = makeStyles(theme => ({
root: {
position: 'absolute',
bottom: '1em',
},
}))
const helperClasses = helperStyles()
<FormHelperText classes={helperClasses}>
{helperText}
</FormHelperText>

You can make them a fixed height by making the helperText equal to an empty space when there is no message to show.
<TextField helperText={error ? error.message : ' '} />

Like #leonormes 's post suggests, adding the errorStyle prop to the material ui component and setting the display property to "table" solved this issue.
The material UI components no longer moves or becomes unaligned when showing an error.
Here's what the component ended up looking like:
<TextField
floatingLabelText="Name"
value={this.state.name}
onChange={e => this.setState({ name: e.target.value })}
errorText={this.props.validationErrors.get('name')}
errorStyle={{ display: "table" }}
/>

You can target the MuiFormHelperText-root class . Below example is when you are applying style inside MUI makeStyles , but you can do the same thing with external CSS file .
'& .MuiFormHelperText-root' : {
position : 'absolute',
bottom : '-1rem'
}

For those who need an updated answer (errorText isn't a thing anymore as far as I could tell), then hopefully this will work:
<Box style={{ minHeight: "100px" }} >
<TextField
{...props}
/>
</Box>
It allows the error text message to be rendered inside the flexbox without affecting the other components, so it shouldn't disturb the things around it.
CodeSandbox

You can do something like this
const useStyles = makeStyles({
helperText: {
'& .MuiFormHelperText-root': {
height: '0',
marginTop: '0'
}
}
});
And then add this class text field control
className={classes.helperText}

Just setting position to absolute didn't work at all. This enables error text to display on input field. So for perfect fix we also have to set bottom with some value to make it fixed. Example below.
errorStyle:{
position: 'absolute',
bottom: '-0.9rem'
}
As mentioned in other answer setting display to table worked as well.
So both the styles works

Related

Change the color of asterisk symbol for required Input Fields and FormDropdown in Fluent UI Components

I am using FluentUI components for developing Teams App.
And have a form where I need to mark some Input and FormDropdown fields as required.
On adding required flag, the required fields sign (*) comes up beside the field label in default i.e black color.
I want to restyle this asterisk sign and change the color of the sign to red.
Any suggestions on how to achieve this.
You can use subComponentStyles property inside styles to modify styles of Label component:
<TextField
label="Required "
required={true}
styles={{
subComponentStyles: {
label: {
root: {
':after': {
position: 'absolute',
content: `'#'`,
color: 'green'
}
},
},
},
}}
/>
Approach is the same for Dropdown component.
Codepen working example.
Label Component implementation.
TextField areaLabel implementation.

How to change width of Mui DatePicker v5

I'm trying to change the width of the calendar popup on the Mui DatePicker but can't seem to figure it out. I have changed the width of the input using:
renderInput={(params) => <TextField {...params} sx={{ ...formStyles }} />}
But I want to change the width of the calendar as well. I'm new to working with any component library, so maybe I'm missing something. The docs said you could override the theme with the name MuiDatePicker, but when I try:
const theme = createTheme({
components: {
MuiDatePicker: {},
},
});
I'm getting a typescript error saying that MuiDatePicker isn't assignable to Components
Are you trying to change the width of the input TextField?
I am doing it like so, and it seems to do the trick everytime:
Wrap your DatePicker in a div
<div className={classes.datePicker}>
<DatePicker format="dd/mm/yyyy">
</div>
Override MUI styles of the div's TextField like so:
datePicker: {
"& .MuiTextField-root": {
width: 200,
},
Not sure if that's the best way to do it, but it works for me, also in MUI v5.

Textfield position shifts up after making a selection MUI?

I have this Autocomplete component, it renders a TextField with options to select from , problem is once I make a selection, it losses margin top, my bet is on the text, since there is no text there is no margin! I partially solved it by add in a empty space, which proves my point but still what is the right way to solve this, any idea how to stop this from happening and yet be able to pass an empty text without losing the margin.
The reason it doesn't work is because of the label, you set the label to an empty string whenever there is a selected value:
label={selected.item === "" ? "test" : ""}
Which affects the following rule:
label + .MuiInput-formControl {
margin-top: 16px;
}
If the label is empty, it will be removed from the DOM, so margin-top doesn't get applied anymore. A simple workaround is simply set the label to a non-empty string even if you don't want to display it:
label={selected.item === "" ? "test" : " "}
You can use placeholder props to the TextField component inside Autocomplete rather than conditional label props.
And then if you want to add margin, you can add some styling to the Autocomplete component like style={{marginTop:20}} or using MUI makeStyles API.
https://v4.mui.com/styles/api/#makestyles-styles-options-hook
...
<Autocomplete
id="combo-box-demo"
key={bool}
options={arr}
getOptionLabel={(option) => option}
onChange={handleChange}
style={{marginTop: 20}} // or using makeStyles
renderInput={(params) => (
<TextField
{...params}
placeholder="test" //label="test"
/>
)}
/>
...

Material-UI checkbox backrground color

I am using material ui checkbox, i wanted it to have its own background color over my div which has colored background. I have set the root to have a backgroundColor as white but the svgicon is a round shape which is not the look i intend to have. Can i shape the checkbox ?
Already have tried many things but not able to figure out how to change the icon
const styles = {
root : {
padding : '0px',
display : 'inline-block',
backgroundColor : 'white'
},
formLabelRoot : {
margin : '0'
}
}
.
.
.
render () {
const { classes } = this.props
return(
<div style={customStyles.divStyle}>
<div style={customStyles.div1}>
<FormControlLabel
classes={{root: classes.formLabelRoot}}
control={
<Checkbox
classes={{root : classes.root }}
color='primary'
/>
}
label={''}
/>
</div>
The background white is making a spherical rounded checkbox apparent
Image of what is happening now
You can override the icons used for the checked and unchecked states. The props you're looking for are icon for the unchecked state and checkedIcon for the checked state. Both of which take a component to be used as the icon.
Documentation here
You might have to make a compromise here if you don't want to go making your own icons.
Something like this is possible without changing the icons. If you're looking for a solid white box with a grey outline as the unchecked box, you might have to provide that svg yourself because I don't see anything like it in #material-ui/icons.
If this IS something you're ok with then target the svg, and give it a fill: "white".

How to hide MUI React ListItem?

I have the following:
<ListItem key={name} hidden={true} aria-hidden={true}>
name
</ListItem>
but the ListItem is still showing up. How can it be hidden?
As far as I know, there is no hidden props on the ListItem component in Material-UI, so you will have to implement you own behavior to hide the ListItem :
You can not render the concerned ListItem at all.
You can render it but hide it using some CSS. See How to display and hide a div with CSS?.
I was looking to programmatically hide a Material-UI FormControl component, and found the same issue (i.e. the lack of a hidden prop).
What worked for me was to add a method that returned the appropriate class string, based on whether I wanted to show the component in question or not.
For example, with styles like:
const styles = createStyles({
...
formcontrol: {
minWidth: 120,
margin: 10
},
invisible: {
visibility: "hidden"
},
});
I added this to my component class:
getStyle() {
let cls: string;
if (this.props.whatever) {
cls = this.props.classes.formcontrol;
} else {
cls = this.props.classes.invisible + " " + this.props.classes.formcontrol;
}
return cls;
}
And then reference that from render() when creating the component I want to sometimes hide:
<FormControl className={this.getStyle()}>
...
</FormControl>
This should work for any styled MUI component.
(Side-note: the display prop appears from the docs to do this, but didn't work for me. Perhaps it works only for Box components, which happen to be what's used in all of the examples in the docs. This is worth further investigation which I have not yet spent the time to do.)

Resources