# Form

Die Form-Component gruppiert Formularfelder, nutzbar nur mit React Hook Form.

```tsx
import { useForm } from "react-hook-form";
import {
  Field,
  Form,
  ResetButton,
  SubmitButton,
} from "@mittwald/flow-react-components/react-hook-form";
import {
  ActionGroup,
  Label,
  Section,
  TextField,
} from "@mittwald/flow-react-components";

export default () => {
  interface Values {
    name: string;
  }
  const form = useForm<Values>();

  const handleSubmit = (values: Values) =>
    alert(JSON.stringify(values));

  return (
    <Form form={form} onSubmit={handleSubmit}>
      <Section>
        <Field
          name="name"
          rules={{
            required: "Bitte gib einen Namen ein",
          }}
        >
          <TextField>
            <Label>Name</Label>
          </TextField>
        </Field>
        <ActionGroup>
          <ResetButton>Zurücksetzen</ResetButton>
          <SubmitButton>Speichern</SubmitButton>
        </ActionGroup>
      </Section>
    </Form>
  );
}
```

---

# Aktionen nach Submit

Aktionen, die nach dem Submit ausgeführt werden sollen – zum Beispiel ein
Form-Reset oder ein Redirect – sollten im Return-Callback des Submit Handlers
erfolgen. Dieser Callback kann auch asynchron sein.

```tsx
const submitHandler = () => {
  // submit logic
  return () => {
    form.reset();
  };
};
```

```tsx
import { sleepLong } from "@/content/04-components/actions/action/examples/lib";
import {
  ActionGroup,
  Label,
  Section,
  TextField,
} from "@mittwald/flow-react-components";
import {
  Field,
  Form,
  ResetButton,
  SubmitButton,
} from "@mittwald/flow-react-components/react-hook-form";
import { useForm } from "react-hook-form";

export default () => {
  interface Values {
    name: string;
  }
  const form = useForm<Values>({
    defaultValues: {
      name: "",
    },
  });

  return (
    <Form
      form={form}
      onSubmit={async () => {
        await sleepLong();
        // recommended way to reset forms after submit
        return () => {
          form.reset();
        };
      }}
    >
      <Section>
        <Field
          name="name"
          rules={{
            required: "The project name is required",
          }}
        >
          <TextField>
            <Label>Name</Label>
          </TextField>
        </Field>
        <ActionGroup>
          <ResetButton>Zurücksetzen</ResetButton>
          <SubmitButton>Speichern</SubmitButton>
        </ActionGroup>
      </Section>
    </Form>
  );
}
```

---

# Properties

| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `autoReset` | `boolean \| FormAutoResetOptions` | `true` | When the form is reset to its default values. `true` resets it after the surrounding modal has closed, `false` never resets it. |
| `form` _(required)_ | `UseFormReturn<F>` | - | The react-hook-form instance returned by `useForm()`. |
| `formComponent` | `FC<Omit<FormComponentType, "ref">>` | - | The component rendered as the form element. Use it to render the form with a routers form component. Defaults to a plain `<form />`. |
| `isReadOnly` | `boolean` | `false` | Whether all fields of the form can be read but not edited. |
| `submitController` | `{ submit: { (): Promise<void>; set(newSubmitHandler: () => void \| Promise<void>): void; extend(submitController: ...): ...; }; }` | - | A controller to submit the form from outside of it. |

### Events

| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `onSubmit` _(required)_ | `FormOnSubmitHandler<F>` | - | Called with the validated form values when the form is submitted. Returning a promise keeps the submit button pending until it settles. |

### Accessibility

| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `aria-describedby` | `string` | - | Identifies the element (or elements) that describes the object. @see aria-labelledby |
| `aria-hidden` | `Booleanish` | - | Indicates whether the element is exposed to an accessibility API. @see aria-disabled. |
| `aria-label` | `string` | - | Defines a string value that labels the current element. @see aria-labelledby. |
| `aria-labelledby` | `string` | - | Identifies the element (or elements) that labels the current element. @see aria-describedby. |

