import React, { useCallback, useContext, useEffect, useMemo, useReducer } from 'react';
import SimpleReactValidator from 'simple-react-validator';
const ValidatorContext = React.createContext(null as any);
const ValidatorOptions = React.createContext(null as any);
export function ValidatorOptionProvider({ value, children }) {
const previousOptions = useContext(ValidatorOptions);
const combinedOptions = useMemo(() => ({
...(previousOptions || {}),
...(value || {}),
messages: {
...((previousOptions || {}).messages || {}),
...((value || {}).messages || {})
},
validators: {
...((previousOptions || {}).validators || {}),
...((value || {}).validators || {})
}
}), [value, previousOptions]);
return
{ children }
;
}
export function useValidator() {
return useContext(ValidatorContext)[0];
}
export function useValidate(name: string|null, value:any = null, type:any = null) {
const validator = useValidator();
useEffect(function() {
if (validator && name) {
return function() {
delete validator.fields[name];
delete validator.errorMessages[name];
};
}
}, [ validator, name ]);
return validator.message(name, value, type || []);
}
export function ValidatorProvider({ children }) {
const options = useContext(ValidatorOptions);
const [,forceUpdate] = useReducer(x => ++x, 0);
const validator = useMemo(() => new SimpleReactValidator({ ...options, autoForceUpdate: { forceUpdate }}), [options, forceUpdate]);
const state = useMemo(() => ([validator, validator.messagesShown]), [validator, validator.messagesShown]);
const handleSubmit = useCallback(function(e: Event) {
if (!validator.allValid()) {
e.preventDefault();
e.stopPropagation();
if (!validator.messagesShown) {
validator.showMessages();
forceUpdate();
}
return ;
}
if (validator.messagesShown) {
validator.hideMessages();
forceUpdate();
}
children.props.onSubmit && children.props.onSubmit(e);
}, [validator, children.props.onSubmit, forceUpdate]);
return
{ React.cloneElement(children, { onSubmit: handleSubmit }) }
;
}