Easily create complex forms in React.
npm install @byteclaw/forms
#Β or using yarn
yarn add @byteclaw/forms
This library supports Yup validation library. In order to use it please install Yup because it isn't a part of this library.
react >= 16.8.3
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>;
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
- default is
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.
Michal KvasniΔΓ‘k π¬ π» π¨ π π‘ π€ π |
Juraj HrΓb π¬ π π» π π€ π |
---|
This project follows the all-contributors specification. Contributions of any kind welcome!
MIT License