import { Meta, Props, Story, Preview } from '@storybook/addon-docs/blocks'
import { action } from "@storybook/addon-actions"
import MetaObjectFieldset from '@/metaform/fieldset/MetaObjectFieldset.vue'
import ContainerLayout from '@/layouts/ContainerLayout.vue'
import LinearLayout from '@/layouts/LinearLayout.vue'
import BaseButton from '@/elements/button/BaseButton.vue'

<Meta title="Extra: Patterns|Forms" />

# Forms

Forms allow for user input by mimicking paper forms where users fill in information into particular fields and submit it to the system.
Form elements should move in a single direction so they should only be distributed through one column when the progression of the form is vertical.

## Labels and descriptions

- Required fields shoud have a starting description like "This is required.";
- Fields that require a specific format (such as, writing a date in `DD/MM/YYYY`) should have the format description expressed in the description - **placeholders are usually discouraged**;

## Validation

- Validation should be checked only when button `save` is pressed,
- Errors are highlighted under the input that needs correction with copy that clearly states the error and the action to do in order to fix it

## Buttons and action

- Buttons shouldn't be disabled since validation should not disable actions,
- The cancel action should always be a link button at the bottom of the page under the primary action,
- Primary action (eg. `save`) is the first and secondary actions follow on the same line (eg. `draft`, `preview`, ecc...)

> These rules have been inspired by a couple of articles written by Adam Silver you can read here https://adamsilver.io/articles/form-design-from-zero-to-hero-all-in-one-blog-post/ and here https://adamsilver.io/articles/where-to-put-buttons-on-forms/

## Example

To test validation, clic save leaving all the fields empty then fill the mandatory ones and hit save again.

<Preview>
  <Story name="default">
    {{
      components: { MetaObjectFieldset, ContainerLayout, LinearLayout, BaseButton },
      data () {
        return {
          value: {
            name: '',
            birthDate: new Date(),
            birthPlace: ''
          },
          validation: {
            name: ''
          }
        }
      },
      computed: {
        template () {
          return [
            { 
              type: 'string',
              key: 'name',
              label: 'Name',
              description: 'This is required.',
              message: this.validation.name,
              error: this.validation.name !== ''
            },
            { 
              type: 'date',
              key: 'birthDate',
              label: 'Birth Date',
              description: 'Write a date as dd/mm/yyyy.'
            },
            { 
              type: 'string',
              key: 'birthPlace',
              label: 'Birth Place'
            }
          ]
        }
      },
      template:
        `<div style="border: 1px dashed black;">
          <container-layout>
            <meta-object-fieldset
              label="Example Object"
              :value="value"
              :template="template"
              @input="onInput" />
          </container-layout>
          <container-layout vspace="small">
            <linear-layout>
              <base-button type="primary" @click="onSave">Save</base-button>
              <base-button type="secondary">Other action</base-button>
            </linear-layout>
          </container-layout>
          <container-layout vspace="small">
            <base-button type="link">Cancel</base-button>
          </container-layout>
        </div>`,
      methods: {
        onInput ($event) {
          this.value = $event.value
        },
        onSave () {
          let valid = true
          
          if (this.value.name === '') {
            this.validation.name = 'This should not be empty.'
            valid = false
          } else {
            this.validation.name = ''
          }
          
          if (valid) {
            // save()
          }
        }
      }
    }}
  </Story>
</Preview>
