Label position for Material-UI text field with icon adornment when shrink false

Viewed 9065

enter image description here

I use Material-UI TextField with an Icon inside like this. The label "Your good name here" should be next to the icon instead of overlapping it.

This happens after I added InputLabelProps={{ shrink: false }} to the TextField.

How could I fix this position correctly? Any help!

Thanks in advance! =)

This is my code pen

import React from "react";
import { makeStyles } from "@material-ui/core/styles";
import Input from "@material-ui/core/Input";
import InputLabel from "@material-ui/core/InputLabel";
import InputAdornment from "@material-ui/core/InputAdornment";
import FormControl from "@material-ui/core/FormControl";
import TextField from "@material-ui/core/TextField";
import Grid from "@material-ui/core/Grid";
import AccountCircle from "@material-ui/icons/AccountCircle";

const useStyles = makeStyles((theme) => ({
  margin: {
    margin: theme.spacing(1)
  }
}));

export default function InputWithIcon() {
  const classes = useStyles();

  return (
    <div>
      <TextField
        className={classes.margin}
        id="input-with-icon-textfield"
        label="Your good name here"
        InputLabelProps={{ shrink: false }}
        InputProps={{
          startAdornment: (
            <InputAdornment position="start">
              <AccountCircle />
            </InputAdornment>
          )
        }}
      />
      <TextField
        className={classes.margin}
        id="input-with-icon-textfield"
        label="Your good name here"
        // InputLabelProps={{ shrink: false }}
        InputProps={{
          startAdornment: (
            <InputAdornment position="start">
              <AccountCircle />
            </InputAdornment>
          )
        }}
      />
    </div>
  );
}
1 Answers

Below are the relevant default styles for the label:

  formControl: {
    position: 'absolute',
    left: 0,
    top: 0,
    transform: 'translate(0, 24px) scale(1)',
  },
  /* Styles applied to the `input` element if `shrink={true}`. */
  shrink: {
    transform: 'translate(0, 1.5px) scale(0.75)',
    transformOrigin: 'top left',
  },

To fix the positioning of the label to account for the width of the input adornment, you need to modify the x-axis portion of the translate CSS (e.g. translate(32px, 24px) scale(1)).

Below is a working example based on your sandbox:

import React from "react";
import { makeStyles } from "@material-ui/core/styles";
import InputAdornment from "@material-ui/core/InputAdornment";
import TextField from "@material-ui/core/TextField";
import AccountCircle from "@material-ui/icons/AccountCircle";

const useStyles = makeStyles((theme) => ({
  margin: {
    margin: theme.spacing(1)
  },
  inputLabelNoShrink: {
    transform: "translate(32px, 24px) scale(1)"
  }
}));

export default function InputWithIcon() {
  const classes = useStyles();
  const [value, setValue] = React.useState("");
  const shrink = value.length > 0;
  return (
    <div>
      <TextField
        className={classes.margin}
        id="input-with-icon-textfield"
        label="Your good name here"
        value={value}
        onChange={(event) => setValue(event.target.value)}
        InputLabelProps={{
          shrink: shrink,
          className: shrink ? undefined : classes.inputLabelNoShrink
        }}
        InputProps={{
          startAdornment: (
            <InputAdornment position="start">
              <AccountCircle />
            </InputAdornment>
          )
        }}
      />
    </div>
  );
}

Edit label position with input adornment

Related