react-any-shape-form v2.0.6
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
,useFieldError
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 | |
normalize | (value: Value) => any | Transform value before display it | |
getValueFromEvent | (...args: any[]) => Value | Get value from onChange cb | |
onChange | (value: Value, event?: unknown) => any | Triggers on field state changes | |
onInvalid | (error: 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 and renderError
for customize form error message.
CSS classes:
.form
- tag.
.form__form-item
- form item wrapper
.form__form-item__label
- form item 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.useFieldError
- get actual field validation errorsForm.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>
</>
)
}
9 days ago
9 days ago
10 days ago
10 days ago
9 days ago
9 days ago
7 days ago
10 days ago
10 days ago
10 days ago
10 days ago
9 days ago
9 days ago
9 days ago
9 days ago
9 days ago
9 days ago
9 days ago
9 days ago
9 days ago
9 days ago
15 days ago
15 days ago
21 days ago
21 days ago
1 month ago
1 month ago
2 months ago
2 months ago
2 months ago
4 months ago
4 months ago
5 months ago
5 months ago
5 months ago