react-hook-form
Advanced tools
Comparing version 1.0.1 to 1.1.0-beta.2
@@ -50,8 +50,9 @@ declare type Validate = (data: string | number) => boolean | string | number | Date; | ||
} | ||
declare type Error = { | ||
ref: any; | ||
message: string | boolean; | ||
type: string; | ||
}; | ||
export interface ErrorMessages { | ||
[key: string]: { | ||
ref: any; | ||
message: string | boolean; | ||
type: string; | ||
} | {}; | ||
[key: string]: Error | {}; | ||
} | ||
@@ -58,0 +59,0 @@ export default function useForm({ mode, validationSchema }?: Props): { |
@@ -71,12 +71,13 @@ import { useRef, useState, useEffect } from 'react'; | ||
var validateField = ({ ref, ref: { type, value, name, checked }, options, required, maxLength, minLength, min, max, pattern, validate }, fields) => { | ||
var validateField = async ({ ref, ref: { type, value, name, checked }, options, required, maxLength, minLength, min, max, pattern, validate, }, fields) => { | ||
const copy = {}; | ||
const isRadio = isRadioInput(type); | ||
if (required && | ||
((type === 'checkbox' && !checked) || | ||
(!isRadioInput(type) && type !== 'checkbox' && value === '') || | ||
(isRadioInput(type) && !getRadioValue(fields[name].options).isValid))) { | ||
(!isRadio && type !== 'checkbox' && value === '') || | ||
(isRadio && !getRadioValue(fields[name].options).isValid))) { | ||
copy[name] = { | ||
type: 'required', | ||
message: required, | ||
ref, | ||
ref: isRadio ? fields[name].options[0].ref : ref, | ||
}; | ||
@@ -133,7 +134,7 @@ return copy; | ||
if (validate) { | ||
const fieldValue = isRadioInput(type) ? getRadioValue(options).value : value; | ||
const fieldValue = isRadio ? getRadioValue(options).value : value; | ||
if (typeof validate === 'function') { | ||
const result = validate(fieldValue); | ||
const result = await validate(fieldValue); | ||
if (typeof result !== 'boolean' || !result) { | ||
copy[name] = Object.assign({}, copy[name], { type: 'validate', message: result || true, ref }); | ||
copy[name] = Object.assign({}, copy[name], { type: 'validate', message: result || true, ref: isRadio ? options[0].ref : ref }); | ||
return copy; | ||
@@ -143,15 +144,22 @@ } | ||
else if (typeof validate === 'object') { | ||
const result = Object.entries(validate).reduce((previous, [key, validate]) => { | ||
const result = typeof validate === 'function' && validate(fieldValue); | ||
if (Object.keys(previous).length) | ||
return previous; | ||
if (typeof result !== 'boolean' || !result) { | ||
return { | ||
type: key, | ||
message: result || true, | ||
}; | ||
} | ||
}, {}); | ||
const result = await new Promise(resolve => { | ||
const values = Object.entries(validate); | ||
values.reduce(async (previous, [key, validate], index) => { | ||
const result = typeof validate === 'function' && (await validate(fieldValue)); | ||
const lastChild = values.length - 1 === index; | ||
if (Object.keys(previous).length) | ||
return lastChild ? resolve(previous) : previous; | ||
if (typeof result !== 'boolean' || !result) { | ||
const temp = { | ||
type: key, | ||
message: result || true, | ||
}; | ||
return lastChild ? resolve(temp) : temp; | ||
} | ||
if (lastChild) | ||
return resolve(previous); | ||
}, {}); | ||
}); | ||
if (Object.keys(result).length) { | ||
copy[name] = Object.assign({}, copy[name], { ref }, result); | ||
copy[name] = Object.assign({}, copy[name], { ref: isRadio ? options[0].ref : ref }, result); | ||
return copy; | ||
@@ -261,2 +269,35 @@ } | ||
/*! ***************************************************************************** | ||
Copyright (c) Microsoft Corporation. All rights reserved. | ||
Licensed under the Apache License, Version 2.0 (the "License"); you may not use | ||
this file except in compliance with the License. You may obtain a copy of the | ||
License at http://www.apache.org/licenses/LICENSE-2.0 | ||
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED | ||
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, | ||
MERCHANTABLITY OR NON-INFRINGEMENT. | ||
See the Apache Version 2.0 License for specific language governing permissions | ||
and limitations under the License. | ||
***************************************************************************** */ | ||
function __rest(s, e) { | ||
var t = {}; | ||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) | ||
t[p] = s[p]; | ||
if (s != null && typeof Object.getOwnPropertySymbols === "function") | ||
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) | ||
t[p[i]] = s[p[i]]; | ||
return t; | ||
} | ||
var omitRefs = (errors) => Object.entries(errors).reduce((previous, [key, values]) => { | ||
if (!values.ref) | ||
return previous; | ||
const rest = __rest(values, ["ref"]); | ||
previous[key] = rest; | ||
return previous; | ||
}, {}); | ||
function useForm({ mode, validationSchema } = { | ||
@@ -269,5 +310,5 @@ mode: 'onSubmit', | ||
const [errors, updateErrorMessage] = useState({}); | ||
function validateWithStateUpdate({ target: { name }, type }) { | ||
async function validateWithStateUpdate({ target: { name }, type }) { | ||
const ref = fields.current[name]; | ||
const error = validateField(ref, fields.current); | ||
const error = await validateField(ref, fields.current); | ||
if (localErrorMessages.current[name] !== error[name] || | ||
@@ -356,2 +397,3 @@ mode === 'onChange' || | ||
let values; | ||
let result; | ||
if (validationSchema) { | ||
@@ -369,12 +411,15 @@ values = Object.values(allFields).reduce((previous, { ref }) => { | ||
else { | ||
const result = Object.values(allFields).reduce((previous, data) => { | ||
const allFieldsValues = Object.values(allFields); | ||
result = await new Promise(resolve => allFieldsValues.reduce(async (previous, data, index) => { | ||
const resolvedPrevious = await previous; | ||
const { ref, ref: { name, type }, options, } = data; | ||
const lastChild = allFieldsValues.length - 1 === index; | ||
removeReferenceAndEventListeners(data); | ||
if (!fields.current[name]) | ||
return previous; | ||
const fieldError = validateField(data, allFields); | ||
return lastChild ? resolve(resolvedPrevious) : resolvedPrevious; | ||
const fieldError = await validateField(data, allFields); | ||
const hasError = fieldError && fieldError[name]; | ||
if (!hasError) { | ||
previous.values[name] = getFieldValue(allFields, ref); | ||
return previous; | ||
resolvedPrevious.values[name] = getFieldValue(allFields, ref); | ||
return lastChild ? resolve(resolvedPrevious) : resolvedPrevious; | ||
} | ||
@@ -393,15 +438,15 @@ if (isRadioInput(type) && Array.isArray(options)) { | ||
} | ||
previous.localErrors = Object.assign({}, (previous.localErrors || []), fieldError); | ||
return previous; | ||
}, { | ||
resolvedPrevious.localErrors = Object.assign({}, (resolvedPrevious.localErrors || []), fieldError); | ||
return lastChild ? resolve(resolvedPrevious) : resolvedPrevious; | ||
}, Promise.resolve({ | ||
localErrors: {}, | ||
values: {}, | ||
}); | ||
localErrors = result.localErrors; | ||
values = result.values; | ||
}))); | ||
} | ||
// if (JSON.stringify(localErrorMessages.current) !== JSON.stringify(localErrors)) { | ||
updateErrorMessage(localErrors); | ||
localErrorMessages.current = localErrors; | ||
// } | ||
localErrors = result.localErrors; | ||
values = result.values; | ||
if (JSON.stringify(omitRefs(localErrorMessages.current)) !== JSON.stringify(omitRefs(localErrors))) { | ||
updateErrorMessage(localErrors); | ||
localErrorMessages.current = localErrors; | ||
} | ||
if (!Object.values(localErrors).length) | ||
@@ -408,0 +453,0 @@ callback(values, e); |
@@ -73,12 +73,13 @@ 'use strict'; | ||
var validateField = ({ ref, ref: { type, value, name, checked }, options, required, maxLength, minLength, min, max, pattern, validate }, fields) => { | ||
var validateField = async ({ ref, ref: { type, value, name, checked }, options, required, maxLength, minLength, min, max, pattern, validate, }, fields) => { | ||
const copy = {}; | ||
const isRadio = isRadioInput(type); | ||
if (required && | ||
((type === 'checkbox' && !checked) || | ||
(!isRadioInput(type) && type !== 'checkbox' && value === '') || | ||
(isRadioInput(type) && !getRadioValue(fields[name].options).isValid))) { | ||
(!isRadio && type !== 'checkbox' && value === '') || | ||
(isRadio && !getRadioValue(fields[name].options).isValid))) { | ||
copy[name] = { | ||
type: 'required', | ||
message: required, | ||
ref, | ||
ref: isRadio ? fields[name].options[0].ref : ref, | ||
}; | ||
@@ -135,7 +136,7 @@ return copy; | ||
if (validate) { | ||
const fieldValue = isRadioInput(type) ? getRadioValue(options).value : value; | ||
const fieldValue = isRadio ? getRadioValue(options).value : value; | ||
if (typeof validate === 'function') { | ||
const result = validate(fieldValue); | ||
const result = await validate(fieldValue); | ||
if (typeof result !== 'boolean' || !result) { | ||
copy[name] = Object.assign({}, copy[name], { type: 'validate', message: result || true, ref }); | ||
copy[name] = Object.assign({}, copy[name], { type: 'validate', message: result || true, ref: isRadio ? options[0].ref : ref }); | ||
return copy; | ||
@@ -145,15 +146,22 @@ } | ||
else if (typeof validate === 'object') { | ||
const result = Object.entries(validate).reduce((previous, [key, validate]) => { | ||
const result = typeof validate === 'function' && validate(fieldValue); | ||
if (Object.keys(previous).length) | ||
return previous; | ||
if (typeof result !== 'boolean' || !result) { | ||
return { | ||
type: key, | ||
message: result || true, | ||
}; | ||
} | ||
}, {}); | ||
const result = await new Promise(resolve => { | ||
const values = Object.entries(validate); | ||
values.reduce(async (previous, [key, validate], index) => { | ||
const result = typeof validate === 'function' && (await validate(fieldValue)); | ||
const lastChild = values.length - 1 === index; | ||
if (Object.keys(previous).length) | ||
return lastChild ? resolve(previous) : previous; | ||
if (typeof result !== 'boolean' || !result) { | ||
const temp = { | ||
type: key, | ||
message: result || true, | ||
}; | ||
return lastChild ? resolve(temp) : temp; | ||
} | ||
if (lastChild) | ||
return resolve(previous); | ||
}, {}); | ||
}); | ||
if (Object.keys(result).length) { | ||
copy[name] = Object.assign({}, copy[name], { ref }, result); | ||
copy[name] = Object.assign({}, copy[name], { ref: isRadio ? options[0].ref : ref }, result); | ||
return copy; | ||
@@ -263,2 +271,35 @@ } | ||
/*! ***************************************************************************** | ||
Copyright (c) Microsoft Corporation. All rights reserved. | ||
Licensed under the Apache License, Version 2.0 (the "License"); you may not use | ||
this file except in compliance with the License. You may obtain a copy of the | ||
License at http://www.apache.org/licenses/LICENSE-2.0 | ||
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED | ||
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, | ||
MERCHANTABLITY OR NON-INFRINGEMENT. | ||
See the Apache Version 2.0 License for specific language governing permissions | ||
and limitations under the License. | ||
***************************************************************************** */ | ||
function __rest(s, e) { | ||
var t = {}; | ||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) | ||
t[p] = s[p]; | ||
if (s != null && typeof Object.getOwnPropertySymbols === "function") | ||
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) | ||
t[p[i]] = s[p[i]]; | ||
return t; | ||
} | ||
var omitRefs = (errors) => Object.entries(errors).reduce((previous, [key, values]) => { | ||
if (!values.ref) | ||
return previous; | ||
const rest = __rest(values, ["ref"]); | ||
previous[key] = rest; | ||
return previous; | ||
}, {}); | ||
function useForm({ mode, validationSchema } = { | ||
@@ -271,5 +312,5 @@ mode: 'onSubmit', | ||
const [errors, updateErrorMessage] = react.useState({}); | ||
function validateWithStateUpdate({ target: { name }, type }) { | ||
async function validateWithStateUpdate({ target: { name }, type }) { | ||
const ref = fields.current[name]; | ||
const error = validateField(ref, fields.current); | ||
const error = await validateField(ref, fields.current); | ||
if (localErrorMessages.current[name] !== error[name] || | ||
@@ -358,2 +399,3 @@ mode === 'onChange' || | ||
let values; | ||
let result; | ||
if (validationSchema) { | ||
@@ -371,12 +413,15 @@ values = Object.values(allFields).reduce((previous, { ref }) => { | ||
else { | ||
const result = Object.values(allFields).reduce((previous, data) => { | ||
const allFieldsValues = Object.values(allFields); | ||
result = await new Promise(resolve => allFieldsValues.reduce(async (previous, data, index) => { | ||
const resolvedPrevious = await previous; | ||
const { ref, ref: { name, type }, options, } = data; | ||
const lastChild = allFieldsValues.length - 1 === index; | ||
removeReferenceAndEventListeners(data); | ||
if (!fields.current[name]) | ||
return previous; | ||
const fieldError = validateField(data, allFields); | ||
return lastChild ? resolve(resolvedPrevious) : resolvedPrevious; | ||
const fieldError = await validateField(data, allFields); | ||
const hasError = fieldError && fieldError[name]; | ||
if (!hasError) { | ||
previous.values[name] = getFieldValue(allFields, ref); | ||
return previous; | ||
resolvedPrevious.values[name] = getFieldValue(allFields, ref); | ||
return lastChild ? resolve(resolvedPrevious) : resolvedPrevious; | ||
} | ||
@@ -395,15 +440,15 @@ if (isRadioInput(type) && Array.isArray(options)) { | ||
} | ||
previous.localErrors = Object.assign({}, (previous.localErrors || []), fieldError); | ||
return previous; | ||
}, { | ||
resolvedPrevious.localErrors = Object.assign({}, (resolvedPrevious.localErrors || []), fieldError); | ||
return lastChild ? resolve(resolvedPrevious) : resolvedPrevious; | ||
}, Promise.resolve({ | ||
localErrors: {}, | ||
values: {}, | ||
}); | ||
localErrors = result.localErrors; | ||
values = result.values; | ||
}))); | ||
} | ||
// if (JSON.stringify(localErrorMessages.current) !== JSON.stringify(localErrors)) { | ||
updateErrorMessage(localErrors); | ||
localErrorMessages.current = localErrors; | ||
// } | ||
localErrors = result.localErrors; | ||
values = result.values; | ||
if (JSON.stringify(omitRefs(localErrorMessages.current)) !== JSON.stringify(omitRefs(localErrors))) { | ||
updateErrorMessage(localErrors); | ||
localErrorMessages.current = localErrors; | ||
} | ||
if (!Object.values(localErrors).length) | ||
@@ -410,0 +455,0 @@ callback(values, e); |
@@ -1,5 +0,5 @@ | ||
import { ErrorMessages, Field } from '..'; | ||
declare const _default: ({ ref, ref: { type, value, name, checked }, options, required, maxLength, minLength, min, max, pattern, validate }: Field, fields: { | ||
import { Field } from '..'; | ||
declare const _default: ({ ref, ref: { type, value, name, checked }, options, required, maxLength, minLength, min, max, pattern, validate, }: Field, fields: { | ||
[key: string]: Field; | ||
}) => ErrorMessages; | ||
}) => Promise<{}>; | ||
export default _default; |
{ | ||
"name": "react-hook-form", | ||
"version": "1.0.1", | ||
"version": "1.1.0-beta.2", | ||
"main": "dist/index.js", | ||
@@ -5,0 +5,0 @@ "module": "dist/index.es.js", |
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
48882
34
1103
2