# Getting started

_Creating a form and fields with `Fielder`._

## Creating a form

Every form starts in the same way - a root "form" component to:

- Create an instance of `Fielder`
- Expose that instance to any child components

```tsx
import React, { useEffect } from 'react';
import { useForm, FielderProvider } from 'fielder';

const LoginForm = ({ children }) => {
  const formState = useForm();

  // Example of reacting to form changes
  useEffect(() => {
    console.log('Form state has changed!', formState);
  }, [formState]);

  return <FielderProvider value={formState}>{children}</FielderProvider>;
};
```

The use of `FielderProvider` ensures that the hooks we use later can access the form state.

> Forms can be a static section on a page, or a dynamic collection of pages (i.e. steppers/wizards/multi-step).

## Adding some fields

Next we want to add some fields to our form.

> It's important to remember that fielder treats fields as dynamic entities. This means they can be added, removed, and/or changed at any time.

```tsx
const MyFormContent = () => {
  const [usernameProps] = useField({
    name: 'username',
    initialValue: '',
  });
  const [passwordProps] = useField({
    name: 'password',
    initialValue: '',
  });

  return (
    <form>
      <input type="text" {...usernameProps} />
      <input type="password" {...passwordProps} />
    </form>
  );
};
```

## Checkbox & Radio inputs

Checkbox and radio inputs are different to all other field types as their state is declared by the `checked`
attribute rather than `value` ([more info here](https://github.com/andyrichardson/fielder/issues/23#issuecomment-576352847)).

### Radio buttons

Using radio buttons is similar to using text fields, with two exceptions:

- The `value` attribute is static
- The `checked` attribute needs to be added (see below)

```tsx
const [hobbiesProps] = useField({
  name: 'hobbies',
  initialValue: 'sports',
});

const radioButtons = useMemo(() => [
  { label: "Sports", value: "sports" },
  { label: "Coding", value: "coding" },
  { label: "Other", value: "other" },
], []);

return (
  <>
    <p>What is your favorite hobby?</p>
    {radioButtons.map(({ label, value }) => (
      <input
        key={value}
        type="radio"
        {...hobbiesProps}
        value={value}
        checked={hobbiesProps.value === value}
      />
      {label}
    ))}
  </>
)
```

### Checkbox groups

Checkbox groups are a means for storing multiple checkbox selections in a single field.

These are almost identical to radio buttons - the only difference being their value is an array corresponding to the selected values.

```tsx
const [hobbiesProps] = useField({
  name: 'hobbies',
  initialValue: ['sports'],
});

const checkboxOptions = useMemo(() => [
  { label: "Sports", value: "sports" },
  { label: "Coding", value: "coding" },
  { label: "Other", value: "other" },
], []);

return (
  <>
    <p>What are your hobbies?</p>
    {checkboxOptions.map(({ label, value }) => (
      <input
        key={value}
        type="checkbox"
        {...hobbiesProps}
        value={value}
        checked={hobbiesProps.value.includes(value)}
      />
      {label}
    ))}
  </>
)
```

### Checkboxes (individual)

If you prefer to have a field for each checkbox, that's also an option.

Be sure to set the initial value of the field to boolean.

```tsx
const [acceptProps] = useField({
  name: 'accept',
  initialValue: false,
});

return (
  <>
    <p>Do you accept these terms?</p>
    <input type="checkbox" {...acceptProps} checked={acceptProps.value} />
  </>
);
```
