dohomi / react-hook-form-mui

Material-UI form components ready to use with react-hook-form
https://react-hook-form-material-ui.vercel.app
MIT License
564 stars 111 forks source link

setFocus isn't working for RadioButtonGroup and custom errors are breaking focus functionality #266

Open AdamZajler opened 6 months ago

AdamZajler commented 6 months ago

Duplicates

Latest version

Current behavior 😯

Currently control.setFocus() cannot be used; on the RadioButtonGroup .

Expected behavior 🤔

Focus on this element can be setted

Steps to reproduce 🕹

codesandbox

Form to embed

import {
  FormContainer,
  RadioButtonGroup,
  useForm,
  TextFieldElement,
  SelectElement,
  CheckboxElement,
} from "react-hook-form-mui";
import { Stack, Button } from "@mui/material";

interface FormValues {
  select: string;
  inputFirstName: string;
  radioType: string;
  agreement: boolean;
}

export default function Form() {
  const control = useForm<FormValues>({
    mode: "onBlur",
    criteriaMode: "all",
    defaultValues: {
      select: "",
      inputFirstName: "",
      radioType: "",
      agreement: false,
    },
  });

  const onSubmit = async (formData: FormValues): Promise<void> => {
    if (formData.agreement === false) {
      control.setError("agreement", {
        type: "custom",
        message: "error after submitting",
      });
      control.setError("select", {
        type: "custom",
        message: "error after submitting",
      });
    }
  };

  return (
    <div className="Form">
      <FormContainer
        FormProps={{ method: "post" }}
        formContext={control}
        onSuccess={onSubmit}
      >
        <Stack gap={4}>
          <SelectElement
            label="Select"
            name="select"
            options={[
              {
                id: "1",
                label: "Label 1",
              },
              {
                id: "2",
                label: "label 2",
              },
            ]}
          />
          <TextFieldElement
            required
            type="text"
            name="inputFirstName"
            label="inputFirstName"
            sx={{ gridColumn: { xs: "1/3", sm: "1/2" } }}
          />
          <RadioButtonGroup
            required
            name="radioType"
            label="radioType"
            options={[
              {
                id: "paid-vouchers",
                label: "test1",
              },
              {
                id: "paid-vouchers-2",
                label: "test2",
              },
            ]}
            row
          />
          <CheckboxElement name="agreement" label="*test" />
          <Stack gap={2}>
            <span onClick={() => control.setFocus("select")}>select focus</span>
            <span onClick={() => control.setFocus("inputFirstName")}>
              inputFirstName focus
            </span>
            <span onClick={() => control.setFocus("radioType")}>
              radioType focus
            </span>
            <span onClick={() => control.setFocus("agreement")}>
              agreement focus
            </span>
            <span
              onClick={() =>
                control.setError("agreement", {
                  type: "custom",
                  message: "lol",
                })
              }
            >
              agreement error
            </span>
          </Stack>
          <Button type="submit" variant="contained">
            SUBMIT
          </Button>
        </Stack>
      </FormContainer>
    </div>
  );
}
dohomi commented 6 months ago

the codesandbox is not viewable

AdamZajler commented 6 months ago

the codesandbox is not viewable

I updated the link ;)

AdamZajler commented 6 months ago

Also I have updated the example because I found new error.

When you are filling the form => you submit it and validate data. If you set some custom errors in validation proces you cant set focus on checkbox BUT if you trigger error by just checking required checkbox and unchecking it OR by onClick with setError you can set focus :thinking:

It looks like setting custom erros is breaking smth

dohomi commented 6 months ago

@AdamZajler what do you expect on a RadioGroup to be focused? I don't see any example of @MUI which is addressing this. I tried to programmatically use ref.current.focus() but this just doesn't do anything on the RadioGroup of @Mui, this might be just not implemented on their side?

AdamZajler commented 6 months ago

@AdamZajler what do you expect on a RadioGroup to be focused? I don't see any example of @mui which is addressing this. I tried to programmatically use ref.current.focus() but this just doesn't do anything on the RadioGroup of @mui, this might be just not implemented on their side?

Huh you're right, I didn't think about it that way :sweat_smile: But what about this case for the checkbox after form submitting?

dohomi commented 6 months ago

@sadik-malik you introduced the handleInputRef functionality inside of Checkbox, do you know if there is anything missing in the current implementation?

sadik-malik commented 1 month ago

@AdamZajler, regarding the checkbox focus functionality: The checkbox receives focus when you click the "agreement focus" button after submitting the form, but without the ripple effect. Try pressing the "space" bar on your keyboard after clicking the "agreement focus" button to see the focus.

The only issue is the missing ripple effect, which was raised a while ago in MUI #9659.

You can use the action prop of the checkbox and call action.focusVisible() along with control.setFocus() to focus the checkbox with the ripple effect.