0.0.27 • Published 3 years ago
@maxima/a-form v0.0.27
AForm
Build statically-typed forms using React and TypeScript based on form schemas.
How to install
yarn install a-formHow to use
For creating a form with a-form follow steps described below.
Define form schema
import { Input, InputArray, InputGroup } from 'a-form';
const aSchema = new InputGroup({
name: new Input<string>(), // <- string input
age: new Input<number>(), // <- number input
address: new InputGroup({ // <- nested inputs
city: new Input<string>(),
zip: new Input<number>()
}),
phoneNumbers: new InputArray(new Input<string>()), // <- array of string inputs
ids: new InputArray(new Input<number>()), // <- array of number inputs
guests: new InputArray( // <- array of nested inputs
new InputGroup({
name: new Input<string>(),
age: new Input<number>()
})
)
});You can also use helper functions for denining form schemas:
import { input, inputArray, inputGroup } from 'a-form';
const aSchema = inputGroup({
name: input<string>(), // <- string input
age: input<number>(), // <- number input
address: inputGroup({ // <- nested inputs
city: input<string>(),
zip: input<number>()
}),
phoneNumbers: inputArray(input<string>()), // <- array of string inputs
ids: inputArray(input<number>()), // <- array of number inputs
guests: inputArray( // <- array of nested inputs
inputGroup({
name: input<string>(),
age: input<number>()
})
)
});Using useForm React hook
import { useForm } from 'a-form';
const AForm: React.SFC<{}> = (props) => {
const validate = (values: typeof initialValues) => ({}); // form always valid
const submit = (values: typeof initialValues) => console.log(values);
const form = useForm({ aSchema, initialValues, validate, submit });
// use form to access properties for rendering form
return (
<form onSubmit={form.handleSubmit}>
{ // ... }
</form>
)
};Using Form component to render your form with render props
const AForm: React.SFC<{}> = (props) => {
const validate = (values: typeof initialValues) => ({}); // form always valid
const submit = (values: typeof initialValues) => console.log(values);
return (
<Form schema={aSchema} validate={validate} submit={submit} initialValues={}>
{
(formProps) =>
(
<form onSubmit={formProps.handleSubmit}>
<div>
<label htmlFor="input-name">Name</label>
<input id="input-name" {...formProps.name} />
{
formProps.name.touched && formProps.name.invalid &&
<span className="error">{formProps.name.error}</span>
}
</div>
<div>
<label htmlFor="input-age">Age</label>
<input id="input-age" {...formProps.age} />
{
formProps.age.touched && formProps.age.invalid &&
<span className="error">{formProps.age.error}</span>
}
</div>
<div>
<label htmlFor="input-address-city">City</label>
<input id="input-address-city" {...formProps.address.city} />
</div>
<div>
<label htmlFor="input-address-zip">Postal code</label>
<input id="input-address-zip" {...formProps.address.zip} />
</div>
{
formProps.phoneNumbers.items.map((phoneNumberProps, index) => {
<div>
<label htmlFor={`input-phone-number-${index}`}>Phone {index}</label>
<input id={`input-phone-number-${index}`} {...phoneNumberProps} />
<button type="button" onClick={() => formProps.phoneNumbers.remove(index)}>×</button>
</div>
})
}
<button type="button" onClick={() => formProps.phoneNumbers.push('')}>Add phone number</button>
<button type="submit">Submit form</button>
</form>
)
}
</Form>
);
}API
Form props / useForm hook config
schema: InputGroup- form schema, which defines available form inputs, for which later field-level props will be availablevalidate(values)- validation function which returns an object with validation errors for each field.submit(values)- function which handles data submissioninitialValues- values of the form, with which the form will be initialized
Form state
values: Values<T>- form valueserrors: Errors<T>- per-input validation errorsactive: Flags<T>- per-input active flags, indicating whether input is focused or nottouched: Flags<T>- per-input touched flags, indicating whether input is touched or notinvalid: boolean- indicates that form has validation errorsvalidating: boolean- indicates that form is currently running validationssubmitting: boolean- indicates that form is currently submittingsubmitted: boolean- indicates that the form was submittedsubmitResult: boolean | undefined- indicates whether the form submission was successfull or failederror: string | undefined- global form-level errordirty: boolean- global dirty flag, indicates that current form values are not deeply equal to initialValues
Form handlers
handleSubmit(event: React.FormEvent): void;- form submit handler, which internally marks all fields as touched, validates and submits form valuesreset(): void;- reset form values to form's initialValuessetValues(values: Values<T>): void;- set form valuessetErrors(errors: Errors<T>): void;- set form errors
Input props
value: T- field valuename: string- field nameerror: string | undefined- validation erroractive: boolean- active flag (indicates that field is currently focused)touched: boolean- touched flag (indicates that field is touched)dirty: boolean- field value was changed and is different from value, specified ininitialValuesprop of the form componentinvalid: boolean- field has validation errorsonBlur(event: React.FocusEvent<HTMLElement>): void- blur event handleronChange(eventOrValue: React.ChangeEvent<HTMLInputElement> | T): void- change event handleronFocus(event: React.FocusEvent<HTMLElement>): void- focus event handler
InputArray props
items: array of field props for each value in the listtouched: booleanpop(): void- remove last value from the listpush(value: T): void- add value specified as agrument to the end of the listshift(): void- remove first value from the listunshift(value: T): void- add value specified as agrument to the beginning of the listinsert(index: number, value: T): void- insert value specified as agrument at a given index into the listreplace(index: number, value: T): void- replace value by existing index with a new valueremove(index: number): void- remove value from the list at index specified as an argumentmove(from: number, to: number): void- move value from one index to anotherswap(indexA: number, indexB: number): void- swap positions of two values in the list, specified by arguments
InputGroup props
touched: booleanchange(values: T)- change form group values
For each of the input defined in particular input group, it's props are available by the name of the input.
Example:
const groupSchema = new InputGroup({
name: new Input<string>(),
tags: new InputArray(Input<string>)
});
// ...
// usage later in form component
formProps.name // <= Input props for name input
formProps.tags // <= InputArray props for tags inputLicence
GPLv3
Copyright hck, 2019
0.0.26
3 years ago
0.0.27
3 years ago
0.0.25
4 years ago
0.0.24
5 years ago
0.0.23
5 years ago
0.0.22
5 years ago
0.0.21
5 years ago
0.0.20
5 years ago
0.0.19
5 years ago
0.0.18
5 years ago
0.0.17
5 years ago
0.0.16
5 years ago
0.0.15
5 years ago
0.0.14
5 years ago
0.0.13
5 years ago
0.0.12
5 years ago
0.0.10
5 years ago
0.0.9
6 years ago
0.0.8
6 years ago
0.0.7
6 years ago
0.0.6
6 years ago
0.0.5
6 years ago
0.0.4
6 years ago
0.0.3
6 years ago
0.0.2
6 years ago
0.0.1
6 years ago