Skip to content

Byteclaw/forms

Repository files navigation

@byteclaw/forms

CircleCI All Contributors Version License

Easily create complex forms in React.

Installation

npm install @byteclaw/forms

#Β or using yarn

yarn add @byteclaw/forms

Yup compatibility

This library supports Yup validation library. In order to use it please install Yup because it isn't a part of this library.

Requirements

  • react >= 16.8.3

Up and running example

import { Fragment } from 'react';
import {
  ArrayField,
  Field,
  Form,
  FormProvider,
  ObjectField,
  createValidatorFromYup,
} from '@byteclaw/forms';
import * as yup from 'yup';

const validator = createValidatorFromYup(
  yup.object().shape({
    productTitle: yup.string().required(),
    images: yup
      .array()
      .of(
        yup.object().shape({
          title: yup.string().required(),
          url: yup
            .string()
            .url()
            .required(),
        }),
      )
      .required(),
    attributes: yup.object().shape({
      color: yup
        .string()
        .matches(/^#[0-9a-fA-F]{6}$/)
        .required(),
    }),
  }),
);

<Form onSubmit={async values => {}} onValidate={validator}>
  {/* global error of form */}
  <FieldError>{({ error }) => error || null}</FieldError>
  <Field name="productTitle" />
  <FieldError name="productTitle">{({ error }) => error || null}</FieldError>
  <ArrayField name="images">
    {({ value }, dispatch) => (
      <Fragment>
        {/* value can be undefined/null if is not initialized */}
        {(value || []).map((val, i) => (
          <ObjectField name={i}>
            <Field name="url" type="url" />
            <FieldError name="url">{({ error }) => error || null}</FieldError>
            <Field name="title" />
            <FieldError name="title">{({ error }) => error || null}</FieldError>
            <button onClick={() => removeItem(i)} type="button">
              Remove
            </button>
          </ObjectField>
        ))}
        <button onClick={() => dispatch({ type: 'CHANGE', value: [...value, {}] })} type="button">
          Add image
        </button>
      </Fragment>
    )}
  </ArrayField>
  <FieldError name="images">{({ error }) => error || null}</FieldError>
  <ObjectField name="attributes">
    <Field name="color" />
    <FieldError name="color">{({ error }) => error || null}</FieldError>
  </ObjectField>
  <FieldError name="attributes">{({ error }) => error || null}</FieldError>
  <FormProvider>
    {form => (
      <button disabled={form.status !== 'IDLE'} type="submit">
        Save
      </button>
    )}
  </FormProvider>
</Form>;

API

Form component is a root component necessary to use Forms at all. It provides a context for all fields in a given form.

Form accepts onValidate, onSubmit and validateOnChange props along with standard attributes accepted by <form />.

  • onValidate<TValues>(values?: TValues): Promise<TValues | void>
    • optional validation function
    • in case of an error please throw ValidationError provided by this library
  • onSubmit<TValues>(values: TValues): Promise<void>
    • optional submit function
    • it can validate form too, in case of an error throw ValidationError provided by this library
  • onChange<TValues>(values: TValues): Promise<void>
    • optional on change function
  • validateOnChange
    • default is false
    • optional
    • will validate form on change

FormProvider is a way to connect to FormState when you need to react on something.

  • children: (state: FormState) => any

Field is a base component to construct simple widgets using <input /> elements. On change is debounced.

FieldError is a base component if you want to render validation errors that are connected with a specific field or a form root.

To connect to a root of ObjectField/ArrayField/Form use it like this:

<FieldError name="">{err => JSON.stringify(err, null, ' ')}<FieldError>

Or specify name as a name that was used by Field component.

ArrayField is a base component to construct complex fields for array values.

ObjectField is a base component to construct nested objects in your form.

ValidationError is a way how to map errors to fields in your form.

Examples

Contributors


Michal KvasničÑk

πŸ’¬ πŸ’» 🎨 πŸ“– πŸ’‘ πŸ€” πŸ‘€ ⚠️

Juraj HrΓ­b

πŸ’¬ πŸ› πŸ’» πŸ“– πŸ€” πŸ‘€

This project follows the all-contributors specification. Contributions of any kind welcome!

License

MIT License