UNPKG

fielder

Version:

A field-first form library for React and React Native

146 lines (126 loc) 3.33 kB
import { FieldsState, FieldState, ValidationTrigger } from '../types'; import { FormAction } from '../useForm'; /** Triggers validation on fields items. */ export const applyValidationToState = ( state: FieldsState, action: FormAction ) => { return Object.keys(state).reduce<{ state: FieldsState; promises: Record<string, Promise<any>>; }>( ({ state, promises }, key) => { const field = state[key]; const validationTrigger = getValidationTriggerForField(action, field); const validationFn = getFieldValidationFn(validationTrigger, field); if (!validationFn || !validationTrigger) { return { state, promises }; } try { const validateResponse = validationFn({ trigger: validationTrigger, value: field.value, form: state, }); if (validateResponse instanceof Promise) { return { promises: { ...promises, [key]: validateResponse, }, state: { ...state, [key]: { ...field, isValidating: true, }, }, }; } return { promises, state: { ...state, [key]: { ...field, isValid: true, isValidating: false, error: undefined, }, }, }; } catch (err: any) { return { promises, state: { ...state, [key]: { ...field, isValid: false, isValidating: false, error: err && err.message ? err.message : err, }, }, }; } }, { state, promises: {} } ); }; const getFieldValidationFn = ( trigger: ValidationTrigger | undefined, field: FieldState ) => { if (!trigger) { return; } if (typeof field._validate === 'function') { return field._validate; } if (typeof field._validate === 'object') { return field._validate[trigger]; } }; /** Return trigger for validation on field (may be undefined) */ const getValidationTriggerForField = ( action: FormAction, field: FieldState ) => { if (!field || !field._isActive || !field._validate) { return; } // Global change - applies to all if (action.type === 'VALIDATE_SUBMISSION') { return 'submit'; } // Global change - applies to all if (action.type === 'SET_FIELD_VALUE' && action.config.name !== field.name) { return 'update'; } // All other actions are field specific if (action.config.name !== field.name) { return; } if (action.type === 'MOUNT_FIELD') { return 'mount'; } if (action.type === 'BLUR_FIELD') { return 'blur'; } if (action.type === 'SET_FIELD_VALUE') { return 'change'; } // On validation update - try to rerun latest field validation trigger if (action.type === 'SET_FIELD_VALIDATION' && field.hasBlurred) { return 'blur'; } if (action.type === 'SET_FIELD_VALIDATION' && field.hasChanged) { return 'change'; } if (action.type === 'SET_FIELD_VALIDATION') { return 'mount'; } if (action.type === 'VALIDATE_FIELD') { return action.config.trigger || 'change'; } };