UNPKG

fielder

Version:

A field-first form library for React and React Native

138 lines (121 loc) 4.21 kB
import { SetFieldValueArgs } from './actions/setFieldValue'; import { ValidateFieldArgs } from './actions/validateField'; import { MountFieldArgs } from './actions/mountField'; import { BlurFieldArgs } from './actions/blurField'; import { UnmountFieldArgs } from './actions/unmountField'; import { SetFieldStateArgs } from './actions/setFieldState'; import { SetFieldValidationArgs } from './actions/setFieldValidation'; export type FormValue = string | boolean | number | string[]; export type FormSchemaType = Record<string, FormValue>; export type FieldsState<T extends FormSchemaType = FormSchemaType> = { [K in keyof T]: FieldState<T, K>; }; export interface FormState<T extends FormSchemaType = FormSchemaType> { fields: FieldsState<T>; /** All mounted fields are valid. */ isValid: boolean; /** Async validation currently active on a mounted fields. */ isValidating: boolean; /** Set value for a field. */ setFieldValue: <K extends keyof T>(a: SetFieldValueArgs<T, K>) => void; /** Trigger blur event for a mounted field. */ blurField: (a: BlurFieldArgs<T>) => void; /** Force trigger validation on a mounted field. */ validateField: (a: ValidateFieldArgs<T>) => void; /** Internal: Premount field during render */ premountField: <K extends keyof T & string>( a: MountFieldArgs<T, K> ) => FieldState<T, K>; /** Internal: Manually mount field. */ mountField: <K extends keyof T & string>( a: MountFieldArgs<T, K> ) => FieldState<T, K>; /** Internal: Manually unmount field. */ unmountField: (a: UnmountFieldArgs<T>) => void; /** Internal: Manually set field state. */ setFieldState: <K extends keyof T>(a: SetFieldStateArgs<T, K>) => void; /** Internal: Set new field validation function */ setFieldValidation: <K extends keyof T>( a: SetFieldValidationArgs<T, K> ) => void; /** Trigger submission validation. * * Throws on synchronous validation errors. * Returns promise if form contains async validation. */ validateSubmission: () => MaybePromise<{ state: FieldsState; errors: Record<string, string>; }>; } export interface FieldState< T extends FormSchemaType | FormValue = FormValue, K extends keyof T = any, // Resolve value and schema form generics V extends FormValue = T extends FormSchemaType ? T[K] : T, S extends FormSchemaType = T extends FormSchemaType ? T : FormSchemaType > { /** The field is currently mounted. */ readonly _isActive: boolean; /** Validation function. */ readonly _validate?: ValidationFn<V, S> | ObjectValidation<V, S>; // Props /** Field name */ readonly name: K; /** Field value */ readonly value: V; // Meta /** Field error */ readonly error?: string; /** Field is currently valid. */ readonly isValid: boolean; /** Field is currently being validated (async). */ readonly isValidating: boolean; /** Field has been blurred since mount. */ readonly hasBlurred: boolean; /** Field has been changed since mount. */ readonly hasChanged: boolean; } /** * Events which trigger validation * * `mount`: Field has been mounted. * * `blur`: Field has had 'onBlur' event. * * `change`: Field has had 'onChange' event. * * `update`: The value of another field in the form has changed. * * `submit`: Submission has begun. */ export type ValidationTrigger = | 'mount' | 'blur' | 'change' | 'update' | 'submit'; /** Arguments passed to a validation function */ export type ValidationArgs< T extends FormValue = FormValue, S extends FormSchemaType = FormSchemaType > = { trigger: ValidationTrigger; value: T; form: FieldsState<S>; }; /** Handler for validation event */ export type ValidationFn< T extends FormValue = FormValue, S extends FormSchemaType = FormSchemaType > = (args: ValidationArgs<T, S>) => void | Promise<void>; /** A map of validation events corresponding to a function. */ export type ObjectValidation< T extends FormValue = FormValue, S extends FormSchemaType = FormSchemaType > = { [k in ValidationTrigger]?: ValidationFn<T, S>; }; type MaybePromise<T> = T | Promise<T>; export type Dispatch<T> = (a: T) => void; export type SetStateAction<T> = T | ((a: T) => T);