reactjsmaterial-ui

Remove Label on Material UI Select Text Field


I have a select field for gender which has the label positioned in the center of the select, which is the desired layout.

Gender Field, nothing selected

When the user selects this field the label flies away to the top left corner as shown. What I want to do is remove the label entirely and replace that with a blue border.

Gender Field, male selected

Here is my code:

          <TextField
            id='gender-select'
            select
            label="Gender"
            className={classes.textField}
            value={gender}
            onChange={data => setGender(data.target.value)}
            margin='normal'
            variant='outlined'>
            {genders.map(option => (
              <MenuItem key={option.value} value={option.value}>
                {option.label}
              </MenuItem>
            ))}
          </TextField>

and here is my styling code:

const useStyles = makeStyles(theme => ({
  textField: {
    marginLeft: theme.spacing(1),
    marginRight: theme.spacing(1),
    marginTop: theme.spacing(1),
    '& .MuiOutlinedInput-root': {
      '& fieldset': {
        borderColor: '#CACACA'
      },
      '&:hover fieldset': {
        borderColor: '#007AFF'
      },
      '&.Mui-focused hover': {
        borderColor: '#007AFF'
      },
      '&.Mui-focused fieldset': {
        borderColor: '007AFF'
      }
    }
  }
})) 

I have tried adding a conditional on the label prop to nullify it, eg:

label={gender== "" ? "Gender": null}

but this simply gives me a blank line in place of the label.

How do I change the label for a blue line when the field is in focus?


Solution

  • The reason your solution didn't quite work is because TextField doesn't watch for changes to the label. It figures out the label width in an effect after the initial rendering.

    Fortunately, there is an easy way to avoid the notch. You can prevent the label from "shrinking" up with InputLabelProps={{shrink: false}}.

    Here is a full working example:

    import React from 'react';
    import { makeStyles } from '@material-ui/core/styles';
    import MenuItem from '@material-ui/core/MenuItem';
    import TextField from '@material-ui/core/TextField';
    
    const genders = [
      {
        value: 'M',
        label: 'Male',
      },
      {
        value: 'F',
        label: 'Female',
      },
      {
        value: 'O',
        label: 'Other',
      },
    ];
    
    const useStyles = makeStyles(theme => ({
      container: {
        display: 'flex',
        flexWrap: 'wrap',
      },
      textField: {
        marginLeft: theme.spacing(1),
        marginRight: theme.spacing(1),
        width: 100
      },
      dense: {
        marginTop: theme.spacing(2),
      },
      menu: {
        width: 100,
      },
    }));
    
    export default function OutlinedTextFields() {
      const classes = useStyles();
      const [gender, setGender] = React.useState("");
    
      const handleChange = event => {
        setGender(event.target.value);
      };
    
      return (
        <form className={classes.container} noValidate autoComplete="off">
          <TextField
            id="outlined-select-gender"
            select
            label={gender=== "" ? "Gender": ""}
            className={classes.textField}
            value={gender}
            onChange={handleChange}
            InputLabelProps={{shrink: false}}
            SelectProps={{
              MenuProps: {
                className: classes.menu,
              },
            }}
            margin="normal"
            variant="outlined"
          >
            {genders.map(option => (
              <MenuItem key={option.value} value={option.value}>
                {option.label}
              </MenuItem>
            ))}
          </TextField>
        </form>
      );
    }
    

    Edit Outlined select no shrink