Socket
Socket
Sign inDemoInstall

react-hook-form

Package Overview
Dependencies
Maintainers
1
Versions
1030
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

react-hook-form - npm Package Compare versions

Comparing version 2.0.3 to 2.1.0-beta.1

dist/logic/combineFieldValues.d.ts

1

dist/index.d.ts

@@ -45,2 +45,3 @@ declare type Validate = (data: string | number) => boolean | string | number | Date;

mutationWatcher?: any;
fields?: Array<any>;
options?: Array<{

@@ -47,0 +48,0 @@ ref: any;

226

dist/index.es.js

@@ -40,3 +40,6 @@ import { useRef, useState, useEffect } from 'react';

function getFieldsValues(fields, filedNames) {
return Object.values(fields).reduce((previous, { ref, ref: { name } }) => {
return Object.values(fields).reduce((previous, data) => {
if (Array.isArray(data))
return;
const { ref, ref: { name } } = data;
const value = getFieldValue(fields, ref);

@@ -82,2 +85,3 @@ if (typeof filedNames === 'string') {

message: required,
// @ts-ignore
ref: isRadio ? fields[name].options[0].ref : ref,

@@ -139,3 +143,3 @@ };

if (typeof result !== 'boolean' || !result) {
copy[name] = Object.assign({}, copy[name], { type: 'validate', message: result || true, ref: isRadio ? options[0].ref : ref });
copy[name] = Object.assign({}, copy[name], { type: 'validate', message: result || true, ref: isRadio && options ? options[0].ref : ref });
return copy;

@@ -164,3 +168,3 @@ }

if (Object.keys(result).length) {
copy[name] = Object.assign({}, copy[name], { ref: isRadio ? options[0].ref : ref }, result);
copy[name] = Object.assign({}, copy[name], { ref: isRadio && options ? options[0].ref : ref }, result);
return copy;

@@ -226,5 +230,5 @@ }

function attachEventListeners({ mode, allFields, watchFields, radioOptionIndex, ref, type, name, validateWithStateUpdate, }) {
const field = allFields[name];
const isOnChange = mode === 'onChange' || watchFields.current[ref.name];
function attachEventListeners({ mode, fields, watchFields, radioOptionIndex, ref, type, name, validateWithStateUpdate, }) {
const field = fields[name];
const isOnChange = mode === 'onChange' || watchFields[ref.name];
const isOnBlur = mode === 'onBlur';

@@ -306,21 +310,77 @@ if (!field || (!isOnChange && !isOnBlur))

async function validateAllFields({ previous, data, index, fieldsLength, resolve, allFields, removeReferenceAndEventListeners, validateWithStateUpdate, }) {
const resolvedPrevious = await previous;
const { ref, ref: { name, type }, options, } = data;
const lastChild = fieldsLength - 1 === index;
removeReferenceAndEventListeners(data);
if (!allFields[name])
return lastChild ? resolve(resolvedPrevious) : resolvedPrevious;
const fieldError = await validateField(data, allFields);
const hasError = fieldError && fieldError[name];
if (!hasError) {
resolvedPrevious.values[name] = getFieldValue(allFields, ref);
return lastChild ? resolve(resolvedPrevious) : resolvedPrevious;
}
if (isRadioInput(type) && Array.isArray(options)) {
options.forEach(option => {
if (option.eventAttached && option.eventAttached.includes('change'))
return;
option.ref.addEventListener('change', validateWithStateUpdate);
option.eventAttached = [...(option.eventAttached || []), 'change'];
});
// @ts-ignore
}
else if (!data.eventAttached || !data.eventAttached.includes('input')) {
ref.addEventListener('input', validateWithStateUpdate);
data.eventAttached = [...(data.eventAttached || []), 'input'];
}
resolvedPrevious.errors = Object.assign({}, (resolvedPrevious.errors || []), fieldError);
return lastChild ? resolve(resolvedPrevious) : resolvedPrevious;
}
function combineFieldValues(data) {
const output = Object.entries(data).reduce((previous, [key, value]) => {
const arrayIndex = key.match(/\[\d+\]$/gi);
if (arrayIndex) {
const index = arrayIndex[0].slice(1, -1);
const filedName = key.substr(0, key.indexOf('['));
if (!previous[filedName])
previous[filedName] = [];
previous[filedName][index] = value;
}
else {
previous[key] = value;
}
return previous;
}, {});
return Object.entries(output).reduce((previous, [key, value]) => {
if (Array.isArray(value)) {
previous[key] = value.filter(Boolean);
return previous;
}
previous[key] = value;
return previous;
}, {});
}
function useForm({ mode, validationSchema } = {
mode: 'onSubmit',
}) {
const fields = useRef({});
const localErrorMessages = useRef({});
const watchFields = useRef({});
const [errors, updateErrorMessage] = useState({});
const fieldsRef = useRef({});
const errorMessagesRef = useRef({});
const watchFieldsRef = useRef({});
const [errors, setErrors] = useState({});
async function validateWithStateUpdate({ target: { name }, type }) {
const ref = fields.current[name];
const error = await validateField(ref, fields.current);
if (localErrorMessages.current[name] !== error[name] ||
const ref = fieldsRef.current[name];
const error = await validateField(ref, fieldsRef.current);
const errorMessage = errorMessagesRef.current;
if (errorMessage[name] !== error[name] ||
mode === 'onChange' ||
(mode === 'onBlur' && type === 'blur') ||
watchFields.current[name]) {
const copy = Object.assign({}, localErrorMessages.current, error);
watchFieldsRef.current[name]) {
const copy = Object.assign({}, errorMessage, error);
if (!error[name])
delete copy[name];
localErrorMessages.current = copy;
updateErrorMessage(copy);
errorMessagesRef.current = copy;
setErrors(copy);
}

@@ -331,3 +391,3 @@ }

target: data,
fields: fields.current,
fields: fieldsRef.current,
validateWithStateUpdate,

@@ -342,14 +402,14 @@ forceDelete,

}
let radioOptionIndex;
const inputData = Object.assign({}, data, { ref: elementRef });
let radioOptionIndex;
const { ref, required, validate, ref: { name, type, value }, } = inputData;
const allFields = fields.current;
const fields = fieldsRef.current;
if (isRadioInput(type)) {
if (!allFields[name]) {
allFields[name] = { options: [], required, validate, ref: { type: 'radio', name } };
if (!fields[name]) {
fields[name] = { options: [], required, validate, ref: { type: 'radio', name } };
}
if (!allFields[name].validate && validate) {
allFields[name].validate = validate;
if (!fields[name].validate && validate) {
fields[name].validate = validate;
}
const options = allFields[name].options || [];
const options = fields[name].options || [];
radioOptionIndex = options.findIndex(({ ref }) => value === ref.value);

@@ -365,11 +425,11 @@ if (radioOptionIndex > -1) {

else {
const isInitialCreate = !allFields[name];
allFields[name] = Object.assign({}, allFields[name], inputData);
const isInitialCreate = !fields[name];
fields[name] = Object.assign({}, fields[name], inputData);
if (isInitialCreate) {
allFields[name].mutationWatcher = onDomRemove(ref, () => removeReferenceAndEventListeners(inputData, true));
fields[name].mutationWatcher = onDomRemove(ref, () => removeReferenceAndEventListeners(inputData, true));
}
}
attachEventListeners({
allFields,
watchFields,
fields,
watchFields: watchFieldsRef,
ref,

@@ -396,23 +456,22 @@ type,

function watch(filedNames, defaultValue) {
const watchFields = watchFieldsRef.current;
if (typeof filedNames === 'string') {
if (!watchFields.current[filedNames])
watchFields.current[filedNames] = true;
if (!watchFields[filedNames])
watchFields[filedNames] = true;
}
else if (Array.isArray(filedNames)) {
filedNames.forEach(name => {
if (!watchFields.current[name])
if (!watchFields[name])
return;
watchFields.current[name] = true;
watchFields[name] = true;
});
}
else {
Object.values(fields.current).forEach(({ ref }) => {
if (!ref)
Object.values(fieldsRef.current).forEach(({ ref }) => {
if (!ref || !watchFields[ref.name])
return;
if (!watchFields.current[ref.name])
return;
watchFields.current[ref.name] = true;
watchFields[ref.name] = true;
});
}
const result = getFieldsValues(fields.current, filedNames);
const result = getFieldsValues(fieldsRef.current, filedNames);
return result === undefined ? defaultValue : result;

@@ -423,14 +482,15 @@ }

e.persist();
const allFields = fields.current;
let localErrors;
let values;
let result;
let fieldErrors;
let fieldValues;
const fields = fieldsRef.current;
const currentFieldValues = Object.values(fields);
const fieldsLength = currentFieldValues.length;
if (validationSchema) {
values = Object.values(allFields).reduce((previous, { ref }) => {
previous[ref.name] = getFieldValue(allFields, ref);
fieldValues = currentFieldValues.reduce((previous, { ref }) => {
previous[ref.name] = getFieldValue(fields, ref);
return previous;
}, {});
localErrors = await validateWithSchema(validationSchema, values);
if (localErrors === undefined) {
callback(values, e);
fieldErrors = await validateWithSchema(validationSchema, fieldValues);
if (fieldErrors === undefined) {
callback(combineFieldValues(fieldValues), e);
return;

@@ -440,54 +500,36 @@ }

else {
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 lastChild ? resolve(resolvedPrevious) : resolvedPrevious;
const fieldError = await validateField(data, allFields);
const hasError = fieldError && fieldError[name];
if (!hasError) {
resolvedPrevious.values[name] = getFieldValue(allFields, ref);
return lastChild ? resolve(resolvedPrevious) : resolvedPrevious;
}
if (isRadioInput(type) && Array.isArray(options)) {
options.forEach(option => {
if (option.eventAttached && option.eventAttached.includes('change'))
return;
option.ref.addEventListener('change', validateWithStateUpdate);
option.eventAttached = [...(option.eventAttached || []), 'change'];
});
// @ts-ignore
}
else if (!fields.current[name].eventAttached || !fields.current[name].eventAttached.includes('input')) {
ref.addEventListener('input', validateWithStateUpdate);
data.eventAttached = [...(data.eventAttached || []), 'input'];
}
resolvedPrevious.localErrors = Object.assign({}, (resolvedPrevious.localErrors || []), fieldError);
return lastChild ? resolve(resolvedPrevious) : resolvedPrevious;
const result = await new Promise(resolve => currentFieldValues.reduce(async (previous, [name, data], index) => {
return await validateAllFields({
previous,
data,
index,
fieldsLength,
allFields: fields,
removeReferenceAndEventListeners,
validateWithStateUpdate,
resolve,
});
}, Promise.resolve({
localErrors: {},
errors: {},
values: {},
})));
localErrors = result.localErrors;
values = result.values;
fieldErrors = result.errors;
fieldValues = result.values;
}
if (JSON.stringify(omitRefs(localErrorMessages.current)) !== JSON.stringify(omitRefs(localErrors))) {
updateErrorMessage(localErrors);
localErrorMessages.current = localErrors;
if (JSON.stringify(omitRefs(errorMessagesRef.current)) !== JSON.stringify(omitRefs(fieldErrors))) {
setErrors(fieldErrors);
errorMessagesRef.current = fieldErrors;
}
if (!Object.values(localErrors).length)
callback(values, e);
if (!Object.values(fieldErrors).length)
callback(combineFieldValues(fieldValues), e);
};
useEffect(() => () => {
fields.current &&
Object.values(fields.current).forEach(({ ref, options }) => isRadioInput(ref.type) && Array.isArray(options)
fieldsRef.current &&
Object.values(fieldsRef.current).forEach(({ ref, options }) => isRadioInput(ref.type) && Array.isArray(options)
? options.forEach(({ ref }) => removeAllEventListeners(ref, validateWithStateUpdate))
: removeAllEventListeners(ref, validateWithStateUpdate));
fields.current = {};
watchFields.current = {};
localErrorMessages.current = {};
updateErrorMessage({});
fieldsRef.current = {};
watchFieldsRef.current = {};
errorMessagesRef.current = {};
setErrors({});
}, [mode]);

@@ -494,0 +536,0 @@ return {

@@ -42,3 +42,6 @@ 'use strict';

function getFieldsValues(fields, filedNames) {
return Object.values(fields).reduce((previous, { ref, ref: { name } }) => {
return Object.values(fields).reduce((previous, data) => {
if (Array.isArray(data))
return;
const { ref, ref: { name } } = data;
const value = getFieldValue(fields, ref);

@@ -84,2 +87,3 @@ if (typeof filedNames === 'string') {

message: required,
// @ts-ignore
ref: isRadio ? fields[name].options[0].ref : ref,

@@ -141,3 +145,3 @@ };

if (typeof result !== 'boolean' || !result) {
copy[name] = Object.assign({}, copy[name], { type: 'validate', message: result || true, ref: isRadio ? options[0].ref : ref });
copy[name] = Object.assign({}, copy[name], { type: 'validate', message: result || true, ref: isRadio && options ? options[0].ref : ref });
return copy;

@@ -166,3 +170,3 @@ }

if (Object.keys(result).length) {
copy[name] = Object.assign({}, copy[name], { ref: isRadio ? options[0].ref : ref }, result);
copy[name] = Object.assign({}, copy[name], { ref: isRadio && options ? options[0].ref : ref }, result);
return copy;

@@ -228,5 +232,5 @@ }

function attachEventListeners({ mode, allFields, watchFields, radioOptionIndex, ref, type, name, validateWithStateUpdate, }) {
const field = allFields[name];
const isOnChange = mode === 'onChange' || watchFields.current[ref.name];
function attachEventListeners({ mode, fields, watchFields, radioOptionIndex, ref, type, name, validateWithStateUpdate, }) {
const field = fields[name];
const isOnChange = mode === 'onChange' || watchFields[ref.name];
const isOnBlur = mode === 'onBlur';

@@ -308,21 +312,77 @@ if (!field || (!isOnChange && !isOnBlur))

async function validateAllFields({ previous, data, index, fieldsLength, resolve, allFields, removeReferenceAndEventListeners, validateWithStateUpdate, }) {
const resolvedPrevious = await previous;
const { ref, ref: { name, type }, options, } = data;
const lastChild = fieldsLength - 1 === index;
removeReferenceAndEventListeners(data);
if (!allFields[name])
return lastChild ? resolve(resolvedPrevious) : resolvedPrevious;
const fieldError = await validateField(data, allFields);
const hasError = fieldError && fieldError[name];
if (!hasError) {
resolvedPrevious.values[name] = getFieldValue(allFields, ref);
return lastChild ? resolve(resolvedPrevious) : resolvedPrevious;
}
if (isRadioInput(type) && Array.isArray(options)) {
options.forEach(option => {
if (option.eventAttached && option.eventAttached.includes('change'))
return;
option.ref.addEventListener('change', validateWithStateUpdate);
option.eventAttached = [...(option.eventAttached || []), 'change'];
});
// @ts-ignore
}
else if (!data.eventAttached || !data.eventAttached.includes('input')) {
ref.addEventListener('input', validateWithStateUpdate);
data.eventAttached = [...(data.eventAttached || []), 'input'];
}
resolvedPrevious.errors = Object.assign({}, (resolvedPrevious.errors || []), fieldError);
return lastChild ? resolve(resolvedPrevious) : resolvedPrevious;
}
function combineFieldValues(data) {
const output = Object.entries(data).reduce((previous, [key, value]) => {
const arrayIndex = key.match(/\[\d+\]$/gi);
if (arrayIndex) {
const index = arrayIndex[0].slice(1, -1);
const filedName = key.substr(0, key.indexOf('['));
if (!previous[filedName])
previous[filedName] = [];
previous[filedName][index] = value;
}
else {
previous[key] = value;
}
return previous;
}, {});
return Object.entries(output).reduce((previous, [key, value]) => {
if (Array.isArray(value)) {
previous[key] = value.filter(Boolean);
return previous;
}
previous[key] = value;
return previous;
}, {});
}
function useForm({ mode, validationSchema } = {
mode: 'onSubmit',
}) {
const fields = react.useRef({});
const localErrorMessages = react.useRef({});
const watchFields = react.useRef({});
const [errors, updateErrorMessage] = react.useState({});
const fieldsRef = react.useRef({});
const errorMessagesRef = react.useRef({});
const watchFieldsRef = react.useRef({});
const [errors, setErrors] = react.useState({});
async function validateWithStateUpdate({ target: { name }, type }) {
const ref = fields.current[name];
const error = await validateField(ref, fields.current);
if (localErrorMessages.current[name] !== error[name] ||
const ref = fieldsRef.current[name];
const error = await validateField(ref, fieldsRef.current);
const errorMessage = errorMessagesRef.current;
if (errorMessage[name] !== error[name] ||
mode === 'onChange' ||
(mode === 'onBlur' && type === 'blur') ||
watchFields.current[name]) {
const copy = Object.assign({}, localErrorMessages.current, error);
watchFieldsRef.current[name]) {
const copy = Object.assign({}, errorMessage, error);
if (!error[name])
delete copy[name];
localErrorMessages.current = copy;
updateErrorMessage(copy);
errorMessagesRef.current = copy;
setErrors(copy);
}

@@ -333,3 +393,3 @@ }

target: data,
fields: fields.current,
fields: fieldsRef.current,
validateWithStateUpdate,

@@ -344,14 +404,14 @@ forceDelete,

}
let radioOptionIndex;
const inputData = Object.assign({}, data, { ref: elementRef });
let radioOptionIndex;
const { ref, required, validate, ref: { name, type, value }, } = inputData;
const allFields = fields.current;
const fields = fieldsRef.current;
if (isRadioInput(type)) {
if (!allFields[name]) {
allFields[name] = { options: [], required, validate, ref: { type: 'radio', name } };
if (!fields[name]) {
fields[name] = { options: [], required, validate, ref: { type: 'radio', name } };
}
if (!allFields[name].validate && validate) {
allFields[name].validate = validate;
if (!fields[name].validate && validate) {
fields[name].validate = validate;
}
const options = allFields[name].options || [];
const options = fields[name].options || [];
radioOptionIndex = options.findIndex(({ ref }) => value === ref.value);

@@ -367,11 +427,11 @@ if (radioOptionIndex > -1) {

else {
const isInitialCreate = !allFields[name];
allFields[name] = Object.assign({}, allFields[name], inputData);
const isInitialCreate = !fields[name];
fields[name] = Object.assign({}, fields[name], inputData);
if (isInitialCreate) {
allFields[name].mutationWatcher = onDomRemove(ref, () => removeReferenceAndEventListeners(inputData, true));
fields[name].mutationWatcher = onDomRemove(ref, () => removeReferenceAndEventListeners(inputData, true));
}
}
attachEventListeners({
allFields,
watchFields,
fields,
watchFields: watchFieldsRef,
ref,

@@ -398,23 +458,22 @@ type,

function watch(filedNames, defaultValue) {
const watchFields = watchFieldsRef.current;
if (typeof filedNames === 'string') {
if (!watchFields.current[filedNames])
watchFields.current[filedNames] = true;
if (!watchFields[filedNames])
watchFields[filedNames] = true;
}
else if (Array.isArray(filedNames)) {
filedNames.forEach(name => {
if (!watchFields.current[name])
if (!watchFields[name])
return;
watchFields.current[name] = true;
watchFields[name] = true;
});
}
else {
Object.values(fields.current).forEach(({ ref }) => {
if (!ref)
Object.values(fieldsRef.current).forEach(({ ref }) => {
if (!ref || !watchFields[ref.name])
return;
if (!watchFields.current[ref.name])
return;
watchFields.current[ref.name] = true;
watchFields[ref.name] = true;
});
}
const result = getFieldsValues(fields.current, filedNames);
const result = getFieldsValues(fieldsRef.current, filedNames);
return result === undefined ? defaultValue : result;

@@ -425,14 +484,15 @@ }

e.persist();
const allFields = fields.current;
let localErrors;
let values;
let result;
let fieldErrors;
let fieldValues;
const fields = fieldsRef.current;
const currentFieldValues = Object.values(fields);
const fieldsLength = currentFieldValues.length;
if (validationSchema) {
values = Object.values(allFields).reduce((previous, { ref }) => {
previous[ref.name] = getFieldValue(allFields, ref);
fieldValues = currentFieldValues.reduce((previous, { ref }) => {
previous[ref.name] = getFieldValue(fields, ref);
return previous;
}, {});
localErrors = await validateWithSchema(validationSchema, values);
if (localErrors === undefined) {
callback(values, e);
fieldErrors = await validateWithSchema(validationSchema, fieldValues);
if (fieldErrors === undefined) {
callback(combineFieldValues(fieldValues), e);
return;

@@ -442,54 +502,36 @@ }

else {
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 lastChild ? resolve(resolvedPrevious) : resolvedPrevious;
const fieldError = await validateField(data, allFields);
const hasError = fieldError && fieldError[name];
if (!hasError) {
resolvedPrevious.values[name] = getFieldValue(allFields, ref);
return lastChild ? resolve(resolvedPrevious) : resolvedPrevious;
}
if (isRadioInput(type) && Array.isArray(options)) {
options.forEach(option => {
if (option.eventAttached && option.eventAttached.includes('change'))
return;
option.ref.addEventListener('change', validateWithStateUpdate);
option.eventAttached = [...(option.eventAttached || []), 'change'];
});
// @ts-ignore
}
else if (!fields.current[name].eventAttached || !fields.current[name].eventAttached.includes('input')) {
ref.addEventListener('input', validateWithStateUpdate);
data.eventAttached = [...(data.eventAttached || []), 'input'];
}
resolvedPrevious.localErrors = Object.assign({}, (resolvedPrevious.localErrors || []), fieldError);
return lastChild ? resolve(resolvedPrevious) : resolvedPrevious;
const result = await new Promise(resolve => currentFieldValues.reduce(async (previous, [name, data], index) => {
return await validateAllFields({
previous,
data,
index,
fieldsLength,
allFields: fields,
removeReferenceAndEventListeners,
validateWithStateUpdate,
resolve,
});
}, Promise.resolve({
localErrors: {},
errors: {},
values: {},
})));
localErrors = result.localErrors;
values = result.values;
fieldErrors = result.errors;
fieldValues = result.values;
}
if (JSON.stringify(omitRefs(localErrorMessages.current)) !== JSON.stringify(omitRefs(localErrors))) {
updateErrorMessage(localErrors);
localErrorMessages.current = localErrors;
if (JSON.stringify(omitRefs(errorMessagesRef.current)) !== JSON.stringify(omitRefs(fieldErrors))) {
setErrors(fieldErrors);
errorMessagesRef.current = fieldErrors;
}
if (!Object.values(localErrors).length)
callback(values, e);
if (!Object.values(fieldErrors).length)
callback(combineFieldValues(fieldValues), e);
};
react.useEffect(() => () => {
fields.current &&
Object.values(fields.current).forEach(({ ref, options }) => isRadioInput(ref.type) && Array.isArray(options)
fieldsRef.current &&
Object.values(fieldsRef.current).forEach(({ ref, options }) => isRadioInput(ref.type) && Array.isArray(options)
? options.forEach(({ ref }) => removeAllEventListeners(ref, validateWithStateUpdate))
: removeAllEventListeners(ref, validateWithStateUpdate));
fields.current = {};
watchFields.current = {};
localErrorMessages.current = {};
updateErrorMessage({});
fieldsRef.current = {};
watchFieldsRef.current = {};
errorMessagesRef.current = {};
setErrors({});
}, [mode]);

@@ -496,0 +538,0 @@ return {

@@ -1,4 +0,4 @@

export default function attachEventListeners({ mode, allFields, watchFields, radioOptionIndex, ref, type, name, validateWithStateUpdate, }: {
export default function attachEventListeners({ mode, fields, watchFields, radioOptionIndex, ref, type, name, validateWithStateUpdate, }: {
mode: any;
allFields: any;
fields: any;
watchFields: any;

@@ -5,0 +5,0 @@ radioOptionIndex: any;

@@ -12,2 +12,3 @@ ## Examples

| Async Submit Validation | https://codesandbox.io/s/xrjv48o0qp |
| Array Fields | https://codesandbox.io/s/6j1760jkjk |
| Async Field Validation | https://codesandbox.io/s/m5pj55yj7x |

@@ -14,0 +15,0 @@ | Normalize/Format/Mask Field | https://codesandbox.io/s/387z7njwzp |

{
"name": "react-hook-form",
"version": "2.0.3",
"version": "2.1.0-beta.1",
"main": "dist/index.js",

@@ -5,0 +5,0 @@ "module": "dist/index.es.js",

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc