@matthew.ngo/reform
Version:
A flexible and powerful React form management library with advanced validation, state observation, and multi-group support
363 lines (255 loc) • 9.22 kB
Markdown
# Reform API Reference
This document provides detailed documentation for all Reform APIs, organized by functionality.
## useReform Hook
The main hook for creating and managing Reform forms.
### Signature
```typescript
function useReform<T extends Record<string, any>>(
config: DynamicFormConfig<T>
): ReformReturn<T>
```
### Parameters
| Parameter | Type | Description |
|-----------|------|-------------|
| config | `DynamicFormConfig<T>` | Configuration object for the form |
### Configuration Options
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| value | `FormGroup<T>[]` | `[]` | Initial form groups |
| minGroups | `number` | `0` | Minimum number of groups |
| maxGroups | `number` | `Infinity` | Maximum number of groups |
| defaultData | `Partial<T>` | `{}` | Default data for new groups |
| fields | `{ [K in keyof T]: FieldConfig<T, K> }` | `{}` | Field configuration |
| onChange | `(groups: FormGroup<T>[]) => void` | `undefined` | Callback when form changes |
| groupSchema | `ObjectSchema<T>` | `undefined` | Yup schema for group validation |
| groupsSchema | `ArraySchema<T>` | `undefined` | Yup schema for validating all groups |
| yupConfig | `Partial<YupSchemaConfig<T>>` | `{}` | Configuration for Yup integration |
### Return Value
The `useReform` hook returns a `ReformReturn<T>` object with the following properties and methods:
## Form Group Management
Methods for managing form groups:
### getGroups
```typescript
getGroups(): FormGroup<T>[]
```
Returns all form groups.
### getGroupData
```typescript
getGroupData(index: number): T | undefined
```
Returns the data for a specific group.
### addGroup
```typescript
addGroup(data?: Partial<T>): void
```
Adds a new group with optional initial data.
### removeGroup
```typescript
removeGroup(index: number): void
```
Removes a group at the specified index.
### updateGroup
```typescript
updateGroup(index: number, data: Partial<T>): void
```
Updates a group's data at the specified index.
### batchUpdate
```typescript
batchUpdate(updates: Array<{ index: number; data: Partial<T> }>): void
```
Updates multiple groups at once.
### batchRemove
```typescript
batchRemove(indices: number[]): void
```
Removes multiple groups at once.
### resetForm
```typescript
resetForm(defaultValues?: Partial<{ groups: FormGroup<T>[] }>): void
```
Resets the form to its initial state or to provided default values.
## Field Management
Methods for managing form fields:
### register
```typescript
register(index: number, field: FieldPath<T>, options?: RegisterOptions): UseFormRegisterReturn
```
Registers a field with React Hook Form and returns props for the input element.
### setValue
```typescript
setValue(index: number, field: FieldPath<T>, value: any, options?: SetValueOptions): void
```
Sets the value of a field.
### getFieldValue
```typescript
getFieldValue(index: number, field: FieldPath<T>): any
```
Gets the value of a field.
## Field Arrays
Methods for managing arrays within form groups:
### arrayFields
```typescript
arrayFields: {
append(index: number, field: FieldPath<T>, value: any): void;
remove(index: number, field: FieldPath<T>, arrayIndex: number): void;
move(index: number, field: FieldPath<T>, from: number, to: number): void;
swap(index: number, field: FieldPath<T>, indexA: number, indexB: number): void;
insert(index: number, field: FieldPath<T>, arrayIndex: number, value: any): void;
update(index: number, field: FieldPath<T>, arrayIndex: number, value: any): void;
replace(index: number, field: FieldPath<T>, values: any[]): void;
}
```
Methods for manipulating array fields within a group.
## Conditional Fields
Methods for conditional field rendering and validation:
### when
```typescript
when(condition: (data: T, index: number) => boolean): {
render(component: React.ReactNode): React.ReactNode;
}
```
Conditionally renders a component based on form data.
## Error Handling
Methods for handling form errors:
### getFieldError
```typescript
getFieldError(index: number, field: FieldPath<T>): string | undefined
```
Gets the error message for a specific field.
### getGroupErrors
```typescript
getGroupErrors(index: number): Record<string, string>
```
Gets all errors for a specific group.
### hasErrors
```typescript
hasErrors(): boolean
```
Checks if the form has any errors.
### clearErrors
```typescript
clearErrors(index?: number, field?: FieldPath<T>): void
```
Clears errors for a specific field, group, or the entire form.
## Validation
Methods for form validation:
### validate
```typescript
validate(index?: number): boolean
```
Validates a specific group or the entire form.
### yup
The form includes Yup integration utilities:
```typescript
yup: {
createEnhancedSchema(baseSchema: ObjectSchema<T>, config?: any): ObjectSchema<T>;
validateWithContext(data: T, groupIndex: number, fieldPath?: string): Promise<{ value: T | null; error: any }>;
updateContextData(data: Record<string, any>): void;
validateAllGroups(): Promise<Array<{ value: T | null; error: any }>>;
// Additional methods from YupContextReturn and YupTransformersReturn
}
```
## Form State
Methods for managing form state:
### isDirty
```typescript
isDirty(): boolean
```
Checks if the form has been modified.
### isSubmitting
```typescript
isSubmitting(): boolean
```
Checks if the form is currently submitting.
### isValid
```typescript
isValid(): boolean
```
Checks if the form is valid.
### formMethods
Access to the underlying React Hook Form methods:
```typescript
formMethods: UseFormReturn<{ groups: FormGroup<T>[] }>
```
## Form Persistence
Reform provides form persistence capabilities through the `useReformPersistence` hook:
```typescript
function useReformPersistence<T extends Record<string, any>>(
reform: ReformReturn<T>,
config: FormPersistenceConfig<T> = {}
): {
saveState(): void;
restoreState(): void;
clearState(): void;
isRestored: boolean;
lastSaved: Date | null;
}
```
### Configuration Options
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| enabled | `boolean` | `false` | Enable/disable persistence |
| storageKey | `string` | `"reform-form-state"` | Key for storing form state |
| storageProvider | `StorageProvider` | `localStorage` | Storage provider |
| autoSave | `boolean` | `false` | Enable auto-saving |
| autoSaveInterval | `number` | `5000` | Auto-save interval in ms |
| debounceAutoSave | `boolean` | `true` | Debounce auto-save |
| debounceDelay | `number` | `500` | Debounce delay in ms |
| onBeforeSave | `(state: any) => any` | `undefined` | Hook before saving |
| onAfterSave | `(state: any) => void` | `undefined` | Hook after saving |
| onAfterRestore | `(state: any) => void` | `undefined` | Hook after restoring |
| metadata | `Record<string, any> \| () => Record<string, any>` | `undefined` | Additional metadata |
## Form Watcher
Reform provides form watching capabilities through the `useReformWatcher` hook:
```typescript
function useReformWatcher<T extends Record<string, any>>(
reform: ReformReturn<T>,
options: FormStateObserverOptions<T> = {}
): {
watchField(config: FieldWatchConfig<T>): () => void;
watchFields(configs: FieldWatchConfig<T>[]): () => void;
getFieldValue(groupIndex: number, field: keyof T): any;
triggerFieldWatch(groupIndex: number, field: keyof T): void;
subscribeToState(handler: FormStateChangeHandler<T>): { unsubscribe: () => void };
getFormState(): FormState;
getPreviousState(): FormState | null;
isDirty(): boolean;
hasErrors(): boolean;
isSubmitting(): boolean;
isValid(): boolean;
watchFieldWithState(config: FieldWatchConfig<T>, stateHandler?: FormStateChangeHandler<T>): () => void;
watchFieldWhenValid(config: FieldWatchConfig<T>): () => void;
watchFieldErrors(field: keyof T, callback: (hasError: boolean, errorMessage: string | null) => void): { unsubscribe: () => void };
createAutoSave(saveFunction: () => void | Promise<void>, debounceMs?: number): {
stop(): void;
start(): void;
trigger(): void;
unsubscribe: () => void;
};
}
```
## Error Renderers
Reform provides custom error rendering through the `useReformErrorRenderer` hook:
```typescript
function useReformErrorRenderer<T extends Record<string, any>>(
reform: ReformReturn<T>
): {
registerErrorRenderer(config: ErrorRendererConfig<T>): () => void;
renderError(field: FieldPath<T>, error: string | null, groupIndex?: number): React.ReactNode;
renderFieldError(groupIndex: number, field: FieldPath<T>): React.ReactNode;
renderGroupErrors(groupIndex: number): React.ReactNode[];
}
```
## Dynamic Validation
Reform provides dynamic validation through the `useDynamicValidation` hook:
```typescript
function useDynamicValidation<T extends Record<string, any>>(
reform: ReformReturn<T>,
config: DynamicSchemaConfig<T>
): {
validateField(groupIndex: number, field: FieldPath<T>, value: any): ValidationRuleResult;
validateGroup(groupIndex: number): boolean;
getFieldRules(groupIndex: number, field: FieldPath<T>): DynamicValidationRule<T>[];
updateContext(newContextData: Record<string, any>): void;
}
```