boonya/react-hook-form-validation

View on GitHub
src/useValidation.ts

Summary

Maintainability
A
1 hr
Test Coverage
A
100%
import { createDefaultValidity, processFormValidity, processFieldValidity, validateRuleSet } from './helpers';
import createProcessor from './processor';
import {
    ValidationRuleSet,
    FormPayload,
    FormValidity,
    HookResult,
    Processor,
    ValidateFormFunction,
    ValidateFieldFunction,
    ResetFormFunction,
} from './types';
import isPlainObject from 'lodash/isPlainObject';
import React from 'react';

export default function useValidation(ruleset: ValidationRuleSet): HookResult {
    validateRuleSet(ruleset);

    const processor = React.useMemo<Processor>(() => createProcessor(ruleset), [ruleset]);
    const defaultValidity = React.useMemo<FormValidity>(() => createDefaultValidity(ruleset), [ruleset]);

    const [currentValidity, setValidity] = React.useState<FormValidity>(defaultValidity);

    const validateForm = React.useCallback<ValidateFormFunction>(async (payload: FormPayload) => {
        if (!isPlainObject(payload)) {
            throw new Error('You have to pass a form payload object to validate the form.');
        }
        const validity = await processFormValidity(processor, currentValidity, payload);
        setValidity(validity);
        return validity;
    }, [processor, currentValidity]);

    const validateField = React.useCallback<ValidateFieldFunction>(async (payload: FormPayload, name: string, index = 0) => {
        if (!isPlainObject(payload)) {
            throw new Error('You have to pass a form payload object to validate the field.');
        }
        if (typeof name !== 'string' || name.trim() === '') {
            throw new Error('You have to pass a field name to validate the field.');
        }
        const validity = await processFieldValidity(processor, currentValidity, payload, name, index);
        setValidity(validity);
        return validity;
    }, [currentValidity, processor]);

    const resetForm = React.useCallback<ResetFormFunction>(() => {
        setValidity(defaultValidity);
        return defaultValidity;
    }, [defaultValidity]);

    return {
        validateForm,
        validateField,
        validity: currentValidity,
        resetForm,
    };
}