Search code examples
reactjsmaterial-uireact-hook-formyup

MUI Text fields label and default value are superposing


I just created a new project with MUI, react-hook-form and yup

I got a login page, which have a UI bug that I can't figure out.

When I load the page, default values are correctly completed by browser, but it's confused with the text field label : enter image description here

Then, if I click anywhere on the webpage, it gets back OK : enter image description here

This is my code :

import * as React from "react";
import Avatar from "@mui/material/Avatar";
import Button from "@mui/material/Button";
import TextField from "@mui/material/TextField";
import FormControlLabel from "@mui/material/FormControlLabel";
import Checkbox from "@mui/material/Checkbox";
import Box from "@mui/material/Box";
import LockOutlinedIcon from "@mui/icons-material/LockOutlined";
import Typography from "@mui/material/Typography";
import Container from "@mui/material/Container";
import { Paper } from "@mui/material";
import { Controller, useForm } from "react-hook-form";
import * as yup from "yup";
import { yupResolver } from "@hookform/resolvers/yup";

export function LoginPage() {
  const schema = yup.object().shape({
    trigram: yup.string().max(3).min(3).required(),
    password: yup.string().required(),
  });
  const {
    handleSubmit,
    control,
    formState: { errors },
  } = useForm({
    resolver: yupResolver(schema),
    defaultValues: {
      trigram: "",
      password: "",
    },
  });
  const onSubmit = (data) => {
    console.log("submit", data);
  };
  return (
    <Container component="main" maxWidth="xs">
      <Paper
        elevation={2}
        sx={{
          p: 4,
        }}
      >
        <Box
          sx={{
            display: "flex",
            flexDirection: "column",
            alignItems: "center",
          }}
        >
          <Avatar sx={{ m: 1, bgcolor: "primary.main" }}>
            <LockOutlinedIcon />
          </Avatar>
          <Typography component="h1" variant="h5">
            Connexion
          </Typography>
          <Box
            component="form"
            onSubmit={handleSubmit(onSubmit)}
            noValidate
            sx={{ mt: 1 }}
          >
            <Controller
              name="trigram"
              control={control}
              render={({ field }) => (
                <TextField
                  {...field}
                  margin="normal"
                  error={!!errors?.email}
                  helperText={errors?.email?.message}
                  required
                  fullWidth
                  label="Trigramme"
                  autoComplete="username"
                  autoFocus
                />
              )}
            />
            <Controller
              name="password"
              control={control}
              render={({ field }) => (
                <TextField
                  {...field}
                  margin="normal"
                  error={!!errors?.email}
                  helperText={errors?.email?.message}
                  required
                  fullWidth
                  label="Mot de passe"
                  autoComplete="current-password"
                  type="password"
                />
              )}
            />
            <Button
              type="submit"
              fullWidth
              variant="contained"
              sx={{ mt: 3, mb: 2 }}
            >
              Connexion
            </Button>
          </Box>
        </Box>
      </Paper>
    </Container>
  );
}

I can't understand what's happening


Solution

  • Add defaultValue="" to the props of each TextField. This is a known issue, described in https://mui.com/material-ui/react-text-field/#limitations

    Adding the following prop InputLabelProps={{ shrink: true }} as well will solve the issue.

    You can also check this Github Issue https://github.com/react-hook-form/react-hook-form/issues/2192