Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/bsabadach/fabform
build react typesafe form with custom validation api easily with typescript
https://github.com/bsabadach/fabform
context-api form-validation react store typescript
Last synced: about 2 months ago
JSON representation
build react typesafe form with custom validation api easily with typescript
- Host: GitHub
- URL: https://github.com/bsabadach/fabform
- Owner: bsabadach
- Created: 2019-03-11T10:37:50.000Z (almost 6 years ago)
- Default Branch: master
- Last Pushed: 2024-10-23T04:28:23.000Z (2 months ago)
- Last Synced: 2024-10-30T14:58:06.220Z (about 2 months ago)
- Topics: context-api, form-validation, react, store, typescript
- Language: TypeScript
- Homepage:
- Size: 319 KB
- Stars: 4
- Watchers: 2
- Forks: 0
- Open Issues: 36
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Fabform
## Motivation
## Installation
## Get started full simple example
```ts
export const AgeConstraint: ValueConstraint<'adult'> = {
name: 'adult',
check(val: FormValueType) {
return val >= 18
}
}
``````html
{
console.log(JSON.stringify(values))
}}>
validateOn='change'>
First name:
(
{isDirty && errors.required && This field is required}
)}
/>
Age:
{({ value, handleChange, errors, isDirty, config }) => (
{isDirty && errors.required && This field is required}
{isDirty && !errors.required && errors.number
&& This value is not a number}
{isDirty && (!errors.number && !errors.required) && errors.adult
&& This person is not of legal age}
)}
```## Usage
### prepare your data
the form must be populated with a flat objet with key of values pairs
1) create your data type:
```ts
export type PersonFormValues = {
firstname: string,
lastname: string,
age: number,
french: boolean,
}
```
- each key will be used to name any form field
- each value must be of the type ```FormValueType```2) create initial state
```ts
export const personFormValues: PersonFormValues = {
age: 35,
firstname: 'jean',
lastname: 'Dupont',
french: true,
}
```### Obtain contextualized components using factory method ```createFormComponent```
```ts
const {
Form,
TextField,
NumberField,
BooleanField,
SubmitAction,
... (other available components)
} = createFormComponents(personFormValues)
```### Build the form view
#### Form component:
```html/* add fields */
```| attribute | description| type | required |
|---|---|---|---|
| onSubmit | callback invoked when submitting form | ```(val:YourFormValuesType) =>void ``` | true |
| onReset | callback invoked when resting form | ```()=>void``` | false |
| onValueChanged | callback automatically invoked when a field value has changed | ```(event:ValueChangedEvent)=>void``` | false |
| validateOn | validation strategy for each field. When not provided all fields will checked before submitting the form| 'blur' or 'change' | false |### Fields common API
They all accept children as function with the same signature
ex:
```html{({ value, handleChange, config, errors, isDirty }) => (
)}
>
```#### Field Common API
| attribute | description | type | required |
|---|---|---|---|
| name | name of the field: must match one of the keys of your custom object | FormValueType | true |
| required | flags the field as required | boolean | false |
| constraint | extra custom constraints to apply on the field (see dedicated paragraph) | ```ValueConstraint or ValueConstraint[]``` | false |
| renderer | external component used to render child | FC:FieldRendererProps | false |#### ```TextField``` additional API
| attribute | description | type | required |
|---|---|---|---|
| pattern | a reg. exp. used as constraint| ```RegExp``` | false |#### Field children function common API
| parameter | description | type |
|---|---|---|
| value | the current value of the field| the type of the value with the same attribute name in the values type|
| handleChange | callback to change the value| ```(val:FormValueType) => void``` |
| config | object that holds input attributes declared on the parent Field| ```config:{type: FieldType, name: string}``` |
| errors | object that holds all generic errors and user derived from user defined constraints| ```FieldErrors``` |
| isDirty | flags indicating that the field value was updated at least once| ```boolean``` |### Other components
all components can be obtained by the ```createFormComponents``` factory return value#### ```FormValues```
provides a way to access to any value of the form anywhere in the form```html
{(values: YourFormValuesType) => (
)/>
```#### ```SubmitAction```
submit the form
```html{(submit) => submit form}
```
#### ```ResetAction```
reassign initial values to current form values and re-initialize form state
```html{reset => reset}
```
### constraint API
any number of custom constrains can be applied on TextField and NumberField as long as they are of the following type:
```ts
type ValueConstraint = {
name: N
check: (value: FormValueType) => boolean
}
```the name you provide will be used as a new key in the errors parameter.
for instance adding following constraint on a text field
```ts
export const NoNumberConstraint:ValueConstraint<'nonumber'>={
name:'nonumber',
check(val: FormValueType) {
return /^([^0-9]*)$/.test(val as string)
}
}
```
then, your IDE should suggest the name as a new key in the error parameter in addition to generic key errors names.![](docs/constraint-ide-suggestion.png)