---
name: forms
description: Best practices for building forms including validation and field types.
---

## Rules

- Always use `useLayoutForm` with pre-defined components.
- Define `width` for all form fields based on the expected content length.
- Derive Zod schemas from Drizzle table schemas using `createSelectSchema` with `t()` for validation messages.

## File Placement

```
src/routes/features/-components   — Form components scoped to a feature
src/lib/schemas/                  — Zod schemas
wcz-layout/hooks                  — shared hooks from npm package
```

## Examples

```ts
// Imports
import { useLayoutForm } from "wcz-layout/hooks";
import { LibrarySchema } from "~/lib/schemas/library";

// Form Component
interface FormProps {
  defaultValues: Library;
  onSubmit: (value: Library) => Promise<void>;
}

export const Form: FC<FormProps> = ({ defaultValues, onSubmit }) => {
  const { t } = useTranslation();

  const form = useLayoutForm({
    defaultValues,
    validators: { onChange: LibrarySchema },
    onSubmit: async ({ value, formApi }) => {
      await onSubmit(value);
      formApi.reset();
    },
  });

  return (
    <form
      onSubmit={(event) => {
        event.preventDefault();
        event.stopPropagation();
        form.handleSubmit();
      }}
    >
      {/* some styling */}
      <form.AppField name="name">
        {(field) => <field.TextField label={t("Library.Name")} required sx={{ width: 420 }} />}
      </form.AppField>
      {/* some styling */}
      <form.AppForm>
        <form.SubmitButton variant="contained">{t("Submit")}</form.SubmitButton>
      </form.AppForm>
    </form>
  );
};

// Autocomplete
<field.Autocomplete
  options={options}
  sx={{ width: 250 }}
  autoHighlight
  autoSelect
  autoComplete
  loading={isLoading}
  textFieldProps={{
    label: t("Customer"),
    required: true,
  }}
/>

// Checkbox
<field.Checkbox label={t("IsThisTrue")} />
```

## Field Types

`Autocomplete` · `Checkbox` · `DatePicker` · `DateRangePicker` · `DateTimePicker` · `DateTimeRangePicker` · `NumberField` · `RadioGroup` · `Slider` · `SubmitButton` · `Switch` · `TextField` · `TimePicker` · `TimeRangePicker`
