# Form

useForm and Form.Field: validation, touched state and submit handling.

Group: Forms

## Import

```tsx
import { Form, useForm } from "@indoku/ui"
```

## Examples

### Basic usage

```tsx
function FormDemo() {
  const [submitted, setSubmitted] = useState<LoginValues | null>(null)

  const form = Form.useForm<LoginValues>({
    defaultValues: { email: "", password: "" },
    validators: {
      email: (v) => (!v.includes("@") ? "Email nggak valid" : undefined),
      password: (v) => (v.length < 8 ? "Minimal 8 karakter" : undefined),
    },
    onSubmit: async (values) => {
      setSubmitted(values)
    },
  })

  return (
    <Stack as="form" gap="4" maxW="sm" onSubmit={form.handleSubmit}>
      <Form.Field meta={form.getFieldMeta("email")} label="Email" required>
        <Input type="email" placeholder="kamu@contoh.com" {...form.getInputProps("email")} />
      </Form.Field>

      <Form.Field
        meta={form.getFieldMeta("password")}
        label="Password"
        required
        helperText="Minimal 8 karakter."
      >
        <Input type="password" {...form.getInputProps("password")} />
      </Form.Field>

      <HStack gap="3">
        <Button type="submit" loading={form.isSubmitting}>
          Masuk
        </Button>
        <Button type="button" variant="outline" onClick={() => { form.reset(); setSubmitted(null) }}>
          Reset
        </Button>
      </HStack>

      {submitted && (
        <Text fontSize="sm" color="fg.muted">
          Submitted: {submitted.email}
        </Text>
      )}
    </Stack>
  )
}
```

## Props

### Input

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `name` * | `string` |  |  |
| `value` * | `V` |  |  |
| `onChange` * | `(e: { target: { value: V } }) => void` |  |  |
| `onBlur` * | `() => void` |  |  |
| `onValueChange` * | `(value: V) => void` |  |  |
| `__key` | `K` |  |  |

### Field

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `meta` * | `FieldMeta` |  |  |
| `label` | `ReactNode` |  |  |
| `helperText` | `ReactNode` |  |  |
| `required` | `boolean` |  |  |
| `children` * | `ReactNode` |  |  |

`*` = required. Style props and HTML attributes are accepted too.
