Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Select, OutlineInput label with shrink property not same as TextField when empty

If I use a TextField component, and set InputLabelProps={{shrink: true}}, the Label stays at the top of the TextField, and the outline is cut to show the Label correctly.

However, if I use Select component, as follows :

<FormControl variant={ this.props.variant }  className={ classes.formControl } fullWidth>
            <InputLabel
                ref={ (input) =>{ this.inputLabel = input }}
                htmlFor={ this.props.id }
                shrink={ true }>
                { this.props.label }
            </InputLabel>
            <Select
                id={ this.props.id }
                value={ this.props.value }
                onChange={ this.onChange }
                input={
                    <OutlinedInput
                        labelWidth={ this.state.labelWidth }
                        name={ this.props.id }
                        id={ this.props.id }
                    />
                    }
                >
                { this.props.options.map(option => (
                    <MenuItem key={ option.value } value={ option.value }>
                        <em>{ option.label }</em>
                    </MenuItem>
                ))}
            </Select>
        </FormControl>

The Label stays at the top of the outline just like TextField, however, the outline is not cut out to display the Label nicely, instead it looks like it is "crossed out"

What am I doing wrong? (Please not, that the this.state.labelWidth has a correct value, even if I hard code this, it still does not work)

Thanks in advance for your help Cheers Jason

like image 905
user11607572 Avatar asked Jun 06 '19 07:06

user11607572


1 Answers

The default behavior is for the shrink property of InputLabel to be automatically managed by Material-UI. Generally shrink is only applied when the Select has a non-empty value or when it has focus. If you want to have shrink applied all the time, then you also need to specify notched on OutlinedInput since that is what controls leaving a space for the label along the outline.

The code below shows both cases (1. always apply shrink and notched, 2. let Material-UI manage shrink and notched):

import React from "react";
import { makeStyles } from "@material-ui/core/styles";
import OutlinedInput from "@material-ui/core/OutlinedInput";
import InputLabel from "@material-ui/core/InputLabel";
import MenuItem from "@material-ui/core/MenuItem";
import FormControl from "@material-ui/core/FormControl";
import Select from "@material-ui/core/Select";

const useStyles = makeStyles(theme => ({
  root: {
    display: "flex",
    flexWrap: "wrap"
  },
  formControl: {
    margin: theme.spacing(1),
    minWidth: 120
  },
  selectEmpty: {
    marginTop: theme.spacing(2)
  }
}));

function SimpleSelect() {
  const classes = useStyles();
  const [values, setValues] = React.useState({
    age: ""
  });

  const inputLabel = React.useRef(null);
  const [labelWidth, setLabelWidth] = React.useState(0);
  React.useEffect(() => {
    setLabelWidth(inputLabel.current.offsetWidth);
  }, []);

  function handleChange(event) {
    setValues(oldValues => ({
      ...oldValues,
      [event.target.name]: event.target.value
    }));
  }

  return (
    <form className={classes.root} autoComplete="off">
      <FormControl variant="outlined" className={classes.formControl}>
        <InputLabel
          shrink
          ref={inputLabel}
          htmlFor="outlined-age-always-notched"
        >
          Age
        </InputLabel>
        <Select
          value={values.age}
          onChange={handleChange}
          input={
            <OutlinedInput
              notched
              labelWidth={labelWidth}
              name="age"
              id="outlined-age-always-notched"
            />
          }
        >
          <MenuItem value="">
            <em>None</em>
          </MenuItem>
          <MenuItem value={10}>Ten</MenuItem>
          <MenuItem value={20}>Twenty</MenuItem>
          <MenuItem value={30}>Thirty</MenuItem>
        </Select>
      </FormControl>
      <FormControl variant="outlined" className={classes.formControl}>
        <InputLabel ref={inputLabel} htmlFor="outlined-age-simple">
          Age
        </InputLabel>
        <Select
          value={values.age}
          onChange={handleChange}
          input={
            <OutlinedInput
              labelWidth={labelWidth}
              name="age"
              id="outlined-age-simple"
            />
          }
        >
          <MenuItem value="">
            <em>None</em>
          </MenuItem>
          <MenuItem value={10}>Ten</MenuItem>
          <MenuItem value={20}>Twenty</MenuItem>
          <MenuItem value={30}>Thirty</MenuItem>
        </Select>
      </FormControl>
    </form>
  );
}

export default SimpleSelect;

Edit Outlined Select

like image 101
Ryan Cogswell Avatar answered Nov 09 '22 19:11

Ryan Cogswell