@stackup/form
v0.3.7
Published
A type-safe approach to managing complex form state in React.
Downloads
4
Readme
A type-safe approach to managing complex form state in React.
This library provides integration with @stackup/validate to handle validation. However, it should be pretty easy to integrate whatever validation library you prefer.
You should also checkout @stackup/inputs, which includes some ready-made form fields.
Usage
import React from "react";
import { useForm, useField } from "@stackup/form";
const Form = () => {
const form = useForm({ initialValue: { email: "", name: "" } });
const validate = useValidation(form, value => {
if (value.email) {
return { valid: true, value };
} else {
return { valid: false, error: { email: "is required" } };
}
});
const submit = useSubmit(validate, value => {
console.log(value);
});
return (
<form onSubmit={submit}>
<Input type="email" label="Email" field={useField(form, "email")} />
<Input type="text" label="Name" field={useField(form, "name")} />
<button type="submit">Save</button>
</form>
);
};
const Input = ({
label,
field: { id, value, error, touched, setValue, setTouched },
...props
}) => (
<div>
<label htmlFor={id}>{label}</label>
<input
{...props}
id={id}
value={value}
onBlur={useCallback(() => setTouched(true), [])}
onChange={useCallback(e => setValue(e.target.value), [setValue])}
/>
{touched && error && <p>{error}</p>}
</div>
);
API
Table of Contents
- useForm
- useField
- useValidation
- useValidate
- useSubmit
- useReset
- useFieldItem
- usePushItem
- useInsertItem
- useRemoveItem
- useIdentifier
- Form
- FormField
- ValidateFn
- Submit
- Submission
- Reset
- UseFormOptions
- UseValidationOptions
useForm
Create a new form. A form requires an initial value, a function to validate, and a submit handler.
A form behaves just like any other field, but with some extra properties for managing submission.
The initial value for the form can be literally anything! Usually, it's an object, but it could be any type of value.
Parameters
options
UseFormOptions<Value>
Examples
Form values can be primitive
const form = useForm({ initialValue: "" });
But usually, they'll contain an object
const form = useForm({
initialValue: {
email: "",
name: ""
}
});
Returns Form<Value>
useField
Create a field for a given property.
Parameters
Examples
const form = useForm({
initialValue: {
email: "",
profile: { name: "" } }
}
});
const email = useField(form, "email");
const profile = useField(form, "profile");
const name = useField(profile, "name");
Returns FormField<any>
useValidation
Use a plain ol' function for validation.
This hook can also be used to incorporate your favorite validation library.
Parameters
form
Form<Value, Value>fn
ValidateFn<Value, Result>opts
UseValidationOptions (optional, default{}
)
Examples
const validation = useValidation(form, value => {
if (!value.email) {
return { valid: false, error: { email: "can't be blank" } };
}
return { valid: true, value };
});
Returns Form<Value, Result>
useValidate
Add validation to the form using @stackup/validate.
Parameters
form
Form<Value, Value>validator
Validator<(Value | any), Result>opts
UseValidationOptions?
Examples
const validator = schema({
email: assert(isString).then(refute(isBlank))
});
const validate = useValidate(form, validator);
Returns Form<Value, Result>
useSubmit
Create a submit handler for the form.
Parameters
form
Form<Value, Result>fn
SubmitFn<Result>opts
ValidateOptions (optional, default{touch:true}
)
Examples
Sumbitting a form
const form = useForm({ initialValue: "foo" });
const submit = useSubmit(form, console.log);
Sumbitting with validation
const form = useForm({ initialValue: "foo" });
const validate = useValidate(form, myValidator);
const submit = useSubmit(validate, console.log);
Returns Submit
useReset
Create a reset handler for the form.
Parameters
form
Form<Value, Result>
Examples
const form = useForm({ initialValue: "foo" });
const reset = useReset(form);
Returns Reset
useFieldItem
Create a field for a specific index in an array.
This hook is intended for use in building forms with "Add another" functionality.
Parameters
Examples
const form = useForm({ initialValue: { pets: [{ name: "" }] } });
const pets = useField(form, "pets");
const pet = useFieldItem(pets, 0);
const name = useField(pet, "name");
Returns FormField<Value>
usePushItem
Adds a new value to the end to an array of values.
This can be used to create a form with repeating fields.
Parameters
Examples
const pets = useField(form, "pets");
const pet = useFieldItem(pets, 0);
const addPet = usePushItem(pets, { name: "" });
useInsertItem
Adds a new value at a specific position to an array of values.
This can be used to create a form with repeating fields.
Parameters
Examples
const pets = useField(form, "pets");
const pet = useFieldItem(pets, 0);
const insert = useInsertItem(pets, 0, { name: "" });
useRemoveItem
Removes a value at the given index from array of values.
This can be used to create a form with repeating fields.
Parameters
Examples
const pets = useField(form, "pets");
const pet = useFieldItem(pets, 0);
const removePet = useRemoveItem(pets, 0);
useIdentifier
Creates a unique identifier that will remain consistent across re-renders.
This hook does not currently support SSR.
Parameters
id
string?
Returns string
Form
Extends FormField<Value>
The value returned by useForm
.
initialValue
The initial values for the form.
Type: Value
initialError
The initial errors on the fields.
Type: FormError<Value>
initialTouched
The initially touched fields.
Type: FormTouched<Value>
setValidating
Indicate that the form is validating
Type: SetState<boolean>
setSubmitting
Indicate that the form is validating
Type: SetState<boolean>
setSubmission
Update the form's submission status
Type: SetState<Submission>
reset
Reset the state of the form
Type: function (opts: ResetOptions<Value>): void
validate
Run validation
Type: function (opts: ValidateOptions): Promise<ValidationResult<Value, Result>>
FormField
The primary form data structure.
id
A unique ID for this form field. This can be used to associate fields with a label.
Type: string
name
The name or array index that was given to useField or useFieldItem.
value
The current value of the field.
Type: Value
error
An error or errors that are associated with this field or it's children.
Type: FormError<Value>
touched
Indicates that this field or it's children have been modified by the user.
Type: FormTouched<Value>
isValidating
Indicates that validation is currently being run
Type: boolean
isSubmitting
Indicates that the form is currently being submitted
Type: boolean
submission
Keeps track of the form's submission status
Type: Submission
setValue
Change the value. Just like with setState
, you can pass a callback
to this function to get the current value and update it.
Type: SetState<Value>
setError
Update the error.
Type: SetState<FormError<Value>>
setTouched
Indicate that this field has been touched. This is usually called in onBlur
.
Type: SetState<FormTouched<Value>>
ValidateFn
A function used for validation. This function must indicate whether or not the form is valid.
The error
property can be used to set errors on the form.
The value
property can be used to transform the form's values before
validation.
Type: function (value: Value): (ValidationResult<Value, Result> | PromiseLike<ValidationResult<Value, Result>>)
Submit
Submits the form.
Type: function (event: FormEvent<HTMLFormElement>): Promise<void>
Submission
Keeps track of submissions.
count
The number of times the form has been submitted
Type: number
error
If the submission flow throws an error, it will appear here.
Type: Error
Reset
Resets the form.
Type: function (event: FormEvent<HTMLFormElement>): Promise<void>
UseFormOptions
The options that can be passed to useForm.
id
Customize the base ID for all fields.
Type: string
initialValue
The initial values for the form.
Type: Value
initialError
The initial errors on the fields.
Type: FormError<Value>
initialTouched
The initially touched fields.
Type: FormTouched<Value>
UseValidationOptions
Configures when validation runs.
onChange
Enables validation whenever values change.
Type: boolean
onBlur
Enables validation whenever a field is touched.
Type: boolean