react-any-shape-form
v2.1.2
Published
Small, type-friendly and flexible react form component.
Downloads
37
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
createForm
method 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
,useFieldErrors
hooks- 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-form
Use 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>
</>
)
}