react-any-shape-form
v2.1.5
Published
Small, type-friendly and flexible react form component.
Maintainers
Readme
React any shape form
Lightweight form library focused on ease of use. This library was inspired by antd form component and react-hook-form.
Features
- Small size
- Type-friendly, all components and hooks fully typed
- Ease to use, you need only
createFormmethod to get all the functionality - Build in promise based validation, you can easy use your own promise function to validate fields
- No extra re-renders
useWatch,useField,useArrayField,useFieldErrorshooks- Access to form state in any place of application, even outside of form component
Docs and examples - https://react-any-shape-form.vercel.app/
Get started
Install:
npm i react-any-shape-formUse it like this:
import { createForm } from 'react-any-shape-form';
const MyForm = createForm({
name: 'Rina',
age: 24,
})
const MyComponent = () =>
<MyForm onFinish={(state) => {
alert(JSON.stringify(state, undefined, 2));
}}>
<MyForm.Item
name="name"
label="Name"
onChange={value => value}
rules={[
{
required: true,
message: 'Name is required',
validateTrigger: ['onFinish']
},
]}
>
{({ value, onChange }) =>
<input value={value} onChange={e => onChange(e.target.value)} />
}
</MyForm.Item>
<MyForm.Item name="age">
{({ value, onChange }) =>
<input type="number" value={value} onChange={(e) => onChange(+e.target.value)} />
}
</MyForm.Item>
<button type="submit">
Submit button
</button>
</MyForm>You can find more examples in docs
Form props
| Field | Type | Description | Default |
|--------------|-------------|-------------------------|-------------|
| initialState | Object | Predefined fields value | {} |
| CSSPrefix | string | Prefix for css classes | 'form' |
| id | string | html form id | undefined |
| children | ReactNode | | |
Form.Item props
| Field | Type | Description | Default |
|-------------------|-------------------------------------------------------|---------------------------------------------------|---------|
| children | FC or ReactElement | Function/component with value, onChange props | {} |
| label | ReactNode | Field label | |
| rules | ValidationRule[] | Validation rule | |
| onChange | (value: Value, event?: unknown) => any | Triggers on field state changes | |
| onInvalid | (errors: ValidationError[], value: Value) => void | Triggers on validation error | |
| renderLabel | (value: Value, formItemId?: string) => ReactElement | Customize label | |
| renderError | (error: ValidationError<Value>) => ReactElement | Customize error | |
Styling
No CSS by default. You need to style form by you own.
You can change classes prefix (.form by default) using CSSPrefix property.
You can use renderLabel to customize <label> and renderError for customize form error message.
CSS classes:
.form - <form> tag class.
.form__form-item - form item wrapper
.form__form-item__label - form item label (<label> tag)
.form__form-item__error - form item error
Look at ./storybook/styles.css as example.
Validation
You can pass array of validation rules to Form.Item.
Don't forget to set error message or return Promise.reject('your-error-message').
You can control validation trigger using validationTrigger:
["onChange"] - trigger fires if value changed (debounced by 300ms)
["onFinish"] - trigger fires only after form submit
[
{
// throw an error if field value is undefined
required: true,
message: "Age is required",
},
{
// if value < 18
min: 18,
type: "number",
message: "some message",
},
{
// if String().length > 100
max: 100,
type: "string",
message: "some error",
},
{
// if myPattern.test() === false
type: "regexp",
pattern: myPattern,
},
{
// If value is not an email address
type: "email",
},
{
// if myValidator function throw an error or return Promise.reject
validator: myValidator,
message: "some error",
},
];Hooks
Form.useWatch- get actual field value
const MyForm = createForm({
name: 'Rina',
age: 24,
})
const SomeComponent = () => {
const name = MyForm.useWatch('name');
...
}Form.useField- get control over field state
const [name, setName] = MyForm.useField('name');Form.useFieldErrors- get actual field validation errors and validation status
const { errors, status } = MyForm.useFieldErrors('name');Form.useArrayField- get control over array field
const MyForm = createForm({
userIds: [] as string[]
})
const SomeComponent = () => {
const { fields, append, delete } = MyForm.useArrayField('userIds');
return (
<>
{fields.map((field, index) =>
<div key={index}>
<input value={field} onChange={e => update(index, e.target.value)} />
<button type="button" onClick={() => remove(index)}>Remove</button>
</div>
)}
<button type="button" onClick={() => append("")}>
Add
</button>
</>
)
}