@matthew.ngo/reform
Version:
A flexible and powerful React form management library with advanced validation, state observation, and multi-group support
273 lines (212 loc) • 8.62 kB
Markdown
# Reform Form Management
Reform provides a comprehensive form management system that helps you create, manage, and validate complex forms with multiple groups. This document covers the form management capabilities of Reform.
## Table of Contents
- [Overview](#overview)
- [Form Groups](#form-groups)
- [Field Management](#field-management)
- [Form State](#form-state)
- [Form Reset](#form-reset)
- [Form Controller](#form-controller)
- [API Reference](#api-reference)
## Overview
Reform's form management system is built around the concept of form groups, which allow you to organize related data together. The core functionality includes:
1. **Form Groups**: Create, update, and manage collections of related data
2. **Field Management**: Register and control form fields with type safety
3. **Form State**: Track and manage form state (dirty, touched, valid, etc.)
4. **Form Reset**: Reset the entire form or specific groups
5. **Form Controller**: Controlled components integration
## Form Groups
Form groups are the fundamental building blocks of Reform forms. Each group contains related data and has a unique identifier.
### Basic Usage
```tsx
import { useReform } from '@reform/core';
type UserForm = {
name: string;
email: string;
};
const MyForm = () => {
const form = useReform<UserForm>({
defaultData: { name: '', email: '' },
minGroups: 1,
maxGroups: 5,
});
// Add a new group
const handleAddGroup = () => {
form.addGroup();
};
// Remove a group
const handleRemoveGroup = (index: number) => {
form.removeGroup(index);
};
return (
<div>
{form.getGroups().map((group, index) => (
<div key={group.id}>
<input {...form.register(index, 'name')} placeholder="Name" />
<input {...form.register(index, 'email')} placeholder="Email" />
<button onClick={() => handleRemoveGroup(index)}>Remove</button>
</div>
))}
<button onClick={handleAddGroup}>Add Group</button>
</div>
);
};
```
### Batch Operations
Reform supports batch operations for efficiently managing multiple groups:
```tsx
// Update multiple groups at once
form.batchUpdate([0, 2, 4], (data) => ({
status: 'active',
lastUpdated: new Date(),
}));
// Remove multiple groups
form.batchRemove([1, 3]);
```
## Field Management
Reform provides type-safe field registration and management:
```tsx
// Register a field with React Hook Form
<input {...form.register(0, 'email')} />
// Set a field value programmatically
form.setValue(0, 'email', 'user@example.com');
// Get a field value
const email = form.getFieldValue(0, 'email');
```
## Form State
Track and manage form state:
```tsx
// Check if a field is dirty
const isDirty = form.fieldState.isDirty(0, 'email');
// Check if a field is touched
const isTouched = form.fieldState.isTouched(0, 'email');
// Get complete field state
const fieldState = form.fieldState.get(0, 'email');
// Check form-wide state
const isFormDirty = form.formState.isDirty;
const isFormValid = form.formState.isValid;
const isSubmitting = form.formState.isSubmitting;
```
## Form Reset
Reset the form to its initial state or to specific values:
```tsx
// Reset the entire form to initial values
form.resetForm();
// Reset with new default values
form.resetForm({
groups: [
{
id: 'new-id-1',
data: { name: 'New Name', email: 'new@example.com' },
},
],
});
// Reset but keep dirty state
form.resetForm(undefined, { keepDirty: true });
// Reset to a clean state with specific number of groups
form.resetToCleanState(3);
// Reset a specific group
form.resetGroup(0);
```
## Form Controller
For more complex form controls, use the `ReformController` component:
```tsx
import { ReformController } from '@reform/core';
const MyForm = () => {
const form = useReform<UserForm>(config);
return (
<div>
<ReformController
index={0}
field="email"
control={form.formMethods.control}
rules={{ required: 'Email is required' }}
render={({ field, fieldState }) => (
<div>
<input
{...field}
placeholder="Email"
className={fieldState.error ? 'error' : ''}
/>
{fieldState.error && <p>{fieldState.error.message}</p>}
</div>
)}
/>
</div>
);
};
```
## API Reference
### useReform
```typescript
function useReform<T extends Record<string, any>>(
config: DynamicFormConfig<T>
): ReformReturn<T>
```
#### Configuration Options
| Option | Type | Default | Description |
| ----------- | --------------------------------------- | ----------- | ------------------------------------- |
| value | `FormGroup<T>[]` | `[]` | Initial form groups |
| minGroups | `number` | `1` | Minimum number of groups |
| maxGroups | `number` | `Infinity` | Maximum number of groups |
| defaultData | `T` | `{}` | Default data for new groups |
| onChange | `(groups: FormGroup<T>[]) => void` | `undefined` | Callback when form changes |
| schema | `ObjectSchema<T>` | `undefined` | Yup schema for validation |
| labels | `Record<string, string>` | `{}` | Field labels for error messages |
### Form Group Management
| Method | Description |
| ------------- | --------------------------------------------- |
| getGroups | Get all form groups |
| setGroups | Set all form groups |
| addGroup | Add a new group |
| removeGroup | Remove a group at the specified index |
| moveGroup | Move a group from one index to another |
| duplicateGroup| Create a copy of an existing group |
| batchUpdate | Update multiple groups at once |
| batchRemove | Remove multiple groups at once |
### Field Management
| Method | Description |
| ------------ | --------------------------------------------- |
| register | Register a field with React Hook Form |
| setValue | Set a field value |
| getFieldValue| Get a field value |
### Form State
| Property/Method | Description |
| --------------- | --------------------------------------------- |
| fieldState | Object with methods to check field state |
| formState | Object with form-wide state properties |
### Form Reset
| Method | Description |
| ---------------- | --------------------------------------------- |
| resetForm | Reset the form to initial or provided values |
| resetToCleanState| Reset to a clean state with n groups |
| resetGroup | Reset a specific group to default values |
### ReformController
```typescript
function ReformController<TFieldValues>({
index,
field,
control,
render,
rules,
defaultValue,
shouldUnregister,
}: ReformControllerProps<TFieldValues>): JSX.Element
```
#### Props
| Prop | Type | Description |
| --------------- | ---------------------------------------------------- | ------------------------------------- |
| index | `number` | Group index |
| field | `string` | Field name |
| control | `Control<TFieldValues>` | Form control from useForm |
| render | `(props: { field, fieldState, formState }) => JSX.Element` | Render function for the field |
| rules | `object` | Validation rules |
| defaultValue | `any` | Default value for the field |
| shouldUnregister| `boolean` | Whether to unregister on unmount |
### FormGroup Type
```typescript
interface FormGroup<T = any> {
id: string;
data: T;
}
```