import { Meta } from '@storybook/addon-docs/blocks'

<Meta title="Components/KaForm/Info" />

# KaForm

This component renders an accessible and usable form element, which works only with Margarita's [form elements](https://holaluz.github.io/margarita/?path=/story/components-form-elements-textfield--text-field).

## Basic setup

This is a very basic form with a single required field with no validation:

```html
<ka-form @submit="onSubmit">
  <ka-form-field label="Name" v-model="name" />
  <ma-button type="submit">Submit</ma-button>
</ka-form>
```

## Usage

In order for a KaForm to work, we need 3 components:

- KaForm: is the parent that encapsulates the whole form. It requires at least one `KaFormField` and a `MaButton type="submit"` in order to work.
- KaFormField: are the inputs of the form. It's a wrapper of `MaOption`, `MaSelect` and `MaTextField` that handles the validation and error messages.
- MaButton: it's the submit button of the form. Needs to be `type="submit"` in order to be accessible.

#### Using KaFormField with input radio behaviour

When a `MaOption` with input radio behaviour be necessary using a `radioValue` prop specifing the value for that option would be required. Otherwise `KaFormField` group won't work until the prop will be added to the `KaFormField` component

## Validations

To validate fields, we should pass `validators` to `MaTextField`. A `validator` is a function that receives the input value as a parameter and returns an error message if the input has error.

We can pass the validators found in `KaForm/_validators` or custom validators, as long as they return `""` if the input is correct and an error message if not.

You can pass multiple validators. They will be checked in the order they are in the array until one fails.

Example of a correct validator:

```ts
function checkIsHello(value: string) {
  return value === 'hello' ? '' : 'error-is-not-hello'
}
```

Moreover, if you want to set a field as `required`, you should pass the prop `is-required` to `ka-form-field`, like so:

```html
<ka-form-field label="Name" v-model="name" is-required />
```

Another example of a field that is required and should be an email:

```html
// import { validators } from '@holaluz/kalimotxo'

<ka-form-field
  label="Email address"
  v-model="email"
  is-required
  :validators="[validators.checkEmail]"
/>
```

## Caveats

- `KaForm` will not work if it does not have `KaFormField` or `MaButton type="submit"` in it.
- `KaForm` does not handle the `loading` state of the `MaButton` in case submitting the form is async. You will have to store the `loading` state as data of the component that renders the `KaForm`.
- `KaForm` does not work with `veevalidate` or `vuelidate`.
- `KaForm` will not work correctly if you nest `KaForms` (if you render a `KaForm` inside another `KaForm`).

## Full example

```html
<template>
  <ka-form @submit="onSubmit">
    <ma-stack space="medium">
      <ka-form-field label="Full name" v-model="name" is-required />
      <ka-form-field
        label="Email address"
        v-model="email"
        is-required
        :validators="[validators.checkEmail]"
      />
      <ka-form-field
        label="Phone number"
        v-model="phone"
        :validators="[validators.checkPhoneNumber]"
      />
      <ka-form-field
        label="Write hello"
        v-model="hello"
        is-required
        :validators="[checkHello]"
      />
      <ka-form-field
        label="Option 1"
        v-model="option"
        :radio-value="Option1"
        id="some-input-radio"
        type="radio"
        is-required
      />
      <ka-form-field
        label="Option 2"
        v-model="option"
        :radio-value="Option2"
        id="some-input-radio"
        type="radio"
        is-required
      />
      <ma-button type="submit">Submit</ma-button>
    </ma-stack>
  </ka-form>
</template>

<script>
  import validators from '../ui/components/KaForm/_validators/validators'

  export default {
    data() {
      return {
        name: '',
        email: '',
        phone: '',
        option: '',
        isLoading: false,
      }
    },
    computed: {
      validators() {
        return validators
      },
    },
    methods: {
      checkHello(value: string) {
        value === 'hello ? '' : this.$t('error-no-hello')
      },
      async onSubmit() {
        this.isLoading = true
        await saveStuffSomewhere()
        this.isLoading = false
      },
    },
  }
</script>
```
